Merge branch 'dev'

# Conflicts:
#	doc/pig.sql
This commit is contained in:
冷冷 2018-05-22 21:24:39 +08:00
commit 209cca47bb
63 changed files with 1307 additions and 409 deletions

View File

@ -124,6 +124,3 @@ pig
<td><img src="http://p3blpcsde.bkt.clouddn.com/17.png"/></td>
</tr>
</table>

File diff suppressed because one or more lines are too long

View File

@ -37,6 +37,27 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!--MySQL-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--tomcat-jdbc排除 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--HikariCP连接池-->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</dependency>
</dependencies>
<build>

View File

@ -2,6 +2,7 @@ package com.github.pig.auth.component.mobile;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pig.common.constant.CommonConstant;
import com.github.pig.common.util.AuthUtils;
import com.xiaoleilu.hutool.map.MapUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -54,7 +55,7 @@ public class MobileLoginSuccessHandler implements AuthenticationSuccessHandler {
}
try {
String[] tokens = extractAndDecodeHeader(header);
String[] tokens = AuthUtils.extractAndDecodeHeader(header);
assert tokens.length == 2;
String clientId = tokens[0];
@ -76,33 +77,6 @@ public class MobileLoginSuccessHandler implements AuthenticationSuccessHandler {
}
}
/**
* Decodes the header into a username and password.
*
* @throws BadCredentialsException if the Basic header is not present or is not valid
* Base64
*/
private String[] extractAndDecodeHeader(String header)
throws IOException {
byte[] base64Token = header.substring(6).getBytes("UTF-8");
byte[] decoded;
try {
decoded = Base64.decode(base64Token);
} catch (IllegalArgumentException e) {
throw new BadCredentialsException(
"Failed to decode basic authentication token");
}
String token = new String(decoded, CommonConstant.UTF8);
int delim = token.indexOf(":");
if (delim == -1) {
throw new BadCredentialsException("Invalid basic authentication token");
}
return new String[]{token.substring(0, delim), token.substring(delim + 1)};
}
}

View File

@ -1,40 +0,0 @@
package com.github.pig.auth.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* @author lengleng
* @date 2017/10/28
*/
@Configuration
@ConfigurationProperties(prefix = "pig.auth")
public class AuthServerConfig {
private String clientId;
private String clientSecret;
private String scope;
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getClientSecret() {
return clientSecret;
}
public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
}
public String getScope() {
return scope;
}
public void setScope(String scope) {
this.scope = scope;
}
}

View File

@ -17,12 +17,14 @@ import org.springframework.security.oauth2.config.annotation.web.configuration.A
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
import javax.sql.DataSource;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@ -37,9 +39,8 @@ import java.util.Map;
@Order(Integer.MIN_VALUE)
@EnableAuthorizationServer
public class PigAuthorizationConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthServerConfig authServerConfig;
private DataSource dataSource;
@Autowired
private AuthenticationManager authenticationManager;
@ -52,12 +53,10 @@ public class PigAuthorizationConfig extends AuthorizationServerConfigurerAdapter
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient(authServerConfig.getClientId())
.secret(authServerConfig.getClientSecret())
.authorizedGrantTypes(SecurityConstants.REFRESH_TOKEN, SecurityConstants.PASSWORD, SecurityConstants.AUTHORIZATION_CODE)
.scopes(authServerConfig.getScope())
.autoApprove(true);
JdbcClientDetailsService clientDetailsService = new JdbcClientDetailsService(dataSource);
clientDetailsService.setSelectClientDetailsSql(SecurityConstants.DEFAULT_SELECT_STATEMENT);
clientDetailsService.setFindClientDetailsSql(SecurityConstants.DEFAULT_FIND_STATEMENT);
clients.withClientDetails(clientDetailsService);
}
@Override

View File

@ -1,7 +1,7 @@
package com.github.pig.auth.config;
import com.github.pig.auth.component.mobile.MobileSecurityConfigurer;
import com.github.pig.common.bean.config.FilterUrlsPropertiesConfig;
import com.github.pig.common.bean.config.FilterIgnorePropertiesConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.context.annotation.Configuration;
@ -20,7 +20,7 @@ import org.springframework.security.config.annotation.web.configurers.Expression
@EnableWebSecurity
public class PigSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
@Autowired
private FilterUrlsPropertiesConfig filterUrlsPropertiesConfig;
private FilterIgnorePropertiesConfig filterIgnorePropertiesConfig;
@Autowired
private MobileSecurityConfigurer mobileSecurityConfigurer;
@ -31,9 +31,7 @@ public class PigSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
.loginProcessingUrl("/authentication/form")
.and()
.authorizeRequests();
for (String url : filterUrlsPropertiesConfig.getAnon()) {
registry.antMatchers(url).permitAll();
}
filterIgnorePropertiesConfig.getUrls().forEach(url -> registry.antMatchers(url).permitAll());
registry.anyRequest().authenticated()
.and()
.csrf().disable();

View File

@ -11,7 +11,6 @@ spring:
enabled: true
profile: ${spring.profiles.active}
label: ${spring.profiles.active}
---
spring:
profiles: dev

View File

@ -1,7 +1,9 @@
package com.github.pig.common.bean.config;
import lombok.Data;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
@ -11,17 +13,13 @@ import java.util.List;
* @author lengleng
* @date 2018/1/9
*/
@Data
@Configuration
@ConditionalOnExpression("!'${urls}'.isEmpty()")
@ConfigurationProperties(prefix = "urls")
public class FilterUrlsPropertiesConfig {
private List<String> anon = new ArrayList<>();
@RefreshScope
@ConditionalOnExpression("!'${ignore}'.isEmpty()")
@ConfigurationProperties(prefix = "ignore")
public class FilterIgnorePropertiesConfig {
private List<String> urls = new ArrayList<>();
public List<String> getAnon() {
return anon;
}
public void setAnon(List<String> anon) {
this.anon = anon;
}
private List<String> clients = new ArrayList<>();
}

View File

@ -62,4 +62,9 @@ public interface CommonConstant {
* 阿里大鱼
*/
String ALIYUN_SMS = "aliyun_sms";
/**
* 路由信息Redis保存的key
*/
String ROUTE_KEY = "_ROUTE_KEY";
}

View File

@ -30,4 +30,9 @@ public interface MqQueueConstant {
* zipkin 队列
*/
String ZIPKIN_NAME_QUEUE = "zipkin";
/**
* 路由配置状态队列
*/
String ROUTE_CONFIG_CHANGE = "route_config_change";
}

View File

@ -62,12 +62,12 @@ public interface SecurityConstants {
/**
* 默认生成图形验证码宽度
*/
String DEFAULT_IMAGE_WIDTH = "150";
String DEFAULT_IMAGE_WIDTH = "100";
/**
* 默认生成图像验证码高度
*/
String DEFAULT_IMAGE_HEIGHT = "32";
String DEFAULT_IMAGE_HEIGHT = "40";
/**
* 默认生成图形验证码长度
@ -114,4 +114,28 @@ public interface SecurityConstants {
* 默认的social的注册地址
*/
String DEFAULT_SOCIAL_SIGNUP_URL = "/social/signup";
/**
* sys_oauth_client_details 表的字段不包括client_idclient_secret
*/
String CLIENT_FIELDS = "client_id, client_secret, resource_ids, scope, "
+ "authorized_grant_types, web_server_redirect_uri, authorities, access_token_validity, "
+ "refresh_token_validity, additional_information, autoapprove";
/**
*JdbcClientDetailsService 查询语句
*/
String BASE_FIND_STATEMENT = "select " + CLIENT_FIELDS
+ " from sys_oauth_client_details";
/**
* 默认的查询语句
*/
String DEFAULT_FIND_STATEMENT = BASE_FIND_STATEMENT + " order by client_id";
/**
* 按条件client_id 查询
*/
String DEFAULT_SELECT_STATEMENT = BASE_FIND_STATEMENT + " where client_id = ?";
}

View File

@ -0,0 +1,39 @@
package com.github.pig.common.constant.enums;
import lombok.Getter;
import lombok.Setter;
/**
* @author LiXunHuan
* @date 2018/1/16
* 短信通道模板
*/
public enum EnumSmsChannelTemplate {
/**
* 登录验证
*/
LOGIN_NAME_LOGIN("loginCodeChannel", "登录验证"),
/**
* 服务异常提醒
*/
SERVICE_STATUS_CHANGE("serviceStatusChange", "Pig4Cloud");
/**
* 模板名称
*/
@Getter
@Setter
private String template;
/**
* 模板签名
*/
@Getter
@Setter
private String signName;
EnumSmsChannelTemplate(String template, String signName) {
this.template = template;
this.signName = signName;
}
}

View File

@ -0,0 +1,85 @@
package com.github.pig.common.entity;
import com.baomidou.mybatisplus.enums.IdType;
import java.util.Date;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.activerecord.Model;
import com.baomidou.mybatisplus.annotations.TableName;
import lombok.Data;
import java.io.Serializable;
/**
* <p>
* 动态路由配置表
* </p>
*
* @author lengleng
* @since 2018-05-15
*/
@Data
@TableName("sys_zuul_route")
public class SysZuulRoute extends Model<SysZuulRoute> {
private static final long serialVersionUID = 1L;
/**
* router Id
*/
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
/**
* 路由路径
*/
private String path;
/**
* 服务名称
*/
@TableField("service_id")
private String serviceId;
/**
* url代理
*/
private String url;
/**
* 转发去掉前缀
*/
@TableField("strip_prefix")
private String stripPrefix;
/**
* 是否重试
*/
private String retryable;
/**
* 是否启用
*/
private String enabled;
/**
* 敏感请求头
*/
@TableField("sensitiveHeaders_list")
private String sensitiveheadersList;
/**
* 创建时间
*/
@TableField("create_time")
private Date createTime;
/**
* 更新时间
*/
@TableField("update_time")
private Date updateTime;
/**
* 删除标识0-正常,1-删除
*/
@TableField("del_flag")
private String delFlag;
@Override
protected Serializable pkVal() {
return this.id;
}
}

View File

@ -0,0 +1,82 @@
package com.github.pig.common.util;
import com.github.pig.common.constant.CommonConstant;
import com.github.pig.common.util.exception.CheckedException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.codec.Base64;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* @author lengleng
* @date 2018/5/13
* 认证授权相关工具类
*/
@Slf4j
public class AuthUtils {
private static final String BASIC_ = "Basic ";
/**
* 从header 请求中的clientId/clientsecect
*
* @param header header中的参数
* @throws CheckedException if the Basic header is not present or is not valid
* Base64
*/
public static String[] extractAndDecodeHeader(String header)
throws IOException {
byte[] base64Token = header.substring(6).getBytes("UTF-8");
byte[] decoded;
try {
decoded = Base64.decode(base64Token);
} catch (IllegalArgumentException e) {
throw new CheckedException(
"Failed to decode basic authentication token");
}
String token = new String(decoded, CommonConstant.UTF8);
int delim = token.indexOf(":");
if (delim == -1) {
throw new CheckedException("Invalid basic authentication token");
}
return new String[]{token.substring(0, delim), token.substring(delim + 1)};
}
/**
* *从header 请求中的clientId/clientsecect
*
* @param request
* @return
* @throws IOException
*/
public static String[] extractAndDecodeHeader(HttpServletRequest request)
throws IOException {
String header = request.getHeader("Authorization");
if (header == null || !header.startsWith(BASIC_)) {
throw new CheckedException("请求头中client信息为空");
}
byte[] base64Token = header.substring(6).getBytes("UTF-8");
byte[] decoded;
try {
decoded = Base64.decode(base64Token);
} catch (IllegalArgumentException e) {
throw new CheckedException(
"Failed to decode basic authentication token");
}
String token = new String(decoded, CommonConstant.UTF8);
int delim = token.indexOf(":");
if (delim == -1) {
throw new CheckedException("Invalid basic authentication token");
}
return new String[]{token.substring(0, delim), token.substring(delim + 1)};
}
}

View File

@ -16,17 +16,32 @@ public class MobileMsgTemplate implements Serializable {
*/
private String mobile;
/**
* 文本
* 组装后的模板内容JSON字符串
*/
private String text;
private String context;
/**
* 类型通道
* 短信通道
*/
private String channel;
/**
* 短信类型(验证码或者通知短信)
* 暂时不用留着后面存数据库备用吧
*/
private String type;
/**
* 短信签名
*/
private String signName;
/**
* 短信模板
*/
private String template;
public MobileMsgTemplate(String mobile, String text, String type) {
public MobileMsgTemplate(String mobile, String context, String channel, String signName, String template){
this.mobile = mobile;
this.text = text;
this.type = type;
this.context = context;
this.channel = channel;
this.signName = signName;
this.template = template;
}
}

View File

@ -64,5 +64,5 @@ public class UserVO implements Serializable {
/**
* 角色列表
*/
private List<SysRole> roleList = new ArrayList<>();
private List<SysRole> roleList;
}

View File

@ -39,7 +39,7 @@
</appender>
<!-- Level: FATAL 0 ERROR 3 WARN 4 INFO 6 DEBUG 7 -->
<root level="WARN">
<root level="INFO">
<appender-ref ref="console" />
<appender-ref ref="debug" />
<appender-ref ref="error" />

View File

@ -24,7 +24,7 @@ endpoints:
spring:
profiles: dev
rabbitmq:
host: 127.0.0.1
host: 139.224.200.249
port: 5682
username: pig
password: lengleng

View File

@ -44,11 +44,6 @@
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<!--rabbitMQ-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<!--swagger ui-->
<dependency>
<groupId>io.springfox</groupId>

View File

@ -1,7 +1,9 @@
package com.github.pig.gateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
@ -9,6 +11,7 @@ import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.web.client.RestTemplate;
/**
* @author lengleng
@ -42,4 +45,9 @@ public class PigGatewayApplication {
LoadBalancerInterceptor loadBalancerInterceptor(LoadBalancerClient loadBalance){
return new LoadBalancerInterceptor(loadBalance);
}
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}

View File

@ -0,0 +1,41 @@
package com.github.pig.gateway.component.config;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.serviceregistry.Registration;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
/**
* @author lengleng
* @date 2018/5/15
* 动态路由配置类
*/
@Configuration
public class DynamicRouteConfiguration {
private Registration registration;
private DiscoveryClient discovery;
private ZuulProperties zuulProperties;
private ServerProperties server;
private RedisTemplate redisTemplate;
public DynamicRouteConfiguration(Registration registration, DiscoveryClient discovery,
ZuulProperties zuulProperties, ServerProperties server, RedisTemplate redisTemplate) {
this.registration = registration;
this.discovery = discovery;
this.zuulProperties = zuulProperties;
this.server = server;
this.redisTemplate = redisTemplate;
}
@Bean
public DynamicRouteLocator dynamicRouteLocator() {
return new DynamicRouteLocator(server.getServletPrefix()
, discovery
, zuulProperties
, registration
, redisTemplate);
}
}

View File

@ -0,0 +1,111 @@
package com.github.pig.gateway.component.config;
import com.github.pig.common.constant.CommonConstant;
import com.github.pig.common.entity.SysZuulRoute;
import com.xiaoleilu.hutool.collection.CollUtil;
import com.xiaoleilu.hutool.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocator;
import org.springframework.data.redis.core.RedisTemplate;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author lengleng
* @date 2018/5/15
* 动态路由实现
*/
@Slf4j
public class DynamicRouteLocator extends DiscoveryClientRouteLocator {
private ZuulProperties properties;
private RedisTemplate redisTemplate;
public DynamicRouteLocator(String servletPath, DiscoveryClient discovery, ZuulProperties properties,
ServiceInstance localServiceInstance, RedisTemplate redisTemplate) {
super(servletPath, discovery, properties, localServiceInstance);
this.properties = properties;
this.redisTemplate = redisTemplate;
}
/**
* 重写路由配置
* <p>
* 1. properties 配置
* 2. eureka 默认配置
* 3. DB数据库配置
*
* @return 路由表
*/
@Override
protected LinkedHashMap<String, ZuulProperties.ZuulRoute> locateRoutes() {
LinkedHashMap<String, ZuulProperties.ZuulRoute> routesMap = new LinkedHashMap<>();
//读取properties配置eureka默认配置
routesMap.putAll(super.locateRoutes());
log.debug("初始默认的路由配置完成");
routesMap.putAll(locateRoutesFromDb());
LinkedHashMap<String, ZuulProperties.ZuulRoute> values = new LinkedHashMap<>();
for (Map.Entry<String, ZuulProperties.ZuulRoute> entry : routesMap.entrySet()) {
String path = entry.getKey();
if (!path.startsWith("/")) {
path = "/" + path;
}
if (StrUtil.isNotBlank(this.properties.getPrefix())) {
path = this.properties.getPrefix() + path;
if (!path.startsWith("/")) {
path = "/" + path;
}
}
values.put(path, entry.getValue());
}
return routesMap;
}
/**
* Redis中保存的没有从upms拉去避免启动链路依赖问题取舍网关依赖业务模块的问题
*
* @return
*/
private Map<String, ZuulProperties.ZuulRoute> locateRoutesFromDb() {
Map<String, ZuulProperties.ZuulRoute> routes = new LinkedHashMap<>();
Object obj = redisTemplate.opsForValue().get(CommonConstant.ROUTE_KEY);
if (obj == null) {
return routes;
}
List<SysZuulRoute> results = (List<SysZuulRoute>) obj;
for (SysZuulRoute result : results) {
if (StrUtil.isBlank(result.getPath()) && StrUtil.isBlank(result.getUrl())) {
continue;
}
ZuulProperties.ZuulRoute zuulRoute = new ZuulProperties.ZuulRoute();
try {
zuulRoute.setId(result.getServiceId());
zuulRoute.setPath(result.getPath());
zuulRoute.setServiceId(result.getServiceId());
zuulRoute.setRetryable(StrUtil.equals(result.getRetryable(), "0") ? Boolean.FALSE : Boolean.TRUE);
zuulRoute.setStripPrefix(StrUtil.equals(result.getStripPrefix(), "0") ? Boolean.FALSE : Boolean.TRUE);
zuulRoute.setUrl(result.getUrl());
List<String> sensitiveHeadersList = StrUtil.splitTrim(result.getSensitiveheadersList(), ",");
if (sensitiveHeadersList != null) {
Set<String> sensitiveHeaderSet = CollUtil.newHashSet();
sensitiveHeadersList.forEach(sensitiveHeader -> sensitiveHeaderSet.add(sensitiveHeader));
zuulRoute.setSensitiveHeaders(sensitiveHeaderSet);
zuulRoute.setCustomSensitiveHeaders(true);
}
} catch (Exception e) {
log.error("从数据库加载路由配置异常", e);
}
log.debug("添加数据库自定义的路由配置,path{}serviceId:{}", zuulRoute.getPath(), zuulRoute.getServiceId());
routes.put(zuulRoute.getPath(), zuulRoute);
}
return routes;
}
}

View File

@ -1,7 +1,6 @@
package com.github.pig.gateway.component.config;
import com.github.pig.common.bean.config.FilterUrlsPropertiesConfig;
import com.github.pig.gateway.component.filter.ValidateCodeFilter;
import com.github.pig.common.bean.config.FilterIgnorePropertiesConfig;
import com.github.pig.gateway.component.handler.PigAccessDeniedHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
@ -15,7 +14,7 @@ import org.springframework.security.oauth2.config.annotation.web.configuration.E
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.expression.OAuth2WebSecurityExpressionHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
/**
* @author lengleng
* @date 2017/10/27
@ -24,24 +23,19 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthentic
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Autowired
private FilterUrlsPropertiesConfig filterUrlsPropertiesConfig;
private FilterIgnorePropertiesConfig filterIgnorePropertiesConfig;
@Autowired
private OAuth2WebSecurityExpressionHandler expressionHandler;
@Autowired
private PigAccessDeniedHandler pigAccessDeniedHandler;
@Autowired
private ValidateCodeFilter validateCodeFilter;
@Override
public void configure(HttpSecurity http) throws Exception {
//http.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class);
//允许使用iframe 嵌套避免swagger-ui 不被加载的问题
http.headers().frameOptions().disable();
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = http
.authorizeRequests();
for (String url : filterUrlsPropertiesConfig.getAnon()) {
registry.antMatchers(url).permitAll();
}
filterIgnorePropertiesConfig.getUrls().forEach(url -> registry.antMatchers(url).permitAll());
registry.anyRequest()
.access("@permissionService.hasPermission(request,authentication)");
}

View File

@ -15,8 +15,10 @@ import com.xiaoleilu.hutool.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
@ -32,12 +34,11 @@ import static org.springframework.cloud.netflix.zuul.filters.support.FilterConst
* 演示环境控制
*/
@Slf4j
@Component
@RefreshScope
@Configuration
@ConditionalOnProperty(value = "security.validate.preview", havingValue = "true")
public class PreviewFilter extends ZuulFilter {
private static final String TOKEN = "token";
@Value("${security.validate.preview:true}")
private boolean isPreview;
@Override
public String filterType() {
@ -53,15 +54,14 @@ public class PreviewFilter extends ZuulFilter {
public boolean shouldFilter() {
HttpServletRequest request = RequestContext.getCurrentContext().getRequest();
if (StrUtil.equalsIgnoreCase(request.getMethod(), HttpMethod.GET.name()) ||
StrUtil.containsIgnoreCase(request.getRequestURI(), TOKEN)) {
return false;
StrUtil.containsIgnoreCase(request.getRequestURI(), TOKEN)){
return false;
}
return isPreview;
return true;
}
@Override
public Object run() {
log.warn("演示环境,没有权限操作 -> {}", isPreview);
RequestContext ctx = RequestContext.getCurrentContext();
R<String> result = new R<>();
result.setCode(479);

View File

@ -1,39 +1,44 @@
package com.github.pig.gateway.component.filter;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pig.common.bean.config.FilterIgnorePropertiesConfig;
import com.github.pig.common.constant.SecurityConstants;
import com.github.pig.common.util.AuthUtils;
import com.github.pig.common.util.R;
import com.github.pig.common.util.exception.ValidateCodeException;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.xiaoleilu.hutool.collection.CollUtil;
import com.xiaoleilu.hutool.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Arrays;
/**
* @author lengleng
* @date 2018/5/10
* 验证码校验true开启false关闭校验
* 更细化可以 clientId 进行区分
* <p>
* security.validate.code.enabled 默认 为false开启需要设置为true
*/
@Slf4j
@RefreshScope
@Component("validateCodeFilter")
@Configuration("validateCodeFilter")
@ConditionalOnProperty(value = "security.validate.code", havingValue = "true")
public class ValidateCodeFilter extends ZuulFilter {
private static final String EXPIRED_CAPTCHA_ERROR = "验证码已过期,请重新获取";
@Value("${security.validate.code:true}")
private boolean isValidate;
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private FilterIgnorePropertiesConfig filterIgnorePropertiesConfig;
@Override
public String filterType() {
@ -45,14 +50,33 @@ public class ValidateCodeFilter extends ZuulFilter {
return FilterConstants.SEND_ERROR_FILTER_ORDER + 1;
}
/**
* 是否校验验证码
* 1. 判断验证码开关是否开启
* 2. 判断请求是否登录请求
* 3. 判断终端是否支持
*
* @return true/false
*/
@Override
public boolean shouldFilter() {
HttpServletRequest request = RequestContext.getCurrentContext().getRequest();
if (isValidate && (StrUtil.containsIgnoreCase(request.getRequestURI(), SecurityConstants.OAUTH_TOKEN_URL)
|| StrUtil.containsIgnoreCase(request.getRequestURI(), SecurityConstants.MOBILE_TOKEN_URL))) {
return true;
if (!StrUtil.containsAnyIgnoreCase(request.getRequestURI(),
SecurityConstants.OAUTH_TOKEN_URL, SecurityConstants.MOBILE_TOKEN_URL)) {
return false;
}
return false;
try {
String[] clientInfos = AuthUtils.extractAndDecodeHeader(request);
if (CollUtil.containsAny(filterIgnorePropertiesConfig.getClients(), Arrays.asList(clientInfos))) {
return false;
}
} catch (IOException e) {
log.error("解析终端信息失败", e);
}
return true;
}
@Override
@ -63,7 +87,6 @@ public class ValidateCodeFilter extends ZuulFilter {
RequestContext ctx = RequestContext.getCurrentContext();
R<String> result = new R<>(e);
result.setCode(478);
result.setMsg("演示环境,没有权限操作");
ctx.setResponseStatusCode(478);
ctx.setSendZuulResponse(false);

View File

@ -1,23 +0,0 @@
package com.github.pig.gateway.feign;
import com.github.pig.common.vo.UserVO;
import com.github.pig.gateway.feign.fallback.UserServiceFallbackImpl;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**
* @author lengleng
* @date 2017/10/31
*/
@FeignClient(name = "pig-upms-service", fallback = UserServiceFallbackImpl.class)
public interface UserService {
/**
* 通过用户名查询用户角色信息
*
* @param username 用户名
* @return UserVo
*/
@GetMapping("/user/findUserByUsername/{username}")
UserVO findUserByUsername(@PathVariable("username") String username);
}

View File

@ -2,6 +2,8 @@ package com.github.pig.gateway.feign.fallback;
import com.github.pig.common.vo.MenuVO;
import com.github.pig.gateway.feign.MenuService;
import com.xiaoleilu.hutool.collection.CollUtil;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
@ -14,12 +16,12 @@ import java.util.Set;
* why add @Service when i up version ?
* https://github.com/spring-cloud/spring-cloud-netflix/issues/762
*/
@Slf4j
@Service
public class MenuServiceFallbackImpl implements MenuService {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public Set<MenuVO> findMenuByRole(String role) {
logger.error("调用{}异常{}","findMenuByRole",role);
return null;
log.error("调用{}异常{}","findMenuByRole",role);
return CollUtil.newHashSet();
}
}

View File

@ -1,23 +0,0 @@
package com.github.pig.gateway.feign.fallback;
import com.github.pig.common.vo.UserVO;
import com.github.pig.gateway.feign.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
/**
* @author lengleng
* @date 2017/10/31
* 用户服务的fallback
*/
@Service
public class UserServiceFallbackImpl implements UserService {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public UserVO findUserByUsername(String username) {
logger.error("调用{}异常:{}", "findUserByUsername", username);
return null;
}
}

View File

@ -23,11 +23,6 @@
<artifactId>pig-common</artifactId>
<version>${pig.version}</version>
</dependency>
<!--rabbitMQ-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<!--阿里大于-->
<dependency>
<groupId>com.aliyun</groupId>

View File

@ -1,6 +1,5 @@
package com.github.pig.mc.handler;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
@ -12,8 +11,6 @@ import com.github.pig.common.constant.CommonConstant;
import com.github.pig.common.util.Assert;
import com.github.pig.common.util.template.MobileMsgTemplate;
import com.github.pig.mc.config.SmsAliyunPropertiesConfig;
import com.github.pig.mc.utils.constant.SmsChannelTemplateConstant;
import com.github.pig.mc.utils.sms.EnumSmsChannelTemplate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ -28,8 +25,8 @@ import org.springframework.stereotype.Component;
public class SmsAliyunMessageHandler extends AbstractMessageHandler {
@Autowired
private SmsAliyunPropertiesConfig smsAliyunPropertiesConfig;
private static final String product = "Dysmsapi";
private static final String domain = "dysmsapi.aliyuncs.com";
private static final String PRODUCT = "Dysmsapi";
private static final String DOMAIN = "dysmsapi.aliyuncs.com";
/**
* 数据校验
@ -39,7 +36,7 @@ public class SmsAliyunMessageHandler extends AbstractMessageHandler {
@Override
public void check(MobileMsgTemplate mobileMsgTemplate) {
Assert.isBlank(mobileMsgTemplate.getMobile(), "手机号不能为空");
Assert.isBlank(mobileMsgTemplate.getText(), "验证码不能为空");
Assert.isBlank(mobileMsgTemplate.getContext(), "短信内容不能为空");
}
/**
@ -56,7 +53,7 @@ public class SmsAliyunMessageHandler extends AbstractMessageHandler {
//初始化acsClient,暂不支持region化
IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", smsAliyunPropertiesConfig.getAccessKey(), smsAliyunPropertiesConfig.getSecretKey());
try {
DefaultProfile.addEndpoint("cn-hou", "cn-hangzhou", product, domain);
DefaultProfile.addEndpoint("cn-hou", "cn-hangzhou", PRODUCT, DOMAIN);
} catch (ClientException e) {
log.error("初始化SDK 异常", e);
e.printStackTrace();
@ -67,20 +64,21 @@ public class SmsAliyunMessageHandler extends AbstractMessageHandler {
SendSmsRequest request = new SendSmsRequest();
//必填:待发送手机号
request.setPhoneNumbers(mobileMsgTemplate.getMobile());
//必填:短信签名-可在短信控制台中找到
request.setSignName(EnumSmsChannelTemplate.LOGIN_NAME_LOGIN.getDescription());
request.setSignName(mobileMsgTemplate.getSignName());
//必填:短信模板-可在短信控制台中找到
request.setTemplateCode(smsAliyunPropertiesConfig.getChannels().get(SmsChannelTemplateConstant.LOGIN_NAME_LOGIN));
//可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}",此处的值为
JSONObject jsonObject = new JSONObject();
jsonObject.put("product", "pig_cloud");
jsonObject.put("code", mobileMsgTemplate.getText());
request.setTemplateParam(jsonObject.toJSONString());
request.setTemplateCode(smsAliyunPropertiesConfig.getChannels().get(mobileMsgTemplate.getTemplate()));
//可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"
request.setTemplateParam(mobileMsgTemplate.getContext());
request.setOutId(mobileMsgTemplate.getMobile());
//hint 此处可能会抛出异常注意catch
try {
SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
log.info("短信发送完毕,手机号:{},返回状态:{}", mobileMsgTemplate.getMobile(), sendSmsResponse.getCode());
} catch (ClientException e) {
log.error("发送异常");
e.printStackTrace();

View File

@ -26,11 +26,16 @@ public class MobileCodeReceiveListener {
@RabbitHandler
public void receive(MobileMsgTemplate mobileMsgTemplate) {
long startTime = System.currentTimeMillis();
log.info("消息中心接收到短信发送请求-> 手机号:{} -> 验证码: {} ", mobileMsgTemplate.getMobile(), mobileMsgTemplate.getText());
String type = mobileMsgTemplate.getType();
SmsMessageHandler messageHandler = messageHandlerMap.get(type);
log.info("消息中心接收到短信发送请求-> 手机号:{} -> 验证码: {} ", mobileMsgTemplate.getMobile(), mobileMsgTemplate.getContext());
String channel = mobileMsgTemplate.getChannel();
SmsMessageHandler messageHandler = messageHandlerMap.get(channel);
if (messageHandler == null) {
log.error("没有找到指定的路由通道,不进行发送处理完毕!");
return;
}
messageHandler.execute(mobileMsgTemplate);
long useTime = System.currentTimeMillis() - startTime;
log.info("调用 {} 短信网关处理完毕,耗时 {}毫秒", type, useTime);
log.info("调用 {} 短信网关处理完毕,耗时 {}毫秒", channel, useTime);
}
}

View File

@ -2,11 +2,15 @@ package com.github.pig.mc.listener;
import com.github.pig.common.constant.MqQueueConstant;
import com.github.pig.common.util.template.MobileMsgTemplate;
import com.github.pig.mc.handler.SmsMessageHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* @author lengleng
* @date 2018年01月25日15:59:00
@ -16,10 +20,22 @@ import org.springframework.stereotype.Component;
@Component
@RabbitListener(queues = MqQueueConstant.MOBILE_SERVICE_STATUS_CHANGE)
public class MobileServiceChangeReceiveListener {
@Autowired
private Map<String, SmsMessageHandler> messageHandlerMap;
@RabbitHandler
public void receive(MobileMsgTemplate mobileMsgTemplate) {
long startTime = System.currentTimeMillis();
log.info("消息中心接收到短信发送请求-> 手机号:{} -> 验证码: {} ", mobileMsgTemplate.getMobile(), mobileMsgTemplate.getText());
log.info("消息中心接收到短信发送请求-> 手机号:{} -> 信息体:{} ", mobileMsgTemplate.getMobile(), mobileMsgTemplate.getContext());
String channel = mobileMsgTemplate.getChannel();
SmsMessageHandler messageHandler = messageHandlerMap.get(channel);
if (messageHandler == null) {
log.error("没有找到指定的路由通道,不进行发送处理完毕!");
return;
}
messageHandler.execute(mobileMsgTemplate);
long useTime = System.currentTimeMillis() - startTime;
log.info("调用 {} 短信网关处理完毕,耗时 {}毫秒", mobileMsgTemplate.getType(), useTime);
}

View File

@ -1,13 +0,0 @@
package com.github.pig.mc.utils.constant;
/**
* @author lengleng
* @date 2018/1/16
* 短信通道模板常量
*/
public interface SmsChannelTemplateConstant {
/**
* 登录验证码
*/
String LOGIN_NAME_LOGIN = "loginCodeChannel";
}

View File

@ -1,42 +0,0 @@
package com.github.pig.mc.utils.sms;
/**
* @author lengleng
* @date 2018/1/16
* 短信通道模板
*/
public enum EnumSmsChannelTemplate {
/**
* 登录验证
*/
LOGIN_NAME_LOGIN("loginCodeChannel", "登录验证");
/**
* 模板名称
*/
private String name;
/**
* 模板签名
*/
private String description;
EnumSmsChannelTemplate(String name, String description) {
this.name = name;
this.description = description;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}

View File

@ -11,7 +11,7 @@ import org.springframework.web.bind.annotation.RestController;
*/
@RestController
public class DemoController {
@GetMapping("/user")
@GetMapping("/")
public Authentication user(Authentication authentication) {
return authentication;
}

View File

@ -29,14 +29,6 @@ spring:
name: pig-sso-client-demo
profiles:
active: dev
redis:
remote: true #是否是cachecloud 获取
host: 106.14.69.75
port: 6381
password:
logging:
config: classpath:logback.xml
---
spring:
profiles: dev

View File

@ -57,11 +57,6 @@
<version>${velocity-engine-core.version}</version>
</dependency>
<!--mybatis-plus end -->
<!--rabbitMQ-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<!--七牛-->
<dependency>
<groupId>com.qiniu</groupId>

View File

@ -42,13 +42,33 @@ public class RabbitConfig {
return new Queue(MqQueueConstant.MOBILE_SERVICE_STATUS_CHANGE);
}
/**
* 初始化钉钉状态改变队列
*
* @return
*/
@Bean
public Queue initDingTalkServiceStatusChangeQueue() {
return new Queue(MqQueueConstant.DINGTALK_SERVICE_STATUS_CHANGE);
}
/**
* 初始化zipkin队列
*
* @return
*/
@Bean
public Queue initZipkinQueue() {
return new Queue(MqQueueConstant.ZIPKIN_NAME_QUEUE);
}
/**
* 初始化路由配置状态队列
*
* @return
*/
@Bean
public Queue initRouteConfigChangeQueue() {
return new Queue(MqQueueConstant.ROUTE_CONFIG_CHANGE);
}
}

View File

@ -0,0 +1,47 @@
package com.github.pig.admin.common.listener;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.github.pig.admin.service.SysZuulRouteService;
import com.github.pig.common.constant.CommonConstant;
import com.github.pig.common.entity.SysZuulRoute;
import com.xiaoleilu.hutool.collection.CollUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author lengleng
* @date 2018/5/16
*/
@Slf4j
@Component
public class RouteConfigInitListener implements ApplicationRunner {
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private SysZuulRouteService sysZuulRouteService;
/**
* Callback used to run the bean.
* 初始化路由配置的数据避免gateway 依赖业务模块
*
* @param args incoming application arguments
*/
@Override
public void run(ApplicationArguments args) {
log.info("开始初始化路由配置数据");
EntityWrapper wrapper = new EntityWrapper();
wrapper.eq(CommonConstant.DEL_FLAG, CommonConstant.STATUS_NORMAL);
List<SysZuulRoute> routeList = sysZuulRouteService.selectList(wrapper);
if (CollUtil.isNotEmpty(routeList)) {
redisTemplate.opsForValue().set(CommonConstant.ROUTE_KEY, routeList);
log.info("更新Redis中路由配置数据{}条", routeList.size());
}
log.info("初始化路由配置数据完毕");
}
}

View File

@ -25,7 +25,7 @@ public class PigResourcesGenerator {
public static void main(String[] args) {
String outputDir = "/Users/lengleng/work/source";
String outputDir = "/Users/lengleng/work/temp";
final String viewOutputDir = outputDir + "/view/";
AutoGenerator mpg = new AutoGenerator();
// 全局配置
@ -48,7 +48,7 @@ public class PigResourcesGenerator {
dsc.setDriverName("com.mysql.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("lengleng");
dsc.setUrl("jdbc:mysql://106.14.69.75:3309/pig?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false");
dsc.setUrl("jdbc:mysql://139.224.200.249:3309/pig?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false");
mpg.setDataSource(dsc);
// 策略配置

View File

@ -0,0 +1,86 @@
package com.github.pig.admin.controller;
import java.util.Map;
import com.github.pig.admin.model.entity.SysOauthClientDetails;
import com.github.pig.common.util.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.github.pig.common.util.Query;
import com.github.pig.admin.service.SysOauthClientDetailsService;
import com.github.pig.common.web.BaseController;
/**
* <p>
* 前端控制器
* </p>
*
* @author lengleng
* @since 2018-05-15
*/
@RestController
@RequestMapping("/client")
public class OauthClientDetailsController extends BaseController {
@Autowired
private SysOauthClientDetailsService sysOauthClientDetailsService;
/**
* 通过ID查询
*
* @param id ID
* @return SysOauthClientDetails
*/
@GetMapping("/{id}")
public SysOauthClientDetails get(@PathVariable Integer id) {
return sysOauthClientDetailsService.selectById(id);
}
/**
* 分页查询信息
*
* @param params 分页对象
* @return 分页对象
*/
@RequestMapping("/page")
public Page page(@RequestParam Map<String, Object> params) {
return sysOauthClientDetailsService.selectPage(new Query<>(params), new EntityWrapper<>());
}
/**
* 添加
*
* @param sysOauthClientDetails 实体
* @return success/false
*/
@PostMapping
public R<Boolean> add(@RequestBody SysOauthClientDetails sysOauthClientDetails) {
return new R<>(sysOauthClientDetailsService.insert(sysOauthClientDetails));
}
/**
* 删除
*
* @param id ID
* @return success/false
*/
@DeleteMapping("/{id}")
public R<Boolean> delete(@PathVariable String id) {
SysOauthClientDetails sysOauthClientDetails = new SysOauthClientDetails();
sysOauthClientDetails.setClientId(id);
return new R<>(sysOauthClientDetailsService.deleteById(sysOauthClientDetails));
}
/**
* 编辑
*
* @param sysOauthClientDetails 实体
* @return success/false
*/
@PutMapping
public R<Boolean> edit(@RequestBody SysOauthClientDetails sysOauthClientDetails) {
return new R<>(sysOauthClientDetailsService.updateById(sysOauthClientDetails));
}
}

View File

@ -0,0 +1,100 @@
package com.github.pig.admin.controller;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.github.pig.admin.service.SysZuulRouteService;
import com.github.pig.common.constant.CommonConstant;
import com.github.pig.common.entity.SysZuulRoute;
import com.github.pig.common.util.Query;
import com.github.pig.common.util.R;
import com.github.pig.common.web.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
import java.util.Map;
/**
* <p>
* 动态路由配置表 前端控制器
* </p>
*
* @author lengleng
* @since 2018-05-15
*/
@RestController
@RequestMapping("/route")
public class ZuulRouteController extends BaseController {
@Autowired
private SysZuulRouteService sysZuulRouteService;
/**
* 通过ID查询
*
* @param id ID
* @return SysZuulRoute
*/
@GetMapping("/{id}")
public SysZuulRoute get(@PathVariable Integer id) {
return sysZuulRouteService.selectById(id);
}
/**
* 分页查询信息
*
* @param params 分页对象
* @return 分页对象
*/
@RequestMapping("/page")
public Page page(@RequestParam Map<String, Object> params) {
params.put(CommonConstant.DEL_FLAG, CommonConstant.STATUS_NORMAL);
return sysZuulRouteService.selectPage(new Query<>(params), new EntityWrapper<>());
}
/**
* 添加
*
* @param sysZuulRoute 实体
* @return success/false
*/
@PostMapping
public R<Boolean> add(@RequestBody SysZuulRoute sysZuulRoute) {
return new R<>(sysZuulRouteService.insert(sysZuulRoute));
}
/**
* 删除
*
* @param id ID
* @return success/false
*/
@DeleteMapping("/{id}")
public R<Boolean> delete(@PathVariable Integer id) {
SysZuulRoute sysZuulRoute = new SysZuulRoute();
sysZuulRoute.setId(id);
sysZuulRoute.setUpdateTime(new Date());
sysZuulRoute.setDelFlag(CommonConstant.STATUS_DEL);
return new R<>(sysZuulRouteService.updateById(sysZuulRoute));
}
/**
* 编辑
*
* @param sysZuulRoute 实体
* @return success/false
*/
@PutMapping
public R<Boolean> edit(@RequestBody SysZuulRoute sysZuulRoute) {
sysZuulRoute.setUpdateTime(new Date());
return new R<>(sysZuulRouteService.updateById(sysZuulRoute));
}
/**
* 刷新配置
*
* @return success/fasle
*/
@GetMapping("/apply")
public R<Boolean> apply() {
return new R<>(sysZuulRouteService.applyZuulRoute());
}
}

View File

@ -0,0 +1,17 @@
package com.github.pig.admin.mapper;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.github.pig.admin.model.entity.SysOauthClientDetails;
/**
* <p>
* Mapper 接口
* </p>
*
* @author lengleng
* @since 2018-05-15
*/
public interface SysOauthClientDetailsMapper extends BaseMapper<SysOauthClientDetails> {
}

View File

@ -0,0 +1,16 @@
package com.github.pig.admin.mapper;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.github.pig.common.entity.SysZuulRoute;
/**
* <p>
* 动态路由配置表 Mapper 接口
* </p>
*
* @author lengleng
* @since 2018-05-15
*/
public interface SysZuulRouteMapper extends BaseMapper<SysZuulRoute> {
}

View File

@ -20,6 +20,7 @@ public class MenuTree extends TreeNode {
private String code;
private String type;
private String label;
private Integer sort;
public MenuTree() {
}
@ -48,5 +49,6 @@ public class MenuTree extends TreeNode {
this.component = menuVo.getComponent();
this.type = menuVo.getType();
this.label = menuVo.getName();
this.sort = menuVo.getSort();
}
}

View File

@ -0,0 +1,154 @@
package com.github.pig.admin.model.entity;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.activerecord.Model;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import java.io.Serializable;
/**
* <p>
*
* </p>
*
* @author lengleng
* @since 2018-05-15
*/
@TableName("sys_oauth_client_details")
public class SysOauthClientDetails extends Model<SysOauthClientDetails> {
private static final long serialVersionUID = 1L;
@TableId(value = "client_id", type = IdType.INPUT)
private String clientId;
@TableField("resource_ids")
private String resourceIds;
@TableField("client_secret")
private String clientSecret;
private String scope;
@TableField("authorized_grant_types")
private String authorizedGrantTypes;
@TableField("web_server_redirect_uri")
private String webServerRedirectUri;
private String authorities;
@TableField("access_token_validity")
private Integer accessTokenValidity;
@TableField("refresh_token_validity")
private Integer refreshTokenValidity;
@TableField("additional_information")
private String additionalInformation;
private String autoapprove;
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getResourceIds() {
return resourceIds;
}
public void setResourceIds(String resourceIds) {
this.resourceIds = resourceIds;
}
public String getClientSecret() {
return clientSecret;
}
public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
}
public String getScope() {
return scope;
}
public void setScope(String scope) {
this.scope = scope;
}
public String getAuthorizedGrantTypes() {
return authorizedGrantTypes;
}
public void setAuthorizedGrantTypes(String authorizedGrantTypes) {
this.authorizedGrantTypes = authorizedGrantTypes;
}
public String getWebServerRedirectUri() {
return webServerRedirectUri;
}
public void setWebServerRedirectUri(String webServerRedirectUri) {
this.webServerRedirectUri = webServerRedirectUri;
}
public String getAuthorities() {
return authorities;
}
public void setAuthorities(String authorities) {
this.authorities = authorities;
}
public Integer getAccessTokenValidity() {
return accessTokenValidity;
}
public void setAccessTokenValidity(Integer accessTokenValidity) {
this.accessTokenValidity = accessTokenValidity;
}
public Integer getRefreshTokenValidity() {
return refreshTokenValidity;
}
public void setRefreshTokenValidity(Integer refreshTokenValidity) {
this.refreshTokenValidity = refreshTokenValidity;
}
public String getAdditionalInformation() {
return additionalInformation;
}
public void setAdditionalInformation(String additionalInformation) {
this.additionalInformation = additionalInformation;
}
public String getAutoapprove() {
return autoapprove;
}
public void setAutoapprove(String autoapprove) {
this.autoapprove = autoapprove;
}
@Override
protected Serializable pkVal() {
return this.clientId;
}
@Override
public String toString() {
return "SysOauthClientDetails{" +
", clientId=" + clientId +
", resourceIds=" + resourceIds +
", clientSecret=" + clientSecret +
", scope=" + scope +
", authorizedGrantTypes=" + authorizedGrantTypes +
", webServerRedirectUri=" + webServerRedirectUri +
", authorities=" + authorities +
", accessTokenValidity=" + accessTokenValidity +
", refreshTokenValidity=" + refreshTokenValidity +
", additionalInformation=" + additionalInformation +
", autoapprove=" + autoapprove +
"}";
}
}

View File

@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import java.io.Serializable;
@ -34,10 +35,12 @@ public class SysUser extends Model<SysUser> {
*/
private String username;
@JsonIgnore
private String password;
/**
* 随机盐
*/
@JsonIgnore
private String salt;
/**
* 创建时间

View File

@ -37,7 +37,6 @@ public interface SysMenuService extends IService<SysMenu> {
* 级联删除菜单
*
* @param id 菜单ID
* @param roleList 角色
* @return 成功失败
*/
Boolean deleteMenu(Integer id);
@ -46,7 +45,6 @@ public interface SysMenuService extends IService<SysMenu> {
* 更新菜单信息
*
* @param sysMenu 菜单信息
* @param roleList 角色
* @return 成功失败
*/
Boolean updateMenuById(SysMenu sysMenu);

View File

@ -0,0 +1,16 @@
package com.github.pig.admin.service;
import com.baomidou.mybatisplus.service.IService;
import com.github.pig.admin.model.entity.SysOauthClientDetails;
/**
* <p>
* 服务类
* </p>
*
* @author lengleng
* @since 2018-05-15
*/
public interface SysOauthClientDetailsService extends IService<SysOauthClientDetails> {
}

View File

@ -0,0 +1,21 @@
package com.github.pig.admin.service;
import com.baomidou.mybatisplus.service.IService;
import com.github.pig.common.entity.SysZuulRoute;
/**
* <p>
* 动态路由配置表 服务类
* </p>
*
* @author lengleng
* @since 2018-05-15
*/
public interface SysZuulRouteService extends IService<SysZuulRoute> {
/**
* 立即生效配置
* @return
*/
Boolean applyZuulRoute();
}

View File

@ -10,16 +10,14 @@ import com.github.pig.admin.service.SysMenuService;
import com.github.pig.common.constant.CommonConstant;
import com.github.pig.common.util.Assert;
import com.github.pig.common.vo.MenuVO;
import com.xiaoleilu.hutool.collection.CollUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;
/**
* <p>
@ -94,12 +92,13 @@ public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> impl
// 获取符合条件得菜单
Set<MenuVO> all = new HashSet<>();
roleNames.forEach(roleName -> all.addAll(findMenuByRoleName(roleName)));
final List<MenuTree> menuTreeList = new ArrayList<>();
List<MenuTree> menuTreeList = new ArrayList<>();
all.forEach(menuVo -> {
if (CommonConstant.MENU.equals(menuVo.getType())) {
menuTreeList.add(new MenuTree(menuVo));
}
});
CollUtil.sort(menuTreeList, Comparator.comparingInt(MenuTree::getSort));
return TreeUtil.bulid(menuTreeList, -1);
}

View File

@ -0,0 +1,20 @@
package com.github.pig.admin.service.impl;
import com.github.pig.admin.mapper.SysOauthClientDetailsMapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.github.pig.admin.model.entity.SysOauthClientDetails;
import com.github.pig.admin.service.SysOauthClientDetailsService;
import org.springframework.stereotype.Service;
/**
* <p>
* 服务实现类
* </p>
*
* @author lengleng
* @since 2018-05-15
*/
@Service
public class SysOauthClientDetailsServiceImpl extends ServiceImpl<SysOauthClientDetailsMapper, SysOauthClientDetails> implements SysOauthClientDetailsService {
}

View File

@ -1,5 +1,6 @@
package com.github.pig.admin.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
@ -17,6 +18,8 @@ import com.github.pig.common.bean.interceptor.DataScope;
import com.github.pig.common.constant.CommonConstant;
import com.github.pig.common.constant.MqQueueConstant;
import com.github.pig.common.constant.SecurityConstants;
import com.github.pig.common.constant.enums.EnumSmsChannel;
import com.github.pig.common.constant.enums.EnumSmsChannelTemplate;
import com.github.pig.common.util.Query;
import com.github.pig.common.util.R;
import com.github.pig.common.util.UserUtils;
@ -125,7 +128,6 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
dataScope.setScopeName("deptId");
dataScope.setIsOnly(true);
dataScope.setDeptIds(getChildDepts());
dataScope.putAll(query.getCondition());
query.setRecords(sysUserMapper.selectUserVoPageDataScope(query, dataScope));
return query;
}
@ -181,8 +183,18 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
}
String code = RandomUtil.randomNumbers(4);
JSONObject contextJson = new JSONObject();
contextJson.put("code", code);
contextJson.put("product", "Pig4Cloud");
log.info("短信发送请求消息中心 -> 手机号:{} -> 验证码:{}", mobile, code);
rabbitTemplate.convertAndSend(MqQueueConstant.MOBILE_CODE_QUEUE, new MobileMsgTemplate(mobile, code, CommonConstant.ALIYUN_SMS));
rabbitTemplate.convertAndSend(MqQueueConstant.MOBILE_CODE_QUEUE,
new MobileMsgTemplate(
mobile,
contextJson.toJSONString(),
CommonConstant.ALIYUN_SMS,
EnumSmsChannelTemplate.LOGIN_NAME_LOGIN.getSignName(),
EnumSmsChannelTemplate.LOGIN_NAME_LOGIN.getTemplate()
));
redisTemplate.opsForValue().set(SecurityConstants.DEFAULT_CODE_KEY + mobile, code, SecurityConstants.DEFAULT_IMAGE_EXPIRE, TimeUnit.SECONDS);
return new R<>(true);
}

View File

@ -0,0 +1,46 @@
package com.github.pig.admin.service.impl;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.github.pig.admin.mapper.SysZuulRouteMapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.github.pig.common.constant.CommonConstant;
import com.github.pig.common.constant.MqQueueConstant;
import com.github.pig.common.entity.SysZuulRoute;
import com.github.pig.admin.service.SysZuulRouteService;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* <p>
* 动态路由配置表 服务实现类
* </p>
*
* @author lengleng
* @since 2018-05-15
*/
@Service
public class SysZuulRouteServiceImpl extends ServiceImpl<SysZuulRouteMapper, SysZuulRoute> implements SysZuulRouteService {
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private RabbitTemplate rabbitTemplate;
/**
* 立即生效配置
*
* @return
*/
@Override
public Boolean applyZuulRoute() {
EntityWrapper wrapper = new EntityWrapper();
wrapper.eq(CommonConstant.DEL_FLAG, CommonConstant.STATUS_NORMAL);
List<SysZuulRoute> routeList = selectList(wrapper);
redisTemplate.opsForValue().set(CommonConstant.ROUTE_KEY, routeList);
rabbitTemplate.convertAndSend(MqQueueConstant.ROUTE_CONFIG_CHANGE, 1);
return Boolean.TRUE;
}
}

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.github.pig.admin.mapper.SysOauthClientDetailsMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.github.pig.admin.model.entity.SysOauthClientDetails">
<id column="client_id" property="clientId" />
<result column="resource_ids" property="resourceIds" />
<result column="client_secret" property="clientSecret" />
<result column="scope" property="scope" />
<result column="authorized_grant_types" property="authorizedGrantTypes" />
<result column="web_server_redirect_uri" property="webServerRedirectUri" />
<result column="authorities" property="authorities" />
<result column="access_token_validity" property="accessTokenValidity" />
<result column="refresh_token_validity" property="refreshTokenValidity" />
<result column="additional_information" property="additionalInformation" />
<result column="autoapprove" property="autoapprove" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
client_id AS clientId, resource_ids AS resourceIds, client_secret AS clientSecret, scope, authorized_grant_types AS authorizedGrantTypes, web_server_redirect_uri AS webServerRedirectUri, authorities, access_token_validity AS accessTokenValidity, refresh_token_validity AS refreshTokenValidity, additional_information AS additionalInformation, autoapprove
</sql>
</mapper>

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.github.pig.admin.mapper.SysZuulRouteMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.github.pig.common.entity.SysZuulRoute">
<id column="id" property="id" />
<result column="path" property="path" />
<result column="service_id" property="serviceId" />
<result column="url" property="url" />
<result column="strip_prefix" property="stripPrefix" />
<result column="retryable" property="retryable" />
<result column="enabled" property="enabled" />
<result column="sensitiveHeaders_list" property="sensitiveheadersList" />
<result column="create_time" property="createTime" />
<result column="update_time" property="updateTime" />
<result column="del_flag" property="delFlag" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id, path, service_id AS serviceId, url, strip_prefix AS stripPrefix, retryable, enabled, sensitiveHeaders_list AS sensitiveheadersList, create_time AS createTime, update_time AS updateTime, del_flag AS delFlag
</sql>
</mapper>

View File

@ -1,4 +1,4 @@
package ${package.Controller};
package $!{package.Controller};
import java.util.Map;
import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;
@ -7,10 +7,11 @@ import com.github.pig.common.constant.CommonConstant;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.github.pig.common.util.Query;
import ${package.Entity}.${entity};
import ${package.Service}.${entity}Service;
#if(${superControllerClassPackage})
import ${superControllerClassPackage};
import com.github.pig.common.util.R;
import $!{package.Entity}.$!{entity};
import $!{package.Service}.$!{entity}Service;
#if($!{superControllerClassPackage})
import $!{superControllerClassPackage};
#end
/**
@ -18,23 +19,23 @@ import ${superControllerClassPackage};
* $!{table.comment} 前端控制器
* </p>
*
* @author ${author}
* @since ${date}
* @author $!{author}
* @since $!{date}
*/
@RestController
@RequestMapping("/${table.entityPath}")
public class ${table.controllerName} extends ${superControllerClass} {
@Autowired private ${entity}Service ${table.entityPath}Service;
@RequestMapping("/$!{table.entityPath}")
public class $!{table.controllerName} extends $!{superControllerClass} {
@Autowired private $!{entity}Service $!{table.entityPath}Service;
/**
* 通过ID查询
*
* @param id ID
* @return ${entity}
* @return $!{entity}
*/
@GetMapping("/{id}")
public ${entity} get(@PathVariable Integer id) {
return ${table.entityPath}Service.selectById(id);
public R<$!{entity}> get(@PathVariable Integer id) {
return new R<>($!{table.entityPath}Service.selectById(id));
}
@ -47,17 +48,17 @@ public class ${table.controllerName} extends ${superControllerClass} {
@RequestMapping("/page")
public Page page(@RequestParam Map<String, Object> params) {
params.put(CommonConstant.DEL_FLAG, CommonConstant.STATUS_NORMAL);
return ${table.entityPath}Service.selectPage(new Query<>(params), new EntityWrapper<>());
return $!{table.entityPath}Service.selectPage(new Query<>(params), new EntityWrapper<>());
}
/**
* 添加
* @param ${table.entityPath} 实体
* @param $!{table.entityPath} 实体
* @return success/false
*/
@PostMapping
public Boolean add(@RequestBody ${entity} ${table.entityPath}) {
return ${table.entityPath}Service.insert(${table.entityPath});
public R<Boolean> add(@RequestBody $!{entity} $!{table.entityPath}) {
return new R<>($!{table.entityPath}Service.insert($!{table.entityPath}));
}
/**
@ -66,22 +67,22 @@ public class ${table.controllerName} extends ${superControllerClass} {
* @return success/false
*/
@DeleteMapping("/{id}")
public Boolean delete(@PathVariable Integer id) {
${entity} ${table.entityPath} = new ${entity}();
${table.entityPath}.setId(id);
${table.entityPath}.setUpdateTime(new Date());
${table.entityPath}.setDelFlag(CommonConstant.STATUS_DEL);
return ${table.entityPath}Service.updateById(${table.entityPath});
public R<Boolean> delete(@PathVariable Integer id) {
$!{entity} $!{table.entityPath} = new $!{entity}();
$!{table.entityPath}.setId(id);
$!{table.entityPath}.setUpdateTime(new Date());
$!{table.entityPath}.setDelFlag(CommonConstant.STATUS_DEL);
return new R<>($!{table.entityPath}Service.updateById($!{table.entityPath}));
}
/**
* 编辑
* @param ${table.entityPath} 实体
* @param $!{table.entityPath} 实体
* @return success/false
*/
@PutMapping
public Boolean edit(@RequestBody ${entity} ${table.entityPath}) {
${table.entityPath}.setUpdateTime(new Date());
return ${table.entityPath}Service.updateById(${table.entityPath});
public R<Boolean> edit(@RequestBody $!{entity} $!{table.entityPath}) {
$!{table.entityPath}.setUpdateTime(new Date());
return new R<>($!{table.entityPath}Service.updateById($!{table.entityPath}));
}
}

View File

@ -1,25 +1,25 @@
<template>
<div class="app-container calendar-list-container">
<div class="filter-container">
<el-button v-if="${table.name}_add" class="filter-item" style="margin-left: 10px;" @click="handleCreate" type="primary" icon="edit">添加
<el-button v-if="$!{table.name}_add" class="filter-item" style="margin-left: 10px;" @click="handleCreate" type="primary" icon="edit">添加
</el-button>
</div>
<el-table :key='tableKey' :data="list" v-loading="listLoading" element-loading-text="给我一点时间" border fit
highlight-current-row style="width: 100%">
#foreach($field in $table.fields)
<el-table-column align="center" label="${field.comment}">
<el-table-column align="center" label="$!{field.comment}">
<template scope="scope">
<span>{{ scope.row.${field.propertyName} }}</span>
<span>{{ scope.row.$!{field.propertyName} }}</span>
</template>
</el-table-column>
#end
<el-table-column label="操作">
<template scope="scope">
<el-button v-if="${table.name}_upd" size="small" type="success"
<el-button v-if="$!{table.name}_upd" size="small" type="success"
@click="handleUpdate(scope.row)">编辑
</el-button>
<el-button v-if="${table.name}_del" size="mini" type="danger"
<el-button v-if="$!{table.name}_del" size="mini" type="danger"
@click="handleDelete(scope.row)">删除
</el-button>
</template>
@ -35,8 +35,8 @@
<el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
<el-form :model="form" :rules="rules" ref="form" label-width="100px">
#foreach($field in $table.fields)
<el-form-item label="${field.comment}" prop="username">
<el-input v-model="form.${field.propertyName}" placeholder="${field.comment}"></el-input>
<el-form-item label="$!{field.comment}" prop="username">
<el-input v-model="form.$!{field.propertyName}" placeholder="$!{field.comment}"></el-input>
</el-form-item>
#end
</el-form>
@ -50,12 +50,12 @@
</template>
<script>
import { fetchList, addObj, putObj, delObj } from '@/api/${table.name}'
import { fetchList, addObj, putObj, delObj } from '@/api/$!{table.name}'
import waves from '@/directive/waves/index.js' // 水波纹指令
import { mapGetters } from 'vuex'
export default {
name: 'table_${table.name}',
name: 'table_$!{table.name}',
directives: {
waves
},
@ -74,9 +74,9 @@
},
dialogFormVisible: false,
dialogStatus: '',
${table.name}_add: false,
${table.name}_upd: false,
${table.name}_del: false,
$!{table.name}_add: false,
$!{table.name}_upd: false,
$!{table.name}_del: false,
textMap: {
update: '编辑',
create: '创建'
@ -100,9 +100,9 @@
},
created() {
this.getList()
this.${table.name}_add = this.permissions['${table.name}_add']
this.${table.name}_upd = this.permissions['${table.name}_upd']
this.${table.name}_del = this.permissions['${table.name}_del']
this.$!{table.name}_add = this.permissions['$!{table.name}_add']
this.$!{table.name}_upd = this.permissions['$!{table.name}_upd']
this.$!{table.name}_del = this.permissions['$!{table.name}_del']
},
methods: {
getList() {

View File

@ -1,16 +1,16 @@
-- 菜单SQL
INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES ('1', '${comments}', 'modules/generator/${pathName}.html', NULL, '1', 'fa fa-file-code-o', '6');
VALUES ('1', '$!{comments}', 'modules/generator/$!{pathName}.html', NULL, '1', 'fa fa-file-code-o', '6');
-- 按钮父菜单ID
set @parentId = @@identity;
-- 菜单对应按钮SQL
INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
SELECT @parentId, '查看', null, '${pathName}:list,${pathName}:info', '2', null, '6';
SELECT @parentId, '查看', null, '$!{pathName}:list,$!{pathName}:info', '2', null, '6';
INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
SELECT @parentId, '新增', null, '${pathName}:save', '2', null, '6';
SELECT @parentId, '新增', null, '$!{pathName}:save', '2', null, '6';
INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
SELECT @parentId, '修改', null, '${pathName}:update', '2', null, '6';
SELECT @parentId, '修改', null, '$!{pathName}:update', '2', null, '6';
INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
SELECT @parentId, '删除', null, '${pathName}:delete', '2', null, '6';
SELECT @parentId, '删除', null, '$!{pathName}:delete', '2', null, '6';

View File

@ -34,10 +34,6 @@
<artifactId>spring-boot-admin-server-ui</artifactId>
<version>${spring-boot-admin-server-ui.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-turbine</artifactId>

View File

@ -1,12 +1,13 @@
package com.github.pig.monitor.filter;
import com.alibaba.fastjson.JSONObject;
import com.github.pig.common.constant.CommonConstant;
import com.github.pig.common.constant.MqQueueConstant;
import com.github.pig.common.constant.enums.EnumSmsChannel;
import com.github.pig.common.util.template.DingTalkMsgTemplate;
import com.github.pig.common.constant.enums.EnumSmsChannelTemplate;
import com.github.pig.common.util.template.MobileMsgTemplate;
import com.github.pig.monitor.config.MonitorPropertiesConfig;
import com.xiaoleilu.hutool.collection.CollectionUtil;
import com.xiaoleilu.hutool.collection.CollUtil;
import com.xiaoleilu.hutool.date.DateUtil;
import de.codecentric.boot.admin.event.ClientApplicationEvent;
import de.codecentric.boot.admin.event.ClientApplicationStatusChangedEvent;
@ -14,6 +15,8 @@ import de.codecentric.boot.admin.notify.AbstractStatusChangeNotifier;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import java.nio.file.Paths;
/**
* @author lengleng
* @date 2018/4/22
@ -39,8 +42,11 @@ public class StatusChangeNotifier extends AbstractStatusChangeNotifier {
@Override
protected boolean shouldNotify(ClientApplicationEvent event) {
boolean shouldNotify = false;
if (STATUS_CHANGE.equals(event.getType())
&& event.getApplication().getStatusInfo().isOffline()
if (!STATUS_CHANGE.equals(event.getType())) {
return shouldNotify;
}
if (event.getApplication().getStatusInfo().isOffline()
|| event.getApplication().getStatusInfo().isDown()) {
shouldNotify = true;
}
@ -60,12 +66,22 @@ public class StatusChangeNotifier extends AbstractStatusChangeNotifier {
event.getApplication().getId(), ((ClientApplicationStatusChangedEvent) event).getTo().getStatus());
String text = String.format("应用:%s 服务ID:%s 下线,时间:%s", event.getApplication().getName(), event.getApplication().getId(), DateUtil.date(event.getTimestamp()).toString());
JSONObject contextJson = new JSONObject();
contextJson.put("name", event.getApplication().getName());
contextJson.put("seid", event.getApplication().getId());
contextJson.put("time", DateUtil.date(event.getTimestamp()).toString());
//开启短信通知
if (monitorMobilePropertiesConfig.getMobile().getEnabled()) {
log.info("开始短信通知,内容:{}", text);
rabbitTemplate.convertAndSend(MqQueueConstant.MOBILE_SERVICE_STATUS_CHANGE,
new MobileMsgTemplate(CollectionUtil.join(monitorMobilePropertiesConfig.getMobile().getMobiles(), ","),
text, EnumSmsChannel.ALIYUN.getName()));
new MobileMsgTemplate(
CollUtil.join(monitorMobilePropertiesConfig.getMobile().getMobiles(), ","),
contextJson.toJSONString(),
CommonConstant.ALIYUN_SMS,
EnumSmsChannelTemplate.SERVICE_STATUS_CHANGE.getSignName(),
EnumSmsChannelTemplate.SERVICE_STATUS_CHANGE.getTemplate()
));
}
if (monitorMobilePropertiesConfig.getDingTalk().getEnabled()) {

View File

@ -20,7 +20,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<pig.version>1.0-BETA</pig.version>
<pig.version>1.0.0</pig.version>
<spring-boot.version>1.5.12.RELEASE</spring-boot.version>
<spring-cloud.version>Edgware.SR3</spring-cloud.version>