diff --git a/changelog.md b/changelog.md index ef98b6e5..ca5e3fe7 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,9 @@ # changelog +## 1.10.0 + +- 新增监控日志 + ## 1.9.0 - 改造限流 diff --git a/doc/docs/_sidebar.md b/doc/docs/_sidebar.md index 66f4775d..bfce503d 100644 --- a/doc/docs/_sidebar.md +++ b/doc/docs/_sidebar.md @@ -1,27 +1,28 @@ -* [首页](/?t=1559633402239) +* [首页](/?t=1559803778913) * 开发文档 - * [快速体验](files/10010_快速体验.md?t=1559633402241) - * [项目接入到SOP](files/10011_项目接入到SOP.md?t=1559633402260) - * [新增接口](files/10020_新增接口.md?t=1559633402260) - * [业务参数校验](files/10030_业务参数校验.md?t=1559633402260) - * [错误处理](files/10040_错误处理.md?t=1559633402260) - * [编写文档](files/10041_编写文档.md?t=1559633402260) - * [接口交互详解](files/10050_接口交互详解.md?t=1559633402261) - * [easyopen支持](files/10070_easyopen支持.md?t=1559633402261) - * [使用签名校验工具](files/10080_使用签名校验工具.md?t=1559633402261) - * [ISV管理](files/10085_ISV管理.md?t=1559633402261) - * [路由授权](files/10090_路由授权.md?t=1559633402261) - * [接口限流](files/10092_接口限流.md?t=1559633402261) - * [SDK开发](files/10095_SDK开发.md?t=1559633402261) - * [使用SpringCloudGateway](files/10096_使用SpringCloudGateway.md?t=1559633402261) - * [应用授权](files/10097_应用授权.md?t=1559633402261) - * [更改数据节点名称](files/10099_更改数据节点名称.md?t=1559633402262) - * [对接前端](files/10100_对接前端.md?t=1559633402262) - * [自定义过滤器](files/10102_自定义过滤器.md?t=1559633402262) - * [文件上传](files/10104_文件上传.md?t=1559633402262) + * [快速体验](files/10010_快速体验.md?t=1559803778920) + * [项目接入到SOP](files/10011_项目接入到SOP.md?t=1559803778940) + * [新增接口](files/10020_新增接口.md?t=1559803778940) + * [业务参数校验](files/10030_业务参数校验.md?t=1559803778940) + * [错误处理](files/10040_错误处理.md?t=1559803778940) + * [编写文档](files/10041_编写文档.md?t=1559803778941) + * [接口交互详解](files/10050_接口交互详解.md?t=1559803778941) + * [easyopen支持](files/10070_easyopen支持.md?t=1559803778941) + * [使用签名校验工具](files/10080_使用签名校验工具.md?t=1559803778941) + * [ISV管理](files/10085_ISV管理.md?t=1559803778941) + * [路由授权](files/10090_路由授权.md?t=1559803778941) + * [接口限流](files/10092_接口限流.md?t=1559803778941) + * [监控日志](files/10093_监控日志.md?t=1559803778941) + * [SDK开发](files/10095_SDK开发.md?t=1559803778941) + * [使用SpringCloudGateway](files/10096_使用SpringCloudGateway.md?t=1559803778942) + * [应用授权](files/10097_应用授权.md?t=1559803778942) + * [更改数据节点名称](files/10099_更改数据节点名称.md?t=1559803778942) + * [对接前端](files/10100_对接前端.md?t=1559803778942) + * [自定义过滤器](files/10102_自定义过滤器.md?t=1559803778942) + * [文件上传](files/10104_文件上传.md?t=1559803778942) * 原理分析 - * [原理分析之@ApiMapping](files/90010_原理分析之@ApiMapping.md?t=1559633402262) - * [原理分析之路由存储](files/90011_原理分析之路由存储.md?t=1559633402262) - * [原理分析之如何路由](files/90012_原理分析之如何路由.md?t=1559633402262) - * [原理分析之文档归纳](files/90013_原理分析之文档归纳.md?t=1559633402262) - * [常见问题](files/90100_常见问题.md?t=1559633402262) + * [原理分析之@ApiMapping](files/90010_原理分析之@ApiMapping.md?t=1559803778942) + * [原理分析之路由存储](files/90011_原理分析之路由存储.md?t=1559803778942) + * [原理分析之如何路由](files/90012_原理分析之如何路由.md?t=1559803778942) + * [原理分析之文档归纳](files/90013_原理分析之文档归纳.md?t=1559803778942) + * [常见问题](files/90100_常见问题.md?t=1559803778942) diff --git a/doc/docs/files/10093_监控日志.md b/doc/docs/files/10093_监控日志.md new file mode 100644 index 00000000..47941706 --- /dev/null +++ b/doc/docs/files/10093_监控日志.md @@ -0,0 +1,44 @@ +# 监控日志 + +1.10.0开始sop-admin提供了简单的监控日志查询,方便在线排查问题。 + +- 错误日志统一在网关负责收集 +- 只收集未知类型的错误日志,开发人员主动throw的异常不收集 +- sop-admin通过网关提供的restful接口获取日志内容,然后在后台展示 +- 收集的日志存放在内存中,重启网关日志会消失 +- 只会收集20条不同的日志内容,相同内容会count+1。可设置`ApiConfig.storeErrorCapacity`属性扩大容量,默认容量20 + +第一次使用需要添加网关服务器实例,前往:`服务管理--监控日志--添加监控服务器` + +## 永久保存日志 + +默认收集的日志存放在内存中,重启网关日志会消失(见:`DefaultServiceErrorManager.java`)。如果要永久保存日志内容,需要自己实现`ServiceErrorManager`接口 + +```java +public class MyServiceErrorManager implements ServiceErrorManager { + ... +} +``` + +然后在ApiConfig中配置 + +```java +@Configuration +public class ZuulConfig extends AlipayZuulConfiguration { + + static { + ... + ApiConfig.getInstance().setServiceErrorManager(new MyServiceErrorManager()); + // 日志收集容量,默认20。只会收集20条不同内容的日志 + ApiConfig.getInstance().setStoreErrorCapacity(20); + ... + } + +} +``` + +- 后台预览 + +![监控日志](images/10093_1.png "10093_1.png") + +![监控日志](images/10093_2.png "10093_2.png") \ No newline at end of file diff --git a/doc/docs/files/images/10093_1.png b/doc/docs/files/images/10093_1.png new file mode 100644 index 00000000..74c70779 Binary files /dev/null and b/doc/docs/files/images/10093_1.png differ diff --git a/doc/docs/files/images/10093_2.png b/doc/docs/files/images/10093_2.png new file mode 100644 index 00000000..997081cf Binary files /dev/null and b/doc/docs/files/images/10093_2.png differ diff --git a/sop-1.10.0.sql b/sop-1.10.0.sql new file mode 100644 index 00000000..8a525835 --- /dev/null +++ b/sop-1.10.0.sql @@ -0,0 +1,13 @@ +DROP TABLE IF EXISTS `config_common`; + +CREATE TABLE `config_common` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `config_group` varchar(64) NOT NULL DEFAULT '' COMMENT '配置分组', + `config_key` varchar(64) NOT NULL DEFAULT '' COMMENT '配置key', + `content` varchar(128) NOT NULL DEFAULT '' COMMENT '内容', + `remark` varchar(128) DEFAULT NULL COMMENT '备注', + `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + UNIQUE KEY `uk_groupkey` (`config_group`,`config_key`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='通用配置表'; diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/LimitNewApi.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/LimitNewApi.java index e665bbb6..e31fe409 100644 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/LimitNewApi.java +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/LimitNewApi.java @@ -9,39 +9,27 @@ import com.gitee.easyopen.util.CopyUtil; import com.gitee.fastmybatis.core.PageInfo; import com.gitee.fastmybatis.core.query.Query; import com.gitee.fastmybatis.core.query.Sort; -import com.gitee.fastmybatis.core.query.expression.ValueExpression; import com.gitee.fastmybatis.core.util.MapperUtil; -import com.gitee.fastmybatis.core.util.MyBeanUtil; import com.gitee.sop.adminserver.api.service.param.LimitNewAddParam; 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.param.RouteSearchParam; import com.gitee.sop.adminserver.api.service.result.LimitNewVO; import com.gitee.sop.adminserver.bean.ConfigLimitDto; -import com.gitee.sop.adminserver.bean.GatewayRouteDefinition; -import com.gitee.sop.adminserver.common.LimitEnum; import com.gitee.sop.adminserver.entity.ConfigLimit; import com.gitee.sop.adminserver.mapper.ConfigLimitMapper; import com.gitee.sop.adminserver.service.RouteConfigService; import com.gitee.sop.adminserver.service.RouteService; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang.BooleanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.function.Function; -import java.util.stream.Collectors; - /** * 限流 * * @author tanghc */ @ApiService -@ApiDoc("服务管理") +@ApiDoc("服务管理-限流管理") @Slf4j public class LimitNewApi { diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/LogApi.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/LogApi.java new file mode 100644 index 00000000..ad037c42 --- /dev/null +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/LogApi.java @@ -0,0 +1,169 @@ +package com.gitee.sop.adminserver.api.service; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +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.QueryUtil; +import com.gitee.sop.adminserver.entity.ConfigCommon; +import com.gitee.sop.adminserver.mapper.ConfigCommonMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.client.RestTemplate; + +import javax.validation.constraints.NotNull; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @author tanghc + */ +@ApiService +@ApiDoc("服务管理-日志监控") +@Slf4j +public class LogApi { + + public static final String LOG_MONITOR_INSTANCE = "log.monitor.instance"; + public static final String CODE_SUCCESS = "10000"; + + @Autowired + ConfigCommonMapper configCommonMapper; + + RestTemplate restTemplate = new RestTemplate(); + + @Value("${zuul.secret}") + private String secret; + + @Api(name = "monitor.log.list") + @ApiDocMethod(description = "获取监控日志") + List listLog() { + List configCommonList = configCommonMapper.listByColumn("config_group", LOG_MONITOR_INSTANCE); + List ret = new ArrayList<>(); + int id = 1; + for (ConfigCommon configCommon : configCommonList) { + int pid = id++; + String ipPort = configCommon.getConfigKey(); + // 父节点 + LogMonitorInstanceVO logMonitorInstanceVOParent = new LogMonitorInstanceVO(); + logMonitorInstanceVOParent.setRawId(configCommon.getId()); + logMonitorInstanceVOParent.setTreeId(pid); + logMonitorInstanceVOParent.setMonitorName(configCommon.getContent()); + ret.add(logMonitorInstanceVOParent); + try { + String logData = this.requestLogServer(ipPort, "listErrors"); + JSONObject jsonObject = JSON.parseObject(logData); + if (CODE_SUCCESS.equals(jsonObject.getString("code"))) { + int errorTotal = 0; + List data = JSON.parseArray(jsonObject.getString("data"), LogMonitorInstanceVO.class); + for (LogMonitorInstanceVO instanceVO : data) { + instanceVO.setTreeId(id++); + instanceVO.setParentId(pid); + errorTotal += instanceVO.getCount(); + } + ret.addAll(data); + logMonitorInstanceVOParent.setCount(errorTotal); + } + } catch (Exception e) { + log.error("获取日志信息出错", e); + throw new ApiException("获取日志信息出错"); + } + } + Collections.sort(ret, Comparator.comparing(LogMonitorInstanceVO::getCount)); + return ret; + } + + @Api(name = "monitor.log.clear") + @ApiDocMethod(description = "清空日志") + void clearLog(@NotNull(message = "id不能为空") Long id) { + ConfigCommon configCommon = configCommonMapper.getById(id); + if (configCommon == null) { + return; + } + try { + String ipPort = configCommon.getConfigKey(); + this.requestLogServer(ipPort, "clearErrors"); + } catch (Exception e) { + throw new ApiException("清除失败"); + } + } + + @Api(name = "monitor.instance.list") + @ApiDocMethod(description = "获取已添加的监控实例") + List listServiceInstance() { + List configCommonList = configCommonMapper.listByColumn("config_group", LOG_MONITOR_INSTANCE); + return configCommonList.stream() + .map(ConfigCommon::getConfigKey) + .collect(Collectors.toList()); + } + + @Api(name = "monitor.instance.add") + @ApiDocMethod(description = "添加监控实例") + void addServiceInstance(LogMonitorInstanceAddParam param) { + String ipPort = param.getIp() + ":" + param.getPort(); + this.checkInstance(ipPort); + + Query query = new Query(); + query.eq("config_group", LOG_MONITOR_INSTANCE) + .eq("config_key", ipPort); + ConfigCommon rec = configCommonMapper.getByQuery(query); + if (rec != null) { + throw new ApiException("该实例已添加"); + } + ConfigCommon configCommon = new ConfigCommon(); + configCommon.setConfigGroup(LOG_MONITOR_INSTANCE); + configCommon.setConfigKey(ipPort); + configCommon.setContent(param.getServiceId() + "(" + ipPort + ")"); + configCommonMapper.saveIgnoreNull(configCommon); + } + + private void checkInstance(String ipPort) { + try { + String json = this.requestLogServer(ipPort, "listErrors"); + JSONObject jsonObject = JSON.parseObject(json); + if (!CODE_SUCCESS.equals(jsonObject.getString("code"))) { + log.error("请求结果:{}", json); + throw new ApiException("添加失败"); + } + } catch (Exception e) { + log.error("添加失败", e); + throw new ApiException("添加失败"); + } + } + + private String requestLogServer(String ipPort, String path) throws Exception { + DefaultMd5Verifier md5Verifier = new DefaultMd5Verifier(); + Map params = new HashMap<>(); + params.put("time", System.currentTimeMillis()); + String sign = md5Verifier.buildSign(params, secret); + params.put("sign", sign); + String query = QueryUtil.buildQueryString(params); + String url = "http://" + ipPort + "/" + path + "?" + query; + ResponseEntity entity = restTemplate.getForEntity(url, String.class); + if (entity.getStatusCode() != HttpStatus.OK) { + throw new IllegalAccessException("无权访问"); + } + return entity.getBody(); + } + + @Api(name = "monitor.instance.del") + @ApiDocMethod(description = "删除监控实例") + void delServiceInstance(@NotNull(message = "id不能为空") Long id) { + configCommonMapper.deleteById(id); + } + +} diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/RouteApi.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/RouteApi.java index d0dab1d1..433a0b00 100644 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/RouteApi.java +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/RouteApi.java @@ -43,7 +43,7 @@ import java.util.stream.Collectors; * @author tanghc */ @ApiService -@ApiDoc("服务管理") +@ApiDoc("服务管理-路由管理") @Slf4j public class RouteApi { diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/ServiceApi.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/ServiceApi.java index aab9df9c..93653a3b 100644 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/ServiceApi.java +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/ServiceApi.java @@ -36,7 +36,7 @@ import java.util.stream.Collectors; * @author tanghc */ @ApiService -@ApiDoc("服务管理") +@ApiDoc("服务管理-服务列表") @Slf4j public class ServiceApi { diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/param/LogMonitorInstanceAddParam.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/param/LogMonitorInstanceAddParam.java new file mode 100644 index 00000000..bc618268 --- /dev/null +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/param/LogMonitorInstanceAddParam.java @@ -0,0 +1,19 @@ +package com.gitee.sop.adminserver.api.service.param; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +/** + * @author tanghc + */ +@Data +public class LogMonitorInstanceAddParam { + @NotBlank(message = "serviceId不能为空") + private String serviceId; + + @NotBlank(message = "ip不能为空") + private String ip; + + private int port; +} diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/result/LogMonitorInstanceVO.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/result/LogMonitorInstanceVO.java new file mode 100644 index 00000000..ab20e814 --- /dev/null +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/api/service/result/LogMonitorInstanceVO.java @@ -0,0 +1,22 @@ +package com.gitee.sop.adminserver.api.service.result; + +import lombok.Data; + +/** + * @author tanghc + */ +@Data +public class LogMonitorInstanceVO { + private String id; + private int treeId; + // 表主键 + private long rawId; + private String name; + private String version; + private String serviceId; + private String errorMsg; + private long count; + + private int parentId; + private String monitorName; +} diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/common/QueryUtil.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/common/QueryUtil.java new file mode 100644 index 00000000..1f00e5c7 --- /dev/null +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/common/QueryUtil.java @@ -0,0 +1,28 @@ +package com.gitee.sop.adminserver.common; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.Map; + +/** + * @author tanghc + */ +public class QueryUtil { + + public static String buildQueryString(Map params) throws UnsupportedEncodingException { + if (params == null || params.size() == 0) { + return ""; + } + StringBuilder query = new StringBuilder(); + int i = 0; + for (Map.Entry entry : params.entrySet()) { + String name = entry.getKey(); + String value = String.valueOf(entry.getValue()); + if (i++ > 0) { + query.append("&"); + } + query.append(name).append("=").append(URLEncoder.encode(value, "UTF-8")); + } + return query.toString(); + } +} diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/config/WebConfig.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/config/WebConfig.java index fe565750..7c8be1f3 100644 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/config/WebConfig.java +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/config/WebConfig.java @@ -32,9 +32,10 @@ public class WebConfig { @Bean ApiConfig apiConfig() { ApiConfig apiConfig = new ApiConfig(); - apiConfig.setJsonResultSerializer(obj -> { - return JSON.toJSONString(obj, SerializerFeature.WriteDateUseDateFormat); - }); + apiConfig.setJsonResultSerializer(obj -> JSON.toJSONString(obj, + SerializerFeature.WriteDateUseDateFormat + , SerializerFeature.WriteNullStringAsEmpty + , SerializerFeature.WriteMapNullValue)); ApiSessionManager apiSessionManager = new ApiSessionManager(); // session有效期 int timeout = NumberUtils.toInt(accessTokenTimeout, 30); diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/entity/ConfigCommon.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/entity/ConfigCommon.java new file mode 100644 index 00000000..cf85d185 --- /dev/null +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/entity/ConfigCommon.java @@ -0,0 +1,45 @@ +package com.gitee.sop.adminserver.entity; + +import lombok.Data; + +import javax.persistence.Column; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import java.util.Date; + + +/** + * 表名:config_common + * 备注:通用配置表 + * + * @author tanghc + */ +@Table(name = "config_common") +@Data +public class ConfigCommon { + @Id + @Column(name = "id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + /** 数据库字段:id */ + private Long id; + + /** 配置分组, 数据库字段:config_group */ + private String configGroup; + + /** 配置key, 数据库字段:config_key */ + private String configKey; + + /** 内容, 数据库字段:content */ + private String content; + + /** 备注, 数据库字段:remark */ + private String remark; + + /** 数据库字段:gmt_create */ + private Date gmtCreate; + + /** 数据库字段:gmt_modified */ + private Date gmtModified; +} diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/mapper/ConfigCommonMapper.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/mapper/ConfigCommonMapper.java new file mode 100644 index 00000000..5a854616 --- /dev/null +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/mapper/ConfigCommonMapper.java @@ -0,0 +1,12 @@ +package com.gitee.sop.adminserver.mapper; + +import com.gitee.fastmybatis.core.mapper.CrudMapper; + +import com.gitee.sop.adminserver.entity.ConfigCommon; + + +/** + * @author tanghc + */ +public interface ConfigCommonMapper extends CrudMapper { +} diff --git a/sop-admin/sop-admin-server/src/main/resources/application-dev.yml b/sop-admin/sop-admin-server/src/main/resources/application-dev.yml index f9ff1e38..e33f7e29 100644 --- a/sop-admin/sop-admin-server/src/main/resources/application-dev.yml +++ b/sop-admin/sop-admin-server/src/main/resources/application-dev.yml @@ -48,3 +48,7 @@ logging: mybatis: fill: {com.gitee.fastmybatis.core.support.DateFillInsert: gmt_create, com.gitee.fastmybatis.core.support.DateFillUpdate: gmt_modified} + +# 不用改,如果要改,建议全局替换修改 +zuul: + secret: MZZOUSTua6LzApIWXCwEgbBmxSzpzC \ No newline at end of file diff --git a/sop-admin/sop-admin-server/src/main/resources/public/index.html b/sop-admin/sop-admin-server/src/main/resources/public/index.html index 3e09c066..3cb31bb6 100644 --- a/sop-admin/sop-admin-server/src/main/resources/public/index.html +++ b/sop-admin/sop-admin-server/src/main/resources/public/index.html @@ -1 +1 @@ -SOP Admin
\ No newline at end of file +SOP Admin
\ No newline at end of file diff --git a/sop-admin/sop-admin-server/src/main/resources/public/static/js/app.bc31495f.js b/sop-admin/sop-admin-server/src/main/resources/public/static/js/app.36a3cb86.js similarity index 51% rename from sop-admin/sop-admin-server/src/main/resources/public/static/js/app.bc31495f.js rename to sop-admin/sop-admin-server/src/main/resources/public/static/js/app.36a3cb86.js index 70c85c97..d0df45df 100644 --- a/sop-admin/sop-admin-server/src/main/resources/public/static/js/app.bc31495f.js +++ b/sop-admin/sop-admin-server/src/main/resources/public/static/js/app.36a3cb86.js @@ -1 +1 @@ -(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["app"],{0:function(e,t,n){e.exports=n("56d7")},"0cb8":function(e,t,n){},"186a":function(e,t,n){"use strict";var a=n("dc52"),i=n.n(a);i.a},"18f0":function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),s=new i.a({id:"icon-link",use:"icon-link-usage",viewBox:"0 0 128 128",content:''});r.a.add(s);t["default"]=s},"1f59":function(e,t,n){},2536:function(e,t,n){},2635:function(e,t,n){},"2a3d":function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),s=new i.a({id:"icon-password",use:"icon-password-usage",viewBox:"0 0 128 128",content:''});r.a.add(s);t["default"]=s},"30c3":function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),s=new i.a({id:"icon-example",use:"icon-example-usage",viewBox:"0 0 128 128",content:''});r.a.add(s);t["default"]=s},"34c8":function(e,t,n){"use strict";var a=n("5332"),i=n.n(a);i.a},"405a":function(e,t,n){"use strict";var a=n("1f59"),i=n.n(a);i.a},"47f1":function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),s=new i.a({id:"icon-table",use:"icon-table-usage",viewBox:"0 0 128 128",content:''});r.a.add(s);t["default"]=s},"4df5":function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),s=new i.a({id:"icon-eye",use:"icon-eye-usage",viewBox:"0 0 128 64",content:''});r.a.add(s);t["default"]=s},"50be":function(e,t,n){"use strict";var a=n("2536"),i=n.n(a);i.a},"51ff":function(e,t,n){var a={"./dashboard.svg":"f782","./example.svg":"30c3","./eye-open.svg":"d7ec","./eye.svg":"4df5","./form.svg":"eb1b","./link.svg":"18f0","./nested.svg":"dcf8","./password.svg":"2a3d","./table.svg":"47f1","./tree.svg":"93cd","./user.svg":"b3b5"};function i(e){var t=o(e);return n(t)}function o(e){var t=a[e];if(!(t+1)){var n=new Error("Cannot find module '"+e+"'");throw n.code="MODULE_NOT_FOUND",n}return t}i.keys=function(){return Object.keys(a)},i.resolve=o,e.exports=i,i.id="51ff"},5332:function(e,t,n){},"56d7":function(e,t,n){"use strict";n.r(t);n("cadf"),n("551c"),n("f751"),n("097d");var a=n("2b0e"),i=(n("f5df"),n("5c96")),o=n.n(i),r=(n("0fae"),n("f0d9")),s=n.n(r),c=(n("b20f"),function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{attrs:{id:"app"}},[n("router-view")],1)}),u=[],l={name:"App"},d=l,h=n("2877"),m=Object(h["a"])(d,c,u,!1,null,null,null),f=m.exports,p=n("2f62"),v=(n("7f7f"),{sidebar:function(e){return e.app.sidebar},device:function(e){return e.app.device},token:function(e){return e.user.token},avatar:function(e){return e.user.avatar},name:function(e){return e.user.name}}),b=v,g=n("a78e"),w=n.n(g),x={sidebar:{opened:!w.a.get("sidebarStatus")||!!+w.a.get("sidebarStatus"),withoutAnimation:!1},device:"desktop"},y={TOGGLE_SIDEBAR:function(e){e.sidebar.opened=!e.sidebar.opened,e.sidebar.withoutAnimation=!1,e.sidebar.opened?w.a.set("sidebarStatus",1):w.a.set("sidebarStatus",0)},CLOSE_SIDEBAR:function(e,t){w.a.set("sidebarStatus",0),e.sidebar.opened=!1,e.sidebar.withoutAnimation=t},TOGGLE_DEVICE:function(e,t){e.device=t}},_={toggleSideBar:function(e){var t=e.commit;t("TOGGLE_SIDEBAR")},closeSideBar:function(e,t){var n=e.commit,a=t.withoutAnimation;n("CLOSE_SIDEBAR",a)},toggleDevice:function(e,t){var n=e.commit;n("TOGGLE_DEVICE",t)}},C={namespaced:!0,state:x,mutations:y,actions:_},k=n("83d6"),O=n.n(k),S=O.a.showSettings,z=O.a.fixedHeader,B=O.a.sidebarLogo,H={showSettings:S,fixedHeader:z,sidebarLogo:B},M={CHANGE_SETTING:function(e,t){var n=t.key,a=t.value;e.hasOwnProperty(n)&&(e[n]=a)}},T={changeSetting:function(e,t){var n=e.commit;n("CHANGE_SETTING",t)}},E={namespaced:!0,state:H,mutations:M,actions:T},L=n("bc3a"),$=n.n(L),V=n("5f87"),A=$.a.create({baseURL:"/api",withCredentials:!0,timeout:5e3});A.interceptors.request.use(function(e){return bt.getters.token&&(e.headers["X-Token"]=Object(V["a"])()),e},function(e){return console.log(e),Promise.reject(e)}),A.interceptors.response.use(function(e){var t=e.data;return 2e4!==t.code?(Object(i["Message"])({message:t.message||"error",type:"error",duration:5e3}),50008!==t.code&&50012!==t.code&&50014!==t.code||i["MessageBox"].confirm("You have been logged out, you can cancel to stay on this page, or log in again","Confirm logout",{confirmButtonText:"Re-Login",cancelButtonText:"Cancel",type:"warning"}).then(function(){bt.dispatch("user/resetToken").then(function(){location.reload()})}),Promise.reject(t.message||"error")):t},function(e){return console.log("err"+e),Object(i["Message"])({message:e.message,type:"error",duration:5e3}),Promise.reject(e)});var j=A;function P(e){return j({url:"/user/login",method:"post",data:e})}function I(e){return j({url:"/user/info",method:"get",params:{token:e}})}function N(){return j({url:"/user/logout",method:"post"})}var D=n("8c4f"),q=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"app-wrapper",class:e.classObj},["mobile"===e.device&&e.sidebar.opened?n("div",{staticClass:"drawer-bg",on:{click:e.handleClickOutside}}):e._e(),e._v(" "),n("sidebar",{staticClass:"sidebar-container"}),e._v(" "),n("div",{staticClass:"main-container"},[n("div",{class:{"fixed-header":e.fixedHeader}},[n("navbar")],1),e._v(" "),n("app-main")],1)],1)},R=[],G=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"navbar"},[n("hamburger",{staticClass:"hamburger-container",attrs:{"is-active":e.sidebar.opened},on:{toggleClick:e.toggleSideBar}}),e._v(" "),n("breadcrumb",{staticClass:"breadcrumb-container"}),e._v(" "),n("div",{staticClass:"right-menu"},[n("el-button",{staticStyle:{"margin-right":"10px"},attrs:{type:"text"},on:{click:e.doLogout}},[e._v("退出")])],1)],1)},F=[],U=n("cebc"),K=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("el-breadcrumb",{staticClass:"app-breadcrumb",attrs:{separator:"/"}},[n("transition-group",{attrs:{name:"breadcrumb"}},e._l(e.levelList,function(t,a){return n("el-breadcrumb-item",{key:t.path},["noRedirect"===t.redirect||a==e.levelList.length-1?n("span",{staticClass:"no-redirect"},[e._v(e._s(t.meta.title))]):n("a",{on:{click:function(n){return n.preventDefault(),e.handleLink(t)}}},[e._v(e._s(t.meta.title))])])}),1)],1)},W=[],J=n("bd11"),X=n.n(J),Y={data:function(){return{levelList:null}},watch:{$route:function(){this.getBreadcrumb()}},created:function(){this.getBreadcrumb()},methods:{getBreadcrumb:function(){var e=this.$route.matched.filter(function(e){return e.meta&&e.meta.title}),t=e[0];this.isDashboard(t)||(e=[{path:"/dashboard",meta:{title:"Dashboard"}}].concat(e)),this.levelList=e.filter(function(e){return e.meta&&e.meta.title&&!1!==e.meta.breadcrumb})},isDashboard:function(e){var t=e&&e.name;return!!t&&t.trim().toLocaleLowerCase()==="Dashboard".toLocaleLowerCase()},pathCompile:function(e){var t=this.$route.params,n=X.a.compile(e);return n(t)},handleLink:function(e){var t=e.redirect,n=e.path;t?this.$router.push(t):this.$router.push(this.pathCompile(n))}}},Q=Y,Z=(n("34c8"),Object(h["a"])(Q,K,W,!1,null,"62cc9144",null)),ee=Z.exports,te=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticStyle:{padding:"0 15px"},on:{click:e.toggleClick}},[n("svg",{staticClass:"hamburger",class:{"is-active":e.isActive},attrs:{viewBox:"0 0 1024 1024",xmlns:"http://www.w3.org/2000/svg",width:"64",height:"64"}},[n("path",{attrs:{d:"M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z"}})])])},ne=[],ae={name:"Hamburger",props:{isActive:{type:Boolean,default:!1}},methods:{toggleClick:function(){this.$emit("toggleClick")}}},ie=ae,oe=(n("186a"),Object(h["a"])(ie,te,ne,!1,null,"49e15297",null)),re=oe.exports,se={components:{Breadcrumb:ee,Hamburger:re},computed:Object(U["a"])({},Object(p["b"])(["sidebar","avatar"])),methods:{toggleSideBar:function(){this.$store.dispatch("app/toggleSideBar")},doLogout:function(){this.logout()}}},ce=se,ue=(n("405a"),Object(h["a"])(ce,G,F,!1,null,"1eff5c58",null)),le=ue.exports,de=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{class:{"has-logo":e.showLogo}},[e.showLogo?n("logo",{attrs:{collapse:e.isCollapse}}):e._e(),e._v(" "),n("el-scrollbar",{attrs:{"wrap-class":"scrollbar-wrapper"}},[n("el-menu",{attrs:{"default-active":e.activeMenu,collapse:e.isCollapse,"background-color":e.variables.menuBg,"text-color":e.variables.menuText,"unique-opened":!1,"active-text-color":e.variables.menuActiveText,"collapse-transition":!1,mode:"vertical"}},e._l(e.routes,function(e){return n("sidebar-item",{key:e.path,attrs:{item:e,"base-path":e.path}})}),1)],1)],1)},he=[],me=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"sidebar-logo-container",class:{collapse:e.collapse}},[n("transition",{attrs:{name:"sidebarLogoFade"}},[e.collapse?n("router-link",{key:"collapse",staticClass:"sidebar-logo-link",attrs:{to:"/"}},[e.logo?n("img",{staticClass:"sidebar-logo",attrs:{src:e.logo}}):n("h1",{staticClass:"sidebar-title"},[e._v(e._s(e.title)+" ")])]):n("router-link",{key:"expand",staticClass:"sidebar-logo-link",attrs:{to:"/"}},[e.logo?n("img",{staticClass:"sidebar-logo",attrs:{src:e.logo}}):e._e(),e._v(" "),n("h1",{staticClass:"sidebar-title"},[e._v(e._s(e.title)+" ")])])],1)],1)},fe=[],pe={name:"SidebarLogo",props:{collapse:{type:Boolean,required:!0}},data:function(){return{title:"SOP Admin",logo:"https://wpimg.wallstcn.com/69a1c46c-eb1c-4b46-8bd4-e9e686ef5251.png"}}},ve=pe,be=(n("7c27"),Object(h["a"])(ve,me,fe,!1,null,"b905289c",null)),ge=be.exports,we=function(){var e=this,t=e.$createElement,n=e._self._c||t;return e.item.hidden?e._e():n("div",{staticClass:"menu-wrapper"},[!e.hasOneShowingChild(e.item.children,e.item)||e.onlyOneChild.children&&!e.onlyOneChild.noShowingChildren||e.item.alwaysShow?n("el-submenu",{ref:"subMenu",attrs:{index:e.resolvePath(e.item.path),"popper-append-to-body":""}},[n("template",{slot:"title"},[e.item.meta?n("item",{attrs:{icon:e.item.meta&&e.item.meta.icon,title:e.item.meta.title}}):e._e()],1),e._v(" "),e._l(e.item.children,function(t){return n("sidebar-item",{key:t.path,staticClass:"nest-menu",attrs:{"is-nest":!0,item:t,"base-path":e.resolvePath(t.path)}})})],2):[e.onlyOneChild.meta?n("app-link",{attrs:{to:e.resolvePath(e.onlyOneChild.path)}},[n("el-menu-item",{class:{"submenu-title-noDropdown":!e.isNest},attrs:{index:e.resolvePath(e.onlyOneChild.path)}},[n("item",{attrs:{icon:e.onlyOneChild.meta.icon||e.item.meta&&e.item.meta.icon,title:e.onlyOneChild.meta.title}})],1)],1):e._e()]],2)},xe=[],ye=n("df7c"),_e=n.n(ye);function Ce(e){return/^(https?:|mailto:|tel:)/.test(e)}var ke,Oe,Se={name:"MenuItem",functional:!0,props:{icon:{type:String,default:""},title:{type:String,default:""}},render:function(e,t){var n=t.props,a=n.icon,i=n.title,o=[];return a&&o.push(e("svg-icon",{attrs:{"icon-class":a}})),i&&o.push(e("span",{slot:"title"},[i])),o}},ze=Se,Be=Object(h["a"])(ze,ke,Oe,!1,null,null,null),He=Be.exports,Me=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("component",e._b({},"component",e.linkProps(e.to),!1),[e._t("default")],2)},Te=[],Ee={props:{to:{type:String,required:!0}},methods:{linkProps:function(e){return Ce(e)?{is:"a",href:e,target:"_blank",rel:"noopener"}:{is:"router-link",to:e}}}},Le=Ee,$e=Object(h["a"])(Le,Me,Te,!1,null,null,null),Ve=$e.exports,Ae={computed:{device:function(){return this.$store.state.app.device}},mounted:function(){this.fixBugIniOS()},methods:{fixBugIniOS:function(){var e=this,t=this.$refs.subMenu;if(t){var n=t.handleMouseleave;t.handleMouseleave=function(t){"mobile"!==e.device&&n(t)}}}}},je={name:"SidebarItem",components:{Item:He,AppLink:Ve},mixins:[Ae],props:{item:{type:Object,required:!0},isNest:{type:Boolean,default:!1},basePath:{type:String,default:""}},data:function(){return this.onlyOneChild=null,{}},methods:{hasOneShowingChild:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],n=arguments.length>1?arguments[1]:void 0,a=t.filter(function(t){return!t.hidden&&(e.onlyOneChild=t,!0)});return 1===a.length||0===a.length&&(this.onlyOneChild=Object(U["a"])({},n,{path:"",noShowingChildren:!0}),!0)},resolvePath:function(e){return Ce(e)?e:Ce(this.basePath)?this.basePath:_e.a.resolve(this.basePath,e)}}},Pe=je,Ie=Object(h["a"])(Pe,we,xe,!1,null,null,null),Ne=Ie.exports,De=n("cf1e"),qe=n.n(De),Re={components:{SidebarItem:Ne,Logo:ge},computed:Object(U["a"])({},Object(p["b"])(["sidebar"]),{routes:function(){return this.$router.options.routes},activeMenu:function(){var e=this.$route,t=e.meta,n=e.path;return t.activeMenu?t.activeMenu:n},showLogo:function(){return this.$store.state.settings.sidebarLogo},variables:function(){return qe.a},isCollapse:function(){return!this.sidebar.opened}})},Ge=Re,Fe=Object(h["a"])(Ge,de,he,!1,null,null,null),Ue=Fe.exports,Ke=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("section",{staticClass:"app-main"},[n("transition",{attrs:{name:"fade-transform",mode:"out-in"}},[n("router-view",{key:e.key})],1)],1)},We=[],Je={name:"AppMain",computed:{key:function(){return this.$route.fullPath}}},Xe=Je,Ye=(n("50be"),Object(h["a"])(Xe,Ke,We,!1,null,"43c24f68",null)),Qe=Ye.exports,Ze=document,et=Ze.body,tt=992,nt={watch:{$route:function(e){"mobile"===this.device&&this.sidebar.opened&&bt.dispatch("app/closeSideBar",{withoutAnimation:!1})}},beforeMount:function(){window.addEventListener("resize",this.$_resizeHandler)},beforeDestroy:function(){window.removeEventListener("resize",this.$_resizeHandler)},mounted:function(){var e=this.$_isMobile();e&&(bt.dispatch("app/toggleDevice","mobile"),bt.dispatch("app/closeSideBar",{withoutAnimation:!0}))},methods:{$_isMobile:function(){var e=et.getBoundingClientRect();return e.width-1'});r.a.add(s);t["default"]=s},"9f2b":function(e,t,n){"use strict";var a=n("5bb9"),i=n.n(a);i.a},b20f:function(e,t,n){e.exports={menuText:"#bfcbd9",menuActiveText:"#409EFF",subMenuActiveText:"#f4f4f5",menuBg:"#304156",menuHover:"#263445",subMenuBg:"#1f2d3d",subMenuHover:"#001528",sideBarWidth:"210px"}},b3b5:function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),s=new i.a({id:"icon-user",use:"icon-user-usage",viewBox:"0 0 130 130",content:''});r.a.add(s);t["default"]=s},cf1e:function(e,t,n){e.exports={menuText:"#bfcbd9",menuActiveText:"#409EFF",subMenuActiveText:"#f4f4f5",menuBg:"#304156",menuHover:"#263445",subMenuBg:"#1f2d3d",subMenuHover:"#001528",sideBarWidth:"210px"}},d7ec:function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),s=new i.a({id:"icon-eye-open",use:"icon-eye-open-usage",viewBox:"0 0 1024 1024",content:''});r.a.add(s);t["default"]=s},dc52:function(e,t,n){},dcf8:function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),s=new i.a({id:"icon-nested",use:"icon-nested-usage",viewBox:"0 0 128 128",content:''});r.a.add(s);t["default"]=s},eb1b:function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),s=new i.a({id:"icon-form",use:"icon-form-usage",viewBox:"0 0 128 128",content:''});r.a.add(s);t["default"]=s},f782:function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),s=new i.a({id:"icon-dashboard",use:"icon-dashboard-usage",viewBox:"0 0 128 100",content:''});r.a.add(s);t["default"]=s}},[[0,"runtime","chunk-elementUI","chunk-libs"]]]); \ No newline at end of file +(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["app"],{0:function(e,t,n){e.exports=n("56d7")},"0cb8":function(e,t,n){},"186a":function(e,t,n){"use strict";var a=n("dc52"),i=n.n(a);i.a},"18f0":function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),s=new i.a({id:"icon-link",use:"icon-link-usage",viewBox:"0 0 128 128",content:''});r.a.add(s);t["default"]=s},"1f59":function(e,t,n){},2536:function(e,t,n){},2635:function(e,t,n){},"2a3d":function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),s=new i.a({id:"icon-password",use:"icon-password-usage",viewBox:"0 0 128 128",content:''});r.a.add(s);t["default"]=s},"30c3":function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),s=new i.a({id:"icon-example",use:"icon-example-usage",viewBox:"0 0 128 128",content:''});r.a.add(s);t["default"]=s},"34c8":function(e,t,n){"use strict";var a=n("5332"),i=n.n(a);i.a},"405a":function(e,t,n){"use strict";var a=n("1f59"),i=n.n(a);i.a},"47f1":function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),s=new i.a({id:"icon-table",use:"icon-table-usage",viewBox:"0 0 128 128",content:''});r.a.add(s);t["default"]=s},"4df5":function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),s=new i.a({id:"icon-eye",use:"icon-eye-usage",viewBox:"0 0 128 64",content:''});r.a.add(s);t["default"]=s},"50be":function(e,t,n){"use strict";var a=n("2536"),i=n.n(a);i.a},"51ff":function(e,t,n){var a={"./dashboard.svg":"f782","./example.svg":"30c3","./eye-open.svg":"d7ec","./eye.svg":"4df5","./form.svg":"eb1b","./link.svg":"18f0","./nested.svg":"dcf8","./password.svg":"2a3d","./table.svg":"47f1","./tree.svg":"93cd","./user.svg":"b3b5"};function i(e){var t=o(e);return n(t)}function o(e){var t=a[e];if(!(t+1)){var n=new Error("Cannot find module '"+e+"'");throw n.code="MODULE_NOT_FOUND",n}return t}i.keys=function(){return Object.keys(a)},i.resolve=o,e.exports=i,i.id="51ff"},5332:function(e,t,n){},"56d7":function(e,t,n){"use strict";n.r(t);n("cadf"),n("551c"),n("f751"),n("097d");var a=n("2b0e"),i=(n("f5df"),n("5c96")),o=n.n(i),r=(n("0fae"),n("f0d9")),s=n.n(r),c=(n("b20f"),function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{attrs:{id:"app"}},[n("router-view")],1)}),u=[],l={name:"App"},d=l,m=n("2877"),h=Object(m["a"])(d,c,u,!1,null,null,null),f=h.exports,p=n("2f62"),v=(n("7f7f"),{sidebar:function(e){return e.app.sidebar},device:function(e){return e.app.device},token:function(e){return e.user.token},avatar:function(e){return e.user.avatar},name:function(e){return e.user.name}}),b=v,g=n("a78e"),w=n.n(g),x={sidebar:{opened:!w.a.get("sidebarStatus")||!!+w.a.get("sidebarStatus"),withoutAnimation:!1},device:"desktop"},y={TOGGLE_SIDEBAR:function(e){e.sidebar.opened=!e.sidebar.opened,e.sidebar.withoutAnimation=!1,e.sidebar.opened?w.a.set("sidebarStatus",1):w.a.set("sidebarStatus",0)},CLOSE_SIDEBAR:function(e,t){w.a.set("sidebarStatus",0),e.sidebar.opened=!1,e.sidebar.withoutAnimation=t},TOGGLE_DEVICE:function(e,t){e.device=t}},_={toggleSideBar:function(e){var t=e.commit;t("TOGGLE_SIDEBAR")},closeSideBar:function(e,t){var n=e.commit,a=t.withoutAnimation;n("CLOSE_SIDEBAR",a)},toggleDevice:function(e,t){var n=e.commit;n("TOGGLE_DEVICE",t)}},C={namespaced:!0,state:x,mutations:y,actions:_},k=n("83d6"),O=n.n(k),S=O.a.showSettings,z=O.a.fixedHeader,B=O.a.sidebarLogo,H={showSettings:S,fixedHeader:z,sidebarLogo:B},M={CHANGE_SETTING:function(e,t){var n=t.key,a=t.value;e.hasOwnProperty(n)&&(e[n]=a)}},T={changeSetting:function(e,t){var n=e.commit;n("CHANGE_SETTING",t)}},E={namespaced:!0,state:H,mutations:M,actions:T},L=n("bc3a"),$=n.n(L),V=n("5f87"),A=$.a.create({baseURL:"/api",withCredentials:!0,timeout:5e3});A.interceptors.request.use(function(e){return bt.getters.token&&(e.headers["X-Token"]=Object(V["a"])()),e},function(e){return console.log(e),Promise.reject(e)}),A.interceptors.response.use(function(e){var t=e.data;return 2e4!==t.code?(Object(i["Message"])({message:t.message||"error",type:"error",duration:5e3}),50008!==t.code&&50012!==t.code&&50014!==t.code||i["MessageBox"].confirm("You have been logged out, you can cancel to stay on this page, or log in again","Confirm logout",{confirmButtonText:"Re-Login",cancelButtonText:"Cancel",type:"warning"}).then(function(){bt.dispatch("user/resetToken").then(function(){location.reload()})}),Promise.reject(t.message||"error")):t},function(e){return console.log("err"+e),Object(i["Message"])({message:e.message,type:"error",duration:5e3}),Promise.reject(e)});var j=A;function P(e){return j({url:"/user/login",method:"post",data:e})}function I(e){return j({url:"/user/info",method:"get",params:{token:e}})}function N(){return j({url:"/user/logout",method:"post"})}var D=n("8c4f"),q=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"app-wrapper",class:e.classObj},["mobile"===e.device&&e.sidebar.opened?n("div",{staticClass:"drawer-bg",on:{click:e.handleClickOutside}}):e._e(),e._v(" "),n("sidebar",{staticClass:"sidebar-container"}),e._v(" "),n("div",{staticClass:"main-container"},[n("div",{class:{"fixed-header":e.fixedHeader}},[n("navbar")],1),e._v(" "),n("app-main")],1)],1)},R=[],G=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"navbar"},[n("hamburger",{staticClass:"hamburger-container",attrs:{"is-active":e.sidebar.opened},on:{toggleClick:e.toggleSideBar}}),e._v(" "),n("breadcrumb",{staticClass:"breadcrumb-container"}),e._v(" "),n("div",{staticClass:"right-menu"},[n("el-button",{staticStyle:{"margin-right":"10px"},attrs:{type:"text"},on:{click:e.doLogout}},[e._v("退出")])],1)],1)},F=[],U=n("cebc"),K=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("el-breadcrumb",{staticClass:"app-breadcrumb",attrs:{separator:"/"}},[n("transition-group",{attrs:{name:"breadcrumb"}},e._l(e.levelList,function(t,a){return n("el-breadcrumb-item",{key:t.path},["noRedirect"===t.redirect||a==e.levelList.length-1?n("span",{staticClass:"no-redirect"},[e._v(e._s(t.meta.title))]):n("a",{on:{click:function(n){return n.preventDefault(),e.handleLink(t)}}},[e._v(e._s(t.meta.title))])])}),1)],1)},W=[],J=n("bd11"),X=n.n(J),Y={data:function(){return{levelList:null}},watch:{$route:function(){this.getBreadcrumb()}},created:function(){this.getBreadcrumb()},methods:{getBreadcrumb:function(){var e=this.$route.matched.filter(function(e){return e.meta&&e.meta.title}),t=e[0];this.isDashboard(t)||(e=[{path:"/dashboard",meta:{title:"Dashboard"}}].concat(e)),this.levelList=e.filter(function(e){return e.meta&&e.meta.title&&!1!==e.meta.breadcrumb})},isDashboard:function(e){var t=e&&e.name;return!!t&&t.trim().toLocaleLowerCase()==="Dashboard".toLocaleLowerCase()},pathCompile:function(e){var t=this.$route.params,n=X.a.compile(e);return n(t)},handleLink:function(e){var t=e.redirect,n=e.path;t?this.$router.push(t):this.$router.push(this.pathCompile(n))}}},Q=Y,Z=(n("34c8"),Object(m["a"])(Q,K,W,!1,null,"62cc9144",null)),ee=Z.exports,te=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticStyle:{padding:"0 15px"},on:{click:e.toggleClick}},[n("svg",{staticClass:"hamburger",class:{"is-active":e.isActive},attrs:{viewBox:"0 0 1024 1024",xmlns:"http://www.w3.org/2000/svg",width:"64",height:"64"}},[n("path",{attrs:{d:"M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z"}})])])},ne=[],ae={name:"Hamburger",props:{isActive:{type:Boolean,default:!1}},methods:{toggleClick:function(){this.$emit("toggleClick")}}},ie=ae,oe=(n("186a"),Object(m["a"])(ie,te,ne,!1,null,"49e15297",null)),re=oe.exports,se={components:{Breadcrumb:ee,Hamburger:re},computed:Object(U["a"])({},Object(p["b"])(["sidebar","avatar"])),methods:{toggleSideBar:function(){this.$store.dispatch("app/toggleSideBar")},doLogout:function(){this.logout()}}},ce=se,ue=(n("405a"),Object(m["a"])(ce,G,F,!1,null,"1eff5c58",null)),le=ue.exports,de=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{class:{"has-logo":e.showLogo}},[e.showLogo?n("logo",{attrs:{collapse:e.isCollapse}}):e._e(),e._v(" "),n("el-scrollbar",{attrs:{"wrap-class":"scrollbar-wrapper"}},[n("el-menu",{attrs:{"default-active":e.activeMenu,collapse:e.isCollapse,"background-color":e.variables.menuBg,"text-color":e.variables.menuText,"unique-opened":!1,"active-text-color":e.variables.menuActiveText,"collapse-transition":!1,mode:"vertical"}},e._l(e.routes,function(e){return n("sidebar-item",{key:e.path,attrs:{item:e,"base-path":e.path}})}),1)],1)],1)},me=[],he=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"sidebar-logo-container",class:{collapse:e.collapse}},[n("transition",{attrs:{name:"sidebarLogoFade"}},[e.collapse?n("router-link",{key:"collapse",staticClass:"sidebar-logo-link",attrs:{to:"/"}},[e.logo?n("img",{staticClass:"sidebar-logo",attrs:{src:e.logo}}):n("h1",{staticClass:"sidebar-title"},[e._v(e._s(e.title)+" ")])]):n("router-link",{key:"expand",staticClass:"sidebar-logo-link",attrs:{to:"/"}},[e.logo?n("img",{staticClass:"sidebar-logo",attrs:{src:e.logo}}):e._e(),e._v(" "),n("h1",{staticClass:"sidebar-title"},[e._v(e._s(e.title)+" ")])])],1)],1)},fe=[],pe={name:"SidebarLogo",props:{collapse:{type:Boolean,required:!0}},data:function(){return{title:"SOP Admin",logo:"https://wpimg.wallstcn.com/69a1c46c-eb1c-4b46-8bd4-e9e686ef5251.png"}}},ve=pe,be=(n("7c27"),Object(m["a"])(ve,he,fe,!1,null,"b905289c",null)),ge=be.exports,we=function(){var e=this,t=e.$createElement,n=e._self._c||t;return e.item.hidden?e._e():n("div",{staticClass:"menu-wrapper"},[!e.hasOneShowingChild(e.item.children,e.item)||e.onlyOneChild.children&&!e.onlyOneChild.noShowingChildren||e.item.alwaysShow?n("el-submenu",{ref:"subMenu",attrs:{index:e.resolvePath(e.item.path),"popper-append-to-body":""}},[n("template",{slot:"title"},[e.item.meta?n("item",{attrs:{icon:e.item.meta&&e.item.meta.icon,title:e.item.meta.title}}):e._e()],1),e._v(" "),e._l(e.item.children,function(t){return n("sidebar-item",{key:t.path,staticClass:"nest-menu",attrs:{"is-nest":!0,item:t,"base-path":e.resolvePath(t.path)}})})],2):[e.onlyOneChild.meta?n("app-link",{attrs:{to:e.resolvePath(e.onlyOneChild.path)}},[n("el-menu-item",{class:{"submenu-title-noDropdown":!e.isNest},attrs:{index:e.resolvePath(e.onlyOneChild.path)}},[n("item",{attrs:{icon:e.onlyOneChild.meta.icon||e.item.meta&&e.item.meta.icon,title:e.onlyOneChild.meta.title}})],1)],1):e._e()]],2)},xe=[],ye=n("df7c"),_e=n.n(ye);function Ce(e){return/^(https?:|mailto:|tel:)/.test(e)}var ke,Oe,Se={name:"MenuItem",functional:!0,props:{icon:{type:String,default:""},title:{type:String,default:""}},render:function(e,t){var n=t.props,a=n.icon,i=n.title,o=[];return a&&o.push(e("svg-icon",{attrs:{"icon-class":a}})),i&&o.push(e("span",{slot:"title"},[i])),o}},ze=Se,Be=Object(m["a"])(ze,ke,Oe,!1,null,null,null),He=Be.exports,Me=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("component",e._b({},"component",e.linkProps(e.to),!1),[e._t("default")],2)},Te=[],Ee={props:{to:{type:String,required:!0}},methods:{linkProps:function(e){return Ce(e)?{is:"a",href:e,target:"_blank",rel:"noopener"}:{is:"router-link",to:e}}}},Le=Ee,$e=Object(m["a"])(Le,Me,Te,!1,null,null,null),Ve=$e.exports,Ae={computed:{device:function(){return this.$store.state.app.device}},mounted:function(){this.fixBugIniOS()},methods:{fixBugIniOS:function(){var e=this,t=this.$refs.subMenu;if(t){var n=t.handleMouseleave;t.handleMouseleave=function(t){"mobile"!==e.device&&n(t)}}}}},je={name:"SidebarItem",components:{Item:He,AppLink:Ve},mixins:[Ae],props:{item:{type:Object,required:!0},isNest:{type:Boolean,default:!1},basePath:{type:String,default:""}},data:function(){return this.onlyOneChild=null,{}},methods:{hasOneShowingChild:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],n=arguments.length>1?arguments[1]:void 0,a=t.filter(function(t){return!t.hidden&&(e.onlyOneChild=t,!0)});return 1===a.length||0===a.length&&(this.onlyOneChild=Object(U["a"])({},n,{path:"",noShowingChildren:!0}),!0)},resolvePath:function(e){return Ce(e)?e:Ce(this.basePath)?this.basePath:_e.a.resolve(this.basePath,e)}}},Pe=je,Ie=Object(m["a"])(Pe,we,xe,!1,null,null,null),Ne=Ie.exports,De=n("cf1e"),qe=n.n(De),Re={components:{SidebarItem:Ne,Logo:ge},computed:Object(U["a"])({},Object(p["b"])(["sidebar"]),{routes:function(){return this.$router.options.routes},activeMenu:function(){var e=this.$route,t=e.meta,n=e.path;return t.activeMenu?t.activeMenu:n},showLogo:function(){return this.$store.state.settings.sidebarLogo},variables:function(){return qe.a},isCollapse:function(){return!this.sidebar.opened}})},Ge=Re,Fe=Object(m["a"])(Ge,de,me,!1,null,null,null),Ue=Fe.exports,Ke=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("section",{staticClass:"app-main"},[n("transition",{attrs:{name:"fade-transform",mode:"out-in"}},[n("router-view",{key:e.key})],1)],1)},We=[],Je={name:"AppMain",computed:{key:function(){return this.$route.fullPath}}},Xe=Je,Ye=(n("50be"),Object(m["a"])(Xe,Ke,We,!1,null,"43c24f68",null)),Qe=Ye.exports,Ze=document,et=Ze.body,tt=992,nt={watch:{$route:function(e){"mobile"===this.device&&this.sidebar.opened&&bt.dispatch("app/closeSideBar",{withoutAnimation:!1})}},beforeMount:function(){window.addEventListener("resize",this.$_resizeHandler)},beforeDestroy:function(){window.removeEventListener("resize",this.$_resizeHandler)},mounted:function(){var e=this.$_isMobile();e&&(bt.dispatch("app/toggleDevice","mobile"),bt.dispatch("app/closeSideBar",{withoutAnimation:!0}))},methods:{$_isMobile:function(){var e=et.getBoundingClientRect();return e.width-1'});r.a.add(s);t["default"]=s},"9f2b":function(e,t,n){"use strict";var a=n("5bb9"),i=n.n(a);i.a},b20f:function(e,t,n){e.exports={menuText:"#bfcbd9",menuActiveText:"#409EFF",subMenuActiveText:"#f4f4f5",menuBg:"#304156",menuHover:"#263445",subMenuBg:"#1f2d3d",subMenuHover:"#001528",sideBarWidth:"210px"}},b3b5:function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),s=new i.a({id:"icon-user",use:"icon-user-usage",viewBox:"0 0 130 130",content:''});r.a.add(s);t["default"]=s},cf1e:function(e,t,n){e.exports={menuText:"#bfcbd9",menuActiveText:"#409EFF",subMenuActiveText:"#f4f4f5",menuBg:"#304156",menuHover:"#263445",subMenuBg:"#1f2d3d",subMenuHover:"#001528",sideBarWidth:"210px"}},d7ec:function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),s=new i.a({id:"icon-eye-open",use:"icon-eye-open-usage",viewBox:"0 0 1024 1024",content:''});r.a.add(s);t["default"]=s},dc52:function(e,t,n){},dcf8:function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),s=new i.a({id:"icon-nested",use:"icon-nested-usage",viewBox:"0 0 128 128",content:''});r.a.add(s);t["default"]=s},eb1b:function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),s=new i.a({id:"icon-form",use:"icon-form-usage",viewBox:"0 0 128 128",content:''});r.a.add(s);t["default"]=s},f782:function(e,t,n){"use strict";n.r(t);var a=n("e017"),i=n.n(a),o=n("21a1"),r=n.n(o),s=new i.a({id:"icon-dashboard",use:"icon-dashboard-usage",viewBox:"0 0 128 100",content:''});r.a.add(s);t["default"]=s}},[[0,"runtime","chunk-elementUI","chunk-libs"]]]); \ No newline at end of file diff --git a/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-2d0aa95b.447435b3.js b/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-2d0aa95b.447435b3.js new file mode 100644 index 00000000..da97f7e1 --- /dev/null +++ b/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-2d0aa95b.447435b3.js @@ -0,0 +1 @@ +(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d0aa95b"],{1248:function(t,e,a){"use strict";a.r(e);var o=function(){var t=this,e=t.$createElement,a=t._self._c||e;return a("div",{staticClass:"app-container"},[a("el-container",[a("el-aside",{staticStyle:{"min-height":"300px",width:"200px"}},[a("el-input",{staticStyle:{"margin-bottom":"20px"},attrs:{"prefix-icon":"el-icon-search",placeholder:"搜索服务...",size:"mini",clearable:""},model:{value:t.filterText,callback:function(e){t.filterText=e},expression:"filterText"}}),t._v(" "),a("el-tree",{ref:"tree2",staticClass:"filter-tree",attrs:{data:t.treeData,props:t.defaultProps,"filter-node-method":t.filterNode,"highlight-current":!0,"expand-on-click-node":!1,"empty-text":"无数据","node-key":"id","default-expand-all":""},on:{"node-click":t.onNodeClick},scopedSlots:t._u([{key:"default",fn:function(e){e.node;var o=e.data;return a("span",{staticClass:"custom-tree-node"},[o.label.length<15?a("span",[t._v(t._s(o.label))]):a("span",[a("el-tooltip",{staticClass:"item",attrs:{content:o.label,effect:"light",placement:"right"}},[a("span",[t._v(t._s(o.label.substring(0,15)+"..."))])])],1)])}}])})],1),t._v(" "),a("el-main",{staticStyle:{"padding-top":"0"}},[a("el-form",{staticClass:"demo-form-inline",attrs:{inline:!0,model:t.searchFormData,size:"mini"}},[a("el-form-item",{attrs:{label:"路由名称"}},[a("el-input",{attrs:{placeholder:"输入接口名或版本号"},model:{value:t.searchFormData.id,callback:function(e){t.$set(t.searchFormData,"id",e)},expression:"searchFormData.id"}})],1),t._v(" "),a("el-form-item",[a("el-button",{attrs:{type:"primary",icon:"el-icon-search"},on:{click:t.onSearchTable}},[t._v("查询")])],1)],1),t._v(" "),a("el-table",{attrs:{data:t.tableData,border:"","max-height":"500"}},[a("el-table-column",{attrs:{prop:"name",label:"接口名 (版本号)",width:"200"},scopedSlots:t._u([{key:"default",fn:function(e){return[t._v("\n "+t._s(e.row.name+(e.row.version?" ("+e.row.version+")":""))+"\n ")]}}])}),t._v(" "),a("el-table-column",{attrs:{prop:"uri",label:"LoadBalance",width:"350"},scopedSlots:t._u([{key:"default",fn:function(e){return[t._v("\n "+t._s(e.row.uri+e.row.path)+"\n ")]}}])}),t._v(" "),a("el-table-column",{attrs:{prop:"roles",label:"访问权限",width:"100"},scopedSlots:t._u([{key:"default",fn:function(e){return[a("span",{domProps:{innerHTML:t._s(t.roleRender(e.row))}})]}}])}),t._v(" "),a("el-table-column",{attrs:{prop:"ignoreValidate",label:"忽略验证",width:"80"},scopedSlots:t._u([{key:"default",fn:function(e){return[1===e.row.ignoreValidate?a("span",{staticStyle:{color:"#67C23A"}},[t._v("是")]):t._e(),t._v(" "),0===e.row.ignoreValidate?a("span",{staticStyle:{color:"#909399"}},[t._v("否")]):t._e()]}}])}),t._v(" "),a("el-table-column",{attrs:{prop:"mergeResult",label:"统一格式输出",width:"120"},scopedSlots:t._u([{key:"default",fn:function(e){return[1===e.row.mergeResult?a("span",{staticStyle:{color:"#67C23A"}},[t._v("是")]):t._e(),t._v(" "),0===e.row.mergeResult?a("span",{staticStyle:{color:"#E6A23C"}},[t._v("否")]):t._e()]}}])}),t._v(" "),a("el-table-column",{attrs:{prop:"status",label:"状态",width:"80"},scopedSlots:t._u([{key:"default",fn:function(e){return[0===e.row.status?a("span",{staticStyle:{color:"#909399"}},[t._v("待审核")]):t._e(),t._v(" "),1===e.row.status?a("span",{staticStyle:{color:"#67C23A"}},[t._v("已启用")]):t._e(),t._v(" "),2===e.row.status?a("span",{staticStyle:{color:"#F56C6C"}},[t._v("已禁用")]):t._e()]}}])}),t._v(" "),a("el-table-column",{attrs:{label:"操作",fixed:"right",width:"100"},scopedSlots:t._u([{key:"default",fn:function(e){return[a("el-button",{attrs:{type:"text",size:"mini"},on:{click:function(a){return t.onTableUpdate(e.row)}}},[t._v("修改")]),t._v(" "),e.row.permission?a("el-button",{attrs:{type:"text",size:"mini"},on:{click:function(a){return t.onTableAuth(e.row)}}},[t._v("授权")]):t._e()]}}])})],1),t._v(" "),a("el-dialog",{attrs:{title:"修改路由",visible:t.routeDialogVisible,"close-on-click-modal":!1},on:{"update:visible":function(e){t.routeDialogVisible=e}}},[a("el-form",{attrs:{model:t.routeDialogFormData,"label-width":"120px",size:"mini"}},[a("el-form-item",{attrs:{label:"id"}},[a("el-input",{attrs:{readonly:"readonly"},model:{value:t.routeDialogFormData.id,callback:function(e){t.$set(t.routeDialogFormData,"id",e)},expression:"routeDialogFormData.id"}})],1),t._v(" "),a("el-form-item",{attrs:{label:"uri"}},[a("el-input",{model:{value:t.routeDialogFormData.uri,callback:function(e){t.$set(t.routeDialogFormData,"uri",e)},expression:"routeDialogFormData.uri"}})],1),t._v(" "),a("el-form-item",{attrs:{label:"path"}},[a("el-input",{model:{value:t.routeDialogFormData.path,callback:function(e){t.$set(t.routeDialogFormData,"path",e)},expression:"routeDialogFormData.path"}})],1),t._v(" "),a("el-form-item",{attrs:{label:"状态"}},[a("el-radio-group",{model:{value:t.routeDialogFormData.status,callback:function(e){t.$set(t.routeDialogFormData,"status",e)},expression:"routeDialogFormData.status"}},[a("el-radio",{attrs:{label:1,name:"status"}},[t._v("启用")]),t._v(" "),a("el-radio",{staticStyle:{color:"#F56C6C"},attrs:{label:2,name:"status"}},[t._v("禁用")])],1)],1)],1),t._v(" "),a("div",{staticClass:"dialog-footer",attrs:{slot:"footer"},slot:"footer"},[a("el-button",{on:{click:function(e){t.routeDialogVisible=!1}}},[t._v("取 消")]),t._v(" "),a("el-button",{attrs:{type:"primary"},on:{click:t.onRouteDialogSave}},[t._v("保 存")])],1)],1),t._v(" "),a("el-dialog",{attrs:{title:"路由授权",visible:t.authDialogVisible,"close-on-click-modal":!1},on:{"update:visible":function(e){t.authDialogVisible=e}}},[a("el-form",{attrs:{model:t.authDialogFormData,"label-width":"120px",size:"mini"}},[a("el-form-item",{attrs:{label:"id"}},[a("el-input",{attrs:{readonly:"readonly"},model:{value:t.authDialogFormData.routeId,callback:function(e){t.$set(t.authDialogFormData,"routeId",e)},expression:"authDialogFormData.routeId"}})],1),t._v(" "),a("el-form-item",{attrs:{label:"角色"}},[a("el-checkbox-group",{model:{value:t.authDialogFormData.roleCode,callback:function(e){t.$set(t.authDialogFormData,"roleCode",e)},expression:"authDialogFormData.roleCode"}},t._l(t.roles,function(e){return a("el-checkbox",{key:e.roleCode,attrs:{label:e.roleCode}},[t._v(t._s(e.description))])}),1)],1)],1),t._v(" "),a("div",{staticClass:"dialog-footer",attrs:{slot:"footer"},slot:"footer"},[a("el-button",{on:{click:function(e){t.authDialogVisible=!1}}},[t._v("取 消")]),t._v(" "),a("el-button",{attrs:{type:"primary"},on:{click:t.onAuthDialogSave}},[t._v("保 存")])],1)],1)],1)],1)],1)},l=[],i={data:function(){return{filterText:"",treeData:[],tableData:[],serviceId:"",searchFormData:{},defaultProps:{children:"children",label:"label"},routeDialogFormData:{status:1},routeDialogVisible:!1,roles:[],authDialogFormData:{routeId:"",roleCode:[]},authDialogVisible:!1}},watch:{filterText:function(t){this.$refs.tree2.filter(t)}},created:function(){this.loadTree(),this.loadRouteRole()},methods:{loadTree:function(){this.post("service.list",{},function(t){var e=t.data;this.treeData=this.convertToTreeData(e,0)})},filterNode:function(t,e){return!t||-1!==e.label.indexOf(t)},onNodeClick:function(t,e,a){t.parentId&&(this.serviceId=t.label,this.searchFormData.serviceId=this.serviceId,this.loadTable())},convertToTreeData:function(t,e){for(var a=[],o={label:"服务列表",parentId:e},l=[],i=0;i0?e.join(", "):'未授权'},onRouteDialogSave:function(){this.routeDialogFormData.serviceId=this.serviceId,this.post("route.update",this.routeDialogFormData,function(){this.routeDialogVisible=!1,this.loadTable()})},onAuthDialogSave:function(){this.post("route.role.update",this.authDialogFormData,function(){console.log(this.authDialogFormData),this.authDialogVisible=!1,this.loadTable()})}}},r=i,s=a("2877"),n=Object(s["a"])(r,o,l,!1,null,null,null);e["default"]=n.exports}}]); \ No newline at end of file diff --git a/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-2d0aa95b.5ba26eff.js b/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-2d0aa95b.5ba26eff.js deleted file mode 100644 index 046978b8..00000000 --- a/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-2d0aa95b.5ba26eff.js +++ /dev/null @@ -1 +0,0 @@ -(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d0aa95b"],{1248:function(t,e,a){"use strict";a.r(e);var o=function(){var t=this,e=t.$createElement,a=t._self._c||e;return a("div",{staticClass:"app-container"},[a("el-container",[a("el-aside",{staticStyle:{"min-height":"300px",width:"200px"}},[a("el-input",{staticStyle:{"margin-bottom":"20px"},attrs:{"prefix-icon":"el-icon-search",placeholder:"搜索服务...",size:"mini",clearable:""},model:{value:t.filterText,callback:function(e){t.filterText=e},expression:"filterText"}}),t._v(" "),a("el-tree",{ref:"tree2",staticClass:"filter-tree",attrs:{data:t.treeData,props:t.defaultProps,"filter-node-method":t.filterNode,"highlight-current":!0,"expand-on-click-node":!1,"empty-text":"无数据","node-key":"id","default-expand-all":""},on:{"node-click":t.onNodeClick},scopedSlots:t._u([{key:"default",fn:function(e){e.node;var o=e.data;return a("span",{staticClass:"custom-tree-node"},[o.label.length<15?a("span",[t._v(t._s(o.label))]):a("span",[a("el-tooltip",{staticClass:"item",attrs:{content:o.label,effect:"light",placement:"right"}},[a("span",[t._v(t._s(o.label.substring(0,15)+"..."))])])],1)])}}])})],1),t._v(" "),a("el-main",{staticStyle:{"padding-top":"0"}},[a("el-form",{staticClass:"demo-form-inline",attrs:{inline:!0,model:t.searchFormData,size:"mini"}},[a("el-form-item",{attrs:{label:"路由名称"}},[a("el-input",{attrs:{placeholder:"输入接口名或版本号"},model:{value:t.searchFormData.id,callback:function(e){t.$set(t.searchFormData,"id",e)},expression:"searchFormData.id"}})],1),t._v(" "),a("el-form-item",[a("el-button",{attrs:{type:"primary",icon:"el-icon-search"},on:{click:t.onSearchTable}},[t._v("查询")])],1)],1),t._v(" "),a("el-table",{attrs:{data:t.tableData,border:"","max-height":"500"}},[a("el-table-column",{attrs:{prop:"name",label:"接口名 (版本号)",width:"200"},scopedSlots:t._u([{key:"default",fn:function(e){return[t._v("\n "+t._s(e.row.name+(e.row.version?" ("+e.row.version+")":""))+"\n ")]}}])}),t._v(" "),a("el-table-column",{attrs:{prop:"uri",label:"LoadBalance",width:"350"},scopedSlots:t._u([{key:"default",fn:function(e){return[t._v("\n "+t._s(e.row.uri+e.row.path)+"\n ")]}}])}),t._v(" "),a("el-table-column",{attrs:{prop:"roles",label:"访问权限",width:"100"},scopedSlots:t._u([{key:"default",fn:function(e){return[a("span",{domProps:{innerHTML:t._s(t.roleRender(e.row))}})]}}])}),t._v(" "),a("el-table-column",{attrs:{prop:"ignoreValidate",label:"忽略验证",width:"80"},scopedSlots:t._u([{key:"default",fn:function(e){return[1===e.row.ignoreValidate?a("span",{staticStyle:{color:"#67C23A"}},[t._v("是")]):t._e(),t._v(" "),0===e.row.ignoreValidate?a("span",{staticStyle:{color:"#909399"}},[t._v("否")]):t._e()]}}])}),t._v(" "),a("el-table-column",{attrs:{prop:"mergeResult",label:"合并结果",width:"80"},scopedSlots:t._u([{key:"default",fn:function(e){return[1===e.row.mergeResult?a("span",{staticStyle:{color:"#67C23A"}},[t._v("合并")]):t._e(),t._v(" "),0===e.row.mergeResult?a("span",{staticStyle:{color:"#E6A23C"}},[t._v("不合并")]):t._e()]}}])}),t._v(" "),a("el-table-column",{attrs:{prop:"status",label:"状态",width:"80"},scopedSlots:t._u([{key:"default",fn:function(e){return[0===e.row.status?a("span",{staticStyle:{color:"#909399"}},[t._v("待审核")]):t._e(),t._v(" "),1===e.row.status?a("span",{staticStyle:{color:"#67C23A"}},[t._v("已启用")]):t._e(),t._v(" "),2===e.row.status?a("span",{staticStyle:{color:"#F56C6C"}},[t._v("已禁用")]):t._e()]}}])}),t._v(" "),a("el-table-column",{attrs:{label:"操作",fixed:"right",width:"100"},scopedSlots:t._u([{key:"default",fn:function(e){return[a("el-button",{attrs:{type:"text",size:"mini"},on:{click:function(a){return t.onTableUpdate(e.row)}}},[t._v("修改")]),t._v(" "),e.row.permission?a("el-button",{attrs:{type:"text",size:"mini"},on:{click:function(a){return t.onTableAuth(e.row)}}},[t._v("授权")]):t._e()]}}])})],1),t._v(" "),a("el-dialog",{attrs:{title:"修改路由",visible:t.routeDialogVisible,"close-on-click-modal":!1},on:{"update:visible":function(e){t.routeDialogVisible=e}}},[a("el-form",{attrs:{model:t.routeDialogFormData,"label-width":"120px",size:"mini"}},[a("el-form-item",{attrs:{label:"id"}},[a("el-input",{attrs:{readonly:"readonly"},model:{value:t.routeDialogFormData.id,callback:function(e){t.$set(t.routeDialogFormData,"id",e)},expression:"routeDialogFormData.id"}})],1),t._v(" "),a("el-form-item",{attrs:{label:"uri"}},[a("el-input",{model:{value:t.routeDialogFormData.uri,callback:function(e){t.$set(t.routeDialogFormData,"uri",e)},expression:"routeDialogFormData.uri"}})],1),t._v(" "),a("el-form-item",{attrs:{label:"path"}},[a("el-input",{model:{value:t.routeDialogFormData.path,callback:function(e){t.$set(t.routeDialogFormData,"path",e)},expression:"routeDialogFormData.path"}})],1),t._v(" "),a("el-form-item",{attrs:{label:"状态"}},[a("el-radio-group",{model:{value:t.routeDialogFormData.status,callback:function(e){t.$set(t.routeDialogFormData,"status",e)},expression:"routeDialogFormData.status"}},[a("el-radio",{attrs:{label:1,name:"status"}},[t._v("启用")]),t._v(" "),a("el-radio",{staticStyle:{color:"#F56C6C"},attrs:{label:2,name:"status"}},[t._v("禁用")])],1)],1)],1),t._v(" "),a("div",{staticClass:"dialog-footer",attrs:{slot:"footer"},slot:"footer"},[a("el-button",{on:{click:function(e){t.routeDialogVisible=!1}}},[t._v("取 消")]),t._v(" "),a("el-button",{attrs:{type:"primary"},on:{click:t.onRouteDialogSave}},[t._v("保 存")])],1)],1),t._v(" "),a("el-dialog",{attrs:{title:"路由授权",visible:t.authDialogVisible,"close-on-click-modal":!1},on:{"update:visible":function(e){t.authDialogVisible=e}}},[a("el-form",{attrs:{model:t.authDialogFormData,"label-width":"120px",size:"mini"}},[a("el-form-item",{attrs:{label:"id"}},[a("el-input",{attrs:{readonly:"readonly"},model:{value:t.authDialogFormData.routeId,callback:function(e){t.$set(t.authDialogFormData,"routeId",e)},expression:"authDialogFormData.routeId"}})],1),t._v(" "),a("el-form-item",{attrs:{label:"角色"}},[a("el-checkbox-group",{model:{value:t.authDialogFormData.roleCode,callback:function(e){t.$set(t.authDialogFormData,"roleCode",e)},expression:"authDialogFormData.roleCode"}},t._l(t.roles,function(e){return a("el-checkbox",{key:e.roleCode,attrs:{label:e.roleCode}},[t._v(t._s(e.description))])}),1)],1)],1),t._v(" "),a("div",{staticClass:"dialog-footer",attrs:{slot:"footer"},slot:"footer"},[a("el-button",{on:{click:function(e){t.authDialogVisible=!1}}},[t._v("取 消")]),t._v(" "),a("el-button",{attrs:{type:"primary"},on:{click:t.onAuthDialogSave}},[t._v("保 存")])],1)],1)],1)],1)],1)},l=[],i={data:function(){return{filterText:"",treeData:[],tableData:[],serviceId:"",searchFormData:{},defaultProps:{children:"children",label:"label"},routeDialogFormData:{status:1},routeDialogVisible:!1,roles:[],authDialogFormData:{routeId:"",roleCode:[]},authDialogVisible:!1}},watch:{filterText:function(t){this.$refs.tree2.filter(t)}},created:function(){this.loadTree(),this.loadRouteRole()},methods:{loadTree:function(){this.post("service.list",{},function(t){var e=t.data;this.treeData=this.convertToTreeData(e,0)})},filterNode:function(t,e){return!t||-1!==e.label.indexOf(t)},onNodeClick:function(t,e,a){t.parentId&&(this.serviceId=t.label,this.searchFormData.serviceId=this.serviceId,this.loadTable())},convertToTreeData:function(t,e){for(var a=[],o={label:"服务列表",parentId:e},l=[],i=0;i0?e.join(", "):'未授权'},onRouteDialogSave:function(){this.routeDialogFormData.serviceId=this.serviceId,this.post("route.update",this.routeDialogFormData,function(){this.routeDialogVisible=!1,this.loadTable()})},onAuthDialogSave:function(){this.post("route.role.update",this.authDialogFormData,function(){console.log(this.authDialogFormData),this.authDialogVisible=!1,this.loadTable()})}}},r=i,s=a("2877"),n=Object(s["a"])(r,o,l,!1,null,null,null);e["default"]=n.exports}}]); \ No newline at end of file diff --git a/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-2d22c2e3.0cbb7297.js b/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-2d22c2e3.46f37153.js similarity index 79% rename from sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-2d22c2e3.0cbb7297.js rename to sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-2d22c2e3.46f37153.js index b71661b0..ef15b9c1 100644 --- a/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-2d22c2e3.0cbb7297.js +++ b/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-2d22c2e3.46f37153.js @@ -1 +1 @@ -(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d22c2e3"],{f1ac:function(t,e,a){"use strict";a.r(e);var n=function(){var t=this,e=t.$createElement,a=t._self._c||e;return a("div",{staticClass:"app-container"},[a("el-form",{staticClass:"demo-form-inline",attrs:{inline:!0,model:t.searchFormData,size:"mini"}},[a("el-form-item",{attrs:{label:"serviceId"}},[a("el-input",{staticStyle:{width:"250px"},attrs:{clearable:!0,placeholder:"serviceId"},model:{value:t.searchFormData.serviceId,callback:function(e){t.$set(t.searchFormData,"serviceId",e)},expression:"searchFormData.serviceId"}})],1),t._v(" "),a("el-form-item",[a("el-button",{attrs:{type:"primary",icon:"el-icon-search"},on:{click:t.onSearchTable}},[t._v("查询")])],1)],1),t._v(" "),a("el-table",{staticStyle:{width:"100%","margin-bottom":"20px"},attrs:{data:t.tableData,border:"","row-key":"id"}},[a("el-table-column",{attrs:{prop:"name",label:"服务名称(serviceId)",width:"200"}}),t._v(" "),a("el-table-column",{attrs:{prop:"instanceId",label:"instanceId",width:"250"}}),t._v(" "),a("el-table-column",{attrs:{prop:"ipAddr",label:"IP地址",width:"150"}}),t._v(" "),a("el-table-column",{attrs:{prop:"serverPort",label:"端口号",width:"100"}}),t._v(" "),a("el-table-column",{attrs:{prop:"status",label:"服务状态",width:"100"},scopedSlots:t._u([{key:"default",fn:function(e){return[e.row.parentId>0&&"UP"===e.row.status?a("el-tag",{attrs:{type:"success"}},[t._v("已上线")]):t._e(),t._v(" "),e.row.parentId>0&&"STARTING"===e.row.status?a("el-tag",{attrs:{type:"info"}},[t._v("正在启动")]):t._e(),t._v(" "),e.row.parentId>0&&"UNKNOWN"===e.row.status?a("el-tag",[t._v("未知")]):t._e(),t._v(" "),e.row.parentId>0&&("OUT_OF_SERVICE"===e.row.status||"DOWN"===e.row.status)?a("el-tag",{attrs:{type:"danger"}},[t._v("已下线")]):t._e()]}}])}),t._v(" "),a("el-table-column",{attrs:{prop:"updateTime",label:"最后更新时间",width:"160"}}),t._v(" "),a("el-table-column",{attrs:{label:"操作",width:"100"},scopedSlots:t._u([{key:"default",fn:function(e){return[e.row.parentId>0&&"UP"===e.row.status?a("el-button",{attrs:{type:"text",size:"mini"},on:{click:function(a){return t.onOffline(e.row)}}},[t._v("下线")]):t._e(),t._v(" "),e.row.parentId>0&&"OUT_OF_SERVICE"===e.row.status?a("el-button",{attrs:{type:"text",size:"mini"},on:{click:function(a){return t.onOnline(e.row)}}},[t._v("上线")]):t._e()]}}])})],1)],1)},r=[],i=(a("7f7f"),a("ac6a"),{data:function(){return{searchFormData:{serviceId:""},tableData:[]}},created:function(){this.loadTable()},methods:{loadTable:function(){this.post("service.instance.list",this.searchFormData,function(t){this.tableData=this.buildTreeData(t.data)})},buildTreeData:function(t){return t.forEach(function(e){var a=e.parentId;0===a||t.forEach(function(t){if(t.id===a){var n=t.child;n||(n=[]),n.push(e),t.children=n}})}),t=t.filter(function(t){return 0===t.parentId}),t},onSearchTable:function(){this.loadTable()},onOffline:function(t){this.confirm("确定要下线【"+t.name+"】吗?",function(e){var a={serviceId:t.name,instanceId:t.instanceId};this.post("service.instance.offline",a,function(){this.tip("下线成功"),e()})})},onOnline:function(t){this.confirm("确定要上线【"+t.name+"】吗?",function(e){var a={serviceId:t.name,instanceId:t.instanceId};this.post("service.instance.online",a,function(){this.tip("上线成功"),e()})})}}}),s=i,o=a("2877"),l=Object(o["a"])(s,n,r,!1,null,null,null);e["default"]=l.exports}}]); \ No newline at end of file +(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d22c2e3"],{f1ac:function(t,e,a){"use strict";a.r(e);var n=function(){var t=this,e=t.$createElement,a=t._self._c||e;return a("div",{staticClass:"app-container"},[a("el-form",{staticClass:"demo-form-inline",attrs:{inline:!0,model:t.searchFormData,size:"mini"}},[a("el-form-item",{attrs:{label:"serviceId"}},[a("el-input",{staticStyle:{width:"250px"},attrs:{clearable:!0,placeholder:"serviceId"},model:{value:t.searchFormData.serviceId,callback:function(e){t.$set(t.searchFormData,"serviceId",e)},expression:"searchFormData.serviceId"}})],1),t._v(" "),a("el-form-item",[a("el-button",{attrs:{type:"primary",icon:"el-icon-search"},on:{click:t.onSearchTable}},[t._v("查询")])],1)],1),t._v(" "),a("el-table",{staticStyle:{width:"100%","margin-bottom":"20px"},attrs:{data:t.tableData,border:"","row-key":"id"}},[a("el-table-column",{attrs:{prop:"name",label:"服务名称(serviceId)",width:"200"}}),t._v(" "),a("el-table-column",{attrs:{prop:"instanceId",label:"instanceId",width:"250"}}),t._v(" "),a("el-table-column",{attrs:{prop:"ipAddr",label:"IP地址",width:"150"}}),t._v(" "),a("el-table-column",{attrs:{prop:"serverPort",label:"端口号",width:"100"}}),t._v(" "),a("el-table-column",{attrs:{prop:"status",label:"服务状态",width:"100"},scopedSlots:t._u([{key:"default",fn:function(e){return[e.row.parentId>0&&"UP"===e.row.status?a("el-tag",{attrs:{type:"success"}},[t._v("已上线")]):t._e(),t._v(" "),e.row.parentId>0&&"STARTING"===e.row.status?a("el-tag",{attrs:{type:"info"}},[t._v("正在启动")]):t._e(),t._v(" "),e.row.parentId>0&&"UNKNOWN"===e.row.status?a("el-tag",[t._v("未知")]):t._e(),t._v(" "),e.row.parentId>0&&("OUT_OF_SERVICE"===e.row.status||"DOWN"===e.row.status)?a("el-tag",{attrs:{type:"danger"}},[t._v("已下线")]):t._e()]}}])}),t._v(" "),a("el-table-column",{attrs:{prop:"updateTime",label:"最后更新时间",width:"160"}}),t._v(" "),a("el-table-column",{attrs:{label:"操作",width:"100"},scopedSlots:t._u([{key:"default",fn:function(e){return[e.row.parentId>0&&"UP"===e.row.status?a("el-button",{attrs:{type:"text",size:"mini"},on:{click:function(a){return t.onOffline(e.row)}}},[t._v("下线")]):t._e(),t._v(" "),e.row.parentId>0&&"OUT_OF_SERVICE"===e.row.status?a("el-button",{attrs:{type:"text",size:"mini"},on:{click:function(a){return t.onOnline(e.row)}}},[t._v("上线")]):t._e()]}}])})],1)],1)},r=[],i=(a("7f7f"),a("ac6a"),{data:function(){return{searchFormData:{serviceId:""},tableData:[]}},created:function(){this.loadTable()},methods:{loadTable:function(){this.post("service.instance.list",this.searchFormData,function(t){this.tableData=this.buildTreeData(t.data)})},buildTreeData:function(t){return t.forEach(function(e){var a=e.parentId;0===a||t.forEach(function(t){if(t.id===a){var n=t.children;n||(n=[]),n.push(e),t.children=n}})}),t=t.filter(function(t){return 0===t.parentId}),t},onSearchTable:function(){this.loadTable()},onOffline:function(t){this.confirm("确定要下线【"+t.name+"】吗?",function(e){var a={serviceId:t.name,instanceId:t.instanceId};this.post("service.instance.offline",a,function(){this.tip("下线成功"),e()})})},onOnline:function(t){this.confirm("确定要上线【"+t.name+"】吗?",function(e){var a={serviceId:t.name,instanceId:t.instanceId};this.post("service.instance.online",a,function(){this.tip("上线成功"),e()})})}}}),s=i,o=a("2877"),l=Object(o["a"])(s,n,r,!1,null,null,null);e["default"]=l.exports}}]); \ No newline at end of file diff --git a/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-4a59cbe4.3309de97.js b/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-4a59cbe4.3309de97.js new file mode 100644 index 00000000..36b45c21 --- /dev/null +++ b/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-4a59cbe4.3309de97.js @@ -0,0 +1 @@ +(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-4a59cbe4"],{"02f4":function(t,e,r){var n=r("4588"),i=r("be13");t.exports=function(t){return function(e,r){var o,a,l=String(i(e)),c=n(r),s=l.length;return c<0||c>=s?t?"":void 0:(o=l.charCodeAt(c),o<55296||o>56319||c+1===s||(a=l.charCodeAt(c+1))<56320||a>57343?t?l.charAt(c):o:t?l.slice(c,c+2):a-56320+(o-55296<<10)+65536)}}},"0390":function(t,e,r){"use strict";var n=r("02f4")(!0);t.exports=function(t,e,r){return e+(r?n(t,e).length:1)}},"0a49":function(t,e,r){var n=r("9b43"),i=r("626a"),o=r("4bf8"),a=r("9def"),l=r("cd1c");t.exports=function(t,e){var r=1==t,c=2==t,s=3==t,u=4==t,f=6==t,d=5==t||f,v=e||l;return function(e,l,p){for(var g,h,b=o(e),m=i(b),D=n(l,p,3),x=a(m.length),y=0,_=r?v(e,x):c?v(e,0):void 0;x>y;y++)if((d||y in m)&&(g=m[y],h=D(g,y,b),t))if(r)_[y]=h;else if(h)switch(t){case 3:return!0;case 5:return g;case 6:return y;case 2:_.push(g)}else if(u)return!1;return f?-1:s||u?u:_}}},"0bfb":function(t,e,r){"use strict";var n=r("cb7c");t.exports=function(){var t=n(this),e="";return t.global&&(e+="g"),t.ignoreCase&&(e+="i"),t.multiline&&(e+="m"),t.unicode&&(e+="u"),t.sticky&&(e+="y"),e}},1169:function(t,e,r){var n=r("2d95");t.exports=Array.isArray||function(t){return"Array"==n(t)}},"20d6":function(t,e,r){"use strict";var n=r("5ca1"),i=r("0a49")(6),o="findIndex",a=!0;o in[]&&Array(1)[o](function(){a=!1}),n(n.P+n.F*a,"Array",{findIndex:function(t){return i(this,t,arguments.length>1?arguments[1]:void 0)}}),r("9c6c")(o)},"214f":function(t,e,r){"use strict";r("b0c5");var n=r("2aba"),i=r("32e9"),o=r("79e5"),a=r("be13"),l=r("2b4c"),c=r("520a"),s=l("species"),u=!o(function(){var t=/./;return t.exec=function(){var t=[];return t.groups={a:"7"},t},"7"!=="".replace(t,"$")}),f=function(){var t=/(?:)/,e=t.exec;t.exec=function(){return e.apply(this,arguments)};var r="ab".split(t);return 2===r.length&&"a"===r[0]&&"b"===r[1]}();t.exports=function(t,e,r){var d=l(t),v=!o(function(){var e={};return e[d]=function(){return 7},7!=""[t](e)}),p=v?!o(function(){var e=!1,r=/a/;return r.exec=function(){return e=!0,null},"split"===t&&(r.constructor={},r.constructor[s]=function(){return r}),r[d](""),!e}):void 0;if(!v||!p||"replace"===t&&!u||"split"===t&&!f){var g=/./[d],h=r(a,d,""[t],function(t,e,r,n,i){return e.exec===c?v&&!i?{done:!0,value:g.call(e,r,n)}:{done:!0,value:t.call(r,e,n)}:{done:!1}}),b=h[0],m=h[1];n(String.prototype,t,b),i(RegExp.prototype,d,2==e?function(t,e){return m.call(t,this,e)}:function(t){return m.call(t,this)})}}},"520a":function(t,e,r){"use strict";var n=r("0bfb"),i=RegExp.prototype.exec,o=String.prototype.replace,a=i,l="lastIndex",c=function(){var t=/a/,e=/b*/g;return i.call(t,"a"),i.call(e,"a"),0!==t[l]||0!==e[l]}(),s=void 0!==/()??/.exec("")[1],u=c||s;u&&(a=function(t){var e,r,a,u,f=this;return s&&(r=new RegExp("^"+f.source+"$(?!\\s)",n.call(f))),c&&(e=f[l]),a=i.call(f,t),c&&a&&(f[l]=f.global?a.index+a[0].length:e),s&&a&&a.length>1&&o.call(a[0],r,function(){for(u=1;u]*>)/g,v=/\$([$&`']|\d\d?)/g,p=function(t){return void 0===t?t:String(t)};r("214f")("replace",2,function(t,e,r,g){return[function(n,i){var o=t(this),a=void 0==n?void 0:n[e];return void 0!==a?a.call(n,o,i):r.call(String(o),n,i)},function(t,e){var i=g(r,t,this,e);if(i.done)return i.value;var f=n(t),d=String(this),v="function"===typeof e;v||(e=String(e));var b=f.global;if(b){var m=f.unicode;f.lastIndex=0}var D=[];while(1){var x=c(f,d);if(null===x)break;if(D.push(x),!b)break;var y=String(x[0]);""===y&&(f.lastIndex=l(d,o(f.lastIndex),m))}for(var _="",w=0,I=0;I=w&&(_+=d.slice(w,k)+L,w=k+S.length)}return _+d.slice(w)}];function h(t,e,n,o,a,l){var c=n+t.length,s=o.length,u=v;return void 0!==a&&(a=i(a),u=d),r.call(l,u,function(r,i){var l;switch(i.charAt(0)){case"$":return"$";case"&":return t;case"`":return e.slice(0,n);case"'":return e.slice(c);case"<":l=a[i.slice(1,-1)];break;default:var u=+i;if(0===u)return r;if(u>s){var d=f(u/10);return 0===d?r:d<=s?void 0===o[d-1]?i.charAt(1):o[d-1]+i.charAt(1):r}l=o[u-1]}return void 0===l?"":l})}})},b0c5:function(t,e,r){"use strict";var n=r("520a");r("5ca1")({target:"RegExp",proto:!0,forced:n!==/./.exec},{exec:n})},cd1c:function(t,e,r){var n=r("e853");t.exports=function(t,e){return new(n(t))(e)}},e853:function(t,e,r){var n=r("d3f4"),i=r("1169"),o=r("2b4c")("species");t.exports=function(t){var e;return i(t)&&(e=t.constructor,"function"!=typeof e||e!==Array&&!i(e.prototype)||(e=void 0),n(e)&&(e=e[o],null===e&&(e=void 0))),void 0===e?Array:e}},ec2a:function(t,e,r){"use strict";r.r(e);var n=function(){var t=this,e=t.$createElement,r=t._self._c||e;return r("div",{staticClass:"app-container"},[r("el-form",{staticClass:"demo-form-inline",attrs:{inline:!0,model:t.searchFormData,size:"mini"}},[r("el-form-item",[r("el-button",{attrs:{type:"primary",icon:"el-icon-plus"},on:{click:t.onAddServer}},[t._v("添加监控服务器")])],1)],1),t._v(" "),r("el-table",{staticStyle:{width:"100%","margin-bottom":"20px"},attrs:{data:t.tableData,border:"","row-key":"treeId","empty-text":"请添加监控服务器"}},[r("el-table-column",{attrs:{prop:"monitorName",label:"网关实例",width:"300"},scopedSlots:t._u([{key:"default",fn:function(e){return[0===e.row.parentId?r("span",[t._v(t._s(e.row.monitorName))]):t._e()]}}])}),t._v(" "),r("el-table-column",{attrs:{prop:"serviceId",label:"serviceId",width:"200"},scopedSlots:t._u([{key:"default",fn:function(e){return[e.row.parentId>0?r("span",[t._v(t._s(e.row.serviceId))]):t._e()]}}])}),t._v(" "),r("el-table-column",{attrs:{prop:"name",label:"接口名 (版本号)",width:"200"},scopedSlots:t._u([{key:"default",fn:function(e){return[t._v("\n "+t._s(e.row.name+(e.row.version?" ("+e.row.version+")":""))+"\n ")]}}])}),t._v(" "),r("el-table-column",{attrs:{prop:"count",label:"出错次数",width:"100"}}),t._v(" "),r("el-table-column",{attrs:{prop:"errorMsg",label:"报错信息",width:"300"},scopedSlots:t._u([{key:"default",fn:function(e){return e.row.parentId>0?[r("div",{staticStyle:{display:"inline-block"},domProps:{innerHTML:t._s(t.showErrorMsg(e.row))}}),t._v(" "),r("el-button",{attrs:{type:"text",size:"mini"},on:{click:function(r){return t.onShowErrorDetail(e.row)}}},[t._v("详情")])]:void 0}}],null,!0)}),t._v(" "),r("el-table-column",{attrs:{label:"操作",width:"180"},scopedSlots:t._u([{key:"default",fn:function(e){return[0===e.row.parentId&&e.row.children?r("el-button",{attrs:{type:"text",size:"mini"},on:{click:function(r){return t.onClearLog(e.row)}}},[t._v("清空日志")]):t._e(),t._v(" "),0===e.row.parentId?r("el-button",{attrs:{type:"text",size:"mini"},on:{click:function(r){return t.onDelete(e.row)}}},[t._v("删除实例")]):t._e()]}}])})],1),t._v(" "),r("el-dialog",{attrs:{title:"选择服务器实例",visible:t.logDialogInstanceVisible,"close-on-click-modal":!1},on:{"update:visible":function(e){t.logDialogInstanceVisible=e}}},[r("el-form",{ref:"logDialogForm",attrs:{model:t.logDialogFormData,rules:t.rulesLog,"label-width":"150px",size:"mini"}},[r("el-form-item",[r("p",{staticStyle:{color:"#878787"}},[t._v("只能选择网关实例,其它实例不支持")])]),t._v(" "),r("el-form-item",{attrs:{prop:"instanceData",label:"服务器实例"}},[r("el-select",{staticStyle:{width:"400px"},attrs:{"value-key":"id"},model:{value:t.logDialogFormData.instanceData,callback:function(e){t.$set(t.logDialogFormData,"instanceData",e)},expression:"logDialogFormData.instanceData"}},t._l(t.serviceData,function(e){return r("el-option",{key:e.id,attrs:{label:e.name+"("+e.ipAddr+":"+e.serverPort+")",value:e,disabled:t.isOptionDisabled(e)}},[r("span",{staticStyle:{float:"left"}},[t._v(t._s(e.name)+" "),t.isOptionDisabled(e)?r("span",[t._v("(已添加)")]):t._e()]),t._v(" "),r("span",{staticStyle:{float:"right",color:"#8492a6","font-size":"13px"}},[t._v(t._s(e.ipAddr+":"+e.serverPort))])])}),1)],1)],1),t._v(" "),r("div",{staticClass:"dialog-footer",attrs:{slot:"footer"},slot:"footer"},[r("el-button",{on:{click:function(e){t.logDialogInstanceVisible=!1}}},[t._v("取 消")]),t._v(" "),r("el-button",{attrs:{type:"primary"},on:{click:t.onLogDialogSave}},[t._v("保 存")])],1)],1),t._v(" "),r("el-dialog",{attrs:{title:"错误详情",visible:t.logDetailVisible,width:"60%"},on:{"update:visible":function(e){t.logDetailVisible=e}}},[r("div",{staticStyle:{"overflow-x":"auto"},domProps:{innerHTML:t._s(t.errorMsgDetail)}}),t._v(" "),r("div",{staticClass:"dialog-footer",attrs:{slot:"footer"},slot:"footer"},[r("el-button",{attrs:{type:"primary"},on:{click:function(e){t.logDetailVisible=!1}}},[t._v("关 闭")])],1)])],1)},i=[],o=(r("a481"),r("ac6a"),r("20d6"),{data:function(){return{searchFormData:{},tableData:[],serviceData:[],addedInstanceList:[],logDialogFormData:{instanceData:null},logDialogInstanceVisible:!1,logDetailVisible:!1,rulesLog:{instanceData:[{required:!0,message:"不能为空",trigger:"blur"}]},errorMsgDetail:""}},created:function(){this.loadServiceInstance(),this.loadTable()},methods:{loadServiceInstance:function(){this.post("service.instance.list",{},function(t){this.serviceData=t.data.filter(function(t){return t.instanceId&&t.instanceId.length>0})}),this.post("monitor.instance.list",{},function(t){this.addedInstanceList=t.data})},loadTable:function(){this.post("monitor.log.list",{},function(t){this.tableData=this.buildTreeData(t.data)})},isOptionDisabled:function(t){var e=t.ipAddr+":"+t.serverPort,r=this.addedInstanceList.findIndex(function(t,r,n){return t===e});return r>-1},buildTreeData:function(t){return t.forEach(function(e){var r=e.parentId;0===r||t.forEach(function(t){if(t.treeId===r){var n=t.children;n||(n=[]),n.push(e),t.children=n}})}),t=t.filter(function(t){return 0===t.parentId}),t},showErrorMsg:function(t){var e=t.errorMsg.replace(/\/g,"");return e.substring(0,30)+"..."},onAddServer:function(){this.logDialogInstanceVisible=!0},onDelete:function(t){this.confirm("确定要删除实例【"+t.monitorName+"】吗?",function(e){this.post("monitor.instance.del",{id:t.rawId},function(t){e(),this.tip("删除成功"),this.loadTable()})})},onClearLog:function(t){this.confirm("确定要清空日志吗?",function(e){this.post("monitor.log.clear",{id:t.rawId},function(t){e(),this.tip("清空成功"),this.loadTable()})})},onShowErrorDetail:function(t){this.errorMsgDetail=t.errorMsg,this.logDetailVisible=!0},onLogDialogSave:function(){var t=this;this.$refs["logDialogForm"].validate(function(e){if(e){var r=t.logDialogFormData.instanceData,n={serviceId:r.serviceId,ip:r.ipAddr,port:r.serverPort};t.post("monitor.instance.add",n,function(t){this.logDialogInstanceVisible=!1,this.loadTable()})}})}}}),a=o,l=r("2877"),c=Object(l["a"])(a,n,i,!1,null,null,null);e["default"]=c.exports}}]); \ No newline at end of file diff --git a/sop-admin/sop-admin-vue/src/router/index.js b/sop-admin/sop-admin-vue/src/router/index.js index c7556d55..c99d3982 100644 --- a/sop-admin/sop-admin-vue/src/router/index.js +++ b/sop-admin/sop-admin-vue/src/router/index.js @@ -78,6 +78,12 @@ export const constantRoutes = [ name: 'Limit', component: () => import('@/views/service/limit/index2'), meta: { title: '限流管理' } + }, + { + path: 'log', + name: 'Log', + component: () => import('@/views/service/log/index'), + meta: { title: '监控日志' } } ] }, diff --git a/sop-admin/sop-admin-vue/src/utils/global.js b/sop-admin/sop-admin-vue/src/utils/global.js index 35646766..1d3b1bca 100644 --- a/sop-admin/sop-admin-vue/src/utils/global.js +++ b/sop-admin/sop-admin-vue/src/utils/global.js @@ -35,7 +35,7 @@ Object.assign(Vue.prototype, { const resp = response.data const code = resp.code if (!code || code === '-9') { - that.$message.error('系统错误') + that.$message.error(resp.msg || '系统错误') return } if (code === '-100' || code === '18' || code === '21') { // 未登录 @@ -96,6 +96,9 @@ Object.assign(Vue.prototype, { }, logout: function() { removeToken() - this.$router.push({ path: `/login?redirect=${this.$route.fullPath}` }) + const fullPath = this.$route.fullPath + if (fullPath.indexOf('login?redirect') === -1) { + this.$router.push({ path: `/login?redirect=${fullPath}` }) + } } }) diff --git a/sop-admin/sop-admin-vue/src/views/service/list/index.vue b/sop-admin/sop-admin-vue/src/views/service/list/index.vue index e712e7d3..511c2052 100644 --- a/sop-admin/sop-admin-vue/src/views/service/list/index.vue +++ b/sop-admin/sop-admin-vue/src/views/service/list/index.vue @@ -92,7 +92,7 @@ export default { // 如果ele是子元素的话 ,把ele扔到他的父亲的child数组中. data.forEach(d => { if (d.id === parentId) { - let childArray = d.child + let childArray = d.children if (!childArray) { childArray = [] } diff --git a/sop-admin/sop-admin-vue/src/views/service/log/index.vue b/sop-admin/sop-admin-vue/src/views/service/log/index.vue new file mode 100644 index 00000000..1b829abd --- /dev/null +++ b/sop-admin/sop-admin-vue/src/views/service/log/index.vue @@ -0,0 +1,234 @@ + + + diff --git a/sop-admin/sop-admin-vue/src/views/service/route/index.vue b/sop-admin/sop-admin-vue/src/views/service/route/index.vue index 28d8cf26..8fbb4f74 100644 --- a/sop-admin/sop-admin-vue/src/views/service/route/index.vue +++ b/sop-admin/sop-admin-vue/src/views/service/route/index.vue @@ -79,12 +79,12 @@ appSecretPair) { for (Map.Entry entry : appSecretPair.entrySet()) { this.isvManager.update(new IsvDefinition(entry.getKey(), entry.getValue())); diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/ErrorDefinition.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/ErrorDefinition.java new file mode 100644 index 00000000..9b974a80 --- /dev/null +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/ErrorDefinition.java @@ -0,0 +1,15 @@ +package com.gitee.sop.gatewaycommon.bean; + +import lombok.Data; + +/** + * @author tanghc + */ +@Data +public class ErrorDefinition { + private String name; + private String version; + private String serviceId; + private String errorMsg; + +} diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/ErrorEntity.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/ErrorEntity.java new file mode 100644 index 00000000..df6b4640 --- /dev/null +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/ErrorEntity.java @@ -0,0 +1,32 @@ +package com.gitee.sop.gatewaycommon.bean; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +import java.util.Objects; + +@Getter +@Setter +@ToString +public class ErrorEntity { + private String id; + private String name; + private String version; + private String serviceId; + private String errorMsg; + private long count; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ErrorEntity that = (ErrorEntity) o; + return id.equals(that.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } +} \ No newline at end of file diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/SopConstants.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/SopConstants.java index 3ce20984..2f824745 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/SopConstants.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/SopConstants.java @@ -33,7 +33,9 @@ public class SopConstants { public static final String CACHE_API_PARAM = "cacheApiParam"; - public static final String X_BIZ_ERROR_CODE = "x-biz-error-code"; + public static final String X_SERVICE_ERROR_CODE = "x-service-error-code"; + + public static final String X_SERVICE_ERROR_MESSAGE = "x-service-error-message"; public static final int BIZ_ERROR_STATUS = 4000; diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/result/GatewayResultExecutor.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/result/GatewayResultExecutor.java index be4bb9b9..884e013a 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/result/GatewayResultExecutor.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/result/GatewayResultExecutor.java @@ -28,7 +28,7 @@ public class GatewayResultExecutor extends BaseExecutorAdapter errorCodeList = exchange.getResponse().getHeaders().get(SopConstants.X_BIZ_ERROR_CODE); + List errorCodeList = exchange.getResponse().getHeaders().get(SopConstants.X_SERVICE_ERROR_CODE); if (!CollectionUtils.isEmpty(errorCodeList)) { String errorCode = errorCodeList.get(0); responseStatus = Integer.valueOf(errorCode); @@ -37,7 +37,18 @@ public class GatewayResultExecutor extends BaseExecutorAdapter getApiParam(ServerWebExchange exchange) { + public String getResponseErrorMessage(ServerWebExchange exchange) { + String errorMsg = null; + List errorMessageList = exchange.getResponse().getHeaders().get(SopConstants.X_SERVICE_ERROR_MESSAGE); + if (!CollectionUtils.isEmpty(errorMessageList)) { + errorMsg = errorMessageList.get(0); + } + exchange.getResponse().getHeaders().remove(SopConstants.X_SERVICE_ERROR_MESSAGE); + return errorMsg; + } + + @Override + public Map getApiParam(ServerWebExchange exchange) { return exchange.getAttribute(SopConstants.CACHE_REQUEST_BODY_FOR_MAP); } diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/DefaultServiceErrorManager.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/DefaultServiceErrorManager.java new file mode 100644 index 00000000..56d1bddf --- /dev/null +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/DefaultServiceErrorManager.java @@ -0,0 +1,51 @@ +package com.gitee.sop.gatewaycommon.manager; + +import com.gitee.sop.gatewaycommon.bean.ApiConfig; +import com.gitee.sop.gatewaycommon.bean.ErrorDefinition; +import com.gitee.sop.gatewaycommon.bean.ErrorEntity; +import org.apache.commons.codec.digest.DigestUtils; +import org.springframework.beans.BeanUtils; + +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author tanghc + */ +public class DefaultServiceErrorManager implements ServiceErrorManager { + + private static Map store = new ConcurrentHashMap<>(128); + + @Override + public Collection listAllErrors() { + return store.values(); + } + + @Override + public void saveError(ErrorDefinition errorDefinition) { + boolean hasCapacity = store.size() < ApiConfig.getInstance().getStoreErrorCapacity(); + // 这里还可以做其它事情,比如错误量到达一定数目后,自动发送邮件/微信给开发人员,方便及时获取异常情况 + String id = this.buildId(errorDefinition); + ErrorEntity errorEntity = store.get(id); + if (errorEntity == null && hasCapacity) { + errorEntity = new ErrorEntity(); + BeanUtils.copyProperties(errorDefinition, errorEntity); + errorEntity.setId(id); + store.put(id, errorEntity); + } + if (errorEntity != null) { + errorEntity.setCount(errorEntity.getCount() + 1); + } + } + + @Override + public void clear() { + store.clear(); + } + + protected String buildId(ErrorDefinition errorDefinition) { + return DigestUtils.md5Hex(errorDefinition.getServiceId() + errorDefinition.getErrorMsg()); + } + +} diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/ServiceErrorManager.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/ServiceErrorManager.java new file mode 100644 index 00000000..8528d4b7 --- /dev/null +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/ServiceErrorManager.java @@ -0,0 +1,29 @@ +package com.gitee.sop.gatewaycommon.manager; + +import com.gitee.sop.gatewaycommon.bean.ErrorDefinition; +import com.gitee.sop.gatewaycommon.bean.ErrorEntity; + +import java.util.Collection; + +/** + * @author tanghc + */ +public interface ServiceErrorManager { + + /** + * 保存错误信息 + * @param errorDefinition + */ + void saveError(ErrorDefinition errorDefinition); + + /** + * 清除日志 + */ + void clear(); + + /** + * 获取所有错误信息 + * @return + */ + Collection listAllErrors(); +} diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/param/ApiParam.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/param/ApiParam.java index 0ccd165c..50a5ea90 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/param/ApiParam.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/param/ApiParam.java @@ -29,6 +29,14 @@ public class ApiParam extends JSONObject implements Param { private transient ApiUploadContext apiUploadContext; + public static ApiParam build(Map map) { + ApiParam apiParam = new ApiParam(); + for (Map.Entry entry : map.entrySet()) { + apiParam.put(entry.getKey(), entry.getValue()); + } + return apiParam; + } + @JSONField(serialize = false) public String getRouteId() { return this.fetchNameVersion(); diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/result/BaseExecutorAdapter.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/result/BaseExecutorAdapter.java index e360c493..780fc514 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/result/BaseExecutorAdapter.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/result/BaseExecutorAdapter.java @@ -4,17 +4,24 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.gitee.sop.gatewaycommon.bean.ApiConfig; import com.gitee.sop.gatewaycommon.bean.ApiContext; +import com.gitee.sop.gatewaycommon.bean.BaseRouteDefinition; +import com.gitee.sop.gatewaycommon.bean.BaseServiceRouteInfo; +import com.gitee.sop.gatewaycommon.bean.ErrorDefinition; import com.gitee.sop.gatewaycommon.bean.SopConstants; import com.gitee.sop.gatewaycommon.bean.TargetRoute; import com.gitee.sop.gatewaycommon.manager.RouteRepositoryContext; import com.gitee.sop.gatewaycommon.message.ErrorEnum; import com.gitee.sop.gatewaycommon.message.ErrorMeta; import com.gitee.sop.gatewaycommon.param.ParamNames; +import lombok.Getter; +import lombok.Setter; import org.apache.commons.lang.BooleanUtils; +import org.springframework.beans.BeanUtils; import org.springframework.http.HttpStatus; import org.springframework.util.StringUtils; import java.util.Map; +import java.util.Optional; /** * @author tanghc @@ -33,17 +40,27 @@ public abstract class BaseExecutorAdapter implements ResultExecutor /** * 获取业务方约定的返回码 + * * @param t * @return 返回返回码 */ public abstract int getResponseStatus(T t); + /** + * 获取微服务端的错误信息 + * + * @param t + * @return + */ + public abstract String getResponseErrorMessage(T t); + /** * 返回Api参数 + * * @param t * @return 返回api参数 */ - public abstract Map getApiParam(T t); + public abstract Map getApiParam(T t); @Override public String mergeResult(T request, String serviceResult) { @@ -65,6 +82,7 @@ public abstract class BaseExecutorAdapter implements ResultExecutor jsonObjectService.put(GATEWAY_CODE_NAME, ISP_BIZ_ERROR.getCode()); jsonObjectService.put(GATEWAY_MSG_NAME, ISP_BIZ_ERROR.getError().getMsg()); } else { + this.storeError(request); // 微服务端有可能返回500错误 // {"path":"/book/getBook3","error":"Internal Server Error","message":"id不能为空","timestamp":"2019-02-13T07:41:00.495+0000","status":500} jsonObjectService = new JSONObject(); @@ -74,8 +92,24 @@ public abstract class BaseExecutorAdapter implements ResultExecutor return this.merge(request, jsonObjectService); } + /** + * 保存错误信息 + * + * @param request + */ + protected void storeError(T request) { + ApiInfo apiInfo = this.getApiInfo(request); + String errorMsg = this.getResponseErrorMessage(request); + ErrorDefinition errorDefinition = new ErrorDefinition(); + BeanUtils.copyProperties(apiInfo, errorDefinition); + errorDefinition.setErrorMsg(errorMsg); + ApiConfig.getInstance().getServiceErrorManager().saveError(errorDefinition); + } + + /** * 该路由是否合并结果 + * * @param request * @return true:需要合并 */ @@ -85,22 +119,43 @@ public abstract class BaseExecutorAdapter implements ResultExecutor if (defaultSetting != null) { return defaultSetting; } - Map params = this.getApiParam(request); - if (params == null) { - return true; - } - Object name = params.get(ParamNames.API_NAME); - Object version = params.get(ParamNames.VERSION_NAME); - if(name == null || version == null) { - return true; - } - TargetRoute targetRoute = RouteRepositoryContext.getRouteRepository().get(String.valueOf(name) + version); - if (targetRoute == null) { - return true; - } else { - int mergeResult = targetRoute.getRouteDefinition().getMergeResult(); - return BooleanUtils.toBoolean(mergeResult); - } + ApiInfo apiInfo = this.getApiInfo(request); + BaseRouteDefinition baseRouteDefinition = apiInfo.baseRouteDefinition; + return Optional.ofNullable(baseRouteDefinition) + .map(routeDefinition -> { + int mergeResult = baseRouteDefinition.getMergeResult(); + return BooleanUtils.toBoolean(mergeResult); + }) + .orElse(true); + } + + protected ApiInfo getApiInfo(T request) { + Map params = this.getApiParam(request); + String name = Optional.ofNullable(params) + .map(map -> (String) map.get(ParamNames.API_NAME)) + .orElse("method.unknown"); + + String version = Optional.ofNullable(params) + .map(map -> (String) map.get(ParamNames.VERSION_NAME)) + .orElse("version.unknown"); + + TargetRoute targetRoute = RouteRepositoryContext.getRouteRepository().get(name + version); + + String serviceId = Optional.ofNullable(targetRoute) + .flatMap(route -> Optional.ofNullable(route.getServiceRouteInfo())) + .map(BaseServiceRouteInfo::getServiceId) + .orElse("serviceId.unknown"); + + BaseRouteDefinition baseRouteDefinition = Optional.ofNullable(targetRoute) + .map(route -> route.getRouteDefinition()) + .orElse(null); + + ApiInfo apiInfo = new ApiInfo(); + apiInfo.name = name; + apiInfo.version = version; + apiInfo.serviceId = serviceId; + apiInfo.baseRouteDefinition = baseRouteDefinition; + return apiInfo; } protected String wrapResult(String serviceResult) { @@ -150,6 +205,7 @@ public abstract class BaseExecutorAdapter implements ResultExecutor /** * 这里需要使用平台的私钥生成一个sign,需要配置两套公私钥。目前暂未实现 + * * @param appKey * @return */ @@ -158,4 +214,13 @@ public abstract class BaseExecutorAdapter implements ResultExecutor return null; } + @Getter + @Setter + protected static class ApiInfo { + private String name; + private String version; + private String serviceId; + private BaseRouteDefinition baseRouteDefinition; + } + } diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/result/JsonResult.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/result/JsonResult.java new file mode 100644 index 00000000..a5786b81 --- /dev/null +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/result/JsonResult.java @@ -0,0 +1,13 @@ +package com.gitee.sop.gatewaycommon.result; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * @author tanghc + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class JsonResult extends ApiResult { + private Object data; +} diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/result/ZuulResultExecutor.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/result/ZuulResultExecutor.java index 233d0bae..aee316f7 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/result/ZuulResultExecutor.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/result/ZuulResultExecutor.java @@ -15,7 +15,6 @@ import lombok.extern.slf4j.Slf4j; import java.util.List; import java.util.Map; -import java.util.Optional; /** * @author tanghc @@ -26,23 +25,36 @@ public class ZuulResultExecutor extends BaseExecutorAdapter> bizHeaders = requestContext.getZuulResponseHeaders(); - Optional first = bizHeaders.stream() - .filter(header -> { - return SopConstants.X_BIZ_ERROR_CODE.equals(header.first()); - }).map(header -> { - return header.second(); - }).findFirst(); + int status = bizHeaders.stream() + .filter(header -> SopConstants.X_SERVICE_ERROR_CODE.equals(header.first())) + .map(header -> Integer.valueOf(header.second())) + .findFirst() + .orElse(requestContext.getResponseStatusCode()); - String status = first.orElseGet(() -> { - int respStatus = requestContext.getResponseStatusCode(); - return String.valueOf(respStatus); - }); + return status; + } - return Integer.valueOf(status); + @Override + public String getResponseErrorMessage(RequestContext requestContext) { + List> bizHeaders = requestContext.getZuulResponseHeaders(); + int index = -1; + String errorMsg = null; + for (int i = 0; i < bizHeaders.size(); i++) { + Pair header = bizHeaders.get(i); + if (SopConstants.X_SERVICE_ERROR_MESSAGE.equals(header.first())) { + errorMsg = header.second(); + index = i; + break; + } + } + if (index > -1) { + requestContext.getZuulResponseHeaders().remove(index); + } + return errorMsg; } @Override - public Map getApiParam(RequestContext requestContext) { + public Map getApiParam(RequestContext requestContext) { return ZuulContext.getApiParam(); } diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/DefaultGlobalExceptionHandler.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/DefaultGlobalExceptionHandler.java index 47b9e9be..c3103b69 100644 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/DefaultGlobalExceptionHandler.java +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/DefaultGlobalExceptionHandler.java @@ -20,6 +20,17 @@ import javax.servlet.http.HttpServletResponse; @Slf4j public class DefaultGlobalExceptionHandler implements GlobalExceptionHandler { + /** + * 与网关约定好的状态码,表示业务出错 + */ + public static final int BIZ_ERROR_CODE = 4000; + /** + * 系统错误 + */ + public static final int SYSTEM_ERROR_CODE = 5050; + + public static final String X_SERVICE_ERROR_CODE = "x-service-error-code"; + @RequestMapping("/error") @ResponseBody public Object error(HttpServletRequest request, HttpServletResponse response) { @@ -27,16 +38,42 @@ public class DefaultGlobalExceptionHandler implements GlobalExceptionHandler { return serviceResultBuilder.buildError(request, response, new ServiceException("系统繁忙")); } + /** + * 捕获手动抛出的异常 + * @param request + * @param response + * @param exception + * @return + */ @ExceptionHandler(ServiceException.class) @ResponseBody public Object serviceExceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception exception) { + response.addHeader(X_SERVICE_ERROR_CODE, String.valueOf(BIZ_ERROR_CODE)); return this.processError(request, response, exception); } + /** + * 捕获未知异常 + * @param request + * @param response + * @param exception + * @return + */ @ExceptionHandler(Exception.class) @ResponseBody public Object exceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception exception) { + response.addHeader(X_SERVICE_ERROR_CODE, String.valueOf(SYSTEM_ERROR_CODE)); log.error("系统错误", exception); + StringBuilder msg = new StringBuilder(); + msg.append(exception.getMessage()); + StackTraceElement[] stackTrace = exception.getStackTrace(); + // 取5行错误内容 + int lineCount = 5; + for (int i = 0; i < stackTrace.length && i < lineCount ; i++) { + StackTraceElement stackTraceElement = stackTrace[i]; + msg.append("
at ").append(stackTraceElement.toString()); + } + response.setHeader("x-service-error-message", msg.toString()); return this.processError(request, response, new ServiceException("系统繁忙")); } diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/result/DefaultServiceResultBuilder.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/result/DefaultServiceResultBuilder.java index cab2072d..a353f5fd 100644 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/result/DefaultServiceResultBuilder.java +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/result/DefaultServiceResultBuilder.java @@ -16,15 +16,9 @@ import javax.servlet.http.HttpServletResponse; public class DefaultServiceResultBuilder implements ServiceResultBuilder { public static final String ISP_UNKNOWN_ERROR = "isp.unknown-error"; - /** - * 与网关约定好的状态码,表示业务出错 - */ - public static final int BIZ_ERROR_CODE = 4000; - public static final String X_BIZ_ERROR_CODE = "x-biz-error-code"; @Override public Object buildError(HttpServletRequest request, HttpServletResponse response, Throwable throwable) { - response.addHeader(X_BIZ_ERROR_CODE, String.valueOf(BIZ_ERROR_CODE)); String subCode, subMsg; if (throwable instanceof ServiceException) { ServiceException ex = (ServiceException) throwable; diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/config/ZuulConfig.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/config/ZuulConfig.java index e96fefe9..e87b22bf 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/config/ZuulConfig.java +++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/config/ZuulConfig.java @@ -41,6 +41,9 @@ public class ZuulConfig extends AlipayZuulConfiguration { //public class ZuulConfig extends EasyopenZuulConfiguration { // static { // new ManagerInitializer(); +// Map appSecretMap = new HashMap<>(); +// appSecretMap.put("easyopen_test", "G9w0BAQEFAAOCAQ8AMIIBCgKCA"); +// ApiConfig.getInstance().addAppSecret(appSecretMap); // } // //} diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/controller/ErrorLogController.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/controller/ErrorLogController.java new file mode 100644 index 00000000..5d7670fc --- /dev/null +++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/controller/ErrorLogController.java @@ -0,0 +1,68 @@ +package com.gitee.sop.gateway.controller; + +import com.gitee.sop.gatewaycommon.bean.ApiConfig; +import com.gitee.sop.gatewaycommon.bean.ErrorEntity; +import com.gitee.sop.gatewaycommon.manager.ServiceErrorManager; +import com.gitee.sop.gatewaycommon.param.ApiParam; +import com.gitee.sop.gatewaycommon.result.ApiResult; +import com.gitee.sop.gatewaycommon.result.JsonResult; +import com.gitee.sop.gatewaycommon.util.RequestUtil; +import com.gitee.sop.gatewaycommon.validate.taobao.TaobaoSigner; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; +import java.util.Collection; +import java.util.Map; + +/** + * @author tanghc + */ +@RestController +public class ErrorLogController { + + TaobaoSigner signer = new TaobaoSigner(); + + @Value("${zuul.secret}") + private String secret; + + @GetMapping("listErrors") + public ApiResult listErrors(HttpServletRequest request) { + try { + this.check(request); + ServiceErrorManager serviceErrorManager = ApiConfig.getInstance().getServiceErrorManager(); + Collection allErrors = serviceErrorManager.listAllErrors(); + JsonResult apiResult = new JsonResult(); + apiResult.setData(allErrors); + return apiResult; + } catch (Exception e) { + ApiResult apiResult = new ApiResult(); + apiResult.setCode("505050"); + apiResult.setMsg(e.getMessage()); + return apiResult; + } + } + + @GetMapping("clearErrors") + public ApiResult clearErrors(HttpServletRequest request) { + try { + this.check(request); + ServiceErrorManager serviceErrorManager = ApiConfig.getInstance().getServiceErrorManager(); + serviceErrorManager.clear(); + return new ApiResult(); + } catch (Exception e) { + ApiResult apiResult = new ApiResult(); + apiResult.setCode("505050"); + apiResult.setMsg(e.getMessage()); + return apiResult; + } + } + + private void check(HttpServletRequest request) { + Map params = RequestUtil.convertRequestParamsToMap(request); + ApiParam apiParam = ApiParam.build(params); + signer.checkSign(apiParam, secret); + } + +} diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/RedirectController.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/controller/RedirectController.java similarity index 95% rename from sop-gateway/src/main/java/com/gitee/sop/gateway/RedirectController.java rename to sop-gateway/src/main/java/com/gitee/sop/gateway/controller/RedirectController.java index 2c8c26c0..3127d28f 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/RedirectController.java +++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/controller/RedirectController.java @@ -1,4 +1,4 @@ -package com.gitee.sop.gateway; +package com.gitee.sop.gateway.controller; import com.gitee.sop.gatewaycommon.bean.SopConstants; import org.springframework.beans.factory.annotation.Value; diff --git a/sop-gateway/src/main/resources/application-dev.yml b/sop-gateway/src/main/resources/application-dev.yml index 789eb0a4..cbb973a9 100644 --- a/sop-gateway/src/main/resources/application-dev.yml +++ b/sop-gateway/src/main/resources/application-dev.yml @@ -11,6 +11,8 @@ zuul: Servlet30WrapperFilter: pre: disable: true + # 不用改,如果要改,建议全局替换修改 + secret: MZZOUSTua6LzApIWXCwEgbBmxSzpzC # 注册中心,根据实际情况修改 eureka: diff --git a/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/config/WebsiteConfig.java b/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/config/WebsiteConfig.java index dd5eb120..d4a3331e 100644 --- a/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/config/WebsiteConfig.java +++ b/sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/config/WebsiteConfig.java @@ -28,7 +28,7 @@ public class WebsiteConfig implements ApplicationRunner { public HttpMessageConverters fastJsonConfigure(){ FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); FastJsonConfig fastJsonConfig = new FastJsonConfig(); - fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteNullStringAsEmpty); + fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteNullStringAsEmpty, SerializerFeature.WriteMapNullValue); // 日期格式化 fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss"); converter.setFastJsonConfig(fastJsonConfig); diff --git a/sop.sql b/sop.sql index 59814eb8..15c2a6eb 100644 --- a/sop.sql +++ b/sop.sql @@ -12,6 +12,7 @@ DROP TABLE IF EXISTS `config_route_limit`; DROP TABLE IF EXISTS `config_route_base`; DROP TABLE IF EXISTS `config_limit`; DROP TABLE IF EXISTS `admin_user_info`; +DROP TABLE IF EXISTS `config_common`; CREATE TABLE `admin_user_info` ( @@ -134,6 +135,17 @@ CREATE TABLE `user_info` ( ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='用户信息表'; +CREATE TABLE `config_common` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `config_group` varchar(64) NOT NULL DEFAULT '' COMMENT '配置分组', + `config_key` varchar(64) NOT NULL DEFAULT '' COMMENT '配置key', + `content` varchar(128) NOT NULL DEFAULT '' COMMENT '内容', + `remark` varchar(128) DEFAULT NULL COMMENT '备注', + `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + UNIQUE KEY `uk_groupkey` (`config_group`,`config_key`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='通用配置表'; SET FOREIGN_KEY_CHECKS = @PREVIOUS_FOREIGN_KEY_CHECKS;