From 72d7f64cd6196d289820bd8ababbcea271fbeac8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9A=AE=E5=85=89=EF=BC=9A=E5=9F=8E=E4=B8=AD=E5=9F=8E?= <806783409@qq.com> Date: Thu, 13 Dec 2018 00:03:28 +0800 Subject: [PATCH] =?UTF-8?q?debug=E5=8F=82=E6=95=B0=E5=B1=95=E7=A4=BA?= =?UTF-8?q?=EF=BC=8C=E5=9F=BA=E6=9C=AC=E5=8A=9F=E8=83=BD=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../manage/framework/config/WebMvcConfig.java | 116 +- .../resources/sql/zyplayer-doc-manage.sql | 140 +- .../controller/MgDocumentController.java | 616 +++++---- .../framework/constant/StorageKeys.java | 32 +- .../src/main/resources/document.html | 1 + .../webjars/mg-ui/js/mg-ui-cache-keys.js | 1 + .../resources/webjars/mg-ui/js/mg-ui-debug.js | 1197 +++++++++-------- .../webjars/mg-ui/js/mg-ui-export.js | 4 + .../main/resources/webjars/mg-ui/js/mg-ui.js | 53 +- .../webjars/zpages/docShowConfig.html | 13 +- .../webjars/zpages/docUrlConfig.html | 21 +- .../webjars/zpages/globalParamConfig.html | 5 +- 12 files changed, 1170 insertions(+), 1029 deletions(-) diff --git a/zyplayer-doc-manage/src/main/java/com/zyplayer/doc/manage/framework/config/WebMvcConfig.java b/zyplayer-doc-manage/src/main/java/com/zyplayer/doc/manage/framework/config/WebMvcConfig.java index ba55ac65..1dc78ab7 100644 --- a/zyplayer-doc-manage/src/main/java/com/zyplayer/doc/manage/framework/config/WebMvcConfig.java +++ b/zyplayer-doc-manage/src/main/java/com/zyplayer/doc/manage/framework/config/WebMvcConfig.java @@ -1,52 +1,64 @@ -package com.zyplayer.doc.manage.framework.config; - -import java.nio.charset.Charset; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.List; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.format.FormatterRegistry; -import org.springframework.format.datetime.DateFormatter; -import org.springframework.http.MediaType; -import org.springframework.http.converter.HttpMessageConverter; -import org.springframework.stereotype.Component; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; - -import com.alibaba.fastjson.serializer.SerializerFeature; -import com.alibaba.fastjson.support.config.FastJsonConfig; -import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; - -@Component -@Configuration -public class WebMvcConfig implements WebMvcConfigurer { - - @Override - public void addFormatters(FormatterRegistry registry) { - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - format.setLenient(true); - DateFormatter dateFormatter = new DateFormatter(); - dateFormatter.setPattern("yyyy-MM-dd HH:mm:ss"); - dateFormatter.setLenient(true); - registry.addFormatter(dateFormatter); - } - - @Bean - public FastJsonHttpMessageConverter fastJsonHttpMessageConverter() { - FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter(); - List supportedMediaTypes = new ArrayList<>(); - supportedMediaTypes.add(new MediaType("application", "json", Charset.forName("UTF-8"))); - fastJsonHttpMessageConverter.setSupportedMediaTypes(supportedMediaTypes); - FastJsonConfig fastJsonConfig = new FastJsonConfig(); - fastJsonConfig.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteDateUseDateFormat); - fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig); - return fastJsonHttpMessageConverter; - } - - @Override - public void configureMessageConverters(List> converters) { - converters.add(0, fastJsonHttpMessageConverter()); - } - -} +package com.zyplayer.doc.manage.framework.config; + +import java.nio.charset.Charset; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.List; + +import com.zyplayer.doc.manage.framework.interceptor.RequestInfoInterceptor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.format.FormatterRegistry; +import org.springframework.format.datetime.DateFormatter; +import org.springframework.http.MediaType; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.fastjson.support.config.FastJsonConfig; +import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; + +@Component +@Configuration +public class WebMvcConfig implements WebMvcConfigurer { + + @Autowired + RequestInfoInterceptor requestInfoInterceptor; + + @Override + public void addFormatters(FormatterRegistry registry) { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + format.setLenient(true); + DateFormatter dateFormatter = new DateFormatter(); + dateFormatter.setPattern("yyyy-MM-dd HH:mm:ss"); + dateFormatter.setLenient(true); + registry.addFormatter(dateFormatter); + } + + @Bean + public FastJsonHttpMessageConverter fastJsonHttpMessageConverter() { + FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter(); + List supportedMediaTypes = new ArrayList<>(); + supportedMediaTypes.add(new MediaType("application", "json", Charset.forName("UTF-8"))); + fastJsonHttpMessageConverter.setSupportedMediaTypes(supportedMediaTypes); + FastJsonConfig fastJsonConfig = new FastJsonConfig(); + fastJsonConfig.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteDateUseDateFormat); + fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig); + return fastJsonHttpMessageConverter; + } + + @Override + public void configureMessageConverters(List> converters) { + converters.add(0, fastJsonHttpMessageConverter()); + } + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(requestInfoInterceptor).excludePathPatterns("/**/*.js", "/**/*.css", "/**/*.png", + "/**/*.gif", "/**/*.jpg", "/**/*.jpeg", "/**/fonts/*"); + } + +} diff --git a/zyplayer-doc-manage/src/main/resources/sql/zyplayer-doc-manage.sql b/zyplayer-doc-manage/src/main/resources/sql/zyplayer-doc-manage.sql index a304a9ad..02c79266 100644 --- a/zyplayer-doc-manage/src/main/resources/sql/zyplayer-doc-manage.sql +++ b/zyplayer-doc-manage/src/main/resources/sql/zyplayer-doc-manage.sql @@ -1,33 +1,107 @@ -/* - Navicat Premium Data Transfer - - Source Server : 127.0.0.1 - Source Server Type : MySQL - Source Server Version : 50624 - Source Host : 127.0.0.1:3306 - Source Schema : zyplayer-doc-manage - - Target Server Type : MySQL - Target Server Version : 50624 - File Encoding : 65001 - - Date: 27/11/2018 20:19:45 -*/ - -SET NAMES utf8mb4; -SET FOREIGN_KEY_CHECKS = 0; - --- ---------------------------- --- Table structure for zyplayer_storage --- ---------------------------- -DROP TABLE IF EXISTS `zyplayer_storage`; -CREATE TABLE `zyplayer_storage` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `doc_key` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `doc_value` varchar(2048) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `creation_time` datetime NULL DEFAULT NULL, - PRIMARY KEY (`id`) USING BTREE, - UNIQUE INDEX `key`(`doc_key`) USING BTREE COMMENT 'key唯一索引' -) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; - -SET FOREIGN_KEY_CHECKS = 1; +/* + Navicat Premium Data Transfer + + Source Server : 127.0.0.1 + Source Server Type : MySQL + Source Server Version : 50624 + Source Host : 127.0.0.1:3306 + Source Schema : zyplayer-doc-manage + + Target Server Type : MySQL + Target Server Version : 50624 + File Encoding : 65001 + + Date: 12/12/2018 14:29:09 +*/ + +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +-- ---------------------------- +-- Table structure for auth_info +-- ---------------------------- +DROP TABLE IF EXISTS `auth_info`; +CREATE TABLE `auth_info` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键自增ID', + `auth_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '权限名', + `auth_desc` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '权限说明', + `can_edit` tinyint(4) NULL DEFAULT 1 COMMENT '是否可编辑 0=否 1=是', + `create_uid` bigint(20) NULL DEFAULT NULL COMMENT '创建人', + `creation_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; + +-- ---------------------------- +-- Records of auth_info +-- ---------------------------- +INSERT INTO `auth_info` VALUES (1, 'DOC_ALL', '文档查看权', 0, 1, '2018-12-01 11:40:42'); +INSERT INTO `auth_info` VALUES (2, 'AUTH_MANAGE', '权限管理权', 0, 1, '2018-12-01 11:40:42'); +INSERT INTO `auth_info` VALUES (3, 'AUTH_ASSIGN', '权限分配权', 0, 1, '2018-12-01 11:40:42'); +INSERT INTO `auth_info` VALUES (4, 'USER_MANAGE', '用户管理权', 0, 1, '2018-12-01 11:40:42'); + +-- ---------------------------- +-- Table structure for user_auth +-- ---------------------------- +DROP TABLE IF EXISTS `user_auth`; +CREATE TABLE `user_auth` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键自增ID', + `user_id` bigint(20) NULL DEFAULT NULL COMMENT '用户ID', + `auth_id` bigint(20) NULL DEFAULT NULL COMMENT '权限ID', + `create_uid` bigint(20) NULL DEFAULT NULL COMMENT '创建用户ID', + `update_uid` bigint(20) NULL DEFAULT NULL COMMENT '更新用户ID', + `del_flag` tinyint(4) NULL DEFAULT 0 COMMENT '是否删除 0=未删除 1=已删除', + `creation_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; + +-- ---------------------------- +-- Records of user_auth +-- ---------------------------- +INSERT INTO `user_auth` VALUES (1, 1, 1, 1, 1, 0, '2018-12-01 11:41:13', '2018-12-01 11:41:13'); +INSERT INTO `user_auth` VALUES (2, 1, 2, 1, 1, 0, '2018-12-01 11:41:13', '2018-12-01 11:41:13'); +INSERT INTO `user_auth` VALUES (3, 1, 3, 1, 1, 0, '2018-12-01 11:41:13', '2018-12-01 11:41:13'); +INSERT INTO `user_auth` VALUES (4, 1, 4, 1, 1, 0, '2018-12-01 11:41:13', '2018-12-01 11:41:13'); + +-- ---------------------------- +-- Table structure for user_info +-- ---------------------------- +DROP TABLE IF EXISTS `user_info`; +CREATE TABLE `user_info` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键自增ID', + `user_no` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户编号,用于登录等', + `password` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '密码', + `user_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户名', + `email` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '邮箱', + `avatar` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '头像', + `del_flag` tinyint(4) NULL DEFAULT 0 COMMENT '是否删除 0=未删除 1=已删除', + `create_uid` bigint(20) NULL DEFAULT NULL COMMENT '创建人', + `creation_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + `update_time` datetime(0) NULL DEFAULT NULL COMMENT '修改时间', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; + +-- ---------------------------- +-- Records of user_info +-- ---------------------------- +INSERT INTO `user_info` VALUES (1, 'zyplayer', 'e10adc3949ba59abbe56e057f20f883e', '暮光:城中城', '806783409@qq.com', NULL, 0, NULL, '2018-12-01 11:37:39', NULL); + +-- ---------------------------- +-- Table structure for zyplayer_storage +-- ---------------------------- +DROP TABLE IF EXISTS `zyplayer_storage`; +CREATE TABLE `zyplayer_storage` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `doc_key` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `doc_value` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL, + `creation_time` datetime(0) NULL DEFAULT NULL, + `update_time` datetime(0) NULL DEFAULT NULL, + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `key`(`doc_key`) USING BTREE COMMENT 'key唯一索引' +) ENGINE = InnoDB AUTO_INCREMENT = 16 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; + +-- ---------------------------- +-- Records of zyplayer_storage +-- ---------------------------- + +SET FOREIGN_KEY_CHECKS = 1; diff --git a/zyplayer-doc-swagger/src/main/java/com/zyplayer/doc/swagger/controller/MgDocumentController.java b/zyplayer-doc-swagger/src/main/java/com/zyplayer/doc/swagger/controller/MgDocumentController.java index 5c55d1b8..23da38d1 100644 --- a/zyplayer-doc-swagger/src/main/java/com/zyplayer/doc/swagger/controller/MgDocumentController.java +++ b/zyplayer-doc-swagger/src/main/java/com/zyplayer/doc/swagger/controller/MgDocumentController.java @@ -1,286 +1,330 @@ -package com.zyplayer.doc.swagger.controller; - -import java.net.URLEncoder; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.lang.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.aop.support.AopUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.ResponseBody; -import org.springframework.web.bind.annotation.RestController; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.TypeReference; -import com.zyplayer.doc.core.json.DocResponseJson; -import com.zyplayer.doc.core.json.ResponseJson; -import com.zyplayer.doc.swagger.framework.configuration.EnableSwaggerMgUi; -import com.zyplayer.doc.swagger.framework.configuration.SpringContextUtil; -import com.zyplayer.doc.swagger.framework.constant.StorageKeys; -import com.zyplayer.doc.swagger.framework.service.MgStorageService; - -import cn.hutool.http.HttpRequest; -import springfox.documentation.swagger.web.SwaggerResource; - -/** - * 文档控制器 - * - * @author 暮光:城中城 - * @since 2018年8月21日 - */ -@RestController -@RequestMapping("/swagger-mg-ui/document") -public class MgDocumentController { - - private static Logger logger = LoggerFactory.getLogger(MgDocumentController.class); - - @Autowired - private MgStorageService storageService; - - /** - * 获取所有的文档地址 - * - * @author 暮光:城中城 - * @since 2018年8月21日 - * @return 文档内容 - */ - @ResponseBody - @PostMapping(value = "/resourcesList") - public ResponseJson> resourcesList() { - String swaggerResourcesStr = storageService.get(StorageKeys.SWAGGER_RESOURCES_LIST); - Set resourcesSet = new HashSet<>(); - if (StringUtils.isNotBlank(swaggerResourcesStr)) { - List resourcesList = JSON.parseArray(swaggerResourcesStr, String.class); - resourcesSet.addAll(resourcesList); - } - return DocResponseJson.ok(resourcesSet); - } - - /** - * 获取所有的文档 - * @author 暮光:城中城 - * @since 2018年8月21日 - * @param request request - * @param response response - */ - @ResponseBody - @PostMapping(value = "/docs") - public void docs(HttpServletRequest request, HttpServletResponse response) { - boolean needRestorage = true; - String choiseDocList = request.getParameter("choiseDocList"); - // 转成set,防止重复 - Set resourcesSet = new HashSet<>(); - Set swaggerDocsDeleteSet = new HashSet<>(); - if (StringUtils.isNotBlank(choiseDocList)) { - needRestorage = false;// 选择的则不再存入 - resourcesSet.addAll(Arrays.asList(choiseDocList.split(","))); - } else { - String swaggerResourcesStr = storageService.get(StorageKeys.SWAGGER_RESOURCES_LIST); - String swaggerDocsDeleteStr = storageService.get(StorageKeys.SWAGGER_DOCS_DELETE_LIST); - if (StringUtils.isNotBlank(swaggerResourcesStr)) { - List resourcesList = JSON.parseArray(swaggerResourcesStr, String.class); - resourcesSet.addAll(resourcesList); - } else { - // 默认加上自身的文档 - String serverPath = "http://" + request.getServerName() // 服务器地址 - + ":" + request.getServerPort() // 端口号 - + request.getContextPath(); - // 是否加入自身的文档 - Object object = SpringContextUtil.getBeanWithAnnotation(EnableSwaggerMgUi.class); - EnableSwaggerMgUi swaggerMgUi = object.getClass().getAnnotation(EnableSwaggerMgUi.class); - if (swaggerMgUi == null) { - // 直接通过superclass去找 - Class superclass = object.getClass().getSuperclass(); - if (superclass != null) { - swaggerMgUi = superclass.getAnnotation(EnableSwaggerMgUi.class); - } - } - if (swaggerMgUi == null) { - // 再通过AopUtils去找 - Class targetClass = AopUtils.getTargetClass(object); - if (targetClass != null) { - swaggerMgUi = targetClass.getAnnotation(EnableSwaggerMgUi.class); - } - } - if (swaggerMgUi == null) { - resourcesSet.add(serverPath + "/swagger-resources"); - } else { - if (swaggerMgUi.selfDoc()) { - resourcesSet.add(serverPath + "/swagger-resources"); - } - // 启动后第一次访问没有数据情况下需要加载进来的swagger-resources地址 - String[] defaultResources = swaggerMgUi.defaultResources(); - if (defaultResources != null && defaultResources.length > 0) { - resourcesSet.addAll(Arrays.asList(defaultResources)); - } - } - } - if (StringUtils.isNotBlank(swaggerDocsDeleteStr)) { - List swaggerDocsDeleteList = JSON.parseArray(swaggerDocsDeleteStr, String.class); - swaggerDocsDeleteSet.addAll(swaggerDocsDeleteList); - } - } - List> swaggerResourceList = new LinkedList<>(); - List swaggerResourceStrList = new LinkedList<>(); - for (String resourcesUrl : resourcesSet) { - List resourceList = null; - try { - String resourcesStr = HttpRequest.get(resourcesUrl).timeout(3000).execute().body(); - resourceList = JSON.parseArray(resourcesStr, SwaggerResource.class); - } catch (Exception e) { - logger.error("获取文档失败:{},{}", resourcesUrl, e.getMessage()); - } - if (resourceList == null || resourceList.isEmpty()) { - continue; - } - resourcesUrl = resourcesUrl.substring(0, resourcesUrl.lastIndexOf("/") + 1); - for (SwaggerResource resource : resourceList) { - String location = resource.getLocation(); - // 最后一个斜杠在resourcesUrl中已经加上,替换掉后面的防止两根斜杠 - location = location.startsWith("/") ? location.replaceFirst("/", "") : location; - if (location.indexOf("?") >= 0) { - try { - String encode = URLEncoder.encode(resource.getName(), "utf-8"); - location = location.substring(0, location.lastIndexOf("?")) + "?group=" + encode; - } catch (Exception e) { - e.printStackTrace(); - } - } - location = resourcesUrl + location; - // 已删除的则不处理 - if (swaggerDocsDeleteSet.contains(location)) { - continue; - } - try { - String resourceStr = HttpRequest.get(location).timeout(3000).execute().body(); - Map jsonObject = JSON.parseObject(resourceStr, new TypeReference>(){}); - if (jsonObject == null || jsonObject.isEmpty()) { - continue; - } - jsonObject.put("fullUrl", location); - swaggerResourceList.add(jsonObject); - // 本来想转对象之后赋值,但是在此转成JSON字符串之后格式就不是之前的了,所有不能转。。。 - // 直接字符串拼接,坑真多~ - resourceStr = resourceStr.substring(1); - resourceStr = "{\"fullUrl\":\"" + location + "\"," - + "\"domainUrl\":\"" + resourcesUrl + "\"," - + resourceStr; - swaggerResourceStrList.add(resourceStr); - } catch (Exception e) { - logger.error("获取文档失败:{},{}", location, e.getMessage()); - } - } - } - if (needRestorage) { - storageService.put(StorageKeys.SWAGGER_RESOURCES_LIST, JSON.toJSONString(resourcesSet)); - } - // 用默认的json解析要内存溢出,解析不了JSONObject、、就只有这样写了~ - DocResponseJson.ok(swaggerResourceStrList).send(response); - } - - /** - * 增加/swagger-resources地址 - * - * @author 暮光:城中城 - * @since 2018年8月21日 - * @param resourcesUrl swagger-resources地址 - * @return 添加结果 - */ - @PostMapping(value = "/addSwaggerResources") - public ResponseJson addSwaggerResources(String resourcesUrl) { - String swaggerResourcesStr = storageService.get(StorageKeys.SWAGGER_RESOURCES_LIST); - String swaggerDocsDeleteStr = storageService.get(StorageKeys.SWAGGER_DOCS_DELETE_LIST); - Set swaggerDocsDeleteSet = new HashSet<>(); - if (StringUtils.isNotBlank(swaggerDocsDeleteStr)) { - List swaggerDocsDeleteList = JSON.parseArray(swaggerDocsDeleteStr, String.class); - swaggerDocsDeleteSet.addAll(swaggerDocsDeleteList); - } - // 转成set,防止重复 - Set resourcesSet = new HashSet<>(); - if (StringUtils.isNotBlank(swaggerResourcesStr)) { - List resourcesList = JSON.parseArray(swaggerResourcesStr, String.class); - resourcesSet.addAll(resourcesList); - } - String resourcesStr = null; - try { -// resourcesStr = HttpRequest.get(resourcesUrl).timeout(3000).execute().body(); -// List resourceList = JSON.parseArray(resourcesStr, SwaggerResource.class); -// if (resourceList == null || resourceList.isEmpty()) { -// return DocResponseJson.warn("该地址未找到文档"); -// } -// // 重新加入的时候把之前的已删除的回恢复 -// String resourcesDomain = resourcesUrl.substring(0, resourcesUrl.lastIndexOf("/") + 1); -// for (SwaggerResource swaggerResource : resourceList) { -// String location = swaggerResource.getLocation(); -// // 最后一个斜杠在resourcesUrl中已经加上,替换掉后面的防止两根斜杠 -// location = location.startsWith("/") ? location.replaceFirst("/", "") : location; -// if (location.indexOf("?") >= 0) { -// try { -// String encode = URLEncoder.encode(swaggerResource.getName(), "utf-8"); -// location = location.substring(0, location.lastIndexOf("?")) + "?group=" + encode; -// } catch (Exception e) { -// e.printStackTrace(); -// } -// } -// location = resourcesDomain + location; -// swaggerDocsDeleteSet.remove(location); -// } - resourcesSet.add(resourcesUrl); - } catch (Exception e) { -// 暂不想支持直接添加地址 -// try { -// SwaggerLocationVo swaggerLocationVo = JSON.parseObject(resourcesStr, SwaggerLocationVo.class); -// if (StringUtils.isNotBlank(swaggerLocationVo.getSwagger())) { -// Set locationSet = new HashSet<>(); -// if (StringUtils.isNotBlank(swaggerLocationListStr)) { -// String swaggerLocationListStr = storageService.get(StorageKeys.SWAGGER_LOCATION_LIST); -// List locationList = JSON.parseArray(swaggerLocationListStr, String.class); -// locationSet.addAll(locationList); -// storageService.put(StorageKeys.SWAGGER_LOCATION_LIST, JSON.toJSONString(locationSet)); -// } -// } else { -// return DocResponseJson.warn("该地址查找文档失败"); -// } -// } catch (Exception e2) { - logger.error("获取文档失败:{},{}", resourcesUrl, e.getMessage()); - return DocResponseJson.warn("该地址查找文档失败"); -// } - } - storageService.put(StorageKeys.SWAGGER_RESOURCES_LIST, JSON.toJSONString(resourcesSet)); - storageService.put(StorageKeys.SWAGGER_DOCS_DELETE_LIST, JSON.toJSONString(swaggerDocsDeleteSet)); - return DocResponseJson.ok(); - } - - /** - * 删除/v2/api-docs - * - * @author 暮光:城中城 - * @since 2018年8月21日 - * @param docUrl 文档地址 - * @return 删除结果 - */ - @PostMapping(value = "/deleteSwaggerDoc") - public ResponseJson deleteSwaggerDoc(String docUrl) { - String swaggerDocsDeleteStr = storageService.get(StorageKeys.SWAGGER_DOCS_DELETE_LIST); - Set swaggerDocsDeleteSet = new HashSet<>(); - if (StringUtils.isNotBlank(swaggerDocsDeleteStr)) { - List swaggerDocsDeleteList = JSON.parseArray(swaggerDocsDeleteStr, String.class); - swaggerDocsDeleteSet.addAll(swaggerDocsDeleteList); - } - swaggerDocsDeleteSet.add(docUrl); - storageService.put(StorageKeys.SWAGGER_DOCS_DELETE_LIST, JSON.toJSONString(swaggerDocsDeleteSet)); - return DocResponseJson.ok(); - } -} +package com.zyplayer.doc.swagger.controller; + +import cn.hutool.http.HttpRequest; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; +import com.zyplayer.doc.core.json.DocResponseJson; +import com.zyplayer.doc.core.json.ResponseJson; +import com.zyplayer.doc.swagger.controller.vo.SwaggerResourcesInfoVo; +import com.zyplayer.doc.swagger.framework.configuration.EnableSwaggerMgUi; +import com.zyplayer.doc.swagger.framework.configuration.SpringContextUtil; +import com.zyplayer.doc.swagger.framework.constant.StorageKeys; +import com.zyplayer.doc.swagger.framework.service.MgStorageService; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.aop.support.AopUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; +import springfox.documentation.swagger.web.SwaggerResource; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.net.URLEncoder; +import java.util.*; + +/** + * 文档控制器 + * + * @author 暮光:城中城 + * @since 2018年8月21日 + */ +@RestController +@RequestMapping("/swagger-mg-ui/document") +public class MgDocumentController { + + private static Logger logger = LoggerFactory.getLogger(MgDocumentController.class); + + @Autowired + private MgStorageService storageService; + + /** + * 获取所有的文档地址 + * + * @author 暮光:城中城 + * @since 2018年8月21日 + * @return 文档内容 + */ + @ResponseBody + @PostMapping(value = "/resourcesList") + public ResponseJson> resourcesList() { + String swaggerResourcesStr = storageService.get(StorageKeys.SWAGGER_RESOURCES_LIST); + Set resourcesSet = new HashSet<>(); + if (StringUtils.isNotBlank(swaggerResourcesStr)) { + List resourcesList = JSON.parseArray(swaggerResourcesStr, SwaggerResourcesInfoVo.class); + resourcesSet.addAll(resourcesList); + } + return DocResponseJson.ok(resourcesSet); + } + + /** + * 获取所有的文档 + * @author 暮光:城中城 + * @since 2018年8月21日 + * @param request request + * @param response response + */ + @ResponseBody + @PostMapping(value = "/docs") + public void docs(HttpServletRequest request, HttpServletResponse response) { + boolean needRestorage = true; + String choiseDocList = request.getParameter("choiseDocList"); + // 转成set,防止重复 + Set resourcesSet = new HashSet<>(); + Set swaggerDocsDeleteSet = new HashSet<>(); + if (StringUtils.isNotBlank(choiseDocList)) { + needRestorage = false;// 选择的则不再存入 + for (String url : choiseDocList.split(",")) { + resourcesSet.add(new SwaggerResourcesInfoVo(url)); + } + } else { + String swaggerResourcesStr = storageService.get(StorageKeys.SWAGGER_RESOURCES_LIST); + String swaggerDocsDeleteStr = storageService.get(StorageKeys.SWAGGER_DOCS_DELETE_LIST); + if (StringUtils.isNotBlank(swaggerResourcesStr)) { + List resourcesList = JSON.parseArray(swaggerResourcesStr, SwaggerResourcesInfoVo.class); + resourcesSet.addAll(resourcesList); + } else { + // 默认加上自身的文档 + String serverPath = "http://" + request.getServerName() // 服务器地址 + + ":" + request.getServerPort() // 端口号 + + request.getContextPath(); + // 是否加入自身的文档 + Object object = SpringContextUtil.getBeanWithAnnotation(EnableSwaggerMgUi.class); + EnableSwaggerMgUi swaggerMgUi = object.getClass().getAnnotation(EnableSwaggerMgUi.class); + if (swaggerMgUi == null) { + // 直接通过superclass去找 + Class superclass = object.getClass().getSuperclass(); + if (superclass != null) { + swaggerMgUi = superclass.getAnnotation(EnableSwaggerMgUi.class); + } + } + if (swaggerMgUi == null) { + // 再通过AopUtils去找 + Class targetClass = AopUtils.getTargetClass(object); + if (targetClass != null) { + swaggerMgUi = targetClass.getAnnotation(EnableSwaggerMgUi.class); + } + } + if (swaggerMgUi == null) { + resourcesSet.add(new SwaggerResourcesInfoVo(serverPath + "/swagger-resources")); + } else { + if (swaggerMgUi.selfDoc()) { + resourcesSet.add(new SwaggerResourcesInfoVo(serverPath + "/swagger-resources")); + } + // 启动后第一次访问没有数据情况下需要加载进来的swagger-resources地址 + String[] defaultResources = swaggerMgUi.defaultResources(); + if (defaultResources != null && defaultResources.length > 0) { + for (String url : defaultResources) { + resourcesSet.add(new SwaggerResourcesInfoVo(url)); + } + } + } + } + if (StringUtils.isNotBlank(swaggerDocsDeleteStr)) { + List swaggerDocsDeleteList = JSON.parseArray(swaggerDocsDeleteStr, String.class); + swaggerDocsDeleteSet.addAll(swaggerDocsDeleteList); + } + } + List> swaggerResourceList = new LinkedList<>(); + List swaggerResourceStrList = new LinkedList<>(); + for (SwaggerResourcesInfoVo resourcesInfoVo : resourcesSet) { + List resourceList = null; + String resourcesUrl = resourcesInfoVo.getUrl(); + try { + String resourcesStr = HttpRequest.get(resourcesUrl).timeout(3000).execute().body(); + resourceList = JSON.parseArray(resourcesStr, SwaggerResource.class); + } catch (Exception e) { + logger.error("获取文档失败:{},{}", resourcesUrl, e.getMessage()); + } + if (resourceList == null || resourceList.isEmpty()) { + continue; + } + resourcesUrl = resourcesUrl.substring(0, resourcesUrl.lastIndexOf("/") + 1); + for (SwaggerResource resource : resourceList) { + String location = resource.getLocation(); + // 最后一个斜杠在resourcesUrl中已经加上,替换掉后面的防止两根斜杠 + location = location.startsWith("/") ? location.replaceFirst("/", "") : location; + if (location.indexOf("?") >= 0) { + try { + String encode = URLEncoder.encode(resource.getName(), "utf-8"); + location = location.substring(0, location.lastIndexOf("?")) + "?group=" + encode; + } catch (Exception e) { + e.printStackTrace(); + } + } + location = resourcesUrl + location; + // 已删除的则不处理 + if (swaggerDocsDeleteSet.contains(location)) { + continue; + } + try { + String resourceStr = HttpRequest.get(location).timeout(3000).execute().body(); + Map jsonObject = JSON.parseObject(resourceStr, new TypeReference>(){}); + if (jsonObject == null || jsonObject.isEmpty()) { + continue; + } + jsonObject.put("fullUrl", location); + swaggerResourceList.add(jsonObject); + // 本来想转对象之后赋值,但是在此转成JSON字符串之后格式就不是之前的了,所有不能转。。。 + // 直接字符串拼接,坑真多~ + resourceStr = resourceStr.substring(1); + resourceStr = "{\"fullUrl\":\"" + location + "\"," + + "\"domainUrl\":\"" + resourcesUrl + "\"," + + resourceStr; + swaggerResourceStrList.add(resourceStr); + } catch (Exception e) { + logger.error("获取文档失败:{},{}", location, e.getMessage()); + } + } + } + if (needRestorage) { + storageService.put(StorageKeys.SWAGGER_RESOURCES_LIST, JSON.toJSONString(resourcesSet)); + } + // 用默认的json解析要内存溢出,解析不了JSONObject、、就只有这样写了~ + DocResponseJson.ok(swaggerResourceStrList).send(response); + } + + /** + * 增加/swagger-resources地址 + * + * @author 暮光:城中城 + * @since 2018年8月21日 + * @param resourcesUrl swagger-resources地址 + * @return 添加结果 + */ + @PostMapping(value = "/addSwaggerResources") + public ResponseJson addSwaggerResources(String resourcesUrl) { + String swaggerResourcesStr = storageService.get(StorageKeys.SWAGGER_RESOURCES_LIST); + String swaggerDocsDeleteStr = storageService.get(StorageKeys.SWAGGER_DOCS_DELETE_LIST); + Set swaggerDocsDeleteSet = new HashSet<>(); + if (StringUtils.isNotBlank(swaggerDocsDeleteStr)) { + List swaggerDocsDeleteList = JSON.parseArray(swaggerDocsDeleteStr, String.class); + swaggerDocsDeleteSet.addAll(swaggerDocsDeleteList); + } + // 转成set,防止重复 + Set resourcesSet = new HashSet<>(); + if (StringUtils.isNotBlank(swaggerResourcesStr)) { + List resourcesList = JSON.parseArray(swaggerResourcesStr, SwaggerResourcesInfoVo.class); + resourcesSet.addAll(resourcesList); + } + try { + String resourcesStr = HttpRequest.get(resourcesUrl).timeout(3000).execute().body(); + List resourceList = JSON.parseArray(resourcesStr, SwaggerResource.class); + if (resourceList == null || resourceList.isEmpty()) { + return DocResponseJson.warn("该地址未找到文档"); + } + // 重新加入的时候把之前的已删除的回恢复 + String resourcesDomain = resourcesUrl.substring(0, resourcesUrl.lastIndexOf("/") + 1); + for (SwaggerResource swaggerResource : resourceList) { + String location = swaggerResource.getLocation(); + // 最后一个斜杠在resourcesUrl中已经加上,替换掉后面的防止两根斜杠 + location = location.startsWith("/") ? location.replaceFirst("/", "") : location; + if (location.indexOf("?") >= 0) { + try { + String encode = URLEncoder.encode(swaggerResource.getName(), "utf-8"); + location = location.substring(0, location.lastIndexOf("?")) + "?group=" + encode; + } catch (Exception e) { + e.printStackTrace(); + } + } + location = resourcesDomain + location; + swaggerDocsDeleteSet.remove(location); + } + resourcesSet.add(new SwaggerResourcesInfoVo(resourcesUrl)); + } catch (Exception e) { +// 暂不想支持直接添加地址 +// try { +// SwaggerLocationVo swaggerLocationVo = JSON.parseObject(resourcesStr, SwaggerLocationVo.class); +// if (StringUtils.isNotBlank(swaggerLocationVo.getSwagger())) { +// Set locationSet = new HashSet<>(); +// if (StringUtils.isNotBlank(swaggerLocationListStr)) { +// String swaggerLocationListStr = storageService.get(StorageKeys.SWAGGER_LOCATION_LIST); +// List locationList = JSON.parseArray(swaggerLocationListStr, String.class); +// locationSet.addAll(locationList); +// storageService.put(StorageKeys.SWAGGER_LOCATION_LIST, JSON.toJSONString(locationSet)); +// } +// } else { +// return DocResponseJson.warn("该地址查找文档失败"); +// } +// } catch (Exception e2) { + logger.error("获取文档失败:{},{}", resourcesUrl, e.getMessage()); + return DocResponseJson.warn("该地址查找文档失败"); +// } + } + storageService.put(StorageKeys.SWAGGER_RESOURCES_LIST, JSON.toJSONString(resourcesSet)); + storageService.put(StorageKeys.SWAGGER_DOCS_DELETE_LIST, JSON.toJSONString(swaggerDocsDeleteSet)); + return DocResponseJson.ok(); + } + + /** + * 增加/swagger-resources地址 + * + * @author 暮光:城中城 + * @since 2018年8月21日 + * @param resourcesUrl swagger-resources地址 + * @return 添加结果 + */ + @PostMapping(value = "/syncDocData") + public ResponseJson syncDocData(String resourcesUrl) { + String swaggerResourcesStr = storageService.get(StorageKeys.SWAGGER_RESOURCES_LIST); + // 转成set,防止重复 + Set resourcesSet = new HashSet<>(); + if (StringUtils.isNotBlank(swaggerResourcesStr)) { + List resourcesList = JSON.parseArray(swaggerResourcesStr, SwaggerResourcesInfoVo.class); + resourcesSet.addAll(resourcesList); + } + try { + String resourcesStr = HttpRequest.get(resourcesUrl).timeout(3000).execute().body(); + List resourceList = JSON.parseArray(resourcesStr, SwaggerResource.class); + if (resourceList == null || resourceList.isEmpty()) { + return DocResponseJson.warn("该地址未找到文档"); + } + // 重新加入的时候把之前的已删除的回恢复 + String resourcesDomain = resourcesUrl.substring(0, resourcesUrl.lastIndexOf("/") + 1); + for (SwaggerResource swaggerResource : resourceList) { + String location = swaggerResource.getLocation(); + // 最后一个斜杠在resourcesUrl中已经加上,替换掉后面的防止两根斜杠 + location = location.startsWith("/") ? location.replaceFirst("/", "") : location; + if (location.indexOf("?") >= 0) { + try { + String encode = URLEncoder.encode(swaggerResource.getName(), "utf-8"); + location = location.substring(0, location.lastIndexOf("?")) + "?group=" + encode; + } catch (Exception e) { + e.printStackTrace(); + } + } + location = resourcesDomain + location; + } + resourcesSet.add(new SwaggerResourcesInfoVo(resourcesUrl)); + } catch (Exception e) { + logger.error("获取文档失败:{},{}", resourcesUrl, e.getMessage()); + return DocResponseJson.warn("该地址查找文档失败"); + } + storageService.put(StorageKeys.SWAGGER_RESOURCES_LIST, JSON.toJSONString(resourcesSet)); + return DocResponseJson.ok(); + } + + /** + * 删除/v2/api-docs + * + * @author 暮光:城中城 + * @since 2018年8月21日 + * @param docUrl 文档地址 + * @return 删除结果 + */ + @PostMapping(value = "/deleteSwaggerDoc") + public ResponseJson deleteSwaggerDoc(String docUrl) { + String swaggerDocsDeleteStr = storageService.get(StorageKeys.SWAGGER_DOCS_DELETE_LIST); + Set swaggerDocsDeleteSet = new HashSet<>(); + if (StringUtils.isNotBlank(swaggerDocsDeleteStr)) { + List swaggerDocsDeleteList = JSON.parseArray(swaggerDocsDeleteStr, String.class); + swaggerDocsDeleteSet.addAll(swaggerDocsDeleteList); + } + swaggerDocsDeleteSet.add(docUrl); + storageService.put(StorageKeys.SWAGGER_DOCS_DELETE_LIST, JSON.toJSONString(swaggerDocsDeleteSet)); + return DocResponseJson.ok(); + } +} diff --git a/zyplayer-doc-swagger/src/main/java/com/zyplayer/doc/swagger/framework/constant/StorageKeys.java b/zyplayer-doc-swagger/src/main/java/com/zyplayer/doc/swagger/framework/constant/StorageKeys.java index db913b51..88bbe4d7 100644 --- a/zyplayer-doc-swagger/src/main/java/com/zyplayer/doc/swagger/framework/constant/StorageKeys.java +++ b/zyplayer-doc-swagger/src/main/java/com/zyplayer/doc/swagger/framework/constant/StorageKeys.java @@ -1,16 +1,18 @@ -package com.zyplayer.doc.swagger.framework.constant; - -/** - * 存储数据的KEY常量类 - * - * @author 暮光:城中城 - * @since 2018年8月21日 - */ -public class StorageKeys { - // 所有文档地址 - public static final String SWAGGER_RESOURCES_LIST = "swagger-resources-list"; - // 已删除的文档 - public static final String SWAGGER_DOCS_DELETE_LIST = "swagger-docs-delete-list"; - // 所有详细文档地址 - public static final String SWAGGER_LOCATION_LIST = "swagger-location-list"; +package com.zyplayer.doc.swagger.framework.constant; + +/** + * 存储数据的KEY常量类 + * + * @author 暮光:城中城 + * @since 2018年8月21日 + */ +public class StorageKeys { + // 所有文档地址 + public static final String SWAGGER_RESOURCES_LIST = "swagger-resources-list"; + // 已删除的文档 + public static final String SWAGGER_DOCS_DELETE_LIST = "swagger-docs-delete-list"; + // 所有详细文档地址 + public static final String SWAGGER_LOCATION_LIST = "swagger-location-list"; + // 文档的离线数据key + public static final String SWAGGER_OFFLINE_DOC_START = "swagger-offline-doc-"; } \ No newline at end of file diff --git a/zyplayer-doc-swagger/src/main/resources/document.html b/zyplayer-doc-swagger/src/main/resources/document.html index 945adc3c..ae5e2324 100644 --- a/zyplayer-doc-swagger/src/main/resources/document.html +++ b/zyplayer-doc-swagger/src/main/resources/document.html @@ -383,6 +383,7 @@ + diff --git a/zyplayer-doc-swagger/src/main/resources/webjars/mg-ui/js/mg-ui-cache-keys.js b/zyplayer-doc-swagger/src/main/resources/webjars/mg-ui/js/mg-ui-cache-keys.js index 853bbbb1..95b33d24 100644 --- a/zyplayer-doc-swagger/src/main/resources/webjars/mg-ui/js/mg-ui-cache-keys.js +++ b/zyplayer-doc-swagger/src/main/resources/webjars/mg-ui/js/mg-ui-cache-keys.js @@ -3,4 +3,5 @@ var cacheKeys = { swaggerResourcesList: 'swagger-resources-list', globalParamList: 'zyplayer-doc-global-param-list', pRequestObjStart: 'p-request-obj-', + pSimulationResponse: 'p-simulation-response', } \ No newline at end of file diff --git a/zyplayer-doc-swagger/src/main/resources/webjars/mg-ui/js/mg-ui-debug.js b/zyplayer-doc-swagger/src/main/resources/webjars/mg-ui/js/mg-ui-debug.js index 0e0e09b6..a4ec6961 100644 --- a/zyplayer-doc-swagger/src/main/resources/webjars/mg-ui/js/mg-ui-debug.js +++ b/zyplayer-doc-swagger/src/main/resources/webjars/mg-ui/js/mg-ui-debug.js @@ -1,588 +1,609 @@ -/** - * 在线调试页面js - * @author 暮光:城中城 - * @since 2018年7月20日 -*/ - -$(document).ready(function(){ - $("#debugRequstType .dropdown-menu li").click(function(){ - var text = $(this).find("a").text(); - $("#debugRequstType .options").text(text); - }); - /** - * 保存参数模板 - * @returns - */ - $(".save-request-template").click(function(){ - Toast.notOpen(); - }); - /** - * 发送请求 - * @returns - */ - $(".send-request").click(function(){ - // 多行编辑状态下转成表单,下面读取表单内容 - if($("#bulkEditFormCheck").prop('checked')) { - var bulkEdit = $("#bulkEditForm").val(); - bulkEditToTable("#tabParamTypeForm", bulkEdit); - } - if($("#bulkEditHeaderCheck").prop('checked')) { - var bulkEdit = $("#bulkEditHeader").val(); - bulkEditToTable("#tabParamHeader", bulkEdit); - } - $("#tabResponseHeader table tbody").empty(); - $("#tabResponseCookie table tbody").empty(); - $("#responseBodyTextArea").val(""); - $("#responseBodyJsonDiv").html("暂无数据"); - - var storeRequestParam = {}; - var docUrl = $("#docUrl").text(); - var options = $("#debugRequstType .btn .options").text(); - var postUrl = $("#postUrlInput").val(); - var requestHeaderForm = $("#requestHeaderForm").serializeArray(); - var requestParamForm = $("#requestParamForm").serializeArray(); - var paramBodySend = $("[name=paramBody]").val(); - var formToUrl = $("[name=formToUrl]").prop('checked') ? 1 : 0; - var paramSendToServer = {}; - requestHeaderForm = serializeArrayToObj(requestHeaderForm); - requestParamForm = serializeArrayToObj(requestParamForm); - storeRequestParam.formToUrl = formToUrl; - paramSendToServer.formToUrl = formToUrl; - if(isNotEmpty(paramBodySend)) { - try { - paramBodySend = JSON.stringify(JSON.parse(paramBodySend)); - } catch (e) { - // e - } - storeRequestParam.body = paramBodySend; - paramSendToServer.body = paramBodySend; - // 替换path参数 - Object.keys(requestParamForm).forEach(function(key){ - postUrl = postUrl.replace("{"+key+"}", requestParamForm[key]); - }); - } else { - var reqParamStr = ""; - paramBodySend = {}; - Object.keys(requestParamForm).forEach(function(key){ - var value = requestParamForm[key]; - if(isNotEmpty(key) && isNotEmpty(value)) { - if(isNotEmpty(reqParamStr)) { - reqParamStr += "&"; - } - reqParamStr += key + "=" + value; - paramBodySend[key] = value; - // 替换path参数 - postUrl = postUrl.replace("{"+key+"}", value); - } - }); - storeRequestParam.form = paramBodySend; - if(formToUrl == 1) { - postUrl += "?" + reqParamStr; - paramBodySend = ""; - } else { - paramSendToServer.form = JSON.stringify(paramBodySend); - } - } - $(".send-request .icon").removeClass("hide"); - // 获取header - var requestHeaderStore = {}; - Object.keys(requestHeaderForm).forEach(function(key){ - var value = requestHeaderForm[key]; - if(isNotEmpty(key) && isNotEmpty(value)) { - requestHeaderStore[key] = value; - } - }); - storeRequestParam.header = requestHeaderStore; - paramSendToServer.header = JSON.stringify(requestHeaderStore); - //console.log(paramBodySend); - var beforSendTime = new Date().getTime(); - paramSendToServer.url = postUrl; - paramSendToServer.method = options; - ajaxTemp("swagger-mg-ui/http/request", "post", "json", paramSendToServer, function(result){ - //console.log(result); - var requestObj = result.data; - setStorage('p-request-obj-' + docUrl, storeRequestParam); - var afterSendTime = new Date().getTime(); - $("#httpRequestStatus").text(requestObj.status); - $("#httpRequestTime").text((afterSendTime - beforSendTime) + "ms"); - try { - var htmlStr = Formatjson.processObjectToHtmlPre(JSON.parse(requestObj.data), 0, false, false, false, false); - $("#responseBodyJsonDiv").html(htmlStr); - } catch (e) { - $("#responseBodyJsonDiv").html(""); - setTimeout(function(){ - $("#responseBodyJsonIframe").contents().find("body").html(requestObj.data); - }, 300); - } - $("#tabResponseHeader table tbody").empty(); - $("#tabResponseCookie table tbody").empty(); - var headers = requestObj.header||[]; - for (var i = 0; i < headers.length; i++) { - var name = getNotEmptyStr(headers[i].name); - var value = getNotEmptyStr(headers[i].value); - $("#tabResponseHeader table tbody").append( - ''+''+name+'' + ''+value+''+'' - ); - } - var cookies = requestObj.cookie||[]; - for (var i = 0; i < cookies.length; i++) { - var name = getNotEmptyStr(cookies[i].name); - var value = getNotEmptyStr(cookies[i].value); - $("#tabResponseCookie table tbody").append( - ''+''+name+'' + ''+value+''+'' - ); - } - }, function(){ - Toast.error("请求失败!"); - }, function(){ - $(".send-request .icon").addClass("hide"); - }); - }); - /** - * 输入框输入之后,如果是最后一行则在增加一行 - * @returns - */ - $(".param-table").on("keyup", "input[name=paramName]", function(){ - var nextTr = $(this).parents("tr").next(); - if(nextTr.length <= 0) { - $(this).parents(".param-table").append(getParamTableTr()); - } - }); - /** - * 参数删除一行 - * @returns - */ - $(".param-table").on("click", ".icon-times", function(){ - $(this).parents("tr").remove(); - }); - /** - * 在线调试管理 - */ - $("#onlineDebugLi").click(function(){ - $(".tab-page,.tab-zpages").hide(); - $(".tab-online-debug-page").show(); - createOnlineDebugParamTable(); - }); - /** - * 在线调试管理-刷新 - */ - $(".tab-online-debug-page .refresh").click(function(){ - createOnlineDebugParamTable(); - }); - /** - * 在线调试管理-展开所有 - */ - $(".tab-online-debug-page .expand-all").click(function(){ - $("#onlineDebugParamTable .option-img").attr("src", "webjars/mg-ui/img/expanded.png") - $("#onlineDebugParamTable .option-img").parent().next().show(); - }); - /** - * 在线调试管理-收起所有 - */ - $(".tab-online-debug-page .collapse-all").click(function(){ - $("#onlineDebugParamTable .option-img").attr("src", "webjars/mg-ui/img/collapsed.png") - $("#onlineDebugParamTable .option-img").parent().next().hide(); - }); - /** - * 在线调试-删除所有参数 - */ - $(".tab-online-debug-page").on("click", ".del-all-param", function(){ - $.zui.store.forEach(function(key, value) {// 遍历所有本地存储的条目 - if(!key.startWith('p-request-obj-')) { - return; - } - $.zui.store.remove(key); - }); - createOnlineDebugParamTable(); - }); - /** - * 在线调试-删除参数 - */ - $(".tab-online-debug-page").on("click", ".del-param", function(){ - var key = $(this).attr("key"); - if(isNotEmpty(key)) { - $.zui.store.remove(key); - $(this).parents("tr").remove(); - } - }); - /** - * 提交模拟返回值 - */ - $("#simulationResultSubmit").click(function(){ - var value = $("#simulationResultText").val(); - value = getNotEmptyStr(value, ""); - var docUrl = $("#simulationResultUrl").text(); - setStorage('p-simulation-response-' + docUrl, value, function() { - Toast.warn("提交成功!"); - }, function(msg) { - Toast.error("提交失败!" + msg); - }); - }); - /** - * 获取模拟返回值 - */ - $("#simulationResultGet").click(function(){ - var docUrl = $("#simulationResultUrl").text(); - getStorage('p-simulation-response-' + docUrl, function(data){ - $("#simulationResultText").val(data); - }); - }); -}); - -/** - * 生成在线调试管理页面 - * @returns - */ -function createOnlineDebugParamTable() { - $("#onlineDebugParamTable tbody").empty(); - $.zui.store.forEach(function(key, value) {// 遍历所有本地存储的条目 - if(!key.startWith('p-request-obj-')) { - return; - } - var newKey = key.substring(14, key.length); - var htmlStr = Formatjson.processObjectToHtmlPre(value, 0, false, false, false, false); - $("#onlineDebugParamTable tbody").append( - '' - +''+newKey+'' - +''+htmlStr+'' - +'' - +'' - ); - }); -} - -/** - * 生成在线调试相关数据 - * @param requestParamObj - * @returns - */ -function createOnlineDebugRequestParam(requestParamObj, url) { - getStorage('p-request-obj-' + url, function(data) { - createOnlineDebugRequestParamFun(data, requestParamObj, url); - }); -} - -/** - * 生成在线调试相关数据 - * @param requestParamObj - * @returns - */ -function createOnlineDebugRequestParamFun(pRequestObj, requestParamObj, url) { - if(isEmptyObject(pRequestObj)) { - pRequestObj = {}; - } - // 清空参数列表 - $("#tabParamHeader table tbody .new").remove(); - $("#tabParamTypeForm table tbody .new").remove(); - $("#tabResponseHeader table tbody").empty(); - $("#tabResponseCookie table tbody").empty(); - $("#tabParamHeader .form-control").val(""); - $("#tabParamTypeForm .form-control").val(""); - $("#responseBodyTextArea").val(""); - $("#responseBodyJsonDiv").html("暂无数据"); - $("#bulkEditHeaderCheck").prop("checked", false); - $("#bulkEditFormCheck").prop("checked", false); - $("#bulkEditHeader,#bulkEditForm").hide(); - $("#tabParamTypeForm table").show(); - $("#requestHeaderForm table").show(); - - var options = $("#debugRequstType .btn .options").text(); - var formToUrl = pRequestObj.formToUrl || 0; - var formToUrlChecked = (options != "GET" && formToUrl == 1); - $("input[name='formToUrl']").prop("checked", formToUrlChecked); - - var onlyUseLastParam = (userSettings.onlyUseLastParam == 1); - var onlyUseLastHeader = onlyUseLastParam && !isEmptyObject(pRequestObj.header); - var onlyUseLastForm = onlyUseLastParam && !isEmptyObject(pRequestObj.form); - var onlyUseLastBody = onlyUseLastParam && !isEmptyObject(pRequestObj.body); - var headerValueCount = 0, formValueCount = 0; - Object.keys(requestParamObj).forEach(function(key){ - var tempParam = requestParamObj[key]; - if (key == "p-body-obj") { - //console.log(tempParam); - var paramObj = onlyUseLastBody ? {} : getParamBodyTransObj(tempParam); - var bodyObj = pRequestObj.body; - try { - bodyObj = JSON.parse(bodyObj); - if(!isEmptyObject(bodyObj)) { - paramObj = $.extend(true, paramObj, bodyObj); - } - $("#tabParamTypeBody textarea").val(JSON.stringify(paramObj, null, 4)); - } catch (e) { - var tempText = isEmpty(bodyObj) ? JSON.stringify(paramObj, null, 4) : bodyObj; - $("#tabParamTypeBody textarea").val(tempText); - } - $("#tabParamBody .nav li").eq(1).find("a").click(); - } else { - if (tempParam.paramIn == "header" && !onlyUseLastHeader) { - //console.log(tempParam); - var headerVal = getNotEmptyStr(tempParam.value); - var headerObj = pRequestObj.header; - if(!isEmptyObject(headerObj) && isNotEmpty(headerObj[key])) { - headerVal = headerObj[key]; - headerObj[key] = "";// 赋值为空,后面不再使用 - } - if(isEmpty(headerVal)) { - headerVal = getAutoFillValue(tempParam.paramType, key); - } - if(headerValueCount > 0) { - $("#tabParamHeader table tbody").append(getParamTableTr(key, headerVal, "", tempParam.paramDesc)); - } else { - $("#tabParamHeader table tbody .base input[name=paramName]").val(key); - $("#tabParamHeader table tbody .base input[name=paramValue]").val(headerVal); - $("#tabParamHeader table tbody .base input[name=paramValue]").attr("placeholder", getNotEmptyStr(tempParam.paramDesc)); - } - headerValueCount++; - } else { - // 只有这几种类型,列出来后面看单独处理不 - var paramInForm = (tempParam.paramIn == "query") - || (tempParam.paramIn == "path") - || (tempParam.paramIn == "body") - || (tempParam.paramIn == "form") - || isNotEmpty(tempParam.paramIn); - if (paramInForm && !onlyUseLastForm) { - //console.log(tempParam); - var formVal = getNotEmptyStr(tempParam.value); - var formObj = pRequestObj.form; - if(!isEmptyObject(formObj) && isNotEmpty(formObj[key])) { - formVal = formObj[key]; - formObj[key] = "";// 赋值为空,后面不再使用 - } - if(isEmpty(formVal)) { - formVal = getAutoFillValue(tempParam.paramType, key); - } - if(formValueCount > 0) { - $("#tabParamTypeForm table tbody").append(getParamTableTr(key, formVal, "", tempParam.paramDesc)); - } else { - $("#tabParamTypeForm table tbody .base input[name=paramName]").val(key); - $("#tabParamTypeForm table tbody .base input[name=paramValue]").val(formVal); - $("#tabParamTypeForm table tbody .base input[name=paramValue]").attr("placeholder", getNotEmptyStr(tempParam.paramDesc)); - } - $("#tabParamBody .nav li").eq(0).find("a").click(); - formValueCount++; - } - } - } - }); - // 处理参数外的header - var headerObj = pRequestObj.header; - if(!isEmptyObject(headerObj)) { - Object.keys(headerObj).forEach(function(key){ - if(isNotEmpty(headerObj[key])) { - if(headerValueCount > 0) { - $("#tabParamHeader table tbody").append(getParamTableTr(key, headerObj[key], "", "")); - } else { - $("#tabParamHeader table tbody .base input[name=paramName]").val(key); - $("#tabParamHeader table tbody .base input[name=paramValue]").val(headerObj[key]); - } - headerValueCount++; - } - }); - } - // 处理参数外的form - var formObj = pRequestObj.form; - if(!isEmptyObject(formObj)) { - Object.keys(formObj).forEach(function(key){ - if(isNotEmpty(formObj[key])) { - if(formValueCount > 0) { - $("#tabParamTypeForm table tbody").append(getParamTableTr(key, formObj[key], "", "")); - } else { - $("#tabParamTypeForm table tbody .base input[name=paramName]").val(key); - $("#tabParamTypeForm table tbody .base input[name=paramValue]").val(formObj[key]); - } - formValueCount++; - } - }); - } - if(headerValueCount > 0) { - $("#tabParamHeader table tbody").append(getParamTableTr("", "", "", "")); - } - if(formValueCount > 0) { - $("#tabParamTypeForm table tbody").append(getParamTableTr("", "", "", "")); - } -} - -/** - * 获取测试的对象 - */ -function getParamBodyTransObj(paramObj) { - var newObject = $.extend(true, {}, paramObj); - Object.keys(newObject).forEach(function(key){ - var subObj = newObject[key]; - if(typeof subObj == 'object') { - if (subObj.hasOwnProperty("isParamObj")) { - var value = getNotEmptyStr(subObj.value); - if(isEmpty(value) && isNotEmpty(subObj.paramType)) { - value = getAutoFillValue(subObj.paramType, key); - } - newObject[key] = value; - } else if(subObj instanceof Array) { - subObj[0] = getParamBodyTransObj(subObj[0]); - } else { - newObject[key] = getParamBodyTransObj(subObj); - } - } - }); - return newObject; -} - -function serializeArrayToBulkEdit(formArr) { - var formObj = serializeArrayToObj(formArr); - var formStr = ""; - Object.keys(formObj).forEach(function(key){ - formStr += key + ":" + formObj[key] + "\n"; - }); - return formStr; -} - -function serializeArrayToObj(formArr) { - var paramObj = {}; - for (var i = 0; i < formArr.length; i++) { - if (formArr[i].name == "paramName" && i < formArr.length) { - var key = formArr[i].value; - var value = formArr[i+1].value; - if(isNotEmpty(key)) { - paramObj[key] = value; - } - } - } - return paramObj; -} - -function bulkEditToTable(tableId, bulkEdit) { - $(tableId + " table tbody .new").remove(); - var valueCount = 0; - var headerArr = bulkEdit.split("\n"); - for (var i = 0; i < headerArr.length; i++) { - var index = headerArr[i].indexOf(":"); - if(index < 0) { - continue; - } - var key = headerArr[i].substring(0, index); - var value = headerArr[i].substring(index+1, headerArr[i].length); - if(valueCount > 0) { - $(tableId + " table tbody").append(getParamTableTr(key, value, "", "")); - } else { - $(tableId + " table tbody .base input[name=paramName]").val(key); - $(tableId + " table tbody .base input[name=paramValue]").val(value); - } - valueCount++; - } - if(valueCount > 0) { - $(tableId + " table tbody").append(getParamTableTr("", "", "", "")); - } -} - -/** - * 获取参数的tr - * @param name - * @param value - * @param namePl - * @param valuePl - * @returns - */ -function getParamTableTr(name, value, namePl, valuePl) { - name = getNotEmptyStr(name); - namePl = getNotEmptyStr(namePl); - value = getNotEmptyStr(value); - valuePl = getNotEmptyStr(valuePl); - - var regExp = new RegExp("\"", "gm"); - name = (typeof name === 'string') ? name.replace(regExp, """) : name; - namePl = (typeof namePl === 'string') ? namePl.replace(regExp, """) : namePl; - value = (typeof value === 'string') ? value.replace(regExp, """) : value; - valuePl = (typeof valuePl === 'string') ? valuePl.replace(regExp, """) : valuePl; - var resultStr = - '' - +'' - +'' - +'' - +''; - return resultStr; -} - -/** - * 获取自动填充的值 - * @param paramType - * @returns - */ -function getAutoFillValue(paramType, paramName) { - if(userSettings.autoFillParam == 0 || isEmpty(paramType)) { - return ""; - } - paramName = getNotEmptyStr(paramName).toLowerCase(); - var isTimeColumn = (paramType.indexOf("date-time") >= 0 - || paramName.endWith("date") || paramName.endWith("time")); - var isTypeColumn = (paramName.endWith("type") || paramName.endWith("status") - || paramName.endWith("level") || paramName.endWith("num")); - var isPriceColumn = (paramName.endWith("money") || paramName.endWith("price") - || paramName.endWith("cash") || paramName.endWith("coin")); - var isBooleanColumn = (paramName.startWith("is")); - var resultValue = ""; - if(paramType.indexOf("int") >= 0){ - if(isTypeColumn) { - resultValue = Math.ceil(Math.random() * 5); - } else if(paramName.endWith("age")) { - resultValue = Math.ceil(Math.random() * 100); - } else { - resultValue = Math.ceil(Math.random() * 100); - } - } else if(paramType.indexOf("double") >= 0){ - resultValue = Math.ceil(Math.random() * 1000); - } else if(paramType.indexOf("float") >= 0){ - resultValue = parseFloat(Math.random() * 1000).toFixed(2); - } else if(paramType.indexOf("byte") >= 0){ - if(isTypeColumn) { - resultValue = Math.ceil(Math.random() * 5); - } else { - resultValue = Math.ceil(Math.random() * 127); - } - } else if(paramType.indexOf("boolean") >= 0){ - resultValue = Math.random() > 0.5; - } else if(isTimeColumn){ - resultValue = getNowDateTime(); - } else { - if(paramName.endWith("id")) { - resultValue = Math.ceil(Math.random() * 1000); - } else if(paramName.endWith("age")) { - resultValue = Math.ceil(Math.random() * 100); - } else if(isPriceColumn){ - resultValue = parseFloat(Math.random() * 1000).toFixed(2); - } else if(isTypeColumn){ - resultValue = Math.ceil(Math.random() * 5); - } else if(isBooleanColumn){ - resultValue = (Math.random() > 0.5) ? 0 : 1; - } else if(paramName.endWith("phone") || paramName.endWith("mobile")){ - var arr = ["15226645814", "15226645815", "15226645816", "15226645817", "15226645818"]; - resultValue = arr[Math.ceil(Math.random() * 5) - 1]; - } else if(paramName.endWith("ids")){ - var counts = Math.ceil(Math.random() * 5); - for (var i = 0; i < counts; i++) { - if(isNotEmpty(resultValue)){resultValue += ",";} - resultValue += Math.ceil(Math.random() * 1000); - } - } else if(paramName.endWith("types")){ - var counts = Math.ceil(Math.random() * 3); - for (var i = 0; i < counts; i++) { - if(isNotEmpty(resultValue)){resultValue += ",";} - resultValue += Math.ceil(Math.random() * 5); - } - } else if(paramName.endWith("md5")){ - resultValue = "5082079d92a8ef985f59e001d445ff20"; - } else if(paramName.endWith("photo")){ - resultValue = "http://www.zyplayer.com/freeplay/img/headIcon/myhead.jpg"; - } else if(paramName.endWith("url") || paramName.endWith("uri")){ - var arr = ["http://www.zyplayer.com", "http://www.kongjianzhou.com"]; - resultValue = arr[Math.ceil(Math.random() * 2) - 1]; - } else if(paramName.endWith("username")){ - var arr = ["张三", "李四", "王二", "暮光:城中城", "海贼王"]; - resultValue = arr[Math.ceil(Math.random() * 5) - 1]; - } else if(userSettings.autoFillParam == 2){ - //var arr = ["您好!","请!","对不起。","谢谢!","再见!","您早!","晚安!","请问您贵姓?","请原谅!","不用谢!","没关系!","欢迎您光临!","请坐!","请喝茶!","请多关照!","请多指教!","谢谢您的合作!","对不起,让您久等了。","没关系,我刚到。","给您添麻烦了。","我能为您做什么?","您好,请问您需要帮助吗?","您走好。","请慢走!"]; - //resultValue = arr[Math.ceil(Math.random() * 24) - 1]; - resultValue = "我是默认字符串"; - } - //console.log(paramType); - } - return resultValue; -} +/** + * 在线调试页面js + * @author 暮光:城中城 + * @since 2018年7月20日 +*/ + +$(document).ready(function(){ + $("#debugRequstType .dropdown-menu li").click(function(){ + var text = $(this).find("a").text(); + $("#debugRequstType .options").text(text); + }); + /** + * 保存参数模板 + * @returns + */ + $(".save-request-template").click(function(){ + Toast.notOpen(); + }); + /** + * 发送请求 + * @returns + */ + $(".send-request").click(function(){ + // 多行编辑状态下转成表单,下面读取表单内容 + if($("#bulkEditFormCheck").prop('checked')) { + var bulkEdit = $("#bulkEditForm").val(); + bulkEditToTable("#tabParamTypeForm", bulkEdit); + } + if($("#bulkEditHeaderCheck").prop('checked')) { + var bulkEdit = $("#bulkEditHeader").val(); + bulkEditToTable("#tabParamHeader", bulkEdit); + } + $("#tabResponseHeader table tbody").empty(); + $("#tabResponseCookie table tbody").empty(); + $("#responseBodyTextArea").val(""); + $("#responseBodyJsonDiv").html("暂无数据"); + + var storeRequestParam = {}; + var docUrl = $("#docUrl").text(); + var options = $("#debugRequstType .btn .options").text(); + var postUrl = $("#postUrlInput").val(); + var requestHeaderForm = $("#requestHeaderForm").serializeArray(); + var requestParamForm = $("#requestParamForm").serializeArray(); + var paramBodySend = $("[name=paramBody]").val(); + var formToUrl = $("[name=formToUrl]").prop('checked') ? 1 : 0; + var paramSendToServer = {}; + requestHeaderForm = serializeArrayToObj(requestHeaderForm); + requestParamForm = serializeArrayToObj(requestParamForm); + storeRequestParam.formToUrl = formToUrl; + paramSendToServer.formToUrl = formToUrl; + if(isNotEmpty(paramBodySend)) { + try { + paramBodySend = JSON.stringify(JSON.parse(paramBodySend)); + } catch (e) { + // e + } + storeRequestParam.body = paramBodySend; + paramSendToServer.body = paramBodySend; + // 替换path参数 + Object.keys(requestParamForm).forEach(function(key){ + postUrl = postUrl.replace("{"+key+"}", requestParamForm[key]); + }); + } else { + var reqParamStr = ""; + paramBodySend = {}; + Object.keys(requestParamForm).forEach(function(key){ + var value = requestParamForm[key]; + if(isNotEmpty(key) && isNotEmpty(value)) { + if(isNotEmpty(reqParamStr)) { + reqParamStr += "&"; + } + reqParamStr += key + "=" + value; + paramBodySend[key] = value; + // 替换path参数 + postUrl = postUrl.replace("{"+key+"}", value); + } + }); + storeRequestParam.form = paramBodySend; + if(formToUrl == 1) { + postUrl += "?" + reqParamStr; + paramBodySend = ""; + } else { + paramSendToServer.form = JSON.stringify(paramBodySend); + } + } + $(".send-request .icon").removeClass("hide"); + // 获取header + var requestHeaderStore = {}; + Object.keys(requestHeaderForm).forEach(function(key){ + var value = requestHeaderForm[key]; + if(isNotEmpty(key) && isNotEmpty(value)) { + requestHeaderStore[key] = value; + } + }); + storeRequestParam.header = requestHeaderStore; + paramSendToServer.header = JSON.stringify(requestHeaderStore); + //console.log(paramBodySend); + var beforSendTime = new Date().getTime(); + paramSendToServer.url = postUrl; + paramSendToServer.method = options; + ajaxTemp("swagger-mg-ui/http/request", "post", "json", paramSendToServer, function(result){ + //console.log(result); + var requestObj = result.data; + setStorage(cacheKeys.pRequestObjStart + docUrl, storeRequestParam); + var afterSendTime = new Date().getTime(); + $("#httpRequestStatus").text(requestObj.status); + $("#httpRequestTime").text((afterSendTime - beforSendTime) + "ms"); + try { + var htmlStr = Formatjson.processObjectToHtmlPre(JSON.parse(requestObj.data), 0, false, false, false, false); + $("#responseBodyJsonDiv").html(htmlStr); + } catch (e) { + $("#responseBodyJsonDiv").html(""); + setTimeout(function(){ + $("#responseBodyJsonIframe").contents().find("body").html(requestObj.data); + }, 300); + } + $("#tabResponseHeader table tbody").empty(); + $("#tabResponseCookie table tbody").empty(); + var headers = requestObj.header||[]; + for (var i = 0; i < headers.length; i++) { + var name = getNotEmptyStr(headers[i].name); + var value = getNotEmptyStr(headers[i].value); + $("#tabResponseHeader table tbody").append( + ''+''+name+'' + ''+value+''+'' + ); + } + var cookies = requestObj.cookie||[]; + for (var i = 0; i < cookies.length; i++) { + var name = getNotEmptyStr(cookies[i].name); + var value = getNotEmptyStr(cookies[i].value); + $("#tabResponseCookie table tbody").append( + ''+''+name+'' + ''+value+''+'' + ); + } + }, function(){ + Toast.error("请求失败!"); + }, function(){ + $(".send-request .icon").addClass("hide"); + }); + }); + /** + * 输入框输入之后,如果是最后一行则在增加一行 + * @returns + */ + $(".param-table").on("keyup", "input[name=paramName]", function(){ + var nextTr = $(this).parents("tr").next(); + if(nextTr.length <= 0) { + $(this).parents(".param-table").append(getParamTableTr()); + } + }); + /** + * 参数删除一行 + * @returns + */ + $(".param-table").on("click", ".icon-times", function(){ + $(this).parents("tr").remove(); + }); + /** + * 在线调试管理 + */ + $("#onlineDebugLi").click(function(){ + $(".tab-page,.tab-zpages").hide(); + $(".tab-online-debug-page").show(); + createOnlineDebugParamTable(); + }); + /** + * 在线调试管理-刷新 + */ + $(".tab-online-debug-page .refresh").click(function(){ + createOnlineDebugParamTable(); + }); + /** + * 在线调试管理-展开所有 + */ + $(".tab-online-debug-page .expand-all").click(function(){ + $("#onlineDebugParamTable .option-img").attr("src", "webjars/mg-ui/img/expanded.png") + $("#onlineDebugParamTable .option-img").parent().next().show(); + }); + /** + * 在线调试管理-收起所有 + */ + $(".tab-online-debug-page .collapse-all").click(function(){ + $("#onlineDebugParamTable .option-img").attr("src", "webjars/mg-ui/img/collapsed.png") + $("#onlineDebugParamTable .option-img").parent().next().hide(); + }); + /** + * 在线调试-删除所有参数 + */ + $(".tab-online-debug-page").on("click", ".del-all-param", function(){ + $.zui.store.forEach(function(key, value) {// 遍历所有本地存储的条目 + if(!key.startWith(cacheKeys.pRequestObjStart)) { + return; + } + $.zui.store.remove(key); + }); + createOnlineDebugParamTable(); + }); + /** + * 在线调试-删除参数 + */ + $(".tab-online-debug-page").on("click", ".del-param", function(){ + var key = $(this).attr("key"); + if(isNotEmpty(key)) { + $.zui.store.remove(key); + $(this).parents("tr").remove(); + } + }); + /** + * 提交模拟返回值 + */ + $("#simulationResultSubmit").click(function(){ + var value = $("#simulationResultText").val(); + value = getNotEmptyStr(value, ""); + var docUrl = $("#simulationResultUrl").text(); + setStorage(cacheKeys.pSimulationResponse + docUrl, value, function() { + Toast.warn("提交成功!"); + }, function(msg) { + Toast.error("提交失败!" + msg); + }); + }); + /** + * 获取模拟返回值 + */ + $("#simulationResultGet").click(function(){ + var docUrl = $("#simulationResultUrl").text(); + getStorage(cacheKeys.pSimulationResponse + docUrl, function(data){ + $("#simulationResultText").val(data); + }); + }); +}); + +/** + * 生成在线调试管理页面 + * @returns + */ +function createOnlineDebugParamTable() { + $("#onlineDebugParamTable tbody").empty(); + $.zui.store.forEach(function(key, value) {// 遍历所有本地存储的条目 + if(!key.startWith(cacheKeys.pRequestObjStart)) { + return; + } + var newKey = key.substring(14, key.length); + var htmlStr = Formatjson.processObjectToHtmlPre(value, 0, false, false, false, false); + $("#onlineDebugParamTable tbody").append( + '' + +''+newKey+'' + +''+htmlStr+'' + +'' + +'' + ); + }); +} + +/** + * 生成在线调试相关数据 + * @param requestParamObj + * @returns + */ +function createOnlineDebugRequestParam(requestParamObj, url) { + getStorage(cacheKeys.pRequestObjStart + url, function(data) { + createOnlineDebugRequestParamFun(data, requestParamObj, url); + }); +} + +/** + * 生成在线调试相关数据 + * @param requestParamObj + * @returns + */ +function createOnlineDebugRequestParamFun(pRequestObj, requestParamObj, url) { + if(isEmptyObject(pRequestObj)) { + pRequestObj = {}; + } + // 清空参数列表 + $("#tabParamHeader table tbody .new").remove(); + $("#tabParamTypeForm table tbody .new").remove(); + $("#tabResponseHeader table tbody").empty(); + $("#tabResponseCookie table tbody").empty(); + $("#tabParamHeader .form-control").val(""); + $("#tabParamTypeForm .form-control").val(""); + $("#responseBodyTextArea").val(""); + $("#responseBodyJsonDiv").html("暂无数据"); + $("#bulkEditHeaderCheck").prop("checked", false); + $("#bulkEditFormCheck").prop("checked", false); + $("#bulkEditHeader,#bulkEditForm").hide(); + $("#tabParamTypeForm table").show(); + $("#requestHeaderForm table").show(); + + var options = $("#debugRequstType .btn .options").text(); + var formToUrl = pRequestObj.formToUrl || 0; + var formToUrlChecked = (options != "GET" && formToUrl == 1); + $("input[name='formToUrl']").prop("checked", formToUrlChecked); + + var onlyUseLastParam = (userSettings.onlyUseLastParam == 1); + var onlyUseLastHeader = onlyUseLastParam && !isEmptyObject(pRequestObj.header); + var onlyUseLastForm = onlyUseLastParam && !isEmptyObject(pRequestObj.form); + var onlyUseLastBody = onlyUseLastParam && !isEmptyObject(pRequestObj.body); + var headerValueCount = 0, formValueCount = 0; + + if(typeof pRequestObj != 'object') { + pRequestObj = {}; + } + if(typeof pRequestObj.header != 'object') { + pRequestObj.header = {}; + } + if(typeof pRequestObj.form != 'object') { + pRequestObj.form = {}; + } + if(typeof pRequestObj.body != 'object') { + pRequestObj.body = {}; + } + for (var i = 0; i < debugGlobalParam.length; i++) { + var item = debugGlobalParam[i]; + if (item.paramIn == 'header') { + pRequestObj.header[item.key] = item.value; + } else if (item.paramIn == 'form') { + pRequestObj.form[item.key] = item.value; + } + } + Object.keys(requestParamObj).forEach(function(key){ + var tempParam = requestParamObj[key]; + if (key == "p-body-obj") { + //console.log(tempParam); + var paramObj = onlyUseLastBody ? {} : getParamBodyTransObj(tempParam); + var bodyObj = pRequestObj.body; + try { + bodyObj = JSON.parse(bodyObj); + if(!isEmptyObject(bodyObj)) { + paramObj = $.extend(true, paramObj, bodyObj); + } + $("#tabParamTypeBody textarea").val(JSON.stringify(paramObj, null, 4)); + } catch (e) { + var tempText = isEmpty(bodyObj) ? JSON.stringify(paramObj, null, 4) : bodyObj; + $("#tabParamTypeBody textarea").val(tempText); + } + $("#tabParamBody .nav li").eq(1).find("a").click(); + } else { + if (tempParam.paramIn == "header" && !onlyUseLastHeader) { + //console.log(tempParam); + var headerVal = getNotEmptyStr(tempParam.value); + var headerObj = pRequestObj.header; + if(!isEmptyObject(headerObj) && isNotEmpty(headerObj[key])) { + headerVal = headerObj[key]; + headerObj[key] = "";// 赋值为空,后面不再使用 + } + if(isEmpty(headerVal)) { + headerVal = getAutoFillValue(tempParam.paramType, key); + } + if(headerValueCount > 0) { + $("#tabParamHeader table tbody").append(getParamTableTr(key, headerVal, "", tempParam.paramDesc)); + } else { + $("#tabParamHeader table tbody .base input[name=paramName]").val(key); + $("#tabParamHeader table tbody .base input[name=paramValue]").val(headerVal); + $("#tabParamHeader table tbody .base input[name=paramValue]").attr("placeholder", getNotEmptyStr(tempParam.paramDesc)); + } + headerValueCount++; + } else { + // 只有这几种类型,列出来后面看单独处理不 + var paramInForm = (tempParam.paramIn == "query") + || (tempParam.paramIn == "path") + || (tempParam.paramIn == "body") + || (tempParam.paramIn == "form") + || isNotEmpty(tempParam.paramIn); + if (paramInForm && !onlyUseLastForm) { + //console.log(tempParam); + var formVal = getNotEmptyStr(tempParam.value); + var formObj = pRequestObj.form; + if(!isEmptyObject(formObj) && isNotEmpty(formObj[key])) { + formVal = formObj[key]; + formObj[key] = "";// 赋值为空,后面不再使用 + } + if(isEmpty(formVal)) { + formVal = getAutoFillValue(tempParam.paramType, key); + } + if(formValueCount > 0) { + $("#tabParamTypeForm table tbody").append(getParamTableTr(key, formVal, "", tempParam.paramDesc)); + } else { + $("#tabParamTypeForm table tbody .base input[name=paramName]").val(key); + $("#tabParamTypeForm table tbody .base input[name=paramValue]").val(formVal); + $("#tabParamTypeForm table tbody .base input[name=paramValue]").attr("placeholder", getNotEmptyStr(tempParam.paramDesc)); + } + $("#tabParamBody .nav li").eq(0).find("a").click(); + formValueCount++; + } + } + } + }); + // 处理参数外的header + var headerObj = pRequestObj.header; + if(!isEmptyObject(headerObj)) { + Object.keys(headerObj).forEach(function(key){ + if(isNotEmpty(headerObj[key])) { + if(headerValueCount > 0) { + $("#tabParamHeader table tbody").append(getParamTableTr(key, headerObj[key], "", "")); + } else { + $("#tabParamHeader table tbody .base input[name=paramName]").val(key); + $("#tabParamHeader table tbody .base input[name=paramValue]").val(headerObj[key]); + } + headerValueCount++; + } + }); + } + // 处理参数外的form + var formObj = pRequestObj.form; + if(!isEmptyObject(formObj)) { + Object.keys(formObj).forEach(function(key){ + if(isNotEmpty(formObj[key])) { + if(formValueCount > 0) { + $("#tabParamTypeForm table tbody").append(getParamTableTr(key, formObj[key], "", "")); + } else { + $("#tabParamTypeForm table tbody .base input[name=paramName]").val(key); + $("#tabParamTypeForm table tbody .base input[name=paramValue]").val(formObj[key]); + } + formValueCount++; + } + }); + } + if(headerValueCount > 0) { + $("#tabParamHeader table tbody").append(getParamTableTr("", "", "", "")); + } + if(formValueCount > 0) { + $("#tabParamTypeForm table tbody").append(getParamTableTr("", "", "", "")); + } +} + +/** + * 获取测试的对象 + */ +function getParamBodyTransObj(paramObj) { + var newObject = $.extend(true, {}, paramObj); + Object.keys(newObject).forEach(function(key){ + var subObj = newObject[key]; + if(typeof subObj == 'object') { + if (subObj.hasOwnProperty("isParamObj")) { + var value = getNotEmptyStr(subObj.value); + if(isEmpty(value) && isNotEmpty(subObj.paramType)) { + value = getAutoFillValue(subObj.paramType, key); + } + newObject[key] = value; + } else if(subObj instanceof Array) { + subObj[0] = getParamBodyTransObj(subObj[0]); + } else { + newObject[key] = getParamBodyTransObj(subObj); + } + } + }); + return newObject; +} + +function serializeArrayToBulkEdit(formArr) { + var formObj = serializeArrayToObj(formArr); + var formStr = ""; + Object.keys(formObj).forEach(function(key){ + formStr += key + ":" + formObj[key] + "\n"; + }); + return formStr; +} + +function serializeArrayToObj(formArr) { + var paramObj = {}; + for (var i = 0; i < formArr.length; i++) { + if (formArr[i].name == "paramName" && i < formArr.length) { + var key = formArr[i].value; + var value = formArr[i+1].value; + if(isNotEmpty(key)) { + paramObj[key] = value; + } + } + } + return paramObj; +} + +function bulkEditToTable(tableId, bulkEdit) { + $(tableId + " table tbody .new").remove(); + var valueCount = 0; + var headerArr = bulkEdit.split("\n"); + for (var i = 0; i < headerArr.length; i++) { + var index = headerArr[i].indexOf(":"); + if(index < 0) { + continue; + } + var key = headerArr[i].substring(0, index); + var value = headerArr[i].substring(index+1, headerArr[i].length); + if(valueCount > 0) { + $(tableId + " table tbody").append(getParamTableTr(key, value, "", "")); + } else { + $(tableId + " table tbody .base input[name=paramName]").val(key); + $(tableId + " table tbody .base input[name=paramValue]").val(value); + } + valueCount++; + } + if(valueCount > 0) { + $(tableId + " table tbody").append(getParamTableTr("", "", "", "")); + } +} + +/** + * 获取参数的tr + * @param name + * @param value + * @param namePl + * @param valuePl + * @returns + */ +function getParamTableTr(name, value, namePl, valuePl) { + name = getNotEmptyStr(name); + namePl = getNotEmptyStr(namePl); + value = getNotEmptyStr(value); + valuePl = getNotEmptyStr(valuePl); + + var regExp = new RegExp("\"", "gm"); + name = (typeof name === 'string') ? name.replace(regExp, """) : name; + namePl = (typeof namePl === 'string') ? namePl.replace(regExp, """) : namePl; + value = (typeof value === 'string') ? value.replace(regExp, """) : value; + valuePl = (typeof valuePl === 'string') ? valuePl.replace(regExp, """) : valuePl; + var resultStr = + '' + +'' + +'' + +'' + +''; + return resultStr; +} + +/** + * 获取自动填充的值 + * @param paramType + * @returns + */ +function getAutoFillValue(paramType, paramName) { + if(userSettings.autoFillParam == 0 || isEmpty(paramType)) { + return ""; + } + paramName = getNotEmptyStr(paramName).toLowerCase(); + var isTimeColumn = (paramType.indexOf("date-time") >= 0 + || paramName.endWith("date") || paramName.endWith("time")); + var isTypeColumn = (paramName.endWith("type") || paramName.endWith("status") + || paramName.endWith("level") || paramName.endWith("num")); + var isPriceColumn = (paramName.endWith("money") || paramName.endWith("price") + || paramName.endWith("cash") || paramName.endWith("coin")); + var isBooleanColumn = (paramName.startWith("is")); + var resultValue = ""; + if(paramType.indexOf("int") >= 0){ + if(isTypeColumn) { + resultValue = Math.ceil(Math.random() * 5); + } else if(paramName.endWith("age")) { + resultValue = Math.ceil(Math.random() * 100); + } else { + resultValue = Math.ceil(Math.random() * 100); + } + } else if(paramType.indexOf("double") >= 0){ + resultValue = Math.ceil(Math.random() * 1000); + } else if(paramType.indexOf("float") >= 0){ + resultValue = parseFloat(Math.random() * 1000).toFixed(2); + } else if(paramType.indexOf("byte") >= 0){ + if(isTypeColumn) { + resultValue = Math.ceil(Math.random() * 5); + } else { + resultValue = Math.ceil(Math.random() * 127); + } + } else if(paramType.indexOf("boolean") >= 0){ + resultValue = Math.random() > 0.5; + } else if(isTimeColumn){ + resultValue = getNowDateTime(); + } else { + if(paramName.endWith("id")) { + resultValue = Math.ceil(Math.random() * 1000); + } else if(paramName.endWith("age")) { + resultValue = Math.ceil(Math.random() * 100); + } else if(isPriceColumn){ + resultValue = parseFloat(Math.random() * 1000).toFixed(2); + } else if(isTypeColumn){ + resultValue = Math.ceil(Math.random() * 5); + } else if(isBooleanColumn){ + resultValue = (Math.random() > 0.5) ? 0 : 1; + } else if(paramName.endWith("phone") || paramName.endWith("mobile")){ + var arr = ["15226645814", "15226645815", "15226645816", "15226645817", "15226645818"]; + resultValue = arr[Math.ceil(Math.random() * 5) - 1]; + } else if(paramName.endWith("ids")){ + var counts = Math.ceil(Math.random() * 5); + for (var i = 0; i < counts; i++) { + if(isNotEmpty(resultValue)){resultValue += ",";} + resultValue += Math.ceil(Math.random() * 1000); + } + } else if(paramName.endWith("types")){ + var counts = Math.ceil(Math.random() * 3); + for (var i = 0; i < counts; i++) { + if(isNotEmpty(resultValue)){resultValue += ",";} + resultValue += Math.ceil(Math.random() * 5); + } + } else if(paramName.endWith("md5")){ + resultValue = "5082079d92a8ef985f59e001d445ff20"; + } else if(paramName.endWith("photo")){ + resultValue = "http://www.zyplayer.com/freeplay/img/headIcon/myhead.jpg"; + } else if(paramName.endWith("url") || paramName.endWith("uri")){ + var arr = ["http://www.zyplayer.com", "http://www.kongjianzhou.com"]; + resultValue = arr[Math.ceil(Math.random() * 2) - 1]; + } else if(paramName.endWith("username")){ + var arr = ["张三", "李四", "王二", "暮光:城中城", "海贼王"]; + resultValue = arr[Math.ceil(Math.random() * 5) - 1]; + } else if(userSettings.autoFillParam == 2){ + //var arr = ["您好!","请!","对不起。","谢谢!","再见!","您早!","晚安!","请问您贵姓?","请原谅!","不用谢!","没关系!","欢迎您光临!","请坐!","请喝茶!","请多关照!","请多指教!","谢谢您的合作!","对不起,让您久等了。","没关系,我刚到。","给您添麻烦了。","我能为您做什么?","您好,请问您需要帮助吗?","您走好。","请慢走!"]; + //resultValue = arr[Math.ceil(Math.random() * 24) - 1]; + resultValue = "我是默认字符串"; + } + //console.log(paramType); + } + return resultValue; +} diff --git a/zyplayer-doc-swagger/src/main/resources/webjars/mg-ui/js/mg-ui-export.js b/zyplayer-doc-swagger/src/main/resources/webjars/mg-ui/js/mg-ui-export.js index 066a6647..d0bf1d04 100644 --- a/zyplayer-doc-swagger/src/main/resources/webjars/mg-ui/js/mg-ui-export.js +++ b/zyplayer-doc-swagger/src/main/resources/webjars/mg-ui/js/mg-ui-export.js @@ -10,5 +10,9 @@ var exports = { exportDocument: function(){ // 定义在mg-ui.js,用于打开导出文档框 exportDocument(); + }, + updateGlobalParam: function(param){ + // 更新调试的全局参数变量 + debugGlobalParam = param; } }; \ No newline at end of file diff --git a/zyplayer-doc-swagger/src/main/resources/webjars/mg-ui/js/mg-ui.js b/zyplayer-doc-swagger/src/main/resources/webjars/mg-ui/js/mg-ui.js index 9bb0d29a..b2926db3 100644 --- a/zyplayer-doc-swagger/src/main/resources/webjars/mg-ui/js/mg-ui.js +++ b/zyplayer-doc-swagger/src/main/resources/webjars/mg-ui/js/mg-ui.js @@ -19,6 +19,8 @@ var projectTreeIdIndex = 1; var projectLoadingIndex = 0; // 请求到的文档列表 var documentJsonArr = []; +// 调试的全局参数变量 +var debugGlobalParam = []; // 用户的配置对象 var userSettings = {}; // 默认用户的配置对象 @@ -86,7 +88,7 @@ function getDocumentListByService() { showGlobalLoadingMessage('等待选择需展示的文档,请选择...', true); for (var i = 0; i < json.data.length; i++) { var item = json.data[i]; - $("#choiseDocListUl").append('
  • '+item+'
  • '); + $("#choiseDocListUl").append('
  • '+item.url+'
  • '); } $('#choiseDocModal').modal({moveable:true, backdrop:'static', keyboard: false}); } else { @@ -159,48 +161,6 @@ $("#changeContentWidth").click(function(){ changeContentWidth(isMinWidth ? 360 : 120); }); -/** - * 修改tree的class - */ -$("input[name='treeShowType']").change(function() { - userSettings.treeShowType = $("input[name='treeShowType']:checked").val(); - updateTreeShowType(); - storeUserSettings(); -}); - -/** - * 切换url分成一层一层的展示、整个url显示为一层展示 - */ -$("input[name='catalogShowType']").change(function() { - userSettings.catalogShowType = $("input[name='catalogShowType']:checked").val(); - regeneratePathTree(); - storeUserSettings(); -}); - -/** - * 是否展示参数类型 - */ -$("input[name='showParamType']").change(function() { - userSettings.showParamType = $("input[name='showParamType']:checked").val(); - storeUserSettings(); -}); - -/** - * 是否仅使用上次请求参数 - */ -$("input[name='onlyUseLastParam']").change(function() { - userSettings.onlyUseLastParam = $("input[name='onlyUseLastParam']:checked").val(); - storeUserSettings(); -}); - -/** - * 是否自动填充请求参数 - */ -$("input[name='autoFillParam']").change(function() { - userSettings.autoFillParam = $("input[name='autoFillParam']:checked").val(); - storeUserSettings(); -}); - /** * 搜索框回车事件 */ @@ -1030,7 +990,7 @@ function updateTreeShowType() { * 存储用户设置 */ function storeUserSettings() { - setStorage('userSettings', userSettings); + setStorage(cacheKeys.userSettings, userSettings); } /** @@ -1046,7 +1006,7 @@ function updateUserSettings(newSetting) { * @returns */ function initUserSettings() { - getStorage('userSettings', function(data) { + getStorage(cacheKeys.userSettings, function(data) { userSettings = data; if(isEmpty(userSettings) || isEmptyObject(userSettings)) { userSettings = defaultUserSettings; @@ -1057,6 +1017,9 @@ function initUserSettings() { // 增加文档 getDocumentListByService(); }); + getStorage(cacheKeys.globalParamList, function(data) { + debugGlobalParam = data; + }); } function showGlobalLoadingMessage(text, loading) { diff --git a/zyplayer-doc-swagger/src/main/resources/webjars/zpages/docShowConfig.html b/zyplayer-doc-swagger/src/main/resources/webjars/zpages/docShowConfig.html index ed0557ac..0b5bdb2f 100644 --- a/zyplayer-doc-swagger/src/main/resources/webjars/zpages/docShowConfig.html +++ b/zyplayer-doc-swagger/src/main/resources/webjars/zpages/docShowConfig.html @@ -77,6 +77,7 @@ var app = new Vue({ el: '#app', data: { + initCount: 5, catalogShowType: '', treeShowType: '', showParamType:'', @@ -122,12 +123,14 @@ }, } }); - + // 存储用户的配置信息 - function storeUserSettings(){ - setStorage(cacheKeys.userSettings, app.userSettings, function(){ - getExport().updateUserSettings(app.userSettings); - }); + function storeUserSettings() { + if (app.initCount-- <= 0) { + setStorage(cacheKeys.userSettings, app.userSettings, function () { + getExport().updateUserSettings(app.userSettings); + }); + } } diff --git a/zyplayer-doc-swagger/src/main/resources/webjars/zpages/docUrlConfig.html b/zyplayer-doc-swagger/src/main/resources/webjars/zpages/docUrlConfig.html index 39e8d62b..1820cbf8 100644 --- a/zyplayer-doc-swagger/src/main/resources/webjars/zpages/docUrlConfig.html +++ b/zyplayer-doc-swagger/src/main/resources/webjars/zpages/docUrlConfig.html @@ -1,5 +1,5 @@ - + @@ -14,15 +14,18 @@ 序号 地址 + 持久化时间 操作 {{index+1}} - {{item}} + {{item.url}} + {{item.lastSync}} + @@ -93,7 +96,8 @@ ajaxTemp(urlBase + "swagger-mg-ui/document/addSwaggerResources", "post", "json", {resourcesUrl: addNewDocumentInput}, function(json){ if(validateResult(json)) { //window.parent.document.location.reload(); - app.swaggerResourcesList.push(addNewDocumentInput); + //app.swaggerResourcesList.push(addNewDocumentInput); + app.refreshList(); $('#addNewDocumentModal').modal('hide'); Toast.success("保存成功,刷新后生效!"); } @@ -117,6 +121,17 @@ setStorage(cacheKeys.swaggerResourcesList, newDocList, function(){ app.swaggerResourcesList = newDocList; }); + }, + syncDocData: function(event){ + var tr = $(event.currentTarget).parents("tr"); + var index = tr.data("index"); + var newDocUrl = app.swaggerResourcesList[index].url; + ajaxTemp(urlBase + "swagger-mg-ui/document/syncDocData", "post", "json", {resourcesUrl: newDocUrl}, function(json){ + if(validateResult(json)) { + app.refreshList(); + Toast.success("持久化成功!"); + } + }); } }, mounted: function(){ diff --git a/zyplayer-doc-swagger/src/main/resources/webjars/zpages/globalParamConfig.html b/zyplayer-doc-swagger/src/main/resources/webjars/zpages/globalParamConfig.html index 847ae442..ba05daff 100644 --- a/zyplayer-doc-swagger/src/main/resources/webjars/zpages/globalParamConfig.html +++ b/zyplayer-doc-swagger/src/main/resources/webjars/zpages/globalParamConfig.html @@ -24,7 +24,7 @@ - @@ -81,11 +81,12 @@ }, addGlobalParamLine: function () { app.globalParamList.push({ - position: 'header', key: '', value: '' + paramIn: 'header', key: '', value: '' }); }, saveAllGlobalParam: function () { setStorage(cacheKeys.globalParamList, app.globalParamList, function(){ + getExport().updateGlobalParam(app.globalParamList); Toast.success("保存成功!"); }); },