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.core.json.ResponseJson;
|
||||||
import com.zyplayer.doc.data.service.elasticsearch.support.ElasticSearchUtil;
|
import com.zyplayer.doc.data.service.elasticsearch.support.ElasticSearchUtil;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.elasticsearch.action.search.SearchRequest;
|
||||||
import org.elasticsearch.client.RequestOptions;
|
import org.elasticsearch.client.RequestOptions;
|
||||||
import org.elasticsearch.client.RestHighLevelClient;
|
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.GetMappingsRequest;
|
||||||
import org.elasticsearch.client.indices.GetMappingsResponse;
|
import org.elasticsearch.client.indices.GetMappingsResponse;
|
||||||
import org.elasticsearch.cluster.metadata.MappingMetaData;
|
import org.elasticsearch.cluster.metadata.MappingMetaData;
|
||||||
import org.elasticsearch.common.unit.TimeValue;
|
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.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -57,9 +64,43 @@ public class EsMappingController {
|
|||||||
return DocResponseJson.warn("获取文档失败");
|
return DocResponseJson.warn("获取文档失败");
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/list")
|
@PostMapping("/execute")
|
||||||
public ResponseJson<Object> list(String keywords) throws IOException {
|
public ResponseJson<Object> execute(String index, String sql) throws IOException {
|
||||||
return DocResponseJson.ok();
|
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',
|
manageUpdateDatasource: '/zyplayer-doc-db/datasource/update',
|
||||||
|
|
||||||
esMappings: '/zyplayer-doc-es/es-mapping/mappings',
|
esMappings: '/zyplayer-doc-es/es-mapping/mappings',
|
||||||
|
esExecuter: '/zyplayer-doc-es/es-mapping/execute',
|
||||||
|
|
||||||
systemUpgradeInfo: '/system/info/upgrade',
|
systemUpgradeInfo: '/system/info/upgrade',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,14 +5,14 @@ var href = window.location.href;
|
|||||||
var _fn = {
|
var _fn = {
|
||||||
href: href,
|
href: href,
|
||||||
// 本地启动时使用本地接口调试
|
// 本地启动时使用本地接口调试
|
||||||
// HOST: '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',
|
HOST1: 'http://local.zyplayer.com:8083/zyplayer-doc-manage',
|
||||||
// 也可以直接使用线上的服务调试
|
// 也可以直接使用线上的服务调试
|
||||||
// HOST: 'http://doc.zyplayer.com/zyplayer-doc-manage',
|
// HOST: 'http://doc.zyplayer.com/zyplayer-doc-manage',
|
||||||
// HOST1: 'http://doc.zyplayer.com/zyplayer-doc-manage',
|
// HOST1: 'http://doc.zyplayer.com/zyplayer-doc-manage',
|
||||||
// 打包时使用下面这两行,文件就放在根目录下,所以当前路劲就好
|
// 打包时使用下面这两行,文件就放在根目录下,所以当前路劲就好
|
||||||
HOST: './',
|
// HOST: './',
|
||||||
HOST1: './',
|
// HOST1: './',
|
||||||
|
|
||||||
mixUrl: function (host, url) {
|
mixUrl: function (host, url) {
|
||||||
var p;
|
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 DataRouterView from './views/data/RouterView.vue'
|
||||||
|
|
||||||
import IndexShow from './views/index/Show.vue'
|
import IndexShow from './views/index/Show.vue'
|
||||||
|
import IndexExecuter from './views/index/Executer.vue'
|
||||||
import IndexRouterView from './views/index/RouterView.vue'
|
import IndexRouterView from './views/index/RouterView.vue'
|
||||||
|
|
||||||
import CommonNoAuth from './views/common/NoAuth.vue'
|
import CommonNoAuth from './views/common/NoAuth.vue'
|
||||||
@@ -34,6 +35,7 @@ let routes = [
|
|||||||
component: IndexRouterView,
|
component: IndexRouterView,
|
||||||
children: [
|
children: [
|
||||||
{path: 'show', name: '索引信息',component: IndexShow},
|
{path: 'show', name: '索引信息',component: IndexShow},
|
||||||
|
{path: 'executer', name: '执行器',component: IndexExecuter},
|
||||||
]
|
]
|
||||||
}, {
|
}, {
|
||||||
path: '/data',
|
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