mirror of
https://gitee.com/durcframework/SOP.git
synced 2025-08-11 21:57:56 +08:00
自定义路由
This commit is contained in:
@@ -7,7 +7,6 @@ import com.gitee.easyopen.doc.DataType;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDoc;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocMethod;
|
||||
import com.gitee.easyopen.exception.ApiException;
|
||||
import com.gitee.easyopen.util.CopyUtil;
|
||||
import com.gitee.easyopen.util.KeyStore;
|
||||
import com.gitee.easyopen.util.RSAUtil;
|
||||
@@ -24,7 +23,10 @@ import com.gitee.sop.adminserver.api.isv.result.IsvVO;
|
||||
import com.gitee.sop.adminserver.api.isv.result.RoleVO;
|
||||
import com.gitee.sop.adminserver.bean.ChannelMsg;
|
||||
import com.gitee.sop.adminserver.bean.ZookeeperContext;
|
||||
import com.gitee.sop.adminserver.common.BizException;
|
||||
import com.gitee.sop.adminserver.common.IdGen;
|
||||
import com.gitee.sop.adminserver.common.ZookeeperOperationException;
|
||||
import com.gitee.sop.adminserver.common.ZookeeperPathNotExistException;
|
||||
import com.gitee.sop.adminserver.entity.IsvInfo;
|
||||
import com.gitee.sop.adminserver.entity.PermIsvRole;
|
||||
import com.gitee.sop.adminserver.entity.PermRole;
|
||||
@@ -133,7 +135,7 @@ public class IsvApi {
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void addIsv(IsvInfoFormAdd param) throws Exception {
|
||||
if (isvInfoMapper.getByColumn("app_key", param.getAppKey()) != null) {
|
||||
throw new ApiException("appKey已存在");
|
||||
throw new BizException("appKey已存在");
|
||||
}
|
||||
formatForm(param);
|
||||
IsvInfo rec = new IsvInfo();
|
||||
@@ -175,9 +177,9 @@ public class IsvApi {
|
||||
try {
|
||||
log.info("消息推送--ISV信息(update), path:{}, data:{}", path, data);
|
||||
ZookeeperContext.updatePathData(path, data);
|
||||
} catch (Exception e) {
|
||||
} catch (ZookeeperPathNotExistException e) {
|
||||
log.error("发送isvChannelMsg失败, path:{}, msg:{}", path, data, e);
|
||||
throw new ApiException("保存失败,请查看日志");
|
||||
throw new BizException("路径不存在");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,7 +224,7 @@ public class IsvApi {
|
||||
routePermissionService.sendIsvRolePermissionToZookeeper(isvInfo.getAppKey(), roleCodeList);
|
||||
} catch (Exception e) {
|
||||
log.error("保存到zookeeper中失败,isvInfo:{}, roleCodeList:{}", isvInfo, roleCodeList);
|
||||
throw new ApiException("保存失败,请查看日志");
|
||||
throw new BizException("保存失败,请查看日志");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -4,7 +4,6 @@ import com.gitee.easyopen.annotation.Api;
|
||||
import com.gitee.easyopen.annotation.ApiService;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDoc;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocMethod;
|
||||
import com.gitee.easyopen.exception.ApiException;
|
||||
import com.gitee.easyopen.util.CopyUtil;
|
||||
import com.gitee.fastmybatis.core.query.Query;
|
||||
import com.gitee.sop.adminserver.api.service.param.LimitParam;
|
||||
@@ -12,6 +11,7 @@ import com.gitee.sop.adminserver.api.service.param.RouteSearchParam;
|
||||
import com.gitee.sop.adminserver.api.service.result.LimitVO;
|
||||
import com.gitee.sop.adminserver.bean.GatewayRouteDefinition;
|
||||
import com.gitee.sop.adminserver.bean.RouteConfigDto;
|
||||
import com.gitee.sop.adminserver.common.BizException;
|
||||
import com.gitee.sop.adminserver.common.LimitEnum;
|
||||
import com.gitee.sop.adminserver.entity.ConfigRouteLimit;
|
||||
import com.gitee.sop.adminserver.mapper.ConfigRouteLimitMapper;
|
||||
@@ -118,7 +118,7 @@ public class LimitApi {
|
||||
routeConfigService.sendRouteConfigMsg(routeConfigDto);
|
||||
} catch (Exception e) {
|
||||
log.error("推送限流消息错误, param:{}", param, e);
|
||||
throw new ApiException("修改失败,请查看日志");
|
||||
throw new BizException("修改失败,请查看日志");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -4,7 +4,6 @@ import com.gitee.easyopen.annotation.Api;
|
||||
import com.gitee.easyopen.annotation.ApiService;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDoc;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocMethod;
|
||||
import com.gitee.easyopen.exception.ApiException;
|
||||
import com.gitee.easyopen.util.CopyUtil;
|
||||
import com.gitee.fastmybatis.core.PageInfo;
|
||||
import com.gitee.fastmybatis.core.query.Query;
|
||||
@@ -15,6 +14,7 @@ import com.gitee.sop.adminserver.api.service.param.LimitNewParam;
|
||||
import com.gitee.sop.adminserver.api.service.param.LimitNewUpdateParam;
|
||||
import com.gitee.sop.adminserver.api.service.result.LimitNewVO;
|
||||
import com.gitee.sop.adminserver.bean.ConfigLimitDto;
|
||||
import com.gitee.sop.adminserver.common.BizException;
|
||||
import com.gitee.sop.adminserver.entity.ConfigLimit;
|
||||
import com.gitee.sop.adminserver.mapper.ConfigLimitMapper;
|
||||
import com.gitee.sop.adminserver.service.RouteConfigService;
|
||||
@@ -65,7 +65,7 @@ public class LimitNewApi {
|
||||
routeConfigService.sendLimitConfigMsg(configLimitDto);
|
||||
} catch (Exception e) {
|
||||
log.error("推送限流消息错误, param:{}", param, e);
|
||||
throw new ApiException("新增失败,请查看日志");
|
||||
throw new BizException("新增失败,请查看日志");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ public class LimitNewApi {
|
||||
routeConfigService.sendLimitConfigMsg(configLimitDto);
|
||||
} catch (Exception e) {
|
||||
log.error("推送限流消息错误, param:{}", param, e);
|
||||
throw new ApiException("修改失败,请查看日志");
|
||||
throw new BizException("修改失败,请查看日志");
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -6,11 +6,11 @@ import com.gitee.easyopen.annotation.Api;
|
||||
import com.gitee.easyopen.annotation.ApiService;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDoc;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocMethod;
|
||||
import com.gitee.easyopen.exception.ApiException;
|
||||
import com.gitee.easyopen.verify.DefaultMd5Verifier;
|
||||
import com.gitee.fastmybatis.core.query.Query;
|
||||
import com.gitee.sop.adminserver.api.service.param.LogMonitorInstanceAddParam;
|
||||
import com.gitee.sop.adminserver.api.service.result.LogMonitorInstanceVO;
|
||||
import com.gitee.sop.adminserver.common.BizException;
|
||||
import com.gitee.sop.adminserver.common.QueryUtil;
|
||||
import com.gitee.sop.adminserver.entity.ConfigCommon;
|
||||
import com.gitee.sop.adminserver.mapper.ConfigCommonMapper;
|
||||
@@ -80,7 +80,7 @@ public class LogApi {
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("获取日志信息出错", e);
|
||||
throw new ApiException("获取日志信息出错");
|
||||
throw new BizException("获取日志信息出错");
|
||||
}
|
||||
}
|
||||
Collections.sort(ret, Comparator.comparing(LogMonitorInstanceVO::getCount));
|
||||
@@ -98,7 +98,7 @@ public class LogApi {
|
||||
String ipPort = configCommon.getConfigKey();
|
||||
this.requestLogServer(ipPort, "clearErrors");
|
||||
} catch (Exception e) {
|
||||
throw new ApiException("清除失败");
|
||||
throw new BizException("清除失败");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ public class LogApi {
|
||||
.eq("config_key", ipPort);
|
||||
ConfigCommon rec = configCommonMapper.getByQuery(query);
|
||||
if (rec != null) {
|
||||
throw new ApiException("该实例已添加");
|
||||
throw new BizException("该实例已添加");
|
||||
}
|
||||
ConfigCommon configCommon = new ConfigCommon();
|
||||
configCommon.setConfigGroup(LOG_MONITOR_INSTANCE);
|
||||
@@ -137,11 +137,11 @@ public class LogApi {
|
||||
JSONObject jsonObject = JSON.parseObject(json);
|
||||
if (!CODE_SUCCESS.equals(jsonObject.getString("code"))) {
|
||||
log.error("请求结果:{}", json);
|
||||
throw new ApiException("添加失败");
|
||||
throw new BizException("添加失败");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("添加失败", e);
|
||||
throw new ApiException("添加失败");
|
||||
throw new BizException("添加失败");
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -5,18 +5,21 @@ import com.gitee.easyopen.annotation.Api;
|
||||
import com.gitee.easyopen.annotation.ApiService;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDoc;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocMethod;
|
||||
import com.gitee.easyopen.exception.ApiException;
|
||||
import com.gitee.easyopen.util.CopyUtil;
|
||||
import com.gitee.fastmybatis.core.query.Query;
|
||||
import com.gitee.sop.adminserver.api.isv.result.RoleVO;
|
||||
import com.gitee.sop.adminserver.api.service.param.RouteParam;
|
||||
import com.gitee.sop.adminserver.api.service.param.RouteAddParam;
|
||||
import com.gitee.sop.adminserver.api.service.param.RouteDeleteParam;
|
||||
import com.gitee.sop.adminserver.api.service.param.RoutePermissionParam;
|
||||
import com.gitee.sop.adminserver.api.service.param.RouteSearchParam;
|
||||
import com.gitee.sop.adminserver.api.service.param.RouteUpdateParam;
|
||||
import com.gitee.sop.adminserver.api.service.result.RouteVO;
|
||||
import com.gitee.sop.adminserver.api.service.result.ServiceInfo;
|
||||
import com.gitee.sop.adminserver.bean.GatewayRouteDefinition;
|
||||
import com.gitee.sop.adminserver.bean.RouteConfigDto;
|
||||
import com.gitee.sop.adminserver.bean.ZookeeperContext;
|
||||
import com.gitee.sop.adminserver.common.BizException;
|
||||
import com.gitee.sop.adminserver.common.ZookeeperPathExistException;
|
||||
import com.gitee.sop.adminserver.common.ZookeeperPathNotExistException;
|
||||
import com.gitee.sop.adminserver.entity.ConfigRouteBase;
|
||||
import com.gitee.sop.adminserver.entity.PermRole;
|
||||
import com.gitee.sop.adminserver.entity.PermRolePermission;
|
||||
@@ -28,14 +31,13 @@ import com.gitee.sop.adminserver.service.RoutePermissionService;
|
||||
import com.gitee.sop.adminserver.service.RouteService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang.BooleanUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -96,67 +98,84 @@ public class RouteApi {
|
||||
return routeDefinitionList;
|
||||
}
|
||||
|
||||
@Api(name = "route.update")
|
||||
@ApiDocMethod(description = "修改路由")
|
||||
void updateRoute(RouteParam param) throws Exception {
|
||||
String serviceIdPath = ZookeeperContext.getSopRouteRootPath() + "/" + param.getServiceId();
|
||||
String zookeeperRoutePath = serviceIdPath + "/" + param.getId();
|
||||
String data = ZookeeperContext.getData(zookeeperRoutePath);
|
||||
GatewayRouteDefinition routeDefinition = JSON.parseObject(data, GatewayRouteDefinition.class);
|
||||
CopyUtil.copyPropertiesIgnoreNull(param, routeDefinition);
|
||||
ZookeeperContext.updatePathData(zookeeperRoutePath, JSON.toJSONString(routeDefinition));
|
||||
|
||||
this.updateRouteConfig(param);
|
||||
}
|
||||
|
||||
@Api(name = "route.add")
|
||||
@ApiDocMethod(description = "新增路由")
|
||||
void addRoute(RouteParam param) throws Exception {
|
||||
String serviceIdPath = ZookeeperContext.getSopRouteRootPath() + "/" + param.getServiceId();
|
||||
String zookeeperRoutePath = serviceIdPath + "/" + param.getId();
|
||||
if (ZookeeperContext.isPathExist(zookeeperRoutePath)) {
|
||||
throw new ApiException("id已存在");
|
||||
}
|
||||
void addRoute(RouteAddParam param) {
|
||||
String id = param.getName() + param.getVersion();
|
||||
String routePath = ZookeeperContext.buildRoutePath(param.getServiceId(), id);
|
||||
GatewayRouteDefinition routeDefinition = new GatewayRouteDefinition();
|
||||
CopyUtil.copyPropertiesIgnoreNull(param, routeDefinition);
|
||||
ZookeeperContext.createNewData(zookeeperRoutePath, JSON.toJSONString(routeDefinition));
|
||||
ServiceInfo serviceInfo = new ServiceInfo();
|
||||
serviceInfo.setServiceId(param.getServiceId());
|
||||
serviceInfo.setDescription(param.getServiceId());
|
||||
String now = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
|
||||
serviceInfo.setCreateTime(now);
|
||||
serviceInfo.setUpdateTime(now);
|
||||
ZookeeperContext.updatePathData(serviceIdPath, JSON.toJSONString(serviceInfo));
|
||||
|
||||
this.updateRouteConfig(param);
|
||||
routeDefinition.setId(id);
|
||||
routeDefinition.setCustom(1);
|
||||
try {
|
||||
ZookeeperContext.addPath(routePath, JSON.toJSONString(routeDefinition));
|
||||
} catch (ZookeeperPathExistException e) {
|
||||
throw new BizException("路由已存在");
|
||||
}
|
||||
this.updateRouteConfig(routeDefinition);
|
||||
}
|
||||
|
||||
private void updateRouteConfig(RouteParam param) {
|
||||
@Api(name = "route.update")
|
||||
@ApiDocMethod(description = "修改路由")
|
||||
void updateRoute(RouteUpdateParam param) {
|
||||
String routePath = ZookeeperContext.buildRoutePath(param.getServiceId(), param.getId());
|
||||
GatewayRouteDefinition routeDefinition = this.getGatewayRouteDefinition(routePath);
|
||||
CopyUtil.copyPropertiesIgnoreNull(param, routeDefinition);
|
||||
try {
|
||||
String routeId = param.getId();
|
||||
ZookeeperContext.updatePathData(routePath, JSON.toJSONString(routeDefinition));
|
||||
} catch (ZookeeperPathNotExistException e) {
|
||||
throw new BizException("路由不存在");
|
||||
}
|
||||
this.updateRouteConfig(routeDefinition);
|
||||
}
|
||||
|
||||
@Api(name = "route.del")
|
||||
@ApiDocMethod(description = "删除路由")
|
||||
void delRoute(RouteDeleteParam param) {
|
||||
String routePath = ZookeeperContext.buildRoutePath(param.getServiceId(), param.getId());
|
||||
GatewayRouteDefinition routeDefinition = this.getGatewayRouteDefinition(routePath);
|
||||
if (!BooleanUtils.toBoolean(routeDefinition.getCustom())) {
|
||||
throw new BizException("非自定义路由,无法删除");
|
||||
}
|
||||
ZookeeperContext.deletePathDeep(routePath);
|
||||
}
|
||||
|
||||
private GatewayRouteDefinition getGatewayRouteDefinition(String zookeeperRoutePath) {
|
||||
String data = null;
|
||||
try {
|
||||
data = ZookeeperContext.getData(zookeeperRoutePath);
|
||||
} catch (ZookeeperPathNotExistException e) {
|
||||
throw new BizException("路由不存在");
|
||||
}
|
||||
return JSON.parseObject(data, GatewayRouteDefinition.class);
|
||||
}
|
||||
|
||||
private void updateRouteConfig(GatewayRouteDefinition routeDefinition) {
|
||||
try {
|
||||
String routeId = routeDefinition.getId();
|
||||
ConfigRouteBase configRouteBase = configRouteBaseMapper.getByColumn("route_id", routeId);
|
||||
boolean doSave = configRouteBase == null;
|
||||
if (doSave) {
|
||||
configRouteBase = new ConfigRouteBase();
|
||||
configRouteBase.setRouteId(param.getId());
|
||||
configRouteBase.setRouteId(routeId);
|
||||
}
|
||||
configRouteBase.setStatus(param.getStatus().byteValue());
|
||||
configRouteBase.setStatus((byte) routeDefinition.getStatus());
|
||||
|
||||
int i = doSave ? configRouteBaseMapper.save(configRouteBase)
|
||||
: configRouteBaseMapper.update(configRouteBase);
|
||||
|
||||
if (i > 0) {
|
||||
this.sendMsg(param);
|
||||
this.sendMsg(routeDefinition);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("发送msg失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendMsg(RouteParam param) throws Exception {
|
||||
private void sendMsg(GatewayRouteDefinition routeDefinition) {
|
||||
RouteConfigDto routeConfigDto = new RouteConfigDto();
|
||||
routeConfigDto.setRouteId(param.getId());
|
||||
routeConfigDto.setStatus(param.getStatus());
|
||||
routeConfigDto.setRouteId(routeDefinition.getId());
|
||||
routeConfigDto.setStatus(routeDefinition.getStatus());
|
||||
routeConfigService.sendRouteConfigMsg(routeConfigDto);
|
||||
}
|
||||
|
||||
@@ -164,7 +183,7 @@ public class RouteApi {
|
||||
@ApiDocMethod(description = "获取路由对应的角色", elementClass = RoleVO.class)
|
||||
List<RoleVO> getRouteRole(RouteSearchParam param) {
|
||||
if (StringUtils.isBlank(param.getId())) {
|
||||
throw new ApiException("id不能为空");
|
||||
throw new BizException("id不能为空");
|
||||
}
|
||||
return this.getRouteRole(param.getId());
|
||||
}
|
||||
@@ -209,7 +228,7 @@ public class RouteApi {
|
||||
routePermissionService.sendRoutePermissionReloadMsg();
|
||||
} catch (Exception e) {
|
||||
log.info("消息推送--路由权限(reload)失败", e);
|
||||
throw new ApiException("修改失败,请查看日志");
|
||||
throw new BizException("修改失败,请查看日志");
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -5,7 +5,7 @@ import com.gitee.easyopen.annotation.Api;
|
||||
import com.gitee.easyopen.annotation.ApiService;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDoc;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocMethod;
|
||||
import com.gitee.easyopen.exception.ApiException;
|
||||
import com.gitee.sop.adminserver.api.service.param.ServiceAddParam;
|
||||
import com.gitee.sop.adminserver.api.service.param.ServiceInstanceParam;
|
||||
import com.gitee.sop.adminserver.api.service.param.ServiceSearchParam;
|
||||
import com.gitee.sop.adminserver.api.service.result.ServiceInfo;
|
||||
@@ -14,11 +14,16 @@ import com.gitee.sop.adminserver.bean.EurekaApplication;
|
||||
import com.gitee.sop.adminserver.bean.EurekaApps;
|
||||
import com.gitee.sop.adminserver.bean.EurekaInstance;
|
||||
import com.gitee.sop.adminserver.bean.EurekaUri;
|
||||
import com.gitee.sop.adminserver.bean.ServiceRouteInfo;
|
||||
import com.gitee.sop.adminserver.bean.ZookeeperContext;
|
||||
import com.gitee.sop.adminserver.common.BizException;
|
||||
import com.gitee.sop.adminserver.common.ZookeeperPathExistException;
|
||||
import com.gitee.sop.adminserver.common.ZookeeperPathNotExistException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import org.apache.commons.lang.BooleanUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.curator.framework.recipes.cache.ChildData;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
@@ -28,6 +33,7 @@ import org.springframework.core.env.Environment;
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -48,8 +54,6 @@ public class ServiceApi {
|
||||
|
||||
private String eurekaUrl;
|
||||
|
||||
// eureka.client.serviceUrl.defaultZone
|
||||
|
||||
@Api(name = "service.list")
|
||||
@ApiDocMethod(description = "服务列表(旧)", elementClass = ServiceInfo.class)
|
||||
List<ServiceInfo> listServiceInfo(ServiceSearchParam param) throws Exception {
|
||||
@@ -74,6 +78,48 @@ public class ServiceApi {
|
||||
return serviceInfoList;
|
||||
}
|
||||
|
||||
@Api(name = "service.custom.add")
|
||||
@ApiDocMethod(description = "添加服务")
|
||||
void addService(ServiceAddParam param) {
|
||||
String serviceId = param.getServiceId();
|
||||
String servicePath = ZookeeperContext.buildServiceIdPath(serviceId);
|
||||
ServiceRouteInfo serviceRouteInfo = new ServiceRouteInfo();
|
||||
Date now = new Date();
|
||||
serviceRouteInfo.setServiceId(serviceId);
|
||||
serviceRouteInfo.setDescription("自定义服务");
|
||||
serviceRouteInfo.setCreateTime(now);
|
||||
serviceRouteInfo.setUpdateTime(now);
|
||||
serviceRouteInfo.setCustom(BooleanUtils.toInteger(true));
|
||||
String serviceData = JSON.toJSONString(serviceRouteInfo);
|
||||
try {
|
||||
ZookeeperContext.addPath(servicePath, serviceData);
|
||||
} catch (ZookeeperPathExistException e) {
|
||||
throw new BizException("服务已存在");
|
||||
}
|
||||
}
|
||||
|
||||
@Api(name = "service.custom.del")
|
||||
@ApiDocMethod(description = "删除自定义服务")
|
||||
void delService(ServiceSearchParam param) {
|
||||
String serviceId = param.getServiceId();
|
||||
String servicePath = ZookeeperContext.buildServiceIdPath(serviceId);
|
||||
String data = null;
|
||||
try {
|
||||
data = ZookeeperContext.getData(servicePath);
|
||||
} catch (ZookeeperPathNotExistException e) {
|
||||
throw new BizException("服务不存在");
|
||||
}
|
||||
if (StringUtils.isBlank(data)) {
|
||||
throw new BizException("非自定义服务,无法删除");
|
||||
}
|
||||
ServiceRouteInfo serviceRouteInfo = JSON.parseObject(data, ServiceRouteInfo.class);
|
||||
int custom = serviceRouteInfo.getCustom();
|
||||
if (!BooleanUtils.toBoolean(custom)) {
|
||||
throw new BizException("非自定义服务,无法删除");
|
||||
}
|
||||
ZookeeperContext.deletePathDeep(servicePath);
|
||||
}
|
||||
|
||||
@Api(name = "service.instance.list")
|
||||
@ApiDocMethod(description = "服务列表", elementClass = ServiceInfoVo.class)
|
||||
List<ServiceInfoVo> listService(ServiceSearchParam param) throws Exception {
|
||||
@@ -133,7 +179,7 @@ public class ServiceApi {
|
||||
return response.body().string();
|
||||
} else {
|
||||
log.error("操作失败,url:{}, msg:{}, code:{}", eurekaUri.getUri(args), response.message(), response.code());
|
||||
throw new ApiException("操作失败", String.valueOf(response.code()));
|
||||
throw new BizException("操作失败", String.valueOf(response.code()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +187,7 @@ public class ServiceApi {
|
||||
protected void after() {
|
||||
String eurekaUrls = environment.getProperty("eureka.client.serviceUrl.defaultZone");
|
||||
if (StringUtils.isBlank(eurekaUrls)) {
|
||||
throw new ApiException("未指定eureka.client.serviceUrl.defaultZone参数");
|
||||
throw new BizException("未指定eureka.client.serviceUrl.defaultZone参数");
|
||||
}
|
||||
String url = eurekaUrls.split("\\,")[0];
|
||||
if (url.endsWith("/")) {
|
||||
|
@@ -41,10 +41,12 @@ public class LimitNewAddParam {
|
||||
|
||||
/** 返回的错误码, 数据库字段:limit_code */
|
||||
@ApiDocField(description = "返回的错误码")
|
||||
@Length(max = 64, message = "limitCode长度不能超过64")
|
||||
private String limitCode;
|
||||
|
||||
/** 返回的错误信息, 数据库字段:limit_msg */
|
||||
@ApiDocField(description = "返回的错误信息")
|
||||
@Length(max = 100, message = "limitMsg长度不能超过100")
|
||||
private String limitMsg;
|
||||
|
||||
/** 令牌桶容量, 数据库字段:token_bucket_count */
|
||||
|
@@ -46,10 +46,12 @@ public class LimitNewUpdateParam {
|
||||
|
||||
/** 返回的错误码, 数据库字段:limit_code */
|
||||
@ApiDocField(description = "返回的错误码")
|
||||
@Length(max = 64, message = "limitCode长度不能超过64")
|
||||
private String limitCode;
|
||||
|
||||
/** 返回的错误信息, 数据库字段:limit_msg */
|
||||
@ApiDocField(description = "返回的错误信息")
|
||||
@Length(max = 100, message = "limitMsg长度不能超过100")
|
||||
private String limitMsg;
|
||||
|
||||
/** 令牌桶容量, 数据库字段:token_bucket_count */
|
||||
|
@@ -0,0 +1,76 @@
|
||||
package com.gitee.sop.adminserver.api.service.param;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* @author tanghc
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class RouteAddParam {
|
||||
|
||||
@NotBlank(message = "serviceId不能为空")
|
||||
@Length(max = 100, message = "serviceId长度不能超过100")
|
||||
@ApiDocField(description = "serviceId")
|
||||
private String serviceId;
|
||||
|
||||
/**
|
||||
* 接口名
|
||||
*/
|
||||
@NotBlank(message = "接口名不能为空")
|
||||
@Length(max = 100, message = "name长度不能超过100")
|
||||
@ApiDocField(description = "接口名")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 版本号
|
||||
*/
|
||||
@NotBlank(message = "版本号不能为空")
|
||||
@Length(max = 100, message = "version长度不能超过100")
|
||||
@ApiDocField(description = "版本号")
|
||||
private String version;
|
||||
|
||||
/**
|
||||
* 路由规则转发的目标uri
|
||||
*/
|
||||
@NotBlank(message = "uri不能为空")
|
||||
@Length(max = 100, message = "uri长度不能超过100")
|
||||
@ApiDocField(description = "路由uri")
|
||||
private String uri;
|
||||
|
||||
/**
|
||||
* uri后面跟的path
|
||||
*/
|
||||
@ApiDocField(description = "路由path")
|
||||
@Length(max = 100, message = "path长度不能超过100")
|
||||
private String path;
|
||||
|
||||
/**
|
||||
* 是否忽略验证,业务参数验证除外
|
||||
*/
|
||||
@ApiDocField(description = "是否忽略验证,业务参数验证除外,1:忽略,0:不忽略")
|
||||
private Integer ignoreValidate;
|
||||
|
||||
/**
|
||||
* 合并结果,统一格式输出
|
||||
*/
|
||||
@ApiDocField(description = "合并结果,统一格式输出,1:合并,2:不合并")
|
||||
private Integer mergeResult;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
@NotNull
|
||||
@ApiDocField(description = "状态,0:审核,1:启用,2:禁用")
|
||||
private Integer status;
|
||||
|
||||
@ApiDocField(description = "是否是自定义路由,1:是,0:否")
|
||||
private Integer custom;
|
||||
|
||||
}
|
@@ -0,0 +1,22 @@
|
||||
package com.gitee.sop.adminserver.api.service.param;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* @author tanghc
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class RouteDeleteParam {
|
||||
@ApiDocField(description = "服务名serviceId")
|
||||
@NotBlank(message = "serviceId不能为空")
|
||||
private String serviceId;
|
||||
|
||||
@ApiDocField(description = "路由id")
|
||||
@NotBlank(message = "id不能为空")
|
||||
private String id;
|
||||
}
|
@@ -3,6 +3,7 @@ package com.gitee.sop.adminserver.api.service.param;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
@@ -12,23 +13,25 @@ import javax.validation.constraints.NotNull;
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class RouteParam {
|
||||
|
||||
@NotBlank(message = "serviceId不能为空")
|
||||
@ApiDocField(description = "serviceId")
|
||||
private String serviceId;
|
||||
public class RouteUpdateParam {
|
||||
|
||||
/**
|
||||
* 路由的Id
|
||||
*/
|
||||
@NotBlank(message = "id不能为空")
|
||||
@ApiDocField(description = "路由id")
|
||||
private String id = "";
|
||||
private String id;
|
||||
|
||||
@NotBlank(message = "serviceId不能为空")
|
||||
@Length(max = 100, message = "serviceId长度不能超过100")
|
||||
@ApiDocField(description = "serviceId")
|
||||
private String serviceId;
|
||||
|
||||
/**
|
||||
* 路由规则转发的目标uri
|
||||
*/
|
||||
@NotBlank(message = "uri不能为空")
|
||||
@Length(max = 100, message = "uri长度不能超过100")
|
||||
@ApiDocField(description = "路由uri")
|
||||
private String uri;
|
||||
|
||||
@@ -36,8 +39,21 @@ public class RouteParam {
|
||||
* uri后面跟的path
|
||||
*/
|
||||
@ApiDocField(description = "路由path")
|
||||
@Length(max = 100, message = "path长度不能超过100")
|
||||
private String path;
|
||||
|
||||
/**
|
||||
* 是否忽略验证,业务参数验证除外
|
||||
*/
|
||||
@ApiDocField(description = "是否忽略验证,业务参数验证除外,1:忽略,0:不忽略")
|
||||
private Integer ignoreValidate;
|
||||
|
||||
/**
|
||||
* 合并结果,统一格式输出
|
||||
*/
|
||||
@ApiDocField(description = "合并结果,统一格式输出,1:合并,2:不合并")
|
||||
private Integer mergeResult;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
@@ -45,4 +61,7 @@ public class RouteParam {
|
||||
@ApiDocField(description = "状态,0:审核,1:启用,2:禁用")
|
||||
private Integer status;
|
||||
|
||||
@ApiDocField(description = "是否是自定义路由,1:是,0:否")
|
||||
private Integer custom;
|
||||
|
||||
}
|
@@ -0,0 +1,21 @@
|
||||
package com.gitee.sop.adminserver.api.service.param;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* @author tanghc
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class ServiceAddParam {
|
||||
|
||||
@ApiDocField(description = "服务名serviceId")
|
||||
@Length(max = 100, message = "长度不能超过100")
|
||||
@NotBlank(message = "serviceId不能为空")
|
||||
private String serviceId;
|
||||
}
|
@@ -19,4 +19,8 @@ public class ServiceInfo {
|
||||
|
||||
@ApiDocField(description = "描述")
|
||||
private String description;
|
||||
|
||||
/** 是否是自定义服务,1:是,0:否 */
|
||||
@ApiDocField(description = "是否是自定义服务,1:是,0:否")
|
||||
private Integer custom;
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
package com.gitee.sop.adminserver.bean;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import lombok.Data;
|
||||
|
||||
@@ -30,11 +31,13 @@ public class GatewayRouteDefinition {
|
||||
/**
|
||||
* 路由断言集合配置
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
private List<GatewayPredicateDefinition> predicates = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 路由过滤器集合配置
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
private List<GatewayFilterDefinition> filters = new ArrayList<>();
|
||||
|
||||
/**
|
||||
@@ -67,14 +70,20 @@ public class GatewayRouteDefinition {
|
||||
private int status = 1;
|
||||
|
||||
/**
|
||||
* 合并结果
|
||||
* 合并结果,统一格式输出
|
||||
*/
|
||||
@ApiDocField(description = "合并结果,1:合并,2:不合并")
|
||||
@ApiDocField(description = "合并结果,统一格式输出,1:合并,0:不合并")
|
||||
private int mergeResult = 1;
|
||||
|
||||
/**
|
||||
* 是否需要授权才能访问
|
||||
*/
|
||||
@ApiDocField(description = "是否需要授权才能访问,1:是,2:否")
|
||||
@ApiDocField(description = "是否需要授权才能访问,1:是,0:否")
|
||||
private int permission;
|
||||
|
||||
/**
|
||||
* 是否是自定义路由
|
||||
*/
|
||||
@ApiDocField(description = "是否是自定义路由,1:是,0:否")
|
||||
private int custom;
|
||||
}
|
@@ -24,4 +24,7 @@ public class ServiceRouteInfo {
|
||||
|
||||
@JSONField(serialize = false)
|
||||
private List<GatewayRouteDefinition> routeDefinitionList;
|
||||
|
||||
/** 是否是自定义服务,1:是,0:否 */
|
||||
private int custom;
|
||||
}
|
@@ -1,6 +1,9 @@
|
||||
package com.gitee.sop.adminserver.bean;
|
||||
|
||||
import com.gitee.easyopen.exception.ApiException;
|
||||
import com.gitee.sop.adminserver.common.ZookeeperOperationException;
|
||||
import com.gitee.sop.adminserver.common.ZookeeperPathExistException;
|
||||
import com.gitee.sop.adminserver.common.ZookeeperPathNotExistException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang.math.NumberUtils;
|
||||
import org.apache.curator.framework.CuratorFramework;
|
||||
@@ -23,6 +26,7 @@ import static com.gitee.sop.adminserver.bean.SopAdminConstants.SOP_ROUTE_PERMISS
|
||||
* @author tanghc
|
||||
*/
|
||||
@Configuration
|
||||
@Slf4j
|
||||
public class ZookeeperContext {
|
||||
|
||||
private static CuratorFramework client;
|
||||
@@ -55,6 +59,24 @@ public class ZookeeperContext {
|
||||
return SopAdminConstants.SOP_SERVICE_ROUTE_PATH;
|
||||
}
|
||||
|
||||
public static String buildServiceIdPath(String serviceId) {
|
||||
if (StringUtils.isBlank(serviceId)) {
|
||||
throw new NullPointerException("serviceId不能为空");
|
||||
}
|
||||
return getSopRouteRootPath() + "/" + serviceId;
|
||||
}
|
||||
|
||||
public static String buildRoutePath(String serviceId, String routeId) {
|
||||
if (StringUtils.isBlank(serviceId)) {
|
||||
throw new NullPointerException("serviceId不能为空");
|
||||
}
|
||||
if (StringUtils.isBlank(routeId)) {
|
||||
throw new NullPointerException("routeId不能为空");
|
||||
}
|
||||
String serviceIdPath = getSopRouteRootPath() + "/" + serviceId;
|
||||
return serviceIdPath + "/" + routeId;
|
||||
}
|
||||
|
||||
public static String getRoutePermissionPath() {
|
||||
return SOP_ROUTE_PERMISSION_PATH;
|
||||
}
|
||||
@@ -95,30 +117,72 @@ public class ZookeeperContext {
|
||||
* 对已存在的path赋值。如果path不存在抛异常
|
||||
*
|
||||
* @param path 已存在的
|
||||
* @param data
|
||||
* @param data 数据
|
||||
* @return
|
||||
* @throws Exception
|
||||
* @throws ZookeeperPathNotExistException
|
||||
*/
|
||||
public static Stat updatePathData(String path, String data) throws Exception {
|
||||
public static Stat updatePathData(String path, String data) throws ZookeeperPathNotExistException {
|
||||
if (!isPathExist(path)) {
|
||||
throw new ApiException("path " + path + " 不存在");
|
||||
throw new ZookeeperPathNotExistException("path " + path + " 不存在");
|
||||
}
|
||||
try {
|
||||
return getClient().setData().forPath(path, data.getBytes());
|
||||
} catch (Exception e) {
|
||||
throw new ZookeeperOperationException("updatePathData error, path=" + path, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建新的path,并赋值。如果path已存在抛异常
|
||||
* @param path 待创建的path
|
||||
* @param data 值
|
||||
* @throws ZookeeperPathExistException
|
||||
*/
|
||||
public static String createNewData(String path, String data) throws Exception {
|
||||
public static String addPath(String path, String data) throws ZookeeperPathExistException {
|
||||
if (isPathExist(path)) {
|
||||
throw new ApiException("path " + path + " 已存在");
|
||||
throw new ZookeeperPathExistException("path " + path + " 已存在");
|
||||
}
|
||||
try {
|
||||
return getClient().create()
|
||||
// 如果指定节点的父节点不存在,则Curator将会自动级联创建父节点
|
||||
.creatingParentContainersIfNeeded()
|
||||
.forPath(path, data.getBytes());
|
||||
} catch (Exception e) {
|
||||
throw new ZookeeperOperationException("addPath error path=" + path, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除节点及子节点
|
||||
* @param path
|
||||
*/
|
||||
public static void deletePathDeep(String path) {
|
||||
try {
|
||||
getClient().delete()
|
||||
.deletingChildrenIfNeeded()
|
||||
.forPath(path);
|
||||
} catch (Exception e) {
|
||||
throw new ZookeeperOperationException("deletePathDeep error path=" + path, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建新的path,并赋值。如果path已存在则不创建
|
||||
* @param path 待创建的path
|
||||
* @param data 值
|
||||
*/
|
||||
public static String addPathQuietly(String path, String data) {
|
||||
if (isPathExist(path)) {
|
||||
return path;
|
||||
}
|
||||
try {
|
||||
return getClient().create()
|
||||
// 如果指定节点的父节点不存在,则Curator将会自动级联创建父节点
|
||||
.creatingParentContainersIfNeeded()
|
||||
.forPath(path, data.getBytes());
|
||||
} catch (Exception e) {
|
||||
throw new ZookeeperOperationException("addPathQuietly error path=" + path, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -126,23 +190,36 @@ public class ZookeeperContext {
|
||||
* @param path
|
||||
* @param data
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String createOrUpdateData(String path, String data) throws Exception {
|
||||
public static String createOrUpdateData(String path, String data) {
|
||||
try {
|
||||
return getClient().create()
|
||||
// 如果节点存在则Curator将会使用给出的数据设置这个节点的值
|
||||
.orSetData()
|
||||
// 如果指定节点的父节点不存在,则Curator将会自动级联创建父节点
|
||||
.creatingParentContainersIfNeeded()
|
||||
.forPath(path, data.getBytes());
|
||||
} catch (Exception e) {
|
||||
throw new ZookeeperOperationException("createOrUpdateData error path=" + path, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getData(String path) throws Exception {
|
||||
/**
|
||||
* 获取节点内容
|
||||
* @param path
|
||||
* @return
|
||||
* @throws ZookeeperPathNotExistException
|
||||
*/
|
||||
public static String getData(String path) throws ZookeeperPathNotExistException {
|
||||
if (!isPathExist(path)) {
|
||||
return null;
|
||||
throw new ZookeeperPathNotExistException("path 不存在, path=" + path);
|
||||
}
|
||||
try {
|
||||
byte[] data = getClient().getData().forPath(path);
|
||||
return new String(data);
|
||||
} catch (Exception e) {
|
||||
throw new ZookeeperOperationException("getData error path=" + path, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -150,9 +227,8 @@ public class ZookeeperContext {
|
||||
*
|
||||
* @param parentPath 父节点
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static List<ChildData> getChildrenData(String parentPath) throws Exception {
|
||||
public static List<ChildData> getChildrenData(String parentPath) {
|
||||
PathChildrenCache pathChildrenCache = buildPathChildrenCache(parentPath);
|
||||
if (pathChildrenCache == null) {
|
||||
return Collections.emptyList();
|
||||
@@ -160,7 +236,7 @@ public class ZookeeperContext {
|
||||
return pathChildrenCache.getCurrentData();
|
||||
}
|
||||
|
||||
public static PathChildrenCache buildPathChildrenCache(String path) throws Exception {
|
||||
public static PathChildrenCache buildPathChildrenCache(String path) {
|
||||
if (!isPathExist(path)) {
|
||||
return null;
|
||||
}
|
||||
@@ -168,7 +244,11 @@ public class ZookeeperContext {
|
||||
// 且第三个参数要设置为true,不然ChildData对象中的getData返回null
|
||||
PathChildrenCache childrenCache = new PathChildrenCache(client, path, true);
|
||||
// 列出子节点数据列表,需要使用BUILD_INITIAL_CACHE同步初始化模式才能获得,异步是获取不到的
|
||||
try {
|
||||
childrenCache.start(PathChildrenCache.StartMode.BUILD_INITIAL_CACHE);
|
||||
} catch (Exception e) {
|
||||
throw new ZookeeperOperationException("buildPathChildrenCache error path=" + path, e);
|
||||
}
|
||||
return childrenCache;
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,33 @@
|
||||
package com.gitee.sop.adminserver.common;
|
||||
|
||||
import com.gitee.easyopen.exception.ApiException;
|
||||
import com.gitee.easyopen.message.Error;
|
||||
|
||||
/**
|
||||
* @author tanghc
|
||||
*/
|
||||
public class BizException extends ApiException {
|
||||
public BizException(String msg) {
|
||||
super(msg, "4000");
|
||||
}
|
||||
|
||||
public BizException(Exception e) {
|
||||
super(e);
|
||||
}
|
||||
|
||||
public BizException(Error<String> error) {
|
||||
super(error);
|
||||
}
|
||||
|
||||
public BizException(String msg, String code) {
|
||||
super(msg, code);
|
||||
}
|
||||
|
||||
public BizException(String msg, String code, Object data) {
|
||||
super(msg, code, data);
|
||||
}
|
||||
|
||||
public BizException(Error<String> error, Object data) {
|
||||
super(error, data);
|
||||
}
|
||||
}
|
@@ -0,0 +1,26 @@
|
||||
package com.gitee.sop.adminserver.common;
|
||||
|
||||
/**
|
||||
* @author tanghc
|
||||
*/
|
||||
public class ZookeeperOperationException extends RuntimeException {
|
||||
|
||||
public ZookeeperOperationException() {
|
||||
}
|
||||
|
||||
public ZookeeperOperationException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ZookeeperOperationException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public ZookeeperOperationException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public ZookeeperOperationException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
package com.gitee.sop.adminserver.common;
|
||||
|
||||
/**
|
||||
* @author tanghc
|
||||
*/
|
||||
public class ZookeeperPathExistException extends Exception {
|
||||
public ZookeeperPathExistException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
package com.gitee.sop.adminserver.common;
|
||||
|
||||
/**
|
||||
* @author tanghc
|
||||
*/
|
||||
public class ZookeeperPathNotExistException extends Exception {
|
||||
public ZookeeperPathNotExistException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
@@ -20,7 +20,7 @@ public class RouteConfigService {
|
||||
* @param routeConfigDto
|
||||
* @throws Exception
|
||||
*/
|
||||
public void sendRouteConfigMsg(RouteConfigDto routeConfigDto) throws Exception {
|
||||
public void sendRouteConfigMsg(RouteConfigDto routeConfigDto) {
|
||||
String configData = JSON.toJSONString(routeConfigDto);
|
||||
ChannelMsg channelMsg = new ChannelMsg("update", configData);
|
||||
String jsonData = JSON.toJSONString(channelMsg);
|
||||
|
@@ -10,7 +10,6 @@ import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
@@ -44,8 +43,7 @@ public class RouteService {
|
||||
return isRoute && gatewayRouteDefinition.getId().contains(id);
|
||||
}
|
||||
})
|
||||
.collect(toList())
|
||||
;
|
||||
.collect(toList());
|
||||
|
||||
return routeDefinitionStream;
|
||||
}
|
||||
|
@@ -1 +1 @@
|
||||
<!DOCTYPE html><html><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1"><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><link rel=icon href=favicon.ico><title>SOP Admin</title><link href=static/css/chunk-elementUI.81cf475c.css rel=stylesheet><link href=static/css/chunk-libs.3dfb7769.css rel=stylesheet><link href=static/css/app.4f0872ef.css rel=stylesheet></head><body><noscript><strong>We're sorry but SOP Admin doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script>(function(e){function t(t){for(var r,o,a=t[0],i=t[1],f=t[2],l=0,d=[];l<a.length;l++)o=a[l],c[o]&&d.push(c[o][0]),c[o]=0;for(r in i)Object.prototype.hasOwnProperty.call(i,r)&&(e[r]=i[r]);s&&s(t);while(d.length)d.shift()();return u.push.apply(u,f||[]),n()}function n(){for(var e,t=0;t<u.length;t++){for(var n=u[t],r=!0,o=1;o<n.length;o++){var a=n[o];0!==c[a]&&(r=!1)}r&&(u.splice(t--,1),e=i(i.s=n[0]))}return e}var r={},o={runtime:0},c={runtime:0},u=[];function a(e){return i.p+"static/js/"+({}[e]||e)+"."+{"chunk-19100986":"3ec98327","chunk-238a81e9":"5955f13d","chunk-29b24c82":"2b3ac7ca","chunk-2d0aa95b":"447435b3","chunk-2d221836":"574c9ab6","chunk-2d22c2e3":"46f37153","chunk-4a59cbe4":"b5e74cc4","chunk-ea2e58a4":"f3f85b0e"}[e]+".js"}function i(t){if(r[t])return r[t].exports;var n=r[t]={i:t,l:!1,exports:{}};return e[t].call(n.exports,n,n.exports,i),n.l=!0,n.exports}i.e=function(e){var t=[],n={"chunk-19100986":1,"chunk-238a81e9":1,"chunk-29b24c82":1,"chunk-ea2e58a4":1};o[e]?t.push(o[e]):0!==o[e]&&n[e]&&t.push(o[e]=new Promise(function(t,n){for(var r="static/css/"+({}[e]||e)+"."+{"chunk-19100986":"a43114f3","chunk-238a81e9":"e8e2beee","chunk-29b24c82":"857979fb","chunk-2d0aa95b":"31d6cfe0","chunk-2d221836":"31d6cfe0","chunk-2d22c2e3":"31d6cfe0","chunk-4a59cbe4":"31d6cfe0","chunk-ea2e58a4":"d10599db"}[e]+".css",c=i.p+r,u=document.getElementsByTagName("link"),a=0;a<u.length;a++){var f=u[a],l=f.getAttribute("data-href")||f.getAttribute("href");if("stylesheet"===f.rel&&(l===r||l===c))return t()}var d=document.getElementsByTagName("style");for(a=0;a<d.length;a++){f=d[a],l=f.getAttribute("data-href");if(l===r||l===c)return t()}var s=document.createElement("link");s.rel="stylesheet",s.type="text/css",s.onload=t,s.onerror=function(t){var r=t&&t.target&&t.target.src||c,u=new Error("Loading CSS chunk "+e+" failed.\n("+r+")");u.code="CSS_CHUNK_LOAD_FAILED",u.request=r,delete o[e],s.parentNode.removeChild(s),n(u)},s.href=c;var h=document.getElementsByTagName("head")[0];h.appendChild(s)}).then(function(){o[e]=0}));var r=c[e];if(0!==r)if(r)t.push(r[2]);else{var u=new Promise(function(t,n){r=c[e]=[t,n]});t.push(r[2]=u);var f,l=document.createElement("script");l.charset="utf-8",l.timeout=120,i.nc&&l.setAttribute("nonce",i.nc),l.src=a(e),f=function(t){l.onerror=l.onload=null,clearTimeout(d);var n=c[e];if(0!==n){if(n){var r=t&&("load"===t.type?"missing":t.type),o=t&&t.target&&t.target.src,u=new Error("Loading chunk "+e+" failed.\n("+r+": "+o+")");u.type=r,u.request=o,n[1](u)}c[e]=void 0}};var d=setTimeout(function(){f({type:"timeout",target:l})},12e4);l.onerror=l.onload=f,document.head.appendChild(l)}return Promise.all(t)},i.m=e,i.c=r,i.d=function(e,t,n){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},i.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)i.d(n,r,function(t){return e[t]}.bind(null,r));return n},i.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="",i.oe=function(e){throw console.error(e),e};var f=window["webpackJsonp"]=window["webpackJsonp"]||[],l=f.push.bind(f);f.push=t,f=f.slice();for(var d=0;d<f.length;d++)t(f[d]);var s=l;n()})([]);</script><script src=static/js/chunk-elementUI.8ebdfbab.js></script><script src=static/js/chunk-libs.9cf9cc40.js></script><script src=static/js/app.36a3cb86.js></script></body></html>
|
||||
<!DOCTYPE html><html><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1"><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><link rel=icon href=favicon.ico><title>SOP Admin</title><link href=static/css/chunk-elementUI.81cf475c.css rel=stylesheet><link href=static/css/chunk-libs.3dfb7769.css rel=stylesheet><link href=static/css/app.4f0872ef.css rel=stylesheet></head><body><noscript><strong>We're sorry but SOP Admin doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script>(function(e){function t(t){for(var r,a,c=t[0],i=t[1],f=t[2],l=0,s=[];l<c.length;l++)a=c[l],o[a]&&s.push(o[a][0]),o[a]=0;for(r in i)Object.prototype.hasOwnProperty.call(i,r)&&(e[r]=i[r]);d&&d(t);while(s.length)s.shift()();return u.push.apply(u,f||[]),n()}function n(){for(var e,t=0;t<u.length;t++){for(var n=u[t],r=!0,a=1;a<n.length;a++){var c=n[a];0!==o[c]&&(r=!1)}r&&(u.splice(t--,1),e=i(i.s=n[0]))}return e}var r={},a={runtime:0},o={runtime:0},u=[];function c(e){return i.p+"static/js/"+({}[e]||e)+"."+{"chunk-238a81e9":"5955f13d","chunk-2a9bc230":"6f8c0d92","chunk-2d221836":"574c9ab6","chunk-2d22c2e3":"46f37153","chunk-37401378":"4e39ec9b","chunk-4a59cbe4":"b5e74cc4","chunk-6a68a33e":"8b63492e","chunk-ea2e58a4":"f3f85b0e"}[e]+".js"}function i(t){if(r[t])return r[t].exports;var n=r[t]={i:t,l:!1,exports:{}};return e[t].call(n.exports,n,n.exports,i),n.l=!0,n.exports}i.e=function(e){var t=[],n={"chunk-238a81e9":1,"chunk-2a9bc230":1,"chunk-37401378":1,"chunk-6a68a33e":1,"chunk-ea2e58a4":1};a[e]?t.push(a[e]):0!==a[e]&&n[e]&&t.push(a[e]=new Promise(function(t,n){for(var r="static/css/"+({}[e]||e)+"."+{"chunk-238a81e9":"e8e2beee","chunk-2a9bc230":"2dae711a","chunk-2d221836":"31d6cfe0","chunk-2d22c2e3":"31d6cfe0","chunk-37401378":"a43114f3","chunk-4a59cbe4":"31d6cfe0","chunk-6a68a33e":"3b12267b","chunk-ea2e58a4":"d10599db"}[e]+".css",o=i.p+r,u=document.getElementsByTagName("link"),c=0;c<u.length;c++){var f=u[c],l=f.getAttribute("data-href")||f.getAttribute("href");if("stylesheet"===f.rel&&(l===r||l===o))return t()}var s=document.getElementsByTagName("style");for(c=0;c<s.length;c++){f=s[c],l=f.getAttribute("data-href");if(l===r||l===o)return t()}var d=document.createElement("link");d.rel="stylesheet",d.type="text/css",d.onload=t,d.onerror=function(t){var r=t&&t.target&&t.target.src||o,u=new Error("Loading CSS chunk "+e+" failed.\n("+r+")");u.code="CSS_CHUNK_LOAD_FAILED",u.request=r,delete a[e],d.parentNode.removeChild(d),n(u)},d.href=o;var h=document.getElementsByTagName("head")[0];h.appendChild(d)}).then(function(){a[e]=0}));var r=o[e];if(0!==r)if(r)t.push(r[2]);else{var u=new Promise(function(t,n){r=o[e]=[t,n]});t.push(r[2]=u);var f,l=document.createElement("script");l.charset="utf-8",l.timeout=120,i.nc&&l.setAttribute("nonce",i.nc),l.src=c(e),f=function(t){l.onerror=l.onload=null,clearTimeout(s);var n=o[e];if(0!==n){if(n){var r=t&&("load"===t.type?"missing":t.type),a=t&&t.target&&t.target.src,u=new Error("Loading chunk "+e+" failed.\n("+r+": "+a+")");u.type=r,u.request=a,n[1](u)}o[e]=void 0}};var s=setTimeout(function(){f({type:"timeout",target:l})},12e4);l.onerror=l.onload=f,document.head.appendChild(l)}return Promise.all(t)},i.m=e,i.c=r,i.d=function(e,t,n){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},i.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)i.d(n,r,function(t){return e[t]}.bind(null,r));return n},i.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="",i.oe=function(e){throw console.error(e),e};var f=window["webpackJsonp"]=window["webpackJsonp"]||[],l=f.push.bind(f);f.push=t,f=f.slice();for(var s=0;s<f.length;s++)t(f[s]);var d=l;n()})([]);</script><script src=static/js/chunk-elementUI.8ebdfbab.js></script><script src=static/js/chunk-libs.9cf9cc40.js></script><script src=static/js/app.3225a72c.js></script></body></html>
|
@@ -1 +0,0 @@
|
||||
.limit-tip[data-v-29df7fee]{cursor:pointer;margin-left:10px}
|
@@ -0,0 +1 @@
|
||||
.limit-tip[data-v-31efca04]{cursor:pointer;margin-left:10px}
|
@@ -0,0 +1 @@
|
||||
.custom-tree-node{-webkit-box-flex:1;-ms-flex:1;flex:1;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;font-size:14px;padding-right:8px}.el-input.is-disabled .el-input__inner,.el-radio__input.is-disabled+span.el-radio__label{color:#909399}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-19100986"],{5040:function(t,n,a){"use strict";var e=a("a5a4"),s=a.n(e);s.a},9406:function(t,n,a){"use strict";a.r(n);var e=function(){var t=this,n=t.$createElement;t._self._c;return t._m(0)},s=[function(){var t=this,n=t.$createElement,a=t._self._c||n;return a("div",{staticClass:"dashboard-container"},[a("div",{staticClass:"dashboard-text"},[t._v("欢迎使用SOP Admin")])])}],i={created:function(){this.post("admin.userinfo.get",{},function(t){})}},c=i,r=(a("5040"),a("2877")),o=Object(r["a"])(c,e,s,!1,null,"b4bd5162",null);n["default"]=o.exports},a5a4:function(t,n,a){}}]);
|
||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-37401378"],{5040:function(t,n,a){"use strict";var e=a("a5a4"),s=a.n(e);s.a},9406:function(t,n,a){"use strict";a.r(n);var e=function(){var t=this,n=t.$createElement;t._self._c;return t._m(0)},s=[function(){var t=this,n=t.$createElement,a=t._self._c||n;return a("div",{staticClass:"dashboard-container"},[a("div",{staticClass:"dashboard-text"},[t._v("欢迎使用SOP Admin")])])}],i={created:function(){this.post("admin.userinfo.get",{},function(t){})}},c=i,r=(a("5040"),a("2877")),o=Object(r["a"])(c,e,s,!1,null,"b4bd5162",null);n["default"]=o.exports},a5a4:function(t,n,a){}}]);
|
File diff suppressed because one or more lines are too long
@@ -8,7 +8,7 @@ import { getToken, removeToken } from './auth'
|
||||
// 创建axios实例
|
||||
const client = axios.create({
|
||||
baseURL: process.env.VUE_APP_BASE_API, // api 的 base_url
|
||||
timeout: 5000 // 请求超时时间
|
||||
timeout: 10000 // 请求超时时间
|
||||
})
|
||||
|
||||
Object.assign(Vue.prototype, {
|
||||
@@ -94,6 +94,14 @@ Object.assign(Vue.prototype, {
|
||||
}
|
||||
}).catch(function() {})
|
||||
},
|
||||
/**
|
||||
* 重置表单
|
||||
* @param formName 表单元素的ref
|
||||
*/
|
||||
resetForm(formName) {
|
||||
const frm = this.$refs[formName]
|
||||
frm && frm.resetFields()
|
||||
},
|
||||
logout: function() {
|
||||
removeToken()
|
||||
const fullPath = this.$route.fullPath
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-container>
|
||||
<el-aside style="min-height: 300px;width: 200px;">
|
||||
<el-aside style="min-height: 300px;width: 250px;">
|
||||
<el-input v-model="filterText" prefix-icon="el-icon-search" placeholder="搜索服务..." style="margin-bottom:20px;" size="mini" clearable />
|
||||
<el-tree
|
||||
ref="tree2"
|
||||
@@ -17,10 +17,10 @@
|
||||
@node-click="onNodeClick"
|
||||
>
|
||||
<span slot-scope="{ node, data }" class="custom-tree-node">
|
||||
<span v-if="data.label.length < 15">{{ data.label }}</span>
|
||||
<span v-if="data.label.length < serviceTextLimitSize">{{ data.label }}</span>
|
||||
<span v-else>
|
||||
<el-tooltip :content="data.label" class="item" effect="light" placement="right">
|
||||
<span>{{ data.label.substring(0, 15) + '...' }}</span>
|
||||
<span>{{ data.label.substring(0, serviceTextLimitSize) + '...' }}</span>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
</span>
|
||||
@@ -222,6 +222,7 @@
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
serviceTextLimitSize: 20,
|
||||
filterText: '',
|
||||
treeData: [],
|
||||
tableData: [],
|
||||
@@ -407,13 +408,8 @@ export default {
|
||||
}
|
||||
})
|
||||
},
|
||||
resetForm(formName) {
|
||||
const frm = this.$refs[formName]
|
||||
frm && frm.resetFields()
|
||||
},
|
||||
onLimitDialogClose: function() {
|
||||
this.resetForm('limitDialogForm')
|
||||
this.limitDialogVisible = false
|
||||
},
|
||||
infoRender: function(row) {
|
||||
const html = []
|
||||
|
@@ -1,28 +1,58 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-container>
|
||||
<el-aside style="min-height: 300px;width: 200px;">
|
||||
<el-input v-model="filterText" prefix-icon="el-icon-search" placeholder="搜索服务..." style="margin-bottom:20px;" size="mini" clearable />
|
||||
<el-aside style="min-height: 300px;width: 250px;">
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
size="mini"
|
||||
icon="el-icon-plus"
|
||||
@click.stop="addService"
|
||||
>
|
||||
新建服务
|
||||
</el-button>
|
||||
<el-input
|
||||
v-model="filterText"
|
||||
prefix-icon="el-icon-search"
|
||||
placeholder="搜索服务..."
|
||||
style="margin-bottom:10px;margin-top:10px;"
|
||||
size="mini"
|
||||
clearable
|
||||
/>
|
||||
<el-tree
|
||||
ref="tree2"
|
||||
ref="serviceTree"
|
||||
:data="treeData"
|
||||
:props="defaultProps"
|
||||
:filter-node-method="filterNode"
|
||||
:highlight-current="true"
|
||||
:expand-on-click-node="false"
|
||||
empty-text="无数据"
|
||||
node-key="id"
|
||||
node-key="serviceId"
|
||||
class="filter-tree"
|
||||
default-expand-all
|
||||
@node-click="onNodeClick"
|
||||
>
|
||||
<span slot-scope="{ node, data }" class="custom-tree-node">
|
||||
<span v-if="data.label.length < 15">{{ data.label }}</span>
|
||||
<div>
|
||||
<el-tooltip v-show="data.custom" content="自定义服务" class="item" effect="light" placement="top">
|
||||
<i class="el-icon-warning-outline"></i>
|
||||
</el-tooltip>
|
||||
<span v-if="data.label.length < serviceTextLimitSize">{{ data.label }}</span>
|
||||
<span v-else>
|
||||
<el-tooltip :content="data.label" class="item" effect="light" placement="right">
|
||||
<span>{{ data.label.substring(0, 15) + '...' }}</span>
|
||||
<span>{{ data.label.substring(0, serviceTextLimitSize) + '...' }}</span>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
</div>
|
||||
<span>
|
||||
<el-button
|
||||
v-if="data.custom === 1"
|
||||
type="text"
|
||||
size="mini"
|
||||
icon="el-icon-delete"
|
||||
title="删除服务"
|
||||
@click.stop="() => onDelService(data)"/>
|
||||
</span>
|
||||
</span>
|
||||
</el-tree>
|
||||
</el-aside>
|
||||
@@ -35,10 +65,20 @@
|
||||
<el-button type="primary" icon="el-icon-search" @click="onSearchTable">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-button
|
||||
v-show="isCustomService"
|
||||
type="primary"
|
||||
size="mini"
|
||||
icon="el-icon-plus"
|
||||
@click.stop="addRoute"
|
||||
>
|
||||
新建路由
|
||||
</el-button>
|
||||
<el-table
|
||||
:data="tableData"
|
||||
border
|
||||
max-height="500"
|
||||
style="margin-top: 10px;"
|
||||
>
|
||||
<el-table-column
|
||||
prop="name"
|
||||
@@ -69,12 +109,12 @@
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="ignoreValidate"
|
||||
label="忽略验证"
|
||||
label="签名校验"
|
||||
width="80"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.ignoreValidate === 1" style="color:#67C23A">是</span>
|
||||
<span v-if="scope.row.ignoreValidate === 0" style="color:#909399">否</span>
|
||||
<span v-if="scope.row.ignoreValidate === 0" style="color:#67C23A">校验</span>
|
||||
<span v-if="scope.row.ignoreValidate === 1" style="color:#E6A23C">不校验</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
@@ -93,7 +133,7 @@
|
||||
width="80"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.status === 0" style="color:#909399">待审核</span>
|
||||
<span v-if="scope.row.status === 0" style="color:#E6A23C">待审核</span>
|
||||
<span v-if="scope.row.status === 1" style="color:#67C23A">已启用</span>
|
||||
<span v-if="scope.row.status === 2" style="color:#F56C6C">已禁用</span>
|
||||
</template>
|
||||
@@ -106,24 +146,50 @@
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" size="mini" @click="onTableUpdate(scope.row)">修改</el-button>
|
||||
<el-button v-if="scope.row.permission" type="text" size="mini" @click="onTableAuth(scope.row)">授权</el-button>
|
||||
<el-button v-if="scope.row.custom" type="text" size="mini" @click="onTableDel(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-main>
|
||||
</el-container>
|
||||
<!-- route dialog -->
|
||||
<el-dialog title="修改路由" :visible.sync="routeDialogVisible" :close-on-click-modal="false">
|
||||
<el-dialog
|
||||
:title="routeDialogTitle"
|
||||
:visible.sync="routeDialogVisible"
|
||||
:close-on-click-modal="false"
|
||||
@close="onCloseRouteDialog"
|
||||
>
|
||||
<el-form
|
||||
ref="routeDialogFormRef"
|
||||
:model="routeDialogFormData"
|
||||
:rules="routeDialogFormRules"
|
||||
label-width="120px"
|
||||
size="mini"
|
||||
>
|
||||
<el-form-item label="id">
|
||||
<el-input v-model="routeDialogFormData.id" readonly="readonly" />
|
||||
<el-input v-show="false" v-model="routeDialogFormData.id" />
|
||||
<el-form-item label="接口名" prop="name">
|
||||
<el-input v-model="routeDialogFormData.name" placeholder="接口名,如:product.goods.list" :disabled="Boolean(routeDialogFormData.id)" />
|
||||
</el-form-item>
|
||||
<el-form-item label="uri">
|
||||
<el-input v-model="routeDialogFormData.uri" />
|
||||
<el-form-item label="版本号" prop="version">
|
||||
<el-input v-model="routeDialogFormData.version" placeholder="版本号,如:1.0" :disabled="Boolean(routeDialogFormData.id)" />
|
||||
</el-form-item>
|
||||
<el-form-item label="path">
|
||||
<el-input v-model="routeDialogFormData.path" />
|
||||
<el-form-item label="uri" prop="uri">
|
||||
<el-input v-model="routeDialogFormData.uri" placeholder="如:http://www.xx.com" :disabled="routePropDisabled()" />
|
||||
</el-form-item>
|
||||
<el-form-item label="path" prop="path">
|
||||
<el-input v-model="routeDialogFormData.path" placeholder="如:/order/list" :disabled="routePropDisabled()" />
|
||||
</el-form-item>
|
||||
<el-form-item label="签名校验">
|
||||
<el-radio-group v-model="routeDialogFormData.ignoreValidate" :disabled="routePropDisabled()">
|
||||
<el-radio :label="0" name="ignoreValidate">校验</el-radio>
|
||||
<el-radio :label="1" name="ignoreValidate">不校验</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="统一格式输出">
|
||||
<el-radio-group v-model="routeDialogFormData.mergeResult" :disabled="routePropDisabled()">
|
||||
<el-radio :label="1" name="mergeResult">是</el-radio>
|
||||
<el-radio :label="0" name="mergeResult">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态">
|
||||
<el-radio-group v-model="routeDialogFormData.status">
|
||||
@@ -138,7 +204,11 @@
|
||||
</div>
|
||||
</el-dialog>
|
||||
<!-- auth dialog -->
|
||||
<el-dialog title="路由授权" :visible.sync="authDialogVisible" :close-on-click-modal="false">
|
||||
<el-dialog
|
||||
title="路由授权"
|
||||
:visible.sync="authDialogVisible"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<el-form
|
||||
:model="authDialogFormData"
|
||||
label-width="120px"
|
||||
@@ -158,27 +228,88 @@
|
||||
<el-button type="primary" @click="onAuthDialogSave">保 存</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</el-main>
|
||||
</el-container>
|
||||
<!--添加服务-->
|
||||
<el-dialog
|
||||
title="添加服务"
|
||||
:visible.sync="addServiceDialogVisible"
|
||||
:close-on-click-modal="false"
|
||||
@close="closeAddServiceDlg"
|
||||
>
|
||||
<el-form
|
||||
ref="addServiceForm"
|
||||
:model="addServiceForm"
|
||||
:rules="addServiceFormRules"
|
||||
label-width="200px"
|
||||
>
|
||||
<el-form-item label="服务名(serviceId)" prop="serviceId">
|
||||
<el-input v-model="addServiceForm.serviceId" placeholder="服务名,如:order-service" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="addServiceDialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onAddService">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.custom-tree-node {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-size: 14px;
|
||||
padding-right: 8px;
|
||||
}
|
||||
.el-input.is-disabled .el-input__inner {color: #909399;}
|
||||
.el-radio__input.is-disabled+span.el-radio__label {color: #909399;}
|
||||
</style>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
serviceTextLimitSize: 20,
|
||||
filterText: '',
|
||||
treeData: [],
|
||||
tableData: [],
|
||||
serviceId: '',
|
||||
searchFormData: {},
|
||||
isCustomService: false,
|
||||
searchFormData: {
|
||||
id: '',
|
||||
serviceId: ''
|
||||
},
|
||||
defaultProps: {
|
||||
children: 'children',
|
||||
label: 'label'
|
||||
},
|
||||
routeDialogTitle: '修改路由',
|
||||
// dialog
|
||||
routeDialogFormData: {
|
||||
status: 1
|
||||
id: '',
|
||||
name: '',
|
||||
version: '1.0',
|
||||
uri: '',
|
||||
path: '',
|
||||
status: 1,
|
||||
mergeResult: 1,
|
||||
ignoreValidate: 0
|
||||
},
|
||||
routeDialogFormRules: {
|
||||
name: [
|
||||
{ required: true, message: '不能为空', trigger: 'blur' },
|
||||
{ min: 1, max: 100, message: '长度在 1 到 100 个字符', trigger: 'blur' }
|
||||
],
|
||||
version: [
|
||||
{ required: true, message: '不能为空', trigger: 'blur' },
|
||||
{ min: 1, max: 100, message: '长度在 1 到 100 个字符', trigger: 'blur' }
|
||||
],
|
||||
uri: [
|
||||
{ required: true, message: '不能为空', trigger: 'blur' },
|
||||
{ min: 1, max: 100, message: '长度在 1 到 100 个字符', trigger: 'blur' }
|
||||
],
|
||||
path: [
|
||||
{ min: 0, max: 100, message: '长度不能超过 100 个字符', trigger: 'blur' }
|
||||
]
|
||||
},
|
||||
routeDialogVisible: false,
|
||||
roles: [],
|
||||
@@ -186,12 +317,23 @@ export default {
|
||||
routeId: '',
|
||||
roleCode: []
|
||||
},
|
||||
authDialogVisible: false
|
||||
authDialogVisible: false,
|
||||
// addService
|
||||
addServiceDialogVisible: false,
|
||||
addServiceForm: {
|
||||
serviceId: ''
|
||||
},
|
||||
addServiceFormRules: {
|
||||
serviceId: [
|
||||
{ required: true, message: '请输入服务名称', trigger: 'blur' },
|
||||
{ min: 1, max: 100, message: '长度在 1 到 100 个字符', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
filterText(val) {
|
||||
this.$refs.tree2.filter(val)
|
||||
this.$refs.serviceTree.filter(val)
|
||||
}
|
||||
},
|
||||
created() {
|
||||
@@ -204,6 +346,12 @@ export default {
|
||||
this.post('service.list', {}, function(resp) {
|
||||
const respData = resp.data
|
||||
this.treeData = this.convertToTreeData(respData, 0)
|
||||
this.$nextTick(() => {
|
||||
// 高亮已选中的
|
||||
if (this.serviceId) {
|
||||
this.$refs.serviceTree.setCurrentKey(this.serviceId)
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
// 树搜索
|
||||
@@ -216,6 +364,7 @@ export default {
|
||||
if (data.parentId) {
|
||||
this.serviceId = data.label
|
||||
this.searchFormData.serviceId = this.serviceId
|
||||
this.isCustomService = Boolean(data.custom)
|
||||
this.loadTable()
|
||||
}
|
||||
},
|
||||
@@ -250,16 +399,18 @@ export default {
|
||||
}
|
||||
const children = []
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
const item = { label: data[i].serviceId, parentId: 1 }
|
||||
children.push(item)
|
||||
data[i].parentId = 1
|
||||
data[i].label = data[i].serviceId
|
||||
children.push(data[i])
|
||||
}
|
||||
root.children = children
|
||||
result.push(root)
|
||||
return result
|
||||
},
|
||||
// table
|
||||
loadTable: function() {
|
||||
this.post('route.list', this.searchFormData, function(resp) {
|
||||
loadTable: function(param) {
|
||||
const postData = param || this.searchFormData
|
||||
this.post('route.list', postData, function(resp) {
|
||||
this.tableData = resp.data
|
||||
})
|
||||
},
|
||||
@@ -267,8 +418,11 @@ export default {
|
||||
this.loadTable()
|
||||
},
|
||||
onTableUpdate: function(row) {
|
||||
Object.assign(this.routeDialogFormData, row)
|
||||
this.routeDialogTitle = '修改路由'
|
||||
this.routeDialogVisible = true
|
||||
this.$nextTick(() => {
|
||||
Object.assign(this.routeDialogFormData, row)
|
||||
})
|
||||
},
|
||||
onTableAuth: function(row) {
|
||||
this.authDialogFormData.routeId = row.id
|
||||
@@ -283,6 +437,28 @@ export default {
|
||||
this.authDialogVisible = true
|
||||
})
|
||||
},
|
||||
onTableDel: function(row) {
|
||||
this.confirm(`确认要删除路由【${row.id}】吗?`, function(done) {
|
||||
const data = {
|
||||
serviceId: this.serviceId,
|
||||
id: row.id
|
||||
}
|
||||
this.post('route.del', data, function() {
|
||||
done()
|
||||
this.tip('删除成功')
|
||||
this.loadTable()
|
||||
})
|
||||
})
|
||||
},
|
||||
onCloseRouteDialog: function() {
|
||||
this.resetForm('routeDialogFormRef')
|
||||
},
|
||||
routePropDisabled: function() {
|
||||
if (!this.routeDialogFormData.id) {
|
||||
return false
|
||||
}
|
||||
return !this.isCustomService
|
||||
},
|
||||
loadRouteRole: function() {
|
||||
if (this.roles.length === 0) {
|
||||
this.post('role.listall', {}, function(resp) {
|
||||
@@ -290,6 +466,15 @@ export default {
|
||||
})
|
||||
}
|
||||
},
|
||||
addRoute: function() {
|
||||
this.routeDialogTitle = '新建路由'
|
||||
this.routeDialogVisible = true
|
||||
this.$nextTick(() => {
|
||||
Object.assign(this.routeDialogFormData, {
|
||||
id: ''
|
||||
})
|
||||
})
|
||||
},
|
||||
roleRender: function(row) {
|
||||
if (!row.permission) {
|
||||
return '(公开)'
|
||||
@@ -302,18 +487,52 @@ export default {
|
||||
return html.length > 0 ? html.join(', ') : '<span class="x-red">未授权</span>'
|
||||
},
|
||||
onRouteDialogSave: function() {
|
||||
this.$refs.routeDialogFormRef.validate((valid) => {
|
||||
if (valid) {
|
||||
const uri = this.routeDialogFormData.id ? 'route.update' : 'route.add'
|
||||
this.routeDialogFormData.serviceId = this.serviceId
|
||||
this.post('route.update', this.routeDialogFormData, function() {
|
||||
this.post(uri, this.routeDialogFormData, function() {
|
||||
this.routeDialogVisible = false
|
||||
this.loadTable()
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
onAuthDialogSave: function() {
|
||||
this.post('route.role.update', this.authDialogFormData, function() {
|
||||
console.log(this.authDialogFormData)
|
||||
this.authDialogVisible = false
|
||||
this.loadTable()
|
||||
})
|
||||
},
|
||||
addService: function() {
|
||||
this.addServiceDialogVisible = true
|
||||
},
|
||||
closeAddServiceDlg: function() {
|
||||
this.$refs.addServiceForm.resetFields()
|
||||
},
|
||||
onAddService: function() {
|
||||
this.$refs.addServiceForm.validate((valid) => {
|
||||
if (valid) {
|
||||
this.post('service.custom.add', this.addServiceForm, function(resp) {
|
||||
this.addServiceDialogVisible = false
|
||||
this.tip('添加成功')
|
||||
this.loadTree()
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
onDelService: function(data) {
|
||||
const serviceId = data.serviceId
|
||||
this.confirm('确认要删除服务' + serviceId + '吗,【对应的路由配置会一起删除】', function(done) {
|
||||
const postData = {
|
||||
serviceId: serviceId
|
||||
}
|
||||
this.post('service.custom.del', postData, function() {
|
||||
done()
|
||||
this.tip('删除成功')
|
||||
this.loadTree()
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user