es文档开发
This commit is contained in:
@@ -4,21 +4,28 @@ import com.zyplayer.doc.core.json.DocResponseJson;
|
||||
import com.zyplayer.doc.core.json.ResponseJson;
|
||||
import com.zyplayer.doc.data.service.elasticsearch.support.ElasticSearchUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.elasticsearch.action.search.SearchRequest;
|
||||
import org.elasticsearch.client.RequestOptions;
|
||||
import org.elasticsearch.client.RestHighLevelClient;
|
||||
import org.elasticsearch.client.indices.GetIndexRequest;
|
||||
import org.elasticsearch.client.indices.GetIndexResponse;
|
||||
import org.elasticsearch.client.indices.GetMappingsRequest;
|
||||
import org.elasticsearch.client.indices.GetMappingsResponse;
|
||||
import org.elasticsearch.cluster.metadata.MappingMetaData;
|
||||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.script.ScriptType;
|
||||
import org.elasticsearch.script.mustache.SearchTemplateRequest;
|
||||
import org.elasticsearch.script.mustache.SearchTemplateResponse;
|
||||
import org.elasticsearch.search.SearchHit;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -57,9 +64,43 @@ public class EsMappingController {
|
||||
return DocResponseJson.warn("获取文档失败");
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
public ResponseJson<Object> list(String keywords) throws IOException {
|
||||
return DocResponseJson.ok();
|
||||
@PostMapping("/execute")
|
||||
public ResponseJson<Object> execute(String index, String sql) throws IOException {
|
||||
SearchTemplateRequest request = new SearchTemplateRequest();
|
||||
request.setRequest(new SearchRequest().indices(index));
|
||||
request.setScriptType(ScriptType.INLINE);
|
||||
request.setScript(sql);
|
||||
request.setScriptParams(new HashMap<>());
|
||||
try {
|
||||
RestHighLevelClient client = elasticSearchUtil.getEsClient("127.0.0.1:9200", "http");
|
||||
SearchTemplateResponse response = client.searchTemplate(request, RequestOptions.DEFAULT);
|
||||
List<Map<String, Object>> resultList = new LinkedList<>();
|
||||
for (SearchHit searchHit : response.getResponse().getHits()) {
|
||||
resultList.add(searchHit.getSourceAsMap());
|
||||
}
|
||||
return DocResponseJson.ok(resultList);
|
||||
} catch (Exception e) {
|
||||
return DocResponseJson.warn(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/index")
|
||||
public ResponseJson<Object> index(String index) throws IOException {
|
||||
GetIndexRequest request = new GetIndexRequest(index);
|
||||
request.setMasterTimeout(TimeValue.timeValueMinutes(1));
|
||||
try {
|
||||
RestHighLevelClient client = elasticSearchUtil.getEsClient("127.0.0.1:9200", "http");
|
||||
GetIndexResponse indexResponse = client.indices().get(request, RequestOptions.DEFAULT);
|
||||
Map<String, Object> resultMap = new HashMap<>();
|
||||
resultMap.put("mapping", indexResponse.getMappings().get(index));
|
||||
resultMap.put("setting", indexResponse.getSettings().get(index).keySet());
|
||||
|
||||
// return DocResponseJson.ok(indexResponse.getSetting(index, "index.number_of_shards"));
|
||||
return DocResponseJson.ok(resultMap);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return DocResponseJson.warn("获取文档失败");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BIN
zyplayer-doc-ui/es-ui/src/assets/img/collapsed.png
Normal file
BIN
zyplayer-doc-ui/es-ui/src/assets/img/collapsed.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 340 B |
BIN
zyplayer-doc-ui/es-ui/src/assets/img/expanded.png
Normal file
BIN
zyplayer-doc-ui/es-ui/src/assets/img/expanded.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 331 B |
@@ -15,6 +15,7 @@ var URL = {
|
||||
manageUpdateDatasource: '/zyplayer-doc-db/datasource/update',
|
||||
|
||||
esMappings: '/zyplayer-doc-es/es-mapping/mappings',
|
||||
esExecuter: '/zyplayer-doc-es/es-mapping/execute',
|
||||
|
||||
systemUpgradeInfo: '/system/info/upgrade',
|
||||
};
|
||||
|
||||
@@ -5,14 +5,14 @@ var href = window.location.href;
|
||||
var _fn = {
|
||||
href: href,
|
||||
// 本地启动时使用本地接口调试
|
||||
// HOST: 'http://local.zyplayer.com:8083/zyplayer-doc-manage',
|
||||
// HOST1: 'http://local.zyplayer.com:8083/zyplayer-doc-manage',
|
||||
HOST: 'http://local.zyplayer.com:8083/zyplayer-doc-manage',
|
||||
HOST1: 'http://local.zyplayer.com:8083/zyplayer-doc-manage',
|
||||
// 也可以直接使用线上的服务调试
|
||||
// HOST: 'http://doc.zyplayer.com/zyplayer-doc-manage',
|
||||
// HOST1: 'http://doc.zyplayer.com/zyplayer-doc-manage',
|
||||
// 打包时使用下面这两行,文件就放在根目录下,所以当前路劲就好
|
||||
HOST: './',
|
||||
HOST1: './',
|
||||
// HOST: './',
|
||||
// HOST1: './',
|
||||
|
||||
mixUrl: function (host, url) {
|
||||
var p;
|
||||
|
||||
122
zyplayer-doc-ui/es-ui/src/common/lib/common/formatjson.js
Normal file
122
zyplayer-doc-ui/es-ui/src/common/lib/common/formatjson.js
Normal file
@@ -0,0 +1,122 @@
|
||||
/**
|
||||
* 将对象处理成json格式化和着色的html
|
||||
* @author 暮光:城中城
|
||||
* @since 2017年5月7日
|
||||
*/
|
||||
export default {
|
||||
// 需要在对象或列表后面添加注释的对象,例:{userList: "用户列表"}
|
||||
// 那么在名字为userList的对象或列表后面都会加上:“用户列表” 这个注释
|
||||
annotationObject: {},
|
||||
tabStr: " ",
|
||||
isArray: function (obj) {
|
||||
return obj && typeof obj === 'object' && typeof obj.length === 'number'
|
||||
&& !(obj.propertyIsEnumerable('length'));
|
||||
},
|
||||
processObjectToHtmlPre: function (obj, indent, addComma, isArray, isPropertyContent, showAnnotation) {
|
||||
var htmlStr = this.processObject(obj, "", indent, addComma, isArray, isPropertyContent, showAnnotation);
|
||||
htmlStr = '<pre class="json">' + htmlStr + '</pre>';
|
||||
return htmlStr;
|
||||
},
|
||||
processObject: function (obj, keyName, indent, addComma, isArray, isPropertyContent, showAnnotation) {
|
||||
var html = "";
|
||||
var comma = (addComma) ? "<span class='comma'>,</span> " : "";
|
||||
var type = typeof obj;
|
||||
if (this.isArray(obj)) {
|
||||
if (obj.length == 0) {
|
||||
html += this.getRow(indent, "<span class='array-brace'>[ ]</span>" + comma, isPropertyContent);
|
||||
} else {// <img class="option-img" src="../../assets/img/expanded.png" />
|
||||
var clpsHtml = '<span><div class="option-img img-expanded"></div></span><span class="collapsible">';
|
||||
var annotation = '';
|
||||
if (showAnnotation && isNotEmpty(keyName) && isNotEmpty(this.annotationObject[keyName])) {
|
||||
annotation = '<span class="annotation">// ' + this.annotationObject[keyName] + '</span>';
|
||||
}
|
||||
html += this.getRow(indent, "<span class='array-brace'>[</span>" + clpsHtml + annotation, isPropertyContent);
|
||||
for (var i = 0; i < obj.length; i++) {
|
||||
html += this.processObject(obj[i], "", indent + 1, i < (obj.length - 1), true, false, showAnnotation);
|
||||
}
|
||||
clpsHtml = "</span>";
|
||||
html += this.getRow(indent, clpsHtml + "<span class='array-brace'>]</span>" + comma);
|
||||
}
|
||||
} else if (type == 'object' && obj == null) {
|
||||
html += this.formatLiteral("null", "", comma, indent, isArray, "null");
|
||||
} else if (type == 'object') {
|
||||
var numProps = 0;
|
||||
for (var prop in obj) {
|
||||
numProps++;
|
||||
}
|
||||
if (numProps == 0) {
|
||||
html += this.getRow(indent, "<span class='object-brace'>{ }</span>" + comma, isPropertyContent);
|
||||
} else { //<img class="option-img img-expanded" src="../../assets/img/expanded.png"/>
|
||||
var clpsHtml = '<span><div class="option-img img-expanded"></div></span><span class="collapsible">';
|
||||
var annotation = '';
|
||||
if (showAnnotation && isNotEmpty(keyName) && isNotEmpty(this.annotationObject[keyName])) {
|
||||
annotation = '<span class="annotation">// ' + this.annotationObject[keyName] + '</span>';
|
||||
}
|
||||
html += this.getRow(indent, "<span class='object-brace'>{</span>" + clpsHtml + annotation, isPropertyContent);
|
||||
var j = 0;
|
||||
for (var prop in obj) {
|
||||
var processStr = '<span class="property-name">"' + prop + '"</span>: ' + this.processObject(obj[prop], prop, indent + 1, ++j < numProps, false, true, showAnnotation);
|
||||
html += this.getRow(indent + 1, processStr);
|
||||
}
|
||||
clpsHtml = "</span>";
|
||||
html += this.getRow(indent, clpsHtml + "<span class='object-brace'>}</span>" + comma);
|
||||
}
|
||||
} else if (type == 'number') {
|
||||
html += this.formatLiteral(obj, "", comma, indent, isArray, "number");
|
||||
} else if (type == 'boolean') {
|
||||
html += this.formatLiteral(obj, "", comma, indent, isArray, "boolean");
|
||||
} else if (type == 'function') {
|
||||
obj = this.formatFunction(indent, obj);
|
||||
html += this.formatLiteral(obj, "", comma, indent, isArray, "function");
|
||||
} else if (type == 'undefined') {
|
||||
html += this.formatLiteral("undefined", "", comma, indent, isArray, "null");
|
||||
} else {
|
||||
html += this.formatLiteral(obj, "\"", comma, indent, isArray, "string");
|
||||
}
|
||||
return html;
|
||||
},
|
||||
expImgClicked: function (img) {
|
||||
var container = img.parentNode.nextSibling;
|
||||
if (!container) return;
|
||||
var disp = "none";
|
||||
var cls = "option-img img-collapsed";
|
||||
if (container.style.display == "none") {
|
||||
disp = "inline";
|
||||
cls = "option-img img-expanded";
|
||||
}
|
||||
img.className = cls;
|
||||
container.style.display = disp;
|
||||
},
|
||||
formatLiteral: function (literal, quote, comma, indent, isArray, style) {
|
||||
if (typeof literal == 'string') {
|
||||
literal = literal.split("<").join("<").split(">").join(">");
|
||||
}
|
||||
var str = "<span class='" + style + "'>" + quote + literal + quote + comma + "</span>";
|
||||
if (isArray) {
|
||||
str = this.getRow(indent, str);
|
||||
}
|
||||
return str;
|
||||
},
|
||||
formatFunction: function (indent, obj) {
|
||||
var tabs = "";
|
||||
for (var i = 0; i < indent; i++) {
|
||||
tabs += this.tabStr;
|
||||
}
|
||||
var funcStrArray = obj.toString().split("\n");
|
||||
var str = "";
|
||||
for (var i = 0; i < funcStrArray.length; i++) {
|
||||
str += ((i == 0) ? "" : tabs) + funcStrArray[i] + "\n";
|
||||
}
|
||||
return str;
|
||||
},
|
||||
getRow: function (indent, data, isPropertyContent) {
|
||||
var tabs = "";
|
||||
for (var i = 0; i < indent && !isPropertyContent; i++) {
|
||||
tabs += this.tabStr;
|
||||
}
|
||||
if (data != null && data.length > 0 && data.charAt(data.length - 1) != "\n") {
|
||||
data = data + "\n";
|
||||
}
|
||||
return tabs + data;
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import DataDatasourceManage from './views/data/DatasourceManage.vue'
|
||||
import DataRouterView from './views/data/RouterView.vue'
|
||||
|
||||
import IndexShow from './views/index/Show.vue'
|
||||
import IndexExecuter from './views/index/Executer.vue'
|
||||
import IndexRouterView from './views/index/RouterView.vue'
|
||||
|
||||
import CommonNoAuth from './views/common/NoAuth.vue'
|
||||
@@ -34,6 +35,7 @@ let routes = [
|
||||
component: IndexRouterView,
|
||||
children: [
|
||||
{path: 'show', name: '索引信息',component: IndexShow},
|
||||
{path: 'executer', name: '执行器',component: IndexExecuter},
|
||||
]
|
||||
}, {
|
||||
path: '/data',
|
||||
|
||||
145
zyplayer-doc-ui/es-ui/src/views/index/Executer.vue
Normal file
145
zyplayer-doc-ui/es-ui/src/views/index/Executer.vue
Normal file
@@ -0,0 +1,145 @@
|
||||
<template>
|
||||
<div class="index-executer-vue">
|
||||
<el-card style="margin: 10px;">
|
||||
<div style="margin: 10px 0;">
|
||||
<span>选择索引:</span>
|
||||
<el-select v-model="executeParam.index" filterable placeholder="选择索引">
|
||||
<el-option label="zyplayer_doc_wiki" value="zyplayer_doc_wiki"></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<el-input type="textarea" v-model="executeParam.sql" :rows="10" placeholder="请输入"></el-input>
|
||||
<div style="text-align: center;margin: 10px 0;">
|
||||
<el-button type="primary" v-on:click="submitExecute">执行</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card style="margin: 10px;">
|
||||
<div style="margin: 10px 0;">
|
||||
<span>执行结果:{{executeResult.errCode == 200 ? '成功' : '失败'}}</span>
|
||||
</div>
|
||||
<div style="margin: 10px 0;" v-if="executeResult.errCode == 200">
|
||||
<div style="margin: 10px 0;">返回结果:</div>
|
||||
<div v-html="executeResult.data" @click="executeResultClick($event)"></div>
|
||||
</div>
|
||||
<div style="margin: 10px 0;" v-else>
|
||||
<div style="margin: 10px 0;">错误信息:</div>
|
||||
<div class="error-text">{{executeResult.errMsg}}</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import global from '../../common/config/global'
|
||||
import formatjson from '../../common/lib/common/formatjson'
|
||||
var app;
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
indexMappingListLoading: false,
|
||||
vueQueryParam: {},
|
||||
indexMappingList: [],
|
||||
executeParam: {
|
||||
sql: '',
|
||||
index: '',
|
||||
},
|
||||
executeResult: {},
|
||||
};
|
||||
},
|
||||
beforeRouteUpdate(to, from, next) {
|
||||
this.initQueryParam(to);
|
||||
next();
|
||||
},
|
||||
mounted: function () {
|
||||
app = this;
|
||||
this.initQueryParam(this.$route);
|
||||
// 延迟设置展开的目录,edit比app先初始化
|
||||
setTimeout(function () {
|
||||
//global.vue.$app.initLoadDataList(app.vueQueryParam.host, app.vueQueryParam.dbName);
|
||||
}, 500);
|
||||
},
|
||||
methods: {
|
||||
submitExecute() {
|
||||
this.indexMappingListLoading = true;
|
||||
this.executeResult = {};
|
||||
this.common.postNonCheck(this.apilist1.esExecuter, this.executeParam, function (json) {
|
||||
var executeResult = json;
|
||||
try {
|
||||
executeResult.data = formatjson.processObjectToHtmlPre(json.data, 0, false, false, false, false);
|
||||
} catch (e) {
|
||||
executeResult.data = "结果解析失败";
|
||||
}
|
||||
app.executeResult = executeResult;
|
||||
app.indexMappingListLoading = false;
|
||||
});
|
||||
},
|
||||
executeResultClick(e) {
|
||||
if (e.target.className.indexOf('option-img') >= 0) {
|
||||
formatjson.expImgClicked(e.target);
|
||||
}
|
||||
},
|
||||
initQueryParam(to) {
|
||||
// this.indexMappingListLoading = true;
|
||||
// this.vueQueryParam = to.query;
|
||||
// this.common.post(this.apilist1.esMappings, this.vueQueryParam, function (json) {
|
||||
// var data = json.data || {};
|
||||
// var properties = data[app.vueQueryParam.index].sourceAsMap.properties;
|
||||
// var propertiesArr = [];
|
||||
// for (var propertiesKey in properties) {
|
||||
// var propertiesItem = properties[propertiesKey];
|
||||
// var item = {
|
||||
// name: propertiesKey, type: propertiesItem.type
|
||||
// };
|
||||
// propertiesArr.push(item);
|
||||
// }
|
||||
// app.indexMappingList = propertiesArr;
|
||||
// app.indexMappingListLoading = false;
|
||||
// });
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.index-executer-vue .el-form-item{margin-bottom: 5px;}
|
||||
.index-executer-vue .edit-table-desc{cursor: pointer; color: #409EFF;}
|
||||
.index-executer-vue .description{cursor: pointer;}
|
||||
.index-executer-vue .error-text{color: #f00;}
|
||||
.index-executer-vue .el-table td, .table-info-vue .el-table th{padding: 5px 0;}
|
||||
|
||||
/* S-JSON展示的样式 */
|
||||
.index-executer-vue pre.json {
|
||||
display: block;
|
||||
padding: 9.5px;
|
||||
margin: 0 0 0 10px;
|
||||
font-size: 12px;
|
||||
line-height: 1.38461538;
|
||||
color: #333;
|
||||
word-break: break-all;
|
||||
word-wrap: break-word;
|
||||
background-color: #f5f5f5;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.index-executer-vue pre.json .option-img{
|
||||
display: inline-block;cursor: pointer;
|
||||
background: url('../../assets/img/collapsed.png') no-repeat center;
|
||||
width: 28px; height: 11px; background-size: 28px 11px;
|
||||
}
|
||||
.index-executer-vue pre.json .img-expanded{
|
||||
background: url('../../assets/img/expanded.png') no-repeat center;
|
||||
}
|
||||
.index-executer-vue pre.json .canvas{font:10pt georgia;background-color:#ececec;color:#000000;border:1px solid #cecece;}
|
||||
.index-executer-vue pre.json .object-brace{color:#00aa00;font-weight:bold;}
|
||||
.index-executer-vue pre.json .array-brace{color:#0033ff;font-weight:bold;}
|
||||
.index-executer-vue pre.json .property-name{color:#cc0000;font-weight:bold;}
|
||||
.index-executer-vue pre.json .string{color:#007777;}
|
||||
.index-executer-vue pre.json .number{color:#aa00aa;}
|
||||
.index-executer-vue pre.json .boolean{color:#0000ff;}
|
||||
.index-executer-vue pre.json .function{color:#aa6633;text-decoration:italic;}
|
||||
.index-executer-vue pre.json .null{color:#0000ff;}
|
||||
.index-executer-vue pre.json .comma{color:#000000;font-weight:bold;}
|
||||
.index-executer-vue pre.json .annotation{color:#aaa;}
|
||||
.index-executer-vue pre img{cursor: pointer;}
|
||||
/* E-JSON展示的样式 */
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user