mirror of
https://gitee.com/durcframework/SOP.git
synced 2025-08-11 21:57:56 +08:00
文档结果支持树状结构
This commit is contained in:
@@ -30,6 +30,7 @@ public class AlipayController {
|
|||||||
|
|
||||||
@ApiOperation(value="获取故事信息", notes = "说明接口的详细信息,介绍,用途,注意事项等。")
|
@ApiOperation(value="获取故事信息", notes = "说明接口的详细信息,介绍,用途,注意事项等。")
|
||||||
@ApiMapping(value = "alipay.story.find")
|
@ApiMapping(value = "alipay.story.find")
|
||||||
|
// 参数必须封装在类中
|
||||||
public StoryVO getStory2(StoryParam story) {
|
public StoryVO getStory2(StoryParam story) {
|
||||||
StoryVO storyVO = new StoryVO();
|
StoryVO storyVO = new StoryVO();
|
||||||
storyVO.id = 1L;
|
storyVO.id = 1L;
|
||||||
@@ -43,6 +44,24 @@ public class AlipayController {
|
|||||||
return story;
|
return story;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 演示文档表格树
|
||||||
|
* @param story
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@ApiOperation(value="获取分类信息", notes = "演示表格树")
|
||||||
|
@ApiMapping(value = "alipay.category.get")
|
||||||
|
public Category getCategory(Category story) {
|
||||||
|
StoryVO storyVO = new StoryVO();
|
||||||
|
storyVO.id = 1L;
|
||||||
|
storyVO.name = "白雪公主";
|
||||||
|
storyVO.gmt_create = new Date();
|
||||||
|
Category category = new Category();
|
||||||
|
category.setCategoryName("娱乐");
|
||||||
|
category.setStory(storyVO);
|
||||||
|
return category;
|
||||||
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public static class StoryVO {
|
public static class StoryVO {
|
||||||
@ApiModelProperty(value = "故事ID", example = "1")
|
@ApiModelProperty(value = "故事ID", example = "1")
|
||||||
@@ -52,4 +71,13 @@ public class AlipayController {
|
|||||||
@ApiModelProperty(value = "创建时间", example = "2019-04-14 19:02:12")
|
@ApiModelProperty(value = "创建时间", example = "2019-04-14 19:02:12")
|
||||||
private Date gmt_create;
|
private Date gmt_create;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Category {
|
||||||
|
@ApiModelProperty(value = "分类名称", example = "娱乐")
|
||||||
|
private String categoryName;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "分类故事")
|
||||||
|
private StoryVO story;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
159
sop-website/website-front/assets/lib/layuiext/Form.js
Normal file
159
sop-website/website-front/assets/lib/layuiext/Form.js
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
/**
|
||||||
|
* 表单插件,使用方法:
|
||||||
|
* var myform = layui.Form('formId');
|
||||||
|
* myform.setData({...})
|
||||||
|
*
|
||||||
|
* var data = myform.getData();
|
||||||
|
*
|
||||||
|
* var name = myform.getData('name')
|
||||||
|
*/
|
||||||
|
layui.define(function (exports) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* form = new Form('formId');
|
||||||
|
* @param formId
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var Form = function (formId) {
|
||||||
|
this.$form = $('#' + formId);
|
||||||
|
this.parseForm(this.$form);
|
||||||
|
}
|
||||||
|
|
||||||
|
Form.prototype = {
|
||||||
|
fire: function (eventName, data) {
|
||||||
|
var handler = this['on' + eventName];
|
||||||
|
handler && handler(data);
|
||||||
|
}
|
||||||
|
, opt: function (attr) {
|
||||||
|
return this[attr];
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
, parseForm: function ($form) {
|
||||||
|
var that = this;
|
||||||
|
this.form = $form[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
, getEls: function () {
|
||||||
|
return this.$form.find('input,select,textarea');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同load(data)
|
||||||
|
*/
|
||||||
|
, setData: function (data) {
|
||||||
|
this.loadData(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
, loadData: function (data) {
|
||||||
|
this.reset();
|
||||||
|
for (var name in data) {
|
||||||
|
var val = data[name];
|
||||||
|
var $el = this.$form.find('[name="' + name + '"]');
|
||||||
|
|
||||||
|
$el.each(function () {
|
||||||
|
var _$el = $(this);
|
||||||
|
if (_$el.is(':radio') || _$el.is(':checkbox')) {
|
||||||
|
_$el.prop('checked', false);
|
||||||
|
var elVal = _$el.val();
|
||||||
|
|
||||||
|
if ($.isArray(val)) {
|
||||||
|
for (var i = 0, len = val.length; i < len; i++) {
|
||||||
|
if (elVal == val[i]) {
|
||||||
|
_$el.prop('checked', true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_$el.prop('checked', elVal == val);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
_$el.val(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 清除表单中的值,清除错误信息
|
||||||
|
*/
|
||||||
|
, clear: function () {
|
||||||
|
this.getEls().each(function () {
|
||||||
|
var _$el = $(this);
|
||||||
|
if (_$el.is(':radio') || _$el.is(':checkbox')) {
|
||||||
|
this.checked = false;
|
||||||
|
} else {
|
||||||
|
this.value = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
var msg = _$el.data('msg');
|
||||||
|
if (msg) {
|
||||||
|
msg.text('');
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 重置表单
|
||||||
|
*/
|
||||||
|
, reset: function () {
|
||||||
|
var form = this.form;
|
||||||
|
if (form && form.reset) {
|
||||||
|
form.reset();
|
||||||
|
} else {
|
||||||
|
this.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 获取表单数据,如果有fieldName参数则返回表单对应的值<br>
|
||||||
|
* var id = form.getData('id') 等同于 var id = form.getData().id;
|
||||||
|
* @param {String} fieldName
|
||||||
|
* @return {Object} 返回JSON对象,如果有fieldName参数,则返回对应的值
|
||||||
|
*/
|
||||||
|
, getData: function (fieldName) {
|
||||||
|
var that = this;
|
||||||
|
var data = {};
|
||||||
|
|
||||||
|
this.getEls().each(function () {
|
||||||
|
var value = that._getInputVal($(this));
|
||||||
|
if (value) {
|
||||||
|
var name = this.name;
|
||||||
|
var dataValue = data[name];
|
||||||
|
if (dataValue) {
|
||||||
|
if ($.isArray(dataValue)) {
|
||||||
|
dataValue.push(value);
|
||||||
|
} else {
|
||||||
|
data[name] = [dataValue, value];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
data[name] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (typeof fieldName === 'string') {
|
||||||
|
return data[fieldName];
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
, _getInputVal: function ($input) {
|
||||||
|
if ($input.is(":radio") || $input.is(":checkbox")) {
|
||||||
|
if ($input.is(':checked')) {
|
||||||
|
return $input.val();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return $input.val();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
exports('Form', function (formId) {
|
||||||
|
return new Form(formId);
|
||||||
|
});
|
||||||
|
});
|
@@ -0,0 +1,18 @@
|
|||||||
|
.treeTable-empty {
|
||||||
|
width: 20px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.treeTable-icon {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.treeTable-icon .layui-icon-triangle-d:before {
|
||||||
|
content: "\e623";
|
||||||
|
}
|
||||||
|
|
||||||
|
.treeTable-icon.open .layui-icon-triangle-d:before {
|
||||||
|
content: "\e625";
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
@@ -0,0 +1,216 @@
|
|||||||
|
layui.define(['layer', 'table'], function (exports) {
|
||||||
|
var $ = layui.jquery;
|
||||||
|
var layer = layui.layer;
|
||||||
|
var table = layui.table;
|
||||||
|
|
||||||
|
var treetable = {
|
||||||
|
// 渲染树形表格
|
||||||
|
render: function (param) {
|
||||||
|
// 检查参数
|
||||||
|
if (!treetable.checkParam(param)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 获取数据
|
||||||
|
if (param.data) {
|
||||||
|
treetable.init(param, param.data);
|
||||||
|
} else {
|
||||||
|
// $.getJSON(param.url, param.where, function (res) {
|
||||||
|
// treetable.init(param, res.data);
|
||||||
|
// });
|
||||||
|
$.ajax({
|
||||||
|
url: param.url,
|
||||||
|
type: param.method || 'get',
|
||||||
|
data: param.where,
|
||||||
|
headers: param.headers || {},
|
||||||
|
dataType: "json",
|
||||||
|
success: function (res) {
|
||||||
|
treetable.init(param, res.data);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 渲染表格
|
||||||
|
init: function (param, data) {
|
||||||
|
var mData = [];
|
||||||
|
var doneCallback = param.done;
|
||||||
|
var tNodes = data;
|
||||||
|
// 补上id和pid字段
|
||||||
|
for (var i = 0; i < tNodes.length; i++) {
|
||||||
|
var tt = tNodes[i];
|
||||||
|
if (!tt.id) {
|
||||||
|
if (!param.treeIdName) {
|
||||||
|
layer.msg('参数treeIdName不能为空', {icon: 5});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tt.id = tt[param.treeIdName];
|
||||||
|
}
|
||||||
|
if (!tt.pid) {
|
||||||
|
if (!param.treePidName) {
|
||||||
|
layer.msg('参数treePidName不能为空', {icon: 5});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tt.pid = tt[param.treePidName];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 对数据进行排序
|
||||||
|
var sort = function (s_pid, data) {
|
||||||
|
for (var i = 0; i < data.length; i++) {
|
||||||
|
if (data[i].pid == s_pid) {
|
||||||
|
var len = mData.length;
|
||||||
|
if (len > 0 && mData[len - 1].id == s_pid) {
|
||||||
|
mData[len - 1].isParent = true;
|
||||||
|
}
|
||||||
|
mData.push(data[i]);
|
||||||
|
sort(data[i].id, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
sort(param.treeSpid, tNodes);
|
||||||
|
|
||||||
|
// 重写参数
|
||||||
|
param.url = undefined;
|
||||||
|
param.data = mData;
|
||||||
|
param.page = {
|
||||||
|
count: param.data.length,
|
||||||
|
limit: param.data.length
|
||||||
|
};
|
||||||
|
param.cols[0][param.treeColIndex].templet = function (d) {
|
||||||
|
var mId = d.id;
|
||||||
|
var mPid = d.pid;
|
||||||
|
var isDir = d.isParent;
|
||||||
|
var emptyNum = treetable.getEmptyNum(mPid, mData);
|
||||||
|
var iconHtml = '';
|
||||||
|
for (var i = 0; i < emptyNum; i++) {
|
||||||
|
iconHtml += '<span class="treeTable-empty"></span>';
|
||||||
|
}
|
||||||
|
if (isDir) {
|
||||||
|
iconHtml += '<i class="layui-icon layui-icon-triangle-d"></i> <i class="layui-icon layui-icon-layer"></i>';
|
||||||
|
} else {
|
||||||
|
iconHtml += '<i class="layui-icon layui-icon-file"></i>';
|
||||||
|
}
|
||||||
|
iconHtml += ' ';
|
||||||
|
var ttype = isDir ? 'dir' : 'file';
|
||||||
|
var vg = '<span class="treeTable-icon open" lay-tid="' + mId + '" lay-tpid="' + mPid + '" lay-ttype="' + ttype + '">';
|
||||||
|
return vg + iconHtml + d[param.cols[0][param.treeColIndex].field] + '</span>'
|
||||||
|
};
|
||||||
|
|
||||||
|
param.done = function (res, curr, count) {
|
||||||
|
$(param.elem).next().addClass('treeTable');
|
||||||
|
$('.treeTable .layui-table-page').css('display', 'none');
|
||||||
|
$(param.elem).next().attr('treeLinkage', param.treeLinkage);
|
||||||
|
// 绑定事件换成对body绑定
|
||||||
|
/*$('.treeTable .treeTable-icon').click(function () {
|
||||||
|
treetable.toggleRows($(this), param.treeLinkage);
|
||||||
|
});*/
|
||||||
|
if (param.treeDefaultClose) {
|
||||||
|
treetable.foldAll(param.elem);
|
||||||
|
}
|
||||||
|
if (doneCallback) {
|
||||||
|
doneCallback(res, curr, count);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 渲染表格
|
||||||
|
table.render(param);
|
||||||
|
},
|
||||||
|
// 计算缩进的数量
|
||||||
|
getEmptyNum: function (pid, data) {
|
||||||
|
var num = 0;
|
||||||
|
if (!pid) {
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
var tPid;
|
||||||
|
for (var i = 0; i < data.length; i++) {
|
||||||
|
if (pid == data[i].id) {
|
||||||
|
num += 1;
|
||||||
|
tPid = data[i].pid;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return num + treetable.getEmptyNum(tPid, data);
|
||||||
|
},
|
||||||
|
// 展开/折叠行
|
||||||
|
toggleRows: function ($dom, linkage) {
|
||||||
|
var type = $dom.attr('lay-ttype');
|
||||||
|
if ('file' == type) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var mId = $dom.attr('lay-tid');
|
||||||
|
var isOpen = $dom.hasClass('open');
|
||||||
|
if (isOpen) {
|
||||||
|
$dom.removeClass('open');
|
||||||
|
} else {
|
||||||
|
$dom.addClass('open');
|
||||||
|
}
|
||||||
|
$dom.closest('tbody').find('tr').each(function () {
|
||||||
|
var $ti = $(this).find('.treeTable-icon');
|
||||||
|
var pid = $ti.attr('lay-tpid');
|
||||||
|
var ttype = $ti.attr('lay-ttype');
|
||||||
|
var tOpen = $ti.hasClass('open');
|
||||||
|
if (mId == pid) {
|
||||||
|
if (isOpen) {
|
||||||
|
$(this).hide();
|
||||||
|
if ('dir' == ttype && tOpen == isOpen) {
|
||||||
|
$ti.trigger('click');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$(this).show();
|
||||||
|
if (linkage && 'dir' == ttype && tOpen == isOpen) {
|
||||||
|
$ti.trigger('click');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 检查参数
|
||||||
|
checkParam: function (param) {
|
||||||
|
if (!param.treeSpid && param.treeSpid != 0) {
|
||||||
|
layer.msg('参数treeSpid不能为空', {icon: 5});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!param.treeColIndex && param.treeColIndex != 0) {
|
||||||
|
layer.msg('参数treeColIndex不能为空', {icon: 5});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
// 展开所有
|
||||||
|
expandAll: function (dom) {
|
||||||
|
$(dom).next('.treeTable').find('.layui-table-body tbody tr').each(function () {
|
||||||
|
var $ti = $(this).find('.treeTable-icon');
|
||||||
|
var ttype = $ti.attr('lay-ttype');
|
||||||
|
var tOpen = $ti.hasClass('open');
|
||||||
|
if ('dir' == ttype && !tOpen) {
|
||||||
|
$ti.trigger('click');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 折叠所有
|
||||||
|
foldAll: function (dom) {
|
||||||
|
$(dom).next('.treeTable').find('.layui-table-body tbody tr').each(function () {
|
||||||
|
var $ti = $(this).find('.treeTable-icon');
|
||||||
|
var ttype = $ti.attr('lay-ttype');
|
||||||
|
var tOpen = $ti.hasClass('open');
|
||||||
|
if ('dir' == ttype && tOpen) {
|
||||||
|
$ti.trigger('click');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
layui.link(layui.cache.base + 'treetable-lay/treetable.css');
|
||||||
|
|
||||||
|
// 给图标列绑定事件
|
||||||
|
$('body').on('click', '.treeTable .treeTable-icon', function () {
|
||||||
|
var treeLinkage = $(this).parents('.treeTable').attr('treeLinkage');
|
||||||
|
if ('true' == treeLinkage) {
|
||||||
|
treetable.toggleRows($(this), true);
|
||||||
|
} else {
|
||||||
|
treetable.toggleRows($(this), false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
exports('treetable', treetable);
|
||||||
|
});
|
@@ -32,6 +32,22 @@
|
|||||||
.prop-type {
|
.prop-type {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.treeTable-empty{margin-left: 20px;}
|
||||||
|
|
||||||
|
/** 修改文件夹图标:未展开 */
|
||||||
|
.treeTable-icon .layui-icon-layer:before {
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 修改文件夹图标:展开 */
|
||||||
|
.treeTable-icon.open .layui-icon-layer:before {
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
/* 修改文件图标:*/
|
||||||
|
.treeTable-icon .layui-icon-file:before {
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body data-find="_5">
|
<body data-find="_5">
|
||||||
@@ -228,20 +244,7 @@
|
|||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
<div class="site-text">
|
<div class="site-text">
|
||||||
<table class="layui-table">
|
<table id="treeTableReq"></table>
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th class="prop-name">参数</th>
|
|
||||||
<th class="prop-type">类型</th>
|
|
||||||
<th>是否必填</th>
|
|
||||||
<th>最大长度</th>
|
|
||||||
<th class="prop-desc">描述</th>
|
|
||||||
<th class="prop-example">示例值</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody id="requestTbody">
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="site-title">
|
<div class="site-title">
|
||||||
@@ -313,20 +316,7 @@
|
|||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
<div class="site-text">
|
<div class="site-text">
|
||||||
<table class="layui-table">
|
<table id="treeTableResp"></table>
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th class="prop-name">参数</th>
|
|
||||||
<th class="prop-type">类型</th>
|
|
||||||
<th>是否必填</th>
|
|
||||||
<th>最大长度</th>
|
|
||||||
<th class="prop-desc">描述</th>
|
|
||||||
<th class="prop-example">示例值</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody id="responseTbody">
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="site-title">
|
<div class="site-title">
|
||||||
|
@@ -1,5 +1,11 @@
|
|||||||
layui.use(['element', 'form'], function(){ //加载code模块
|
layui.config({
|
||||||
|
base: '../../assets/lib/layuiext/module/'
|
||||||
|
}).extend({
|
||||||
|
treetable: 'treetable-lay/treetable'
|
||||||
|
}).use(['element', 'form', 'treetable'], function(){ //加载code模块
|
||||||
var form = layui.form;
|
var form = layui.form;
|
||||||
|
var treetable = layui.treetable;
|
||||||
|
var $ = layui.jquery;
|
||||||
|
|
||||||
// key:module
|
// key:module
|
||||||
var docItemStore = {};
|
var docItemStore = {};
|
||||||
@@ -85,39 +91,56 @@ layui.use(['element', 'form'], function(){ //加载code模块
|
|||||||
}
|
}
|
||||||
|
|
||||||
function createRequestParameter(docItem) {
|
function createRequestParameter(docItem) {
|
||||||
var html = createParameterBody(docItem.requestParameters);
|
var data = buildTreeData(docItem.requestParameters);
|
||||||
$('#requestTbody').html(html);
|
createTreeTable('treeTableReq', data);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createResponseParameter(docItem) {
|
function createResponseParameter(docItem) {
|
||||||
var html = createParameterBody(docItem.responseParameters);
|
var data = buildTreeData(docItem.responseParameters);
|
||||||
$('#responseTbody').html(html);
|
createTreeTable('treeTableResp', data);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createParameterBody(parameters) {
|
function buildTreeData(parameters, parentId) {
|
||||||
/*
|
var data = [];
|
||||||
<tr>
|
parentId = parentId || 0;
|
||||||
<th class="prop-name">参数</th>
|
|
||||||
<th class="prop-type">类型</th>
|
|
||||||
<th>是否必填</th>
|
|
||||||
<th>最大长度</th>
|
|
||||||
<th class="prop-desc">描述</th>
|
|
||||||
<th class="prop-example">示例值</th>
|
|
||||||
</tr>
|
|
||||||
*/
|
|
||||||
var html = [];
|
|
||||||
for (var i = 0; i < parameters.length; i++) {
|
for (var i = 0; i < parameters.length; i++) {
|
||||||
var parameter = parameters[i];
|
var parameter = parameters[i];
|
||||||
html.push('<tr>\n' +
|
parameter.id = parentId * 100 + (i + 1);
|
||||||
' <th class="prop-name">'+parameter.name+'</th>\n' +
|
parameter.parentId = parentId;
|
||||||
' <th class="prop-type">'+parameter.type+'</th>\n' +
|
data.push(parameter);
|
||||||
' <th>'+(parameter.required ? '<span style="color:red;">是</span>' : '否')+'</th>\n' +
|
var refs = parameter.refs;
|
||||||
' <th>-</th>\n' +
|
if (refs && refs.length > 0) {
|
||||||
' <th class="prop-desc">'+parameter.description+'</th>\n' +
|
var childData = buildTreeData(refs, parameter.id);
|
||||||
' <th class="prop-example">' + (parameter.example || parameter['x-example']) +'</th>\n' +
|
data = data.concat(childData);
|
||||||
'</tr>')
|
|
||||||
}
|
}
|
||||||
return html.join('');
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createTreeTable(id, data) {
|
||||||
|
var el = '#' + id;
|
||||||
|
$(el).text('');
|
||||||
|
treetable.render({
|
||||||
|
elem: el,
|
||||||
|
treeColIndex: 0,
|
||||||
|
treeSpid: 0,
|
||||||
|
treeIdName: 'id',
|
||||||
|
treePidName: 'parentId',
|
||||||
|
treeDefaultClose: false,
|
||||||
|
treeLinkage: false,
|
||||||
|
data: data,
|
||||||
|
page: false,
|
||||||
|
cols: [[
|
||||||
|
{field: 'name', title: '参数'}
|
||||||
|
,{field: 'type', title: '类型', width: 80}
|
||||||
|
,{field: 'required', title: '是否必填', width: 100, templet:function (row) {
|
||||||
|
return row.required ? '<span style="color: red;">是</span>' : '否';
|
||||||
|
}}
|
||||||
|
,{field: 'maxLength', title: '最大长度', width: 100}
|
||||||
|
,{field: 'description', title: '描述', width: 200}
|
||||||
|
,{field: 'paramExample', title: '示例值', width: 200}
|
||||||
|
]]
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function createResponseCode(docItem) {
|
function createResponseCode(docItem) {
|
||||||
|
@@ -2,6 +2,9 @@ package com.gitee.sop.websiteserver.bean;
|
|||||||
|
|
||||||
import com.alibaba.fastjson.annotation.JSONField;
|
import com.alibaba.fastjson.annotation.JSONField;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 参数 类型 是否必填 最大长度 描述 示例值
|
* 参数 类型 是否必填 最大长度 描述 示例值
|
||||||
@@ -9,8 +12,10 @@ import lombok.Data;
|
|||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public class DocParameter {
|
public class DocParameter {
|
||||||
|
private String module;
|
||||||
private String name;
|
private String name;
|
||||||
private String type;
|
private String type;
|
||||||
|
private String maxLength = "-";
|
||||||
private boolean required;
|
private boolean required;
|
||||||
private String description;
|
private String description;
|
||||||
private String example = "";
|
private String example = "";
|
||||||
@@ -18,4 +23,9 @@ public class DocParameter {
|
|||||||
@JSONField(name = "x-example")
|
@JSONField(name = "x-example")
|
||||||
private String x_example = "";
|
private String x_example = "";
|
||||||
|
|
||||||
|
private List<DocParameter> refs;
|
||||||
|
|
||||||
|
public String getParamExample() {
|
||||||
|
return StringUtils.isBlank(example) ? x_example : example;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -7,9 +7,12 @@ import com.gitee.sop.websiteserver.bean.DocItem;
|
|||||||
import com.gitee.sop.websiteserver.bean.DocModule;
|
import com.gitee.sop.websiteserver.bean.DocModule;
|
||||||
import com.gitee.sop.websiteserver.bean.DocParameter;
|
import com.gitee.sop.websiteserver.bean.DocParameter;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@@ -66,9 +69,7 @@ public class SwaggerDocParser implements DocParser {
|
|||||||
docItem.setDescription(docInfo.getString("description"));
|
docItem.setDescription(docInfo.getString("description"));
|
||||||
String moduleName = this.buildModuleName(docInfo, docRoot);
|
String moduleName = this.buildModuleName(docInfo, docRoot);
|
||||||
docItem.setModule(moduleName);
|
docItem.setModule(moduleName);
|
||||||
Optional<JSONArray> parametersOptional = Optional.ofNullable(docInfo.getJSONArray("parameters"));
|
List<DocParameter> docParameterList = this.buildRequestParameterList(docInfo, docRoot);
|
||||||
JSONArray parameters = parametersOptional.orElse(new JSONArray());
|
|
||||||
List<DocParameter> docParameterList = parameters.toJavaList(DocParameter.class);
|
|
||||||
docItem.setRequestParameters(docParameterList);
|
docItem.setRequestParameters(docParameterList);
|
||||||
|
|
||||||
List<DocParameter> responseParameterList = this.buildResponseParameterList(docInfo, docRoot);
|
List<DocParameter> responseParameterList = this.buildResponseParameterList(docInfo, docRoot);
|
||||||
@@ -86,21 +87,86 @@ public class SwaggerDocParser implements DocParser {
|
|||||||
return title;
|
return title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected List<DocParameter> buildRequestParameterList(JSONObject docInfo, JSONObject docRoot) {
|
||||||
|
Optional<JSONArray> parametersOptional = Optional.ofNullable(docInfo.getJSONArray("parameters"));
|
||||||
|
JSONArray parameters = parametersOptional.orElse(new JSONArray());
|
||||||
|
List<DocParameter> docParameterList = new ArrayList<>();
|
||||||
|
for (int i = 0; i < parameters.size(); i++) {
|
||||||
|
JSONObject fieldJson = parameters.getJSONObject(i);
|
||||||
|
DocParameter docParameter = fieldJson.toJavaObject(DocParameter.class);
|
||||||
|
docParameterList.add(docParameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, List<DocParameter>> collect = docParameterList.stream()
|
||||||
|
.filter(docParameter -> docParameter.getName().contains("."))
|
||||||
|
.map(docParameter -> {
|
||||||
|
String name = docParameter.getName();
|
||||||
|
int index = name.indexOf('.');
|
||||||
|
String module = name.substring(0, index);
|
||||||
|
String newName = name.substring(index + 1);
|
||||||
|
DocParameter ret = new DocParameter();
|
||||||
|
BeanUtils.copyProperties(docParameter, ret);
|
||||||
|
ret.setName(newName);
|
||||||
|
ret.setModule(module);
|
||||||
|
return ret;
|
||||||
|
})
|
||||||
|
.collect(Collectors.groupingBy(DocParameter::getModule));
|
||||||
|
|
||||||
|
collect.entrySet().stream()
|
||||||
|
.forEach(entry -> {
|
||||||
|
DocParameter moduleDoc = new DocParameter();
|
||||||
|
moduleDoc.setName(entry.getKey());
|
||||||
|
moduleDoc.setType("object");
|
||||||
|
moduleDoc.setRefs(entry.getValue());
|
||||||
|
docParameterList.add(moduleDoc);
|
||||||
|
});
|
||||||
|
|
||||||
|
List<DocParameter> ret = docParameterList.stream()
|
||||||
|
.filter(docParameter -> !docParameter.getName().contains("."))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
protected List<DocParameter> buildResponseParameterList(JSONObject docInfo, JSONObject docRoot) {
|
protected List<DocParameter> buildResponseParameterList(JSONObject docInfo, JSONObject docRoot) {
|
||||||
String responseRef = getResponseRef(docInfo);
|
String responseRef = getResponseRef(docInfo);
|
||||||
List<DocParameter> respParameterList = new ArrayList<>();
|
List<DocParameter> respParameterList = Collections.emptyList();
|
||||||
if (StringUtils.isNotBlank(responseRef)) {
|
if (StringUtils.isNotBlank(responseRef)) {
|
||||||
JSONObject responseObject = docRoot.getJSONObject("definitions").getJSONObject(responseRef);
|
respParameterList = this.buildDocParameters(responseRef, docRoot);
|
||||||
|
}
|
||||||
|
return respParameterList;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<DocParameter> buildDocParameters(String ref, JSONObject docRoot) {
|
||||||
|
JSONObject responseObject = docRoot.getJSONObject("definitions").getJSONObject(ref);
|
||||||
JSONObject properties = responseObject.getJSONObject("properties");
|
JSONObject properties = responseObject.getJSONObject("properties");
|
||||||
Set<String> fieldNames = properties.keySet();
|
Set<String> fieldNames = properties.keySet();
|
||||||
|
List<DocParameter> docParameterList = new ArrayList<>();
|
||||||
for (String fieldName : fieldNames) {
|
for (String fieldName : fieldNames) {
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
"description": "分类故事",
|
||||||
|
"$ref": "#/definitions/StoryVO",
|
||||||
|
"originalRef": "StoryVO"
|
||||||
|
}
|
||||||
|
*/
|
||||||
JSONObject fieldInfo = properties.getJSONObject(fieldName);
|
JSONObject fieldInfo = properties.getJSONObject(fieldName);
|
||||||
DocParameter respParam = fieldInfo.toJavaObject(DocParameter.class);
|
DocParameter respParam = fieldInfo.toJavaObject(DocParameter.class);
|
||||||
respParam.setName(fieldName);
|
respParam.setName(fieldName);
|
||||||
respParameterList.add(respParam);
|
docParameterList.add(respParam);
|
||||||
|
String originalRef = getRef(fieldInfo);
|
||||||
|
if (StringUtils.isNotBlank(originalRef)) {
|
||||||
|
List<DocParameter> refs = buildDocParameters(originalRef, docRoot);
|
||||||
|
respParam.setRefs(refs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return respParameterList;
|
return docParameterList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getRef(JSONObject fieldInfo) {
|
||||||
|
return Optional.ofNullable(fieldInfo)
|
||||||
|
.map(jsonObject -> jsonObject.getString("originalRef"))
|
||||||
|
.orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getResponseRef(JSONObject docInfo) {
|
protected String getResponseRef(JSONObject docInfo) {
|
||||||
|
Reference in New Issue
Block a user