tanghc 6 years ago
parent e28fd3b2ec
commit 2f2b52a5dd
  1. 10
      README.md
  2. 6
      changelog.md
  3. 34
      doc/docs/_sidebar.md
  4. 119
      doc/docs/files/10041_编写文档.md
  5. 0
      doc/docs/files/10096_使用SpringCloudGateway.md
  6. 19
      doc/docs/files/90013_原理分析之文档归纳.md
  7. BIN
      doc/docs/files/images/10041_1.png
  8. BIN
      doc/docs/files/images/10041_2.png
  9. BIN
      doc/docs/files/images/10041_3.png
  10. 2
      sop-example/sop-book/sop-book-api/src/main/java/com/gitee/book/api/domain/Book.java
  11. 2
      sop-example/sop-book/sop-book-api/src/main/java/com/gitee/book/api/service/BookService.java
  12. 23
      sop-example/sop-book/sop-book-web/pom.xml
  13. 12
      sop-example/sop-book/sop-book-web/src/main/java/com/gitee/sop/bookweb/config/OpenServiceConfig.java
  14. 19
      sop-example/sop-book/sop-book-web/src/main/java/com/gitee/sop/bookweb/controller/AlipayBookController.java
  15. 2
      sop-example/sop-book/sop-book-web/src/main/java/com/gitee/sop/bookweb/controller/BookController.java
  16. 5
      sop-example/sop-book/sop-book-web/src/main/java/com/gitee/sop/bookweb/param/BookParam.java
  17. 16
      sop-example/sop-book/sop-book-web/src/main/java/com/gitee/sop/bookweb/vo/BookVO.java
  18. 5
      sop-example/sop-story/sop-story-web/pom.xml
  19. 14
      sop-website/readme.md
  20. 647
      sop-website/website-front/pages/doc/code.html
  21. 40
      sop-website/website-front/pages/doc/doc.html
  22. 17
      sop-website/website-front/pages/doc/doc.js
  23. 116
      sop-website/website-front/pages/doc/sign.html
  24. 4
      sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/bean/DocParameter.java
  25. 11
      sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/controller/DocController.java
  26. 10
      sop-website/website-server/src/main/java/com/gitee/sop/websiteserver/manager/DocManagerImpl.java
  27. 3
      sop-website/website-server/src/main/resources/application-dev.yml
  28. 113
      sop.sql

@ -41,12 +41,11 @@ SOP封装了开放平台大部分功能包括:签名验证、统一异常处
- 接入方管理+秘钥管理
- 接口权限分配
- SDK
- 接口限流
- 文档整合
## 后期规划
- 文档整合
- springmvc项目接入demo
- 限流
- 监控
## admin界面预览
@ -66,10 +65,11 @@ SOP封装了开放平台大部分功能包括:签名验证、统一异常处
- doc:开发文档
- sop-registry:注册中心,eureka实现
- sop-gateway:网关,统一访问入口,Spring Cloud Zuul实现,可切换成Spring Cloud Gateway
- sop-common:公共模块,封装常用功能,包含签名校验、错误处理等功能
- sop-example:微服务示例
- sop-common:公共模块,封装常用功能,包含签名校验、错误处理、限流等功能
- sop-example:微服务示例,含springboot,springmvc示例
- sop-sdk:基础sdk,含Java、C#版本
- sop-test:接口调用测试用例
- sop-website:开放平台对应网站,提供文档API等内容
## 相关文档

@ -1,5 +1,11 @@
# changelog
## 1.3.0
- 新增接口限流功能
- 新增文档整合功能
- 新增springmvc项目接入demo
## 1.2.0
- SOP Admin新增用户登录

@ -1,18 +1,20 @@
* [首页](/?t=1554693919573)
* [首页](/?t=1555326144824)
* 开发文档
* [快速体验](files/10010_快速体验.md?t=1554693919573)
* [项目接入到SOP](files/10011_项目接入到SOP.md?t=1554693919596)
* [新增接口](files/10020_新增接口.md?t=1554693919596)
* [业务参数校验](files/10030_业务参数校验.md?t=1554693919596)
* [错误处理](files/10040_错误处理.md?t=1554693919596)
* [接口交互详解](files/10050_接口交互详解.md?t=1554693919596)
* [使用SpringCloudGateway](files/10060_使用SpringCloudGateway.md?t=1554693919596)
* [easyopen支持](files/10070_easyopen支持.md?t=1554693919596)
* [使用签名校验工具](files/10080_使用签名校验工具.md?t=1554693919596)
* [ISV管理](files/10085_ISV管理.md?t=1554693919596)
* [路由授权](files/10090_路由授权.md?t=1554693919596)
* [SDK开发](files/10095_SDK开发.md?t=1554693919597)
* [快速体验](files/10010_快速体验.md?t=1555326144827)
* [项目接入到SOP](files/10011_项目接入到SOP.md?t=1555326144859)
* [新增接口](files/10020_新增接口.md?t=1555326144859)
* [业务参数校验](files/10030_业务参数校验.md?t=1555326144859)
* [错误处理](files/10040_错误处理.md?t=1555326144859)
* [编写文档](files/10041_编写文档.md?t=1555326144859)
* [接口交互详解](files/10050_接口交互详解.md?t=1555326144859)
* [easyopen支持](files/10070_easyopen支持.md?t=1555326144860)
* [使用签名校验工具](files/10080_使用签名校验工具.md?t=1555326144860)
* [ISV管理](files/10085_ISV管理.md?t=1555326144860)
* [路由授权](files/10090_路由授权.md?t=1555326144860)
* [SDK开发](files/10095_SDK开发.md?t=1555326144860)
* [使用SpringCloudGateway](files/10096_使用SpringCloudGateway.md?t=1555326144860)
* 原理分析
* [原理分析之@ApiMapping](files/90010_原理分析之@ApiMapping.md?t=1554693919597)
* [原理分析之路由存储](files/90011_原理分析之路由存储.md?t=1554693919597)
* [原理分析之如何路由](files/90012_原理分析之如何路由.md?t=1554693919597)
* [原理分析之@ApiMapping](files/90010_原理分析之@ApiMapping.md?t=1555326144861)
* [原理分析之路由存储](files/90011_原理分析之路由存储.md?t=1555326144861)
* [原理分析之如何路由](files/90012_原理分析之如何路由.md?t=1555326144861)
* [原理分析之文档归纳](files/90013_原理分析之文档归纳.md?t=1555326144861)

@ -0,0 +1,119 @@
# 编写文档
作为开放平台,必须要提供文档API。
SOP采用微服务架构实现,因此文档应该由各个微服务各自实现。难点就是如何统一归纳各个微服务端提供的文档信息,并且统一展示。
写完接口后使用swagger注解来定义自己的文档信息。步骤如下:
- maven添加swagger
```xml
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
<exclusions>
<exclusion>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>1.5.21</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
```
- 在config中添加swagger配置
```java
@Configuration
public class OpenServiceConfig extends AlipayServiceConfiguration {
// 开启文档
@Configuration
@EnableSwagger2
public static class Swagger2 extends SwaggerSupport {
@Override
protected String getDocTitle() {
// 不能重复。比如订单服务返回:`订单API`;库存服务返回:`库存API`
return "图书API";
}
}
}
```
其中`getDocTitle()`返回文档模块名,不能和其它微服务重复。比如订单服务返回:`订单API`;库存服务返回:`库存API`
- 编写swagger注解
分别在请求参数和返回结果类中编写`@ApiModelProperty`
```java
// 请求参数
@Data
public class BookParam {
@ApiModelProperty(value = "图书id", example = "1")
private int id;
@ApiModelProperty(value = "图书ISBN", example = "xxxx")
private String isbn;
}
// 返回结果
@Data
public class BookVO {
@ApiModelProperty(value = "图书id", example = "1")
private int id;
@ApiModelProperty(value = "图书名称", example = "白雪公主")
private String name;
@ApiModelProperty(value = "isbn", example = "xxxxxx")
private String isbn;
}
```
- 在接口方法上编写`@ApiOperation`注解
```java
@ApiOperation(value="查询书本信息", notes = "可以根据ISBN查询书本信息")
@ApiMapping(value = "book.search")
public BookVO searchBook(BookParam param) {
BookVO bookVO = new BookVO();
bookVO.setId(1);
bookVO.setName("白雪公主,ISBN:" + param.getIsbn());
bookVO.setIsbn("ABCSSSSDDD");
return bookVO;
}
```
其中`value`属性填接口名称,简明扼要。`notes`填写接口的详细信息,介绍,用途,注意事项等。
## 查看文档
- 启动website-server(运行WebsiteServerApplication.java)
- 找到sop-website/website-front/pages/doc/doc.html,IDEA下右键--Debug
如果没有IDEA可以下个webstorm,同样有本地静态服务器功能。
效果图如下
![预览](images/10041_1.png "10041_1.png")
## 注解对应关系
swagger注解和文档界面显示关系如下图所示:
![预览](images/10041_2.png "10041_2.png")
![预览](images/10041_3.png "10041_3.png")

@ -0,0 +1,19 @@
# 原理分析之文档归纳
作为开放平台,必须要提供文档API。
SOP采用微服务架构实现,因此文档应该由各个微服务各自实现。难点是如何归纳各个微服务端提供的文档信息,并统一展示。
SOP的解决思路如下:
- 各微服务使用swagger定义自己的接口信息
- sop-website项目在启动时向注册中心获取所有服务实例,分别调用各个服务提供的swagger文档信息,保存到本地
- sop-website前端页面负责展示swagger提供的文档信息
由于注册中心的存在,可以很方便的获取每个微服务提供的接口,因此可以获取到swagger提供的文档信息。
如此一来的好处是,各微服务不用关心文档改怎么展示,只需要写好swagger注解即可;文档信息展示统一交给另外一个工程来维护,各司其职。
SOP设计初衷亦是如此,微服务只管写业务代码,其它的都交给SOP来处理。

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

@ -1,4 +1,4 @@
package com.hhdd.book.api.service;
package com.gitee.book.api.service;
import com.gitee.book.api.domain.Book;
import org.springframework.web.bind.annotation.RequestMapping;

@ -44,6 +44,29 @@
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
<exclusions>
<exclusion>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>1.5.21</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>

@ -1,7 +1,9 @@
package com.gitee.sop.bookweb.config;
import com.gitee.sop.servercommon.configuration.AlipayServiceConfiguration;
import com.gitee.sop.servercommon.swagger.SwaggerSupport;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* 使用支付宝开放平台功能
@ -9,7 +11,15 @@ import org.springframework.context.annotation.Configuration;
*/
@Configuration
public class OpenServiceConfig extends AlipayServiceConfiguration {
// 开启文档
@Configuration
@EnableSwagger2
public static class Swagger2 extends SwaggerSupport {
@Override
protected String getDocTitle() {
return "图书API";
}
}
}
/**

@ -1,15 +1,18 @@
package com.gitee.sop.bookweb.controller;
import com.gitee.book.api.domain.Book;
import com.gitee.sop.bookweb.consumer.StoryServiceConsumer;
import com.gitee.sop.bookweb.param.BookParam;
import com.gitee.sop.bookweb.vo.BookVO;
import com.gitee.sop.servercommon.annotation.ApiMapping;
import com.gitee.sop.story.api.domain.Story;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;
/**
* 支付宝服务端假设签名验证通过后到达这里进行具体的业务处理
* 这里演示如何接受业务参数
* @author tanghc
*/
@ -19,9 +22,19 @@ public class AlipayBookController {
@Autowired
StoryServiceConsumer storyServiceConsumer;
@ApiOperation(value="查询书本信息", notes = "可以根据ISBN查询书本信息")
@ApiMapping(value = "book.search")
public BookVO searchBook(BookParam param) {
BookVO bookVO = new BookVO();
bookVO.setId(1);
bookVO.setName("白雪公主,ISBN:" + param.getIsbn());
bookVO.setIsbn("ABCSSSSDDD");
return bookVO;
}
@ApiMapping(value = "alipay.book.get")
public Story getBook() {
Story story = new Story();
public Book getBook() {
Book story = new Book();
story.setId(1);
story.setName("白雪公主(alipay.book.get)");
return story;

@ -4,7 +4,7 @@ import com.gitee.book.api.domain.Book;
import com.gitee.sop.bookweb.consumer.StoryServiceConsumer;
import com.gitee.sop.bookweb.param.BookParam;
import com.gitee.sop.story.api.domain.Story;
import com.hhdd.book.api.service.BookService;
import com.gitee.book.api.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;

@ -1,5 +1,6 @@
package com.gitee.sop.bookweb.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
@ -7,5 +8,9 @@ import lombok.Data;
*/
@Data
public class BookParam {
@ApiModelProperty(value = "图书id", example = "1")
private int id;
@ApiModelProperty(value = "图书ISBN", example = "xxxx")
private String isbn;
}

@ -0,0 +1,16 @@
package com.gitee.sop.bookweb.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class BookVO {
@ApiModelProperty(value = "图书id", example = "1")
private int id;
@ApiModelProperty(value = "图书名称", example = "白雪公主")
private String name;
@ApiModelProperty(value = "isbn", example = "xxxxxx")
private String isbn;
}

@ -17,7 +17,6 @@
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
<swagger.version>2.9.2</swagger.version>
</properties>
<dependencies>
@ -44,7 +43,7 @@
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
<version>2.9.2</version>
<exclusions>
<exclusion>
<groupId>io.swagger</groupId>
@ -60,7 +59,7 @@
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
<version>2.9.2</version>
</dependency>
<dependency>

@ -0,0 +1,14 @@
# 开放平台网站
包括文档功能,用户注册等,具体业务需要自己实现。
前后端分离
- website-front: 前端页面
- website-server: 后台接口
## 使用方式
- 确保注册中心、网关、微服务正常启动
- 启动website-server(运行WebsiteServerApplication.java)
- 找到sop-website/website-front/pages/doc/doc.html,IDEA下右键--Debug

@ -0,0 +1,647 @@
<html data-find="_6">
<head>
<script src="https://www.googletagservices.com/activeview/js/current/osd.js?cb=%2Fr20100101"></script>
<meta charset="utf-8">
<title>返回状态码</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="format-detection" content="telephone=no">
<link rel="stylesheet" href="../../assets/lib/layui/css/layui.css" media="all">
<link rel="stylesheet" href="../../assets/css/global.css" media="all">
<link id="layuicss-skincodecss" rel="stylesheet" href="../../assets/lib/layui/css/modules/code.css" media="all">
<link id="layuicss-layer" rel="stylesheet" href="../../assets/lib/layui/css/modules/layer/default/layer.css?v=3.1.1"
media="all">
<style type="text/css">
.site-content table {
border-collapse: collapse;
border-spacing: 0;
empty-cells: show;
vertical-align: top;
width: 100%;
overflow-x: auto;
overflow-y: hidden;
-webkit-overflow-scrolling: touch;
margin: 12px 0 24px;
}
.site-content table + p {
margin-top: 24px;
}
.site-content table th,
.site-content table td {
padding: 8px 12px;
font-size: 14px;
text-align: left;
word-break: break-word;
word-wrap: break-word;
min-width: 100px;
color: gray;
}
.site-content table thead tr{
background-color: #f2f2f2;
}
.site-content table thead td,
.site-content table tbody td{
border-bottom: 1px solid #e6e6e6;
border-left: 1px solid #e6e6e6;
border-right: 1px solid #e6e6e6;
border-top: 1px solid #e6e6e6;
}
</style>
</head>
<body data-find="_5">
<div class="layui-header header header-doc" spring="">
<div class="layui-main">
<a class="logo" href="#" style="color: #ffffff">
开放平台
</a>
<ul class="layui-nav">
<li class="layui-nav-item layui-this">
<a href="doc.html">文档中心<!-- --></a>
</li>
<span class="layui-nav-bar" style="left: 162px; top: 55px; width: 0px; opacity: 0;"></span>
</ul>
</div>
</div>
<!-- 让IE8/9支持媒体查询,从而兼容栅格 -->
<!--[if lt IE 9]>
<script src="https://cdn.staticfile.org/html5shiv/r29/html5.min.js"></script>
<script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<div class="layui-main site-inline">
<div class="site-tree">
<ul id="docItemTree" class="layui-tree">
<li><h2 class="docModule">文档专区</h2></li>
<li class="site-tree-noicon layui-this">
<a href="#">
<cite>公共错误码</cite>
</a>
</li>
</ul>
</div>
<div class="site-content">
<div class="site-title">
<fieldset class="layui-elem-field layui-field-title site-title">
<legend><a name="use">公共错误码</a></legend>
</fieldset>
</div>
<div class="site-text">
<p>网关会对开发者的接口非业务调用错误做统一处理,返回码如下:</p>
<table>
<thead>
<tr>
<td rowspan="1" colspan="1">
<div><strong>code(返回码)</strong></div>
</td>
<td rowspan="1" colspan="1">
<div><strong>msg(返回码描述)</strong></div>
</td>
<td rowspan="1" colspan="1">
<div><strong>sub_code(明细返回码)</strong></div>
</td>
<td rowspan="1" colspan="1">
<div><strong>sub_msg(明细返回码描述)</strong></div>
</td>
<td rowspan="1" colspan="1">
<div><strong>解决方案</strong></div>
</td>
</tr>
</thead>
<tbody>
<tr>
<td rowspan="1" colspan="1">
<div>10000</div>
</td>
<td rowspan="1" colspan="1">
<div>Success(接口调用成功)</div>
</td>
<td rowspan="1" colspan="1">
<div>&nbsp;</div>
</td>
<td rowspan="1" colspan="1">
<div>&nbsp;</div>
</td>
<td rowspan="1" colspan="1">
<div>&nbsp;</div>
</td>
</tr>
<tr>
<td rowspan="3" colspan="1">
<div>20000</div>
</td>
<td rowspan="3" colspan="1">
<div>服务不可用</div>
</td>
<td rowspan="1" colspan="1">
<div>isp.unknow-error</div>
</td>
<td rowspan="1" colspan="1">
<div>服务暂不可用(业务系统不可用)</div>
</td>
<td rowspan="1" colspan="1">
<div>稍后重试</div>
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">
<div>aop.unknow-error</div>
</td>
<td rowspan="1" colspan="1">
<div>服务暂不可用(网关自身的未知错误)</div>
</td>
<td rowspan="1" colspan="1">
<div>稍后重试</div>
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">
<div>isp.service-not-available</div>
</td>
<td rowspan="1" colspan="1">
<div>服务暂不可用</div>
</td>
<td rowspan="1" colspan="1">
<div>稍后重试</div>
</td>
</tr>
<tr>
<td rowspan="6" colspan="1">
<div>20001</div>
</td>
<td rowspan="6" colspan="1">
<div>授权权限不足</div>
</td>
<td rowspan="1" colspan="1">
<div>aop.invalid-auth-token</div>
</td>
<td rowspan="1" colspan="1">
<div>无效的访问令牌</div>
</td>
<td rowspan="1" colspan="1">
<div>请刷新授权令牌或重新授权获取新的令牌</div>
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">
<div>aop.auth-token-time-out</div>
</td>
<td rowspan="1" colspan="1">
<div>访问令牌已过期</div>
</td>
<td rowspan="1" colspan="1">
<div>请刷新授权令牌或重新授权获取新的令牌</div>
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">
<div>aop.invalid-app-auth-token</div>
</td>
<td rowspan="1" colspan="1">
<div>无效的应用授权令牌</div>
</td>
<td rowspan="1" colspan="1">
<div>请刷新应用授权令牌或重新授权获取新的令牌</div>
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">
<div>aop.invalid-app-auth-token-no-api</div>
</td>
<td rowspan="1" colspan="1">
<div>商户未授权当前接口</div>
</td>
<td rowspan="1" colspan="1">
<div>请重新授权获取新的应用授权令牌</div>
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">
<div>aop.app-auth-token-time-out</div>
</td>
<td rowspan="1" colspan="1">
<div>应用授权令牌已过期</div>
</td>
<td rowspan="1" colspan="1">
<div>请刷新应用授权令牌或重新授权获取新的令牌</div>
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">
<div>aop.no-product-reg-by-partner</div>
</td>
<td rowspan="1" colspan="1">
<div>商户未签约任何产品</div>
</td>
<td rowspan="1" colspan="1">
<div>ISV代理调用的场景,请上线商户的服务窗</div>
</td>
</tr>
<tr>
<td rowspan="8" colspan="1">
<div>40001</div>
</td>
<td rowspan="8" colspan="1">
<div>缺少必选参数</div>
</td>
<td rowspan="1" colspan="1">
<div>isv.missing-method</div>
</td>
<td rowspan="1" colspan="1">
<div>缺少方法名参数</div>
</td>
<td rowspan="1" colspan="1">
<div>请求参数里面必须要有method参数</div>
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">
<div>isv.missing-signature</div>
</td>
<td rowspan="1" colspan="1">
<div>缺少签名参数</div>
</td>
<td rowspan="1" colspan="1">
<div>检查请求参数,缺少sign参数</div>
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">
<div>isv.missing-signature-type</div>
</td>
<td rowspan="1" colspan="1">
<div>缺少签名类型参数</div>
</td>
<td rowspan="1" colspan="1">
<div>检查请求参数,缺少sign_type参数</div>
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">
<div>isv.missing-signature-key</div>
</td>
<td rowspan="1" colspan="1">
<div>缺少签名配置</div>
</td>
<td rowspan="1" colspan="1">
<div>未上传公钥配置</div>
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">
<div>isv.missing-app-id</div>
</td>
<td rowspan="1" colspan="1">
<div>缺少appId参数</div>
</td>
<td rowspan="1" colspan="1">
<div>检查请求参数,缺少app_id参数</div>
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">
<div>isv.missing-timestamp</div>
</td>
<td rowspan="1" colspan="1">
<div>缺少时间戳参数</div>
</td>
<td rowspan="1" colspan="1">
<div>检查请求参数,缺少timestamp参数</div>
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">
<div>isv.missing-version</div>
</td>
<td rowspan="1" colspan="1">
<div>缺少版本参数</div>
</td>
<td rowspan="1" colspan="1">
<div>检查请求参数,缺少version参数</div>
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">
<div>isv.decryption-error-missing-encrypt-type</div>
</td>
<td rowspan="1" colspan="1">
<div>解密出错, 未指定加密算法</div>
</td>
<td rowspan="1" colspan="1">
<div>检查参数,缺少encrypt_type参数</div>
</td>
</tr>
<tr>
<td rowspan="20" colspan="1">
<div>40002</div>
</td>
<td rowspan="20" colspan="1">
<div>非法的参数</div>
</td>
<td rowspan="1" colspan="1">
<div>isv.invalid-parameter</div>
</td>
<td rowspan="1" colspan="1">
<div>参数无效</div>
</td>
<td rowspan="1" colspan="1">
<div>检查参数,格式不对、非法值、越界等</div>
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">
<div>isv.upload-fail</div>
</td>
<td rowspan="1" colspan="1">
<div>文件上传失败</div>
</td>
<td rowspan="1" colspan="1">
<div>文件写入失败,重试</div>
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">
<div>isv.invalid-file-extension</div>
</td>
<td rowspan="1" colspan="1">
<div>文件扩展名无效</div>
</td>
<td rowspan="1" colspan="1">
<div>检查传入的文件扩展名称,目前支持格式:csv,txt,zip,rar,gz,doc,docx,xls,xlsx,pdf,bmp,gif,jpg,jpeg,png</div>
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">
<div>isv.invalid-file-size</div>
</td>
<td rowspan="1" colspan="1">
<div>文件大小无效</div>
</td>
<td rowspan="1" colspan="1">
<div>检查文件大小,目前支持最大为:50MB&nbsp;</div>
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">
<div>isv.invalid-method</div>
</td>
<td rowspan="1" colspan="1">
<div>不存在的方法名</div>
</td>
<td rowspan="1" colspan="1">
<div>检查入参method是否正确</div>
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">
<div>isv.invalid-format</div>
</td>
<td rowspan="1" colspan="1">
<div>无效的数据格式</div>
</td>
<td rowspan="1" colspan="1">
<div>检查入参format,目前只支持json和xml 2种格式</div>
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">
<div>isv.invalid-signature-type</div>
</td>
<td rowspan="1" colspan="1">
<div>无效的签名类型</div>
</td>
<td rowspan="1" colspan="1">
<div>检查入参sign_type,目前只支持RSA,RSA2,HMAC_SHA1</div>
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">
<div>isv.invalid-signature</div>
</td>
<td rowspan="1" colspan="1">
<div>无效签名</div>
</td>
<td rowspan="1" colspan="1">
<div>1.公私钥是否是一对 2.检查公钥上传是否与私钥匹配 3.存在中文需要做urlencode 4.签名算法是否无误
</div>
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">
<div>isv.invalid-encrypt-type</div>
</td>
<td rowspan="1" colspan="1">
<div>无效的加密类型</div>
</td>
<td rowspan="1" colspan="1">
<div>检查入参encrypt_type,目前只支持AES</div>
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">
<div>isv.invalid-encrypt</div>
</td>
<td rowspan="1" colspan="1">
<div>解密异常</div>
</td>
<td rowspan="1" colspan="1">
<div>重试</div>
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">
<div>isv.invalid-app-id</div>
</td>
<td rowspan="1" colspan="1">
<div>无效的appId参数</div>
</td>
<td rowspan="1" colspan="1">
<div>检查入参app_id,app_id不存在,或者未上线</div>
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">
<div>isv.invalid-timestamp</div>
</td>
<td rowspan="1" colspan="1">
<div>非法的时间戳参数</div>
</td>
<td rowspan="1" colspan="1">
<div>时间戳参数timestamp非法,请检查格式需要为"yyyy-MM-dd HH:mm:ss"</div>
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">
<div>isv.invalid-charset</div>
</td>
<td rowspan="1" colspan="1">
<div>字符集错误</div>
</td>
<td rowspan="1" colspan="1">
<div>请求参数charset错误,目前支持格式:GBK,UTF-8</div>
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">
<div>isv.invalid-digest</div>
</td>
<td rowspan="1" colspan="1">
<div>摘要错误</div>
</td>
<td rowspan="1" colspan="1">
<div>检查请求参数,文件摘要参数必填</div>
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">
<div>isv.decryption-error-not-valid-encrypt-type</div>
</td>
<td rowspan="1" colspan="1">
<div>解密出错,不支持的加密算法</div>
</td>
<td rowspan="1" colspan="1">
<div>检查入参encrypt_type,目前只支持AES</div>
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">
<div>isv.decryption-error-not-valid-encrypt-key</div>
</td>
<td rowspan="1" colspan="1">
<div>解密出错, 未配置加密密钥或加密密钥格式错误</div>
</td>
<td rowspan="1" colspan="1">
<div>没有配置加密密钥</div>
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">
<div>isv.decryption-error-unknown</div>
</td>
<td rowspan="1" colspan="1">
<div>解密出错,未知异常</div>
</td>
<td rowspan="1" colspan="1">
<div>重试</div>
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">
<div>isv.missing-signature-config</div>
</td>
<td rowspan="1" colspan="1">
<div>验签出错, 未配置对应签名算法的公钥或者证书</div>
</td>
<td rowspan="1" colspan="1">
<div>没有配置应用公钥</div>
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">
<div>isv.not-support-app-auth</div>
</td>
<td rowspan="1" colspan="1">
<div>本接口不支持第三方代理调用</div>
</td>
<td rowspan="1" colspan="1">
<div>本接口不支持第三方代理调用</div>
</td>
</tr>
<tr height="34px">
<td rowspan="1" colspan="1">
<div>isv.suspected-attack</div>
</td>
<td rowspan="1" colspan="1">
<div>可疑的攻击请求</div>
</td>
<td rowspan="1" colspan="1">
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">
<div>40004</div>
</td>
<td rowspan="1" colspan="1">
<div>业务处理失败</div>
</td>
<td rowspan="1" colspan="3">
<div>对应业务错误码,明细错误码和解决方案请参见具体的API接口文档</div>
</td>
</tr>
<tr>
<td rowspan="4" colspan="1">
<div>40006</div>
</td>
<td rowspan="4" colspan="1">
<div>权限不足</div>
</td>
<td rowspan="1" colspan="1">
<div>isv.insufficient-isv-permissions</div>
</td>
<td rowspan="1" colspan="1">
<div>ISV权限不足</div>
</td>
<td rowspan="1" colspan="1">
<div>请检查配置的账户是否有当前接口权限</div>
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">
<div>isv.insufficient-user-permissions</div>
</td>
<td rowspan="1" colspan="1">
<div>用户权限不足</div>
</td>
<td rowspan="1" colspan="1">
<div>代理的商户没有当前接口权限</div>
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">
<div>isv.route-no-permissions</div>
</td>
<td rowspan="1" colspan="1">
<div>用户权限不足</div>
</td>
<td rowspan="1" colspan="1">
<div>没有当前接口权限</div>
</td>
</tr>
<tr>
<td rowspan="1" colspan="1">
<div>isv.access-forbidden</div>
</td>
<td rowspan="1" colspan="1">
<div>用户权限不足</div>
</td>
<td rowspan="1" colspan="1">
<div>无权访问(接口被禁用)</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div><!-- layui-main end~ -->
<div class="layui-footer footer footer-doc">
<div class="layui-main">
<p>© 2019 <a href="https://gitee.com/durcframework/SOP" target="_blank">SOP</a> MIT license</p>
</div>
</div>
<script src="../../assets/lib/layui/layui.js" charset="utf-8"></script>
<script src="../../config/config.js" charset="utf-8"></script>
<script src="../../assets/lib/jquery/3.2.1/jquery.min.js" charset="utf-8"></script>
<script>
layui.use('code', function(){ //加载code模块
layui.code(); //引用code方法
});
</script>
</body>
</html>

@ -2,7 +2,7 @@
<head>
<script src="https://www.googletagservices.com/activeview/js/current/osd.js?cb=%2Fr20100101"></script>
<meta charset="utf-8">
<title>滑块文档 - layui</title>
<title>文档中心</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
@ -12,15 +12,9 @@
<link rel="stylesheet" href="../../assets/lib/layui/css/layui.css" media="all">
<link rel="stylesheet" href="../../assets/css/global.css" media="all">
<!--<script src="https://pagead2.googlesyndication.com/pub-config/r20160913/ca-pub-6111334333458862.js"></script>-->
<!--<script src="https://pagead2.googlesyndication.com/pagead/js/r20190408/r20190131/show_ads_impl.js" id="google_shimpl"></script>-->
<!--<script src="https://hm.baidu.com/hm.js?d214947968792b839fd669a4decaaffc"></script>-->
<!--<link rel="preload" href="https://adservice.google.com/adsid/integrator.js?domain=www.layui.com" as="script">-->
<!--<script type="text/javascript" src="https://adservice.google.com/adsid/integrator.js?domain=www.layui.com"></script>-->
<link id="layuicss-skincodecss" rel="stylesheet" href="../../assets/lib/layui/css/modules/code.css" media="all">
<link id="layuicss-layer" rel="stylesheet" href="../../assets/lib/layui/css/modules/layer/default/layer.css?v=3.1.1"
media="all">
<!--<link rel="preload" href="https://pagead2.googlesyndication.com/pagead/js/r20190408/r20190131/show_ads_impl.js" as="script">-->
<style type="text/css">
.layui-table {
word-wrap: break-word;
@ -30,9 +24,11 @@
.layui-table th {
white-space: nowrap !important;
}
.prop-name {
width: 105px;
}
.prop-type {
width: 50px;
}
@ -47,7 +43,7 @@
</a>
<ul class="layui-nav">
<li class="layui-nav-item layui-this">
<a href="/">文档中心<!-- --></a>
<a href="doc.html">文档中心<!-- --></a>
</li>
<span class="layui-nav-bar" style="left: 162px; top: 55px; width: 0px; opacity: 0;"></span>
@ -80,16 +76,19 @@
</div>
<div class="site-content">
<h1 class="site-h1"><i class="layui-icon layui-icon-slider"></i> <span class="sop-name"></span>(<span class="sop-summary"></span>)
<h1 class="site-h1"><i class="layui-icon layui-icon-slider"></i> <span class="sop-name"></span>(<span
class="sop-summary"></span>)
</h1>
<blockquote class="layui-elem-quote layui-text sop-description">
</blockquote>
<div class="site-title">
<fieldset class="layui-elem-field layui-field-title site-title">
<legend><a name="use">公共参数</a></legend>
</fieldset>
<div class="site-text" data-find="_2">
</div>
<div class="site-text">
<h3>请求地址</h3>
<table class="layui-table">
<thead>
@ -171,7 +170,7 @@
<td>String</td>
<td></td>
<td>344</td>
<td>商户请求参数的签名串,详见<a href="#" target="_blank">签名</a></td>
<td>商户请求参数的签名串,详见<a href="sign.html" target="_blank">签名</a></td>
<td>详见示例</td>
</tr>
@ -189,7 +188,7 @@
<td>String</td>
<td></td>
<td>3</td>
<td> 调用的接口版本,固定为:1.0</td>
<td>调用的接口版本,固定为:1.0</td>
<td>1.0</td>
</tr>
@ -223,9 +222,11 @@
</table>
</div>
<div class="site-title">
<fieldset class="layui-elem-field layui-field-title site-title">
<legend><a name="use">请求参数</a></legend>
</fieldset>
</div>
<div class="site-text">
<table class="layui-table">
<thead>
@ -243,9 +244,11 @@
</table>
</div>
<div class="site-title">
<fieldset class="layui-elem-field layui-field-title site-title">
<legend><a name="use">公共响应参数</a></legend>
</fieldset>
</div>
<div class="site-text">
<table class="layui-table">
<thead>
@ -264,7 +267,7 @@
<td>String</td>
<td></td>
<td>-</td>
<td>网关返回码,<a href="#" target="_blank">详见文档</a></td>
<td>网关返回码,<a href="code.html" target="_blank">详见文档</a></td>
<td>40004</td>
</tr>
<tr>
@ -272,7 +275,7 @@
<td>String</td>
<td></td>
<td>-</td>
<td>网关返回码描述,<a href="#" target="_blank">详见文档</a></td>
<td>网关返回码描述,<a href="code.html" target="_blank">详见文档</a></td>
<td>Business Failed</td>
</tr>
<tr>
@ -296,7 +299,7 @@
<td>String</td>
<td></td>
<td>-</td>
<td>签名,<a href="#" target="_blank">详见文档</a></td>
<td>签名,<a href="sign.html" target="_blank">详见文档</a></td>
<td>xxx</td>
</tr>
</tbody>
@ -304,9 +307,11 @@
</div>
<div class="site-title">
<fieldset class="layui-elem-field layui-field-title site-title">
<legend><a name="use">响应参数</a></legend>
</fieldset>
</div>
<div class="site-text">
<table class="layui-table">
<thead>
@ -324,24 +329,27 @@
</table>
</div>
<div class="site-title">
<fieldset class="layui-elem-field layui-field-title site-title">
<legend><a name="use">响应示例</a></legend>
</fieldset>
</div>
<div class="site-text">
<pre id="responseExampleJson">
</pre>
</div>
<div class="site-title">
<fieldset class="layui-elem-field layui-field-title site-title">
<legend><a name="use">异常示例</a></legend>
</fieldset>
</div>
<div class="site-text">
<pre id="responseErrorJson">
</pre>
</div>
</div>
</div><!-- layui-main end~ -->
<div class="layui-footer footer footer-doc">

@ -1,6 +1,9 @@
layui.use(['element', 'form'], function(){ //加载code模块
var form = layui.form;
// key:module
var docItemStore = {};
function initDocModules() {
$.getJSON(SopConfig.url + '/doc/getDocBaseInfo', function (baseInfo) {
var html = [];
@ -26,6 +29,7 @@ layui.use(['element', 'form'], function(){ //加载code模块
var html = ['<li><h2>' + docModule + '</h2></li>'];
for (var i = 0; i < docItems.length; i++) {
var docItem = docItems[i];
docItemStore[docItem.nameVersion] = docItem;
/*
<li class="site-tree-noicon layui-this">
<a href="/">
@ -35,12 +39,12 @@ layui.use(['element', 'form'], function(){ //加载code模块
*/
var selectedClass = i === 0 ? 'layui-this' : '';
html.push('<li class="site-tree-noicon ' + selectedClass + '">');
html.push('<a href="#" sopname="'+docItem.name+'" sopversion="'+docItem.version+'"><cite>'+docItem.summary+'</cite></a>')
html.push('<a href="#" nameversion="'+docItem.nameVersion+'"><cite>'+docItem.summary+'</cite></a>')
}
$('#docItemTree').html(html.join(''));
if (docItems && docItems.length > 0) {
var firstItem = docItems[0];
selectDocItem(firstItem.name, firstItem.version)
selectDocItem(firstItem.nameVersion);
}
})
}
@ -51,13 +55,13 @@ layui.use(['element', 'form'], function(){ //加载code模块
})
$('#docItemTree').on('click', 'a', function () {
var $tagA = $(this);
selectDocItem($tagA.attr('sopname'), $tagA.attr('sopversion'));
selectDocItem($tagA.attr('nameversion'));
$tagA.parent().addClass('layui-this').siblings().removeClass('layui-this');
})
}
function selectDocItem(name, version) {
$.getJSON(SopConfig.url + '/doc/item/' + name + '/' + version + '/', function (docItem) {
function selectDocItem(nameVersion) {
var docItem = docItemStore[nameVersion];
$('.sop-name').text(docItem.name);
$('.sop-version').text(docItem.version);
$('.sop-summary').text(docItem.summary);
@ -66,7 +70,6 @@ layui.use(['element', 'form'], function(){ //加载code模块
createRequestParameter(docItem);
createResponseParameter(docItem);
createResponseCode(docItem);
})
}
function createRequestParameter(docItem) {
@ -99,7 +102,7 @@ layui.use(['element', 'form'], function(){ //加载code模块
' <th>'+(parameter.required ? '<span style="color:red;">是</span>' : '否')+'</th>\n' +
' <th>-</th>\n' +
' <th class="prop-desc">'+parameter.description+'</th>\n' +
' <th class="prop-example">' + parameter.example +'</th>\n' +
' <th class="prop-example">' + (parameter.example || parameter['x-example']) +'</th>\n' +
'</tr>')
}
return html.join('');

@ -0,0 +1,116 @@
<html data-find="_6">
<head>
<script src="https://www.googletagservices.com/activeview/js/current/osd.js?cb=%2Fr20100101"></script>
<meta charset="utf-8">
<title>签名</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="format-detection" content="telephone=no">
<link rel="stylesheet" href="../../assets/lib/layui/css/layui.css" media="all">
<link rel="stylesheet" href="../../assets/css/global.css" media="all">
<link id="layuicss-skincodecss" rel="stylesheet" href="../../assets/lib/layui/css/modules/code.css" media="all">
<link id="layuicss-layer" rel="stylesheet" href="../../assets/lib/layui/css/modules/layer/default/layer.css?v=3.1.1"
media="all">
<style type="text/css">
</style>
</head>
<body data-find="_5">
<div class="layui-header header header-doc" spring="">
<div class="layui-main">
<a class="logo" href="#" style="color: #ffffff">
开放平台
</a>
<ul class="layui-nav">
<li class="layui-nav-item layui-this">
<a href="doc.html">文档中心<!-- --></a>
</li>
<span class="layui-nav-bar" style="left: 162px; top: 55px; width: 0px; opacity: 0;"></span>
</ul>
</div>
</div>
<!-- 让IE8/9支持媒体查询,从而兼容栅格 -->
<!--[if lt IE 9]>
<script src="https://cdn.staticfile.org/html5shiv/r29/html5.min.js"></script>
<script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<div class="layui-main site-inline">
<div class="site-tree">
<ul id="docItemTree" class="layui-tree">
<li><h2 class="docModule">签名专区</h2></li>
<li class="site-tree-noicon layui-this">
<a href="#">
<cite>自行实现签名</cite>
</a>
</li>
</ul>
</div>
<div class="site-content">
<div class="site-title">
<fieldset class="layui-elem-field layui-field-title site-title">
<legend><a name="use">自行实现签名</a></legend>
</fieldset>
</div>
<div class="site-text">
<p>如果未使用开放平台SDK,需要自行实现签名过程。</p>
<fieldset class="layui-elem-field layui-field-title site-title">
<legend><a name="use">如何签名</a></legend>
</fieldset>
<p>1.筛选并排序</p>
<p>
获取所有请求参数,不包括字节类型参数,如文件、字节流,剔除sign字段,剔除值为空的参数,并按照第一个字符的键值ASCII码递增排序(字母升序排序),如果遇到相同字符则按照第二个字符的键值ASCII码递增排序,以此类推。</p>
<p>2.拼接</p>
<p>将排序后的参数与其对应值,组合成“参数=参数值”的格式,并且把这些参数用&amp;字符连接起来,此时生成的字符串为待签名字符串。</p>
<p>例如下面的请求示例,参数值都是示例,开发者参考格式即可:</p>
<pre class="layui-code">REQUEST URL: http://open-test.yourdomain.com/api
REQUEST METHOD: POST
CONTENT:
app_id=2014072300007148
method=alipay.mobile.public.menu.add
charset=GBK
sign_type=RSA2
timestamp=2014-07-24 03:07:50
biz_content={"button":[{"actionParam":"ZFB_HFCZ","actionType":"out","name":"话费充值"},{"name":"查询","subButton":[{"actionParam":"ZFB_YECX","actionType":"out","name":"余额查询"},{"actionParam":"ZFB_LLCX","actionType":"out","name":"流量查询"},{"actionParam":"ZFB_HFCX","actionType":"out","name":"话费查询"}]},{"actionParam":"http://m.alipay.com","actionType":"link","name":"最新优惠"}]}
sign=e9zEAe4TTQ4LPLQvETPoLGXTiURcxiAKfMVQ6Hrrsx2hmyIEGvSfAQzbLxHrhyZ48wOJXTsD4FPnt+YGdK57+fP1BCbf9rIVycfjhYCqlFhbTu9pFnZgT55W+xbAFb9y7vL0MyAxwXUXvZtQVqEwW7pURtKilbcBTEW7TAxzgro=
version=1.0
</pre>
<p>则待签名字符串为:</p>
<pre class="layui-code">app_id=2014072300007148&amp;biz_content={"button":[{"actionParam":"ZFB_HFCZ","actionType":"out","name":"话费充值"},{"name":"查询","subButton":[{"actionParam":"ZFB_YECX","actionType":"out","name":"余额查询"},{"actionParam":"ZFB_LLCX","actionType":"out","name":"流量查询"},{"actionParam":"ZFB_HFCX","actionType":"out","name":"话费查询"}]},{"actionParam":"http://m.alipay.com","actionType":"link","name":"最新优惠"}]}&amp;charset=GBK&amp;method=alipay.mobile.public.menu.add&amp;sign_type=RSA2&amp;timestamp=2014-07-24 03:07:50&amp;version=1.0</pre>
<p>3.调用签名函数</p>
<p>
使用各自语言对应的SHA256WithRSA(对应sign_type为RSA2)或SHA1WithRSA(对应sign_type为RSA)签名函数利用商户私钥对待签名字符串进行签名,并进行Base64编码。</p>
<p>4.把生成的签名赋值给sign参数,拼接到请求参数中。</p>
<pre class="layui-code">/**
@param content 加签内容
@param privateKey 加签私钥
@param charset 加签字符集
@param charset 签名方法
**/
String AlipaySignature.rsaSign(String content, String privateKey, String charset,String signType)
</pre>
</div>
</div>
</div><!-- layui-main end~ -->
<div class="layui-footer footer footer-doc">
<div class="layui-main">
<p>© 2019 <a href="https://gitee.com/durcframework/SOP" target="_blank">SOP</a> MIT license</p>
</div>
</div>
<script src="../../assets/lib/layui/layui.js" charset="utf-8"></script>
<script src="../../config/config.js" charset="utf-8"></script>
<script src="../../assets/lib/jquery/3.2.1/jquery.min.js" charset="utf-8"></script>
<script>
layui.use('code', function(){ //加载code模块
layui.code(); //引用code方法
});
</script>
</body>
</html>

@ -1,5 +1,6 @@
package com.gitee.sop.websiteserver.bean;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
/**
@ -14,4 +15,7 @@ public class DocParameter {
private String description;
private String example = "";
@JSONField(name = "x-example")
private String x_example = "";
}

@ -5,6 +5,7 @@ import com.gitee.sop.websiteserver.bean.DocModule;
import com.gitee.sop.websiteserver.manager.DocManager;
import com.gitee.sop.websiteserver.vo.DocBaseInfoVO;
import com.gitee.sop.websiteserver.vo.DocModuleVO;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
@ -32,6 +33,9 @@ public class DocController {
@Value("${api.url-prod}")
String urlProd;
@Value("${api.pwd}")
String pwd;
@GetMapping("/getDocBaseInfo")
public DocBaseInfoVO getDocBaseInfo() {
List<DocModuleVO> docModuleVOList = docManager.listAll()
@ -60,4 +64,11 @@ public class DocController {
return docManager.get(method, version);
}
@GetMapping("/doc/reload")
public void reload(String pwd) {
if (StringUtils.equals(this.pwd, pwd)) {
docManager.load();
}
}
}

@ -3,8 +3,8 @@ package com.gitee.sop.websiteserver.manager;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.gitee.sop.websiteserver.bean.DocModule;
import com.gitee.sop.websiteserver.bean.DocItem;
import com.gitee.sop.websiteserver.bean.DocModule;
import com.gitee.sop.websiteserver.bean.DocParameter;
import com.gitee.sop.websiteserver.bean.EurekaApplication;
import com.gitee.sop.websiteserver.bean.EurekaApps;
@ -20,6 +20,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import javax.annotation.PostConstruct;
@ -61,6 +62,7 @@ public class DocManagerImpl implements DocManager {
public void load() {
try {
Map<String, List<ServiceInfoVO>> listMap = this.getAllServiceList();
log.info("服务列表:{}", JSON.toJSONString(listMap.keySet()));
// {"STORY-SERVICE":[{"ipAddr":"10.1.30.54","name":"STORY-SERVICE","serverPort":"2222"}],"API-GATEWAY":[{"ipAddr":"10.1.30.54","name":"API-GATEWAY","serverPort":"8081"}]}
for (Map.Entry<String, List<ServiceInfoVO>> entry : listMap.entrySet()) {
ServiceInfoVO serviceInfoVo = entry.getValue().get(0);
@ -79,10 +81,16 @@ public class DocManagerImpl implements DocManager {
private void loadDocInfo(ServiceInfoVO serviceInfoVo) {
String url = "http://" + serviceInfoVo.getIpAddr() + ":" + serviceInfoVo.getServerPort() + "/v2/api-docs";
try {
ResponseEntity<String> entity = restTemplate.getForEntity(url, String.class);
String docInfoJson = entity.getBody();
DocModule docDefinition = this.parseDocJson(docInfoJson);
docDefinitionMap.put(docDefinition.getModule(), docDefinition);
} catch (RestClientException e) {
// 这里报错可能是因为有些微服务没有配置swagger文档,导致404访问不到
// 这里catch跳过即可
log.warn("读取文档失败, url:{}", url, e);
}
}
private DocModule parseDocJson(String docInfoJson) {

@ -20,4 +20,5 @@ api:
# 测试地址
url-test: http://api-test.yourdomain.com/api
# 正式地址
url-prod: http://api.yourdomain.com/api
url-prod: http://open.yourdomain.com/api
pwd: doc#123

@ -1,3 +1,10 @@
#
# SQL Export
# Created by Querious (201048)
# Created: 2019年4月15日 GMT+8 下午8:09:15
# Encoding: Unicode (UTF-8)
#
CREATE DATABASE IF NOT EXISTS `sop` DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
USE `sop`;
@ -13,6 +20,49 @@ DROP TABLE IF EXISTS `perm_role_permission`;
DROP TABLE IF EXISTS `perm_role`;
DROP TABLE IF EXISTS `perm_isv_role`;
DROP TABLE IF EXISTS `isv_info`;
DROP TABLE IF EXISTS `config_route_limit`;
DROP TABLE IF EXISTS `config_route_base`;
DROP TABLE IF EXISTS `admin_user_info`;
CREATE TABLE `admin_user_info` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(64) NOT NULL DEFAULT '' COMMENT '用户名',
`password` varchar(128) NOT NULL DEFAULT '' COMMENT '密码',
`status` tinyint(3) unsigned NOT NULL DEFAULT '1' COMMENT '状态,1:启用,2:禁用',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_username` (`username`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='后台用户表';
CREATE TABLE `config_route_base` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`route_id` varchar(64) NOT NULL DEFAULT '' COMMENT '路由id',
`status` tinyint(4) NOT NULL DEFAULT '1' COMMENT '状态,1:启用,2:禁用',
`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_routeid` (`route_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='路由配置表';
CREATE TABLE `config_route_limit` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`route_id` varchar(64) NOT NULL COMMENT '路由id',
`service_id` varchar(64) NOT NULL DEFAULT '',
`limit_type` tinyint(4) NOT NULL DEFAULT '1' COMMENT '限流策略,1:漏桶策略,2:令牌桶策略',
`exec_count_per_second` int(11) DEFAULT NULL COMMENT '每秒可处理请求数',
`limit_code` varchar(20) DEFAULT NULL COMMENT '返回的错误码',
`limit_msg` varchar(100) DEFAULT NULL COMMENT '返回的错误信息',
`token_bucket_count` int(11) DEFAULT NULL COMMENT '令牌桶容量',
`limit_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '限流开启状态,1:开启,0关闭',
`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_routeid` (`route_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='路由限流配置';
CREATE TABLE `isv_info` (
@ -26,7 +76,7 @@ CREATE TABLE `isv_info` (
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_app_key` (`app_key`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 COMMENT='isv信息表';
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 COMMENT='isv信息表';
CREATE TABLE `perm_isv_role` (
@ -37,7 +87,7 @@ CREATE TABLE `perm_isv_role` (
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_user_role` (`isv_id`,`role_code`)
) ENGINE=InnoDB AUTO_INCREMENT=34 DEFAULT CHARSET=utf8 COMMENT='isv角色';
) ENGINE=InnoDB AUTO_INCREMENT=37 DEFAULT CHARSET=utf8 COMMENT='isv角色';
CREATE TABLE `perm_role` (
@ -59,21 +109,9 @@ CREATE TABLE `perm_role_permission` (
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_role_perm` (`role_code`,`route_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8 COMMENT='角色权限表';
DROP TABLE IF EXISTS `admin_user_info`;
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8 COMMENT='角色权限表';
CREATE TABLE `admin_user_info` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(64) NOT NULL DEFAULT '' COMMENT '用户名',
`password` varchar(128) NOT NULL DEFAULT '' COMMENT '密码',
`status` tinyint(3) unsigned NOT NULL DEFAULT '1' COMMENT '状态,1:启用,2:禁用',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_username` (`username`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='后台用户表';
SET FOREIGN_KEY_CHECKS = @PREVIOUS_FOREIGN_KEY_CHECKS;
@ -83,15 +121,44 @@ SET @PREVIOUS_FOREIGN_KEY_CHECKS = @@FOREIGN_KEY_CHECKS;
SET FOREIGN_KEY_CHECKS = 0;
LOCK TABLES `admin_user_info` WRITE;
ALTER TABLE `admin_user_info` DISABLE KEYS;
INSERT INTO `admin_user_info` (`id`, `username`, `password`, `status`, `gmt_create`, `gmt_modified`) VALUES
(1,'admin','14e1b600b1fd579f47433b88e8d85291',1,'2019-04-02 19:55:26','2019-04-02 19:55:26');
ALTER TABLE `admin_user_info` ENABLE KEYS;
UNLOCK TABLES;
LOCK TABLES `config_route_base` WRITE;
ALTER TABLE `config_route_base` DISABLE KEYS;
INSERT INTO `config_route_base` (`id`, `route_id`, `status`, `gmt_create`, `gmt_modified`) VALUES
(1,'story.get1.1',1,'2019-04-09 19:15:58','2019-04-09 19:16:54'),
(2,'alipay.story.get1.0',1,'2019-04-09 19:19:57','2019-04-11 09:35:26'),
(3,'alipay.story.find1.0',1,'2019-04-11 09:29:55','2019-04-11 09:35:02');
ALTER TABLE `config_route_base` ENABLE KEYS;
UNLOCK TABLES;
LOCK TABLES `config_route_limit` WRITE;
ALTER TABLE `config_route_limit` DISABLE KEYS;
INSERT INTO `config_route_limit` (`id`, `route_id`, `service_id`, `limit_type`, `exec_count_per_second`, `limit_code`, `limit_msg`, `token_bucket_count`, `limit_status`, `gmt_create`, `gmt_modified`) VALUES
(1,'alipay.story.find1.0','story-service',1,10,'isp.service-busy','服务器正忙',NULL,1,'2019-04-10 20:55:08','2019-04-10 21:04:35'),
(2,'alipay.story.get1.0','story-service',2,5,'isp.service-busy','服务器正忙',5,0,'2019-04-10 21:05:51','2019-04-11 18:18:03'),
(3,'alipay.story.get1.2','story-service',2,10,'isp.service-busy','服务器正忙',3,1,'2019-04-11 17:26:04','2019-04-11 18:19:33');
ALTER TABLE `config_route_limit` ENABLE KEYS;
UNLOCK TABLES;
LOCK TABLES `isv_info` WRITE;
ALTER TABLE `isv_info` DISABLE KEYS;
INSERT INTO `isv_info` (`id`, `app_key`, `secret`, `pub_key`, `pri_key`, `status`, `gmt_create`, `gmt_modified`) VALUES
(1,'2019032617262200001','','MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlyb9aUBaljQP/vjmBFe1mF8HsWSvyfC2NTlpT/V9E+sBxTr8TSkbzJCeeeOEm4LCaVXL0Qz63MZoT24v7AIXTuMdj4jyiM/WJ4tjrWAgnmohNOegfntTto16C3l234vXz4ryWZMR/7W+MXy5B92wPGQEJ0LKFwNEoLspDEWZ7RdE53VH7w6y6sIZUfK+YkXWSwehfKPKlx+lDw3zRJ3/yvMF+U+BAdW/MfECe1GuBnCFKnlMRh3UKczWyXWkL6ItOpYHHJi/jx85op5BWDje2pY9QowzfN94+0DB3T7UvZeweu3zlP6diwAJDzLaFQX8ULfWhY+wfKxIRgs9NoiSAQIDAQAB','MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCXJv1pQFqWNA/++OYEV7WYXwexZK/J8LY1OWlP9X0T6wHFOvxNKRvMkJ5544SbgsJpVcvRDPrcxmhPbi/sAhdO4x2PiPKIz9Yni2OtYCCeaiE056B+e1O2jXoLeXbfi9fPivJZkxH/tb4xfLkH3bA8ZAQnQsoXA0SguykMRZntF0TndUfvDrLqwhlR8r5iRdZLB6F8o8qXH6UPDfNEnf/K8wX5T4EB1b8x8QJ7Ua4GcIUqeUxGHdQpzNbJdaQvoi06lgccmL+PHzminkFYON7alj1CjDN833j7QMHdPtS9l7B67fOU/p2LAAkPMtoVBfxQt9aFj7B8rEhGCz02iJIBAgMBAAECggEARqOuIpY0v6WtJBfmR3lGIOOokLrhfJrGTLF8CiZMQha+SRJ7/wOLPlsH9SbjPlopyViTXCuYwbzn2tdABigkBHYXxpDV6CJZjzmRZ+FY3S/0POlTFElGojYUJ3CooWiVfyUMhdg5vSuOq0oCny53woFrf32zPHYGiKdvU5Djku1onbDU0Lw8w+5tguuEZ76kZ/lUcccGy5978FFmYpzY/65RHCpvLiLqYyWTtaNT1aQ/9pw4jX9HO9NfdJ9gYFK8r/2f36ZE4hxluAfeOXQfRC/WhPmiw/ReUhxPznG/WgKaa/OaRtAx3inbQ+JuCND7uuKeRe4osP2jLPHPP6AUwQKBgQDUNu3BkLoKaimjGOjCTAwtp71g1oo+k5/uEInAo7lyEwpV0EuUMwLA/HCqUgR4K9pyYV+Oyb8d6f0+Hz0BMD92I2pqlXrD7xV2WzDvyXM3s63NvorRooKcyfd9i6ccMjAyTR2qfLkxv0hlbBbsPHz4BbU63xhTJp3Ghi0/ey/1HQKBgQC2VsgqC6ykfSidZUNLmQZe3J0p/Qf9VLkfrQ+xaHapOs6AzDU2H2osuysqXTLJHsGfrwVaTs00ER2z8ljTJPBUtNtOLrwNRlvgdnzyVAKHfOgDBGwJgiwpeE9voB1oAV/mXqSaUWNnuwlOIhvQEBwekqNyWvhLqC7nCAIhj3yvNQKBgQCqYbeec56LAhWP903Zwcj9VvG7sESqXUhIkUqoOkuIBTWFFIm54QLTA1tJxDQGb98heoCIWf5x/A3xNI98RsqNBX5JON6qNWjb7/dobitti3t99v/ptDp9u8JTMC7penoryLKK0Ty3bkan95Kn9SC42YxaSghzqkt+uvfVQgiNGQKBgGxU6P2aDAt6VNwWosHSe+d2WWXt8IZBhO9d6dn0f7ORvcjmCqNKTNGgrkewMZEuVcliueJquR47IROdY8qmwqcBAN7Vg2K7r7CPlTKAWTRYMJxCT1Hi5gwJb+CZF3+IeYqsJk2NF2s0w5WJTE70k1BSvQsfIzAIDz2yE1oPHvwVAoGAA6e+xQkVH4fMEph55RJIZ5goI4Y76BSvt2N5OKZKd4HtaV+eIhM3SDsVYRLIm9ZquJHMiZQGyUGnsvrKL6AAVNK7eQZCRDk9KQz+0GKOGqku0nOZjUbAu6A2/vtXAaAuFSFx1rUQVVjFulLexkXR3KcztL1Qu2k5pB6Si0K/uwQ=',1,'2019-03-27 10:10:34','2019-04-01 20:54:01'),
(3,'asdfasdf','222','333','4444',1,'2019-03-27 11:01:11','2019-04-01 16:23:06'),
(3,'asdfasdf','','333','4444',2,'2019-03-27 11:01:11','2019-04-14 23:30:17'),
(5,'20190331562013861008375808','29864b93427447f5ac6c44df746f84ef','MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4aMIx2q8rCVu5z6dgNQQSX2vwhvIcRb7FaqSk0ZK8AV9qQeE1TvfFVlAzOHlysE1yTRb0Mb6W2aw7IAS7Bkc3onYBQR4zNQYjYoDBzLukjF8o84hoVFRnh7sV8zszid2vb5H/YQr3M+5sYhlXY8KfILk3vhdbWpHM/umplcrxlwIDAQAB','MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALhowjHarysJW7nPp2A1BBJfa/CG8hxFvsVqpKTRkrwBX2pB4TVO98VWUDM4eXKwTXJNFvQxvpbZrDsgBLsGRzeidgFBHjM1BiNigMHMu6SMXyjziGhUVGeHuxXzOzOJ3a9vkf9hCvcz7mxiGVdjwp8guTe+F1takcz+6amVyvGXAgMBAAECgYBj40LFVGoryp7n0CYeg7kX5p4GJGKCk/jY4IIcUPTFZ4zydorxoDuvpag9hmqqh/r7XeyAC23sMi4LvLUzRRxPh+7PuwL6nLce7vytsMCZQTPpBgz7dUfbi2HAxsuMOLjH3sVGycutARJsz6bT+9PyBEuVtUqwBrDGpFvwT0z6yQJBAOANC8nysb+O4rn/fbJtHIhtQoV74yu00mLnfwv8/J1+WyAEc32WZ4KYINqCe8ft1UknhPQx9UV6JaPCnlpF6w0CQQDStJhd38uQ7dVUQZHGP24xS/K38AYiSheEr7uewhkJfC2cKqE/lBk3oEG4s7asjhwlFLWLWSBLVM/Ta9Yj0hYzAkBe82hxl1bY9bcEWFBu02rqLlOouk4V8bXPkIf5DqgIHsqDkR9Ys+r+H3ac4/uNSS/ApuzjiGCHpzJYalwtqb/pAkEAvAKlSm5dCC8QAaSYXJtQyfAI3hPwhTwzjBP6iAiNqqcBU62+QCr37Wiz/Alv4LzVZEj8TSDz7gP5hZ9dbo0RfQJBALJ7NhTaeMN4jxBJ6Xg4rNZPb4yhAXuFxCp+a+FyXTsbWnW/ar8KJ3LHox0GOao6wne4qN3h7eqLOrYnnvOSFl0=',1,'2019-03-31 20:34:12','2019-03-31 22:07:50'),
(6,'20190331562037310372184064','d6b2a6603236491f87eed958292be136','MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCcZTAaR5K7mk1epfLwK6XRrBiakiwIJK3wtUd8EzpcAnS7Yr8uq5U4yJKZQqu5BtFiWmTFFmAm4aBQKXH1u+6kfcRduYZDLC0cfBPA7IfLnumdrR8uiCgQgGSF71Q4NhebrOqzTAftxZ1vYMCDay1DY2BQxEiGICoCQ0abtvrfNQIDAQAB','MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBAJxlMBpHkruaTV6l8vArpdGsGJqSLAgkrfC1R3wTOlwCdLtivy6rlTjIkplCq7kG0WJaZMUWYCbhoFApcfW77qR9xF25hkMsLRx8E8Dsh8ue6Z2tHy6IKBCAZIXvVDg2F5us6rNMB+3FnW9gwINrLUNjYFDESIYgKgJDRpu2+t81AgMBAAECgYEAiu/FzQLakvkgVL4eVUihVeSKMv86SL21HMsex1YZmVXBOBsgdqiNt1VQDwFQpt4sszBUp1Yac1Ar6Cr5h3G+LVS17n517MjVeEihrmxK6VL1bUoC9Mpj4ZwuLQ0jeFYVBWEhESV/O59O8YRvk0YpIzUUaLj0+qEQBsPKLPSp8MECQQDY3A9Z+i19fPpd5hBl5x7cyzx9KeX2aru0kUMMmm3JeL1dSPSUuqmnTFdtveQrIUab9OYdJgxLtKoh3J8YqDqFAkEAuJ9jn1VNCIpXF8xsI4w1U5QFdXKnGGZ8PePHqWG1B8A9afj2o7T6gDW/xzX/k8g/2belAR3y4nXGo0EikMso8QJBANXWqYygFZtYUcmlwyW48cXm4o7Jcem69bzoQKV84iV42cHS3tqJ9iDyNoQQa53cAjRnGUJE8nr0e49IbdlyicECQQCz8vdhJ/1ro5t8IM4OX+ziR9aCQXxItivHDytfF1Mh+OhjUDzmF9JKARmqDCHOY1KI3QzBZ/WDcZRpL2WHh92hAkEAyetUnYn1F5zVJWxo+yC9PH6WYssZahNy22GdBcZblmDc/YQWw+sa9d55/5aMoYWn6AVO9Tb2gsMW2W0jM2/zCw==',2,'2019-03-31 22:07:20','2019-03-31 22:07:26'),
(7,'20190401562373672858288128','','MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCOgSo6GfwM8a+rUT4m61nZa7q5cJpjL7luxQKuJvkMl/QydVrzRPinCh6zqgBJDa7YY2X6z5TyTkjYuDkYMrdyHcYvCDuJ0NpRPZMR+QDE70yp9wJ+kOqTa8bepJtxzuCYLxFz+wRsIFt0nIxC6ttCaM9OEw/Bflhws3xczw4uqQIDAQAB','MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAI6BKjoZ/Azxr6tRPibrWdlrurlwmmMvuW7FAq4m+QyX9DJ1WvNE+KcKHrOqAEkNrthjZfrPlPJOSNi4ORgyt3Idxi8IO4nQ2lE9kxH5AMTvTKn3An6Q6pNrxt6km3HO4JgvEXP7BGwgW3ScjELq20Joz04TD8F+WHCzfFzPDi6pAgMBAAECgYA/zuQ6ieILZbjUDBe5U46yxQMh/6KRoQ/14m81zauckPm+EkA8R3jTSru+lPN1wpO0vqUuLf6ylI0XxT2DcUokOgY07ZdE54pu5XAsyY0eanFwt6C1LrHYpORV3Mp9XuI3fXrxYqVlxLuj1N7MGinXUuW7aZCHaEuSnZ55OL9dkQJBANKOeFiYDISSuIFHSrndSgr+a8E44jS/2/7lE49p5l3WVOFTHh0IZQNTs/IKsKJkUnYDE4W/Ab7NTnWZpXYeM30CQQCtQrtxPEzLl4dtupPOBJJoApj2lq7Q6tIGx178K6wS9Rz3GEvkA7fz1Tpm+nmPZflWZ9mVmEaVuMTMpl3HN/edAkBylyzx8lYltIALg5QskT1hvFNChkW9tYjyMROzIkxIV4Q8WPLzlAT9iYlOOfkld/nU1hnC2VAG2k9P+z2sigU1AkBAl1AptsEqZSMn1RalBy9NdypvQ12IpQIHZOwUNnO/3YEe3P/t0TUSwbs0CMyomOuLOsvy6QHnbypu4Na1HjhBAkAWjtdhuvU15HAa5jMgiUVfQM3YFuz2k3QkRagtZZ33bqnYs4wNxEZqB5t+vEj+8r3fmSN0BpNR1VW71j53Ir0H',1,'2019-04-01 20:24:01','2019-04-01 20:27:33'),
(8,'20190401562373796095328256','','MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCbxn0En2cj29t8i+m1dT7seF9XQx3cEaoClXFTlmc78Y1ZuQFbyY99VSwv8JbtpGxPvBSVD9SPmXWNBRBbSHT+gxStcdXD9QeD3knGFy/1V+z3E2Rj/6LIlFmgTlGh1fmEgttPjsUW1Dj704/ydyIrw+CAyAMKQyrFg0wYmNW+UQIDAQAB','MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJvGfQSfZyPb23yL6bV1Pux4X1dDHdwRqgKVcVOWZzvxjVm5AVvJj31VLC/wlu2kbE+8FJUP1I+ZdY0FEFtIdP6DFK1x1cP1B4PeScYXL/VX7PcTZGP/osiUWaBOUaHV+YSC20+OxRbUOPvTj/J3IivD4IDIAwpDKsWDTBiY1b5RAgMBAAECgYAE27/ycPZKjATgcYyseCeqQGbY1eMMhhCDXB3YuYwmtnXuInMEZdjv08Q5CovqhYJLSlZp/8BlaifcahgEgNIFQXmxAF0U0HsNC6W4Dk1gGgQaVmYaZv5ex7uIcFB1qFvlO60kWf82YeRnO5KsFBODOJ1XSNwqjL2GeLSHBSVyQQJBAOsvDmClBsETSdiNSFMz+D9WCnCh1Ip4AoCzA/yG+PRSwYjZDdceP2DXieiZXPlxTFZ7MIXxAafgeyeQA2hpkQUCQQCpkCUSbrZ+nd4BYdnxZOSf0//cUT0o6+3kROX7gsXV7zRAWWxojT6DkGVlduDLZM/hjWeHRjWUxKC/jgbzvundAkBckhUSrWJPNQxoFJRXS6l3JKLPWqOSLVKu3ce/6lCrurc66lSsS9eegrhhuZwDAzmNAMhEsGx6a72OAP2WZ5cRAkBd8cT4X2qw4BpePa6YdcPNYZHCqSfvgje9XwbkwGGH1A3pESJlEsxt7BShkKmfRu1+E/AmHJoXIJHHT5M+fKnpAkA+VfyAAviKeCwUSq+5oUa0B+ozEA3frp/40cKQP7k02aamocAQCDRaC1ZlWffeQqYMnYe1/Mjr/SdX/Ut3X0CC',1,'2019-04-01 20:24:25','2019-04-01 20:24:48');
(8,'20190401562373796095328256','','MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCbxn0En2cj29t8i+m1dT7seF9XQx3cEaoClXFTlmc78Y1ZuQFbyY99VSwv8JbtpGxPvBSVD9SPmXWNBRBbSHT+gxStcdXD9QeD3knGFy/1V+z3E2Rj/6LIlFmgTlGh1fmEgttPjsUW1Dj704/ydyIrw+CAyAMKQyrFg0wYmNW+UQIDAQAB','MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJvGfQSfZyPb23yL6bV1Pux4X1dDHdwRqgKVcVOWZzvxjVm5AVvJj31VLC/wlu2kbE+8FJUP1I+ZdY0FEFtIdP6DFK1x1cP1B4PeScYXL/VX7PcTZGP/osiUWaBOUaHV+YSC20+OxRbUOPvTj/J3IivD4IDIAwpDKsWDTBiY1b5RAgMBAAECgYAE27/ycPZKjATgcYyseCeqQGbY1eMMhhCDXB3YuYwmtnXuInMEZdjv08Q5CovqhYJLSlZp/8BlaifcahgEgNIFQXmxAF0U0HsNC6W4Dk1gGgQaVmYaZv5ex7uIcFB1qFvlO60kWf82YeRnO5KsFBODOJ1XSNwqjL2GeLSHBSVyQQJBAOsvDmClBsETSdiNSFMz+D9WCnCh1Ip4AoCzA/yG+PRSwYjZDdceP2DXieiZXPlxTFZ7MIXxAafgeyeQA2hpkQUCQQCpkCUSbrZ+nd4BYdnxZOSf0//cUT0o6+3kROX7gsXV7zRAWWxojT6DkGVlduDLZM/hjWeHRjWUxKC/jgbzvundAkBckhUSrWJPNQxoFJRXS6l3JKLPWqOSLVKu3ce/6lCrurc66lSsS9eegrhhuZwDAzmNAMhEsGx6a72OAP2WZ5cRAkBd8cT4X2qw4BpePa6YdcPNYZHCqSfvgje9XwbkwGGH1A3pESJlEsxt7BShkKmfRu1+E/AmHJoXIJHHT5M+fKnpAkA+VfyAAviKeCwUSq+5oUa0B+ozEA3frp/40cKQP7k02aamocAQCDRaC1ZlWffeQqYMnYe1/Mjr/SdX/Ut3X0CC',1,'2019-04-01 20:24:25','2019-04-01 20:24:48'),
(9,'201904035630907729292csharp','','MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5+OvJxeSzf44NxQ/cl7Ii+BzPg2k6sRcvH4ffOtU5Dzq1/oEvg02nxIhmwOHBZmjbmuUu0aLsfglUTAwqfXftfAKZidshsgj9NNh0/kxk0avRZ1UoljWGz/FxVZA0ogbxxhohPZ9jWcD+eBQcIwF2DtHfAJqWWZrYFnCMeHD8mPzxo2kwXSvDzi0vf9I2tKiYvNG26a9FqeYtPOoi81sdS3+70HOMdxP8ejXtyfnKpKz7Dx506LCIRS5moWS3Q5eTLV3NGX/1CSJ8wpQA2DAQTjVhX5eVu7Yqz12t8W+sjWM/tHUR6cgwYYR10p7tSCeCPzkigjGxKm4cYXWtATQJQIDAQAB','MIIEowIBAAKCAQEA5+OvJxeSzf44NxQ/cl7Ii+BzPg2k6sRcvH4ffOtU5Dzq1/oEvg02nxIhmwOHBZmjbmuUu0aLsfglUTAwqfXftfAKZidshsgj9NNh0/kxk0avRZ1UoljWGz/FxVZA0ogbxxhohPZ9jWcD+eBQcIwF2DtHfAJqWWZrYFnCMeHD8mPzxo2kwXSvDzi0vf9I2tKiYvNG26a9FqeYtPOoi81sdS3+70HOMdxP8ejXtyfnKpKz7Dx506LCIRS5moWS3Q5eTLV3NGX/1CSJ8wpQA2DAQTjVhX5eVu7Yqz12t8W+sjWM/tHUR6cgwYYR10p7tSCeCPzkigjGxKm4cYXWtATQJQIDAQABAoIBAHFDsgrrJca+NKEan77ycwx3jnKx4WrWjOF4zVKL9AQjiSYDNgvKknJyPb3kpC/lEoHdxGERHSzJoxib7DkoIqRQYhPxj73pxj5QfYk3P7LLJNNg/LTrpXDb3nL8JV9wIflGf87qQvstZTDJEyFWE4jBs7Hr0BxovWvri8InnzkmERJ1cbGJgNHe1Y3Zo2tw0yaHxQCxLuajP+notRZhD9bEp7uKeI0w9AvlW6k8m/7y10F0BK/TlyW8rQiEC391yOiRYoMcUh4hd2Q9bMx3jngZgX8PXIvZZcup4/pvWlv1alwhB2tsnLdazP62r1MO80vLyLunzGO+7WwCjEYlVaECgYEA+lQRFmbhKaPuAuXMtY31Fbga8nedka5TjnEV7+/kX+yowE2OlNujF+ZG8UTddTxAGv56yVNi/mjRlgD74j8z0eOsgvOq9mwbCrgLhLo51H9O/wAxtb+hBKtC5l50pBr4gER6d8W6EQNTSGojnMIaLXTkAZ5Qf6Z8e2HFVdOn0X0CgYEA7SSrTokwzukt5KldNu5ukyyd+C3D1i6orbg6qD73EP9CfNMfGSBn7dDv9wMSJH01+Ty+RgTROgtjGRDbMJWnfbdt/61NePr9ar5sb6Nbsf7/I0w7cZF5dsaFYgzaOfQYquzXPbLQHkpMT64bqpv/Mwy4F2lFvaYWY5fA4pC2uckCgYEAg75Ym9ybJaoTqky8ttQ2Jy8UZ4VSVQhVC0My02sCWwWXLlXi8y7An+Rec73Ve0yxREOn5WrQT6pkmzh7V/ABWrYi5WxODpCIjtSbo0fLBa3Wqle00b0/hdCITetqIa/cFs1zUrOqICgK3bKWeXqiAkhhcwSZwwSgwOKM04Wn7ZUCgYBvhHX2mbdVJfyJ8kc+hMOE/E9RHRxiBVEXWHJlGi8PVCqNDq8qHr4g7Mdbzprig+s0yKblwHAvrpkseWvKHiZEjVTyDipHgShY4TGXEigVvUd37uppTrLi8xpYcJjS9gH/px7VCdiq1d+q/MJP6coJ1KphgATm2UrgDMYNBWaYWQKBgEHRxrmER7btUF60/YgcqPHFc8RpYQB2ZZE0kyKGDqk2Data1XYUY6vsPAU28yRLAaWr/D2H17iyLkxP80VLm6QhifxCadv90Q/Wl1DFfOJQMW6avyQ0so6G0wFq/LJxaFK4iLXQn1RJnmTp6BYiJMmK2BhFbRzw8ssMoF6ad2rr',1,'2019-04-03 19:54:05','2019-04-03 20:11:58');
ALTER TABLE `isv_info` ENABLE KEYS;
UNLOCK TABLES;
@ -103,7 +170,8 @@ INSERT INTO `perm_isv_role` (`id`, `isv_id`, `role_code`, `gmt_create`, `gmt_mod
(17,6,'vip','2019-03-31 22:07:26','2019-03-31 22:07:26'),
(18,5,'normal','2019-03-31 22:07:50','2019-03-31 22:07:50'),
(32,7,'normal','2019-04-01 20:27:33','2019-04-01 20:27:33'),
(33,1,'normal','2019-04-01 20:54:01','2019-04-01 20:54:01');
(33,1,'normal','2019-04-01 20:54:01','2019-04-01 20:54:01'),
(36,9,'normal','2019-04-03 20:11:58','2019-04-03 20:11:58');
ALTER TABLE `perm_isv_role` ENABLE KEYS;
UNLOCK TABLES;
@ -120,16 +188,11 @@ UNLOCK TABLES;
LOCK TABLES `perm_role_permission` WRITE;
ALTER TABLE `perm_role_permission` DISABLE KEYS;
INSERT INTO `perm_role_permission` (`id`, `role_code`, `route_id`, `gmt_create`, `gmt_modified`) VALUES
(10,'normal','permission.story.get1.0','2019-04-01 20:54:44','2019-04-01 20:54:44');
(11,'normal','permission.story.get1.0','2019-04-03 10:09:35','2019-04-03 10:09:35');
ALTER TABLE `perm_role_permission` ENABLE KEYS;
UNLOCK TABLES;
LOCK TABLES `admin_user_info` WRITE;
ALTER TABLE `admin_user_info` DISABLE KEYS;
INSERT INTO `admin_user_info` (`id`, `username`, `password`, `status`, `gmt_create`, `gmt_modified`) VALUES
(1,'admin','14e1b600b1fd579f47433b88e8d85291',1,'2019-04-02 19:55:26','2019-04-02 19:55:26');
ALTER TABLE `admin_user_info` ENABLE KEYS;
UNLOCK TABLES;
SET FOREIGN_KEY_CHECKS = @PREVIOUS_FOREIGN_KEY_CHECKS;

Loading…
Cancel
Save