parent
e28fd3b2ec
commit
2f2b52a5dd
@ -1,18 +1,20 @@ |
|||||||
* [首页](/?t=1554693919573) |
* [首页](/?t=1555326144824) |
||||||
* 开发文档 |
* 开发文档 |
||||||
* [快速体验](files/10010_快速体验.md?t=1554693919573) |
* [快速体验](files/10010_快速体验.md?t=1555326144827) |
||||||
* [项目接入到SOP](files/10011_项目接入到SOP.md?t=1554693919596) |
* [项目接入到SOP](files/10011_项目接入到SOP.md?t=1555326144859) |
||||||
* [新增接口](files/10020_新增接口.md?t=1554693919596) |
* [新增接口](files/10020_新增接口.md?t=1555326144859) |
||||||
* [业务参数校验](files/10030_业务参数校验.md?t=1554693919596) |
* [业务参数校验](files/10030_业务参数校验.md?t=1555326144859) |
||||||
* [错误处理](files/10040_错误处理.md?t=1554693919596) |
* [错误处理](files/10040_错误处理.md?t=1555326144859) |
||||||
* [接口交互详解](files/10050_接口交互详解.md?t=1554693919596) |
* [编写文档](files/10041_编写文档.md?t=1555326144859) |
||||||
* [使用SpringCloudGateway](files/10060_使用SpringCloudGateway.md?t=1554693919596) |
* [接口交互详解](files/10050_接口交互详解.md?t=1555326144859) |
||||||
* [easyopen支持](files/10070_easyopen支持.md?t=1554693919596) |
* [easyopen支持](files/10070_easyopen支持.md?t=1555326144860) |
||||||
* [使用签名校验工具](files/10080_使用签名校验工具.md?t=1554693919596) |
* [使用签名校验工具](files/10080_使用签名校验工具.md?t=1555326144860) |
||||||
* [ISV管理](files/10085_ISV管理.md?t=1554693919596) |
* [ISV管理](files/10085_ISV管理.md?t=1555326144860) |
||||||
* [路由授权](files/10090_路由授权.md?t=1554693919596) |
* [路由授权](files/10090_路由授权.md?t=1555326144860) |
||||||
* [SDK开发](files/10095_SDK开发.md?t=1554693919597) |
* [SDK开发](files/10095_SDK开发.md?t=1555326144860) |
||||||
|
* [使用SpringCloudGateway](files/10096_使用SpringCloudGateway.md?t=1555326144860) |
||||||
* 原理分析 |
* 原理分析 |
||||||
* [原理分析之@ApiMapping](files/90010_原理分析之@ApiMapping.md?t=1554693919597) |
* [原理分析之@ApiMapping](files/90010_原理分析之@ApiMapping.md?t=1555326144861) |
||||||
* [原理分析之路由存储](files/90011_原理分析之路由存储.md?t=1554693919597) |
* [原理分析之路由存储](files/90011_原理分析之路由存储.md?t=1555326144861) |
||||||
* [原理分析之如何路由](files/90012_原理分析之如何路由.md?t=1554693919597) |
* [原理分析之如何路由](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来处理。 |
||||||
|
|
||||||
|
|
After Width: | Height: | Size: 206 KiB |
After Width: | Height: | Size: 101 KiB |
After Width: | Height: | Size: 26 KiB |
@ -1,4 +1,4 @@ |
|||||||
package com.hhdd.book.api.domain; |
package com.gitee.book.api.domain; |
||||||
|
|
||||||
import lombok.Data; |
import lombok.Data; |
||||||
|
|
@ -1,4 +1,4 @@ |
|||||||
package com.hhdd.book.api.service; |
package com.gitee.book.api.service; |
||||||
|
|
||||||
import com.gitee.book.api.domain.Book; |
import com.gitee.book.api.domain.Book; |
||||||
import org.springframework.web.bind.annotation.RequestMapping; |
import org.springframework.web.bind.annotation.RequestMapping; |
@ -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; |
||||||
|
} |
@ -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> </div> |
||||||
|
</td> |
||||||
|
<td rowspan="1" colspan="1"> |
||||||
|
<div> </div> |
||||||
|
</td> |
||||||
|
<td rowspan="1" colspan="1"> |
||||||
|
<div> </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 </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> |
@ -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>将排序后的参数与其对应值,组合成“参数=参数值”的格式,并且把这些参数用&字符连接起来,此时生成的字符串为待签名字符串。</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&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":"最新优惠"}]}&charset=GBK&method=alipay.mobile.public.menu.add&sign_type=RSA2&timestamp=2014-07-24 03:07:50&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> |
Loading…
Reference in new issue