fix(操作日志): 增加Diff插件展示变更对比内容。
This commit is contained in:
parent
55d3661616
commit
e074c50ba9
|
@ -2,16 +2,11 @@ package io.metersphere.log.utils;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONArray;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import io.metersphere.commons.utils.BeanUtils;
|
import io.metersphere.commons.utils.BeanUtils;
|
||||||
import io.metersphere.commons.utils.LogUtil;
|
import io.metersphere.commons.utils.LogUtil;
|
||||||
import io.metersphere.log.utils.dff.Diff;
|
|
||||||
import io.metersphere.log.utils.dff.JsonDiff;
|
|
||||||
import io.metersphere.log.utils.dff.Operation;
|
|
||||||
import io.metersphere.log.vo.DetailColumn;
|
import io.metersphere.log.vo.DetailColumn;
|
||||||
import io.metersphere.log.vo.OperatingLogDetails;
|
import io.metersphere.log.vo.OperatingLogDetails;
|
||||||
import io.metersphere.log.vo.StatusReference;
|
import io.metersphere.log.vo.StatusReference;
|
||||||
|
@ -60,7 +55,7 @@ public class ReflexObjectUtil {
|
||||||
column.setDepthDff(true);
|
column.setDepthDff(true);
|
||||||
if (val != null) {
|
if (val != null) {
|
||||||
try {
|
try {
|
||||||
if (ReflexObjectUtil.isJsonArray(val.toString())) {
|
if (f.getName().equals("loadConfiguration")) {
|
||||||
val = "{\"" + "压力配置" + "\":" + val.toString() + "}";
|
val = "{\"" + "压力配置" + "\":" + val.toString() + "}";
|
||||||
}
|
}
|
||||||
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||||
|
@ -121,51 +116,10 @@ public class ReflexObjectUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 深度对比
|
// 深度对比
|
||||||
if (originalColumns.get(i).isDepthDff() && originalColumns.get(i).getOriginalValue() != null && newColumns.get(i).getOriginalValue() != null) {
|
DetailColumn column = new DetailColumn();
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
BeanUtils.copyBean(column, originalColumns.get(i));
|
||||||
JsonNode source = mapper.readTree(originalColumns.get(i).getOriginalValue().toString());
|
column.setNewValue(newColumns.get(i).getOriginalValue());
|
||||||
JsonNode target = mapper.readTree(newColumns.get(i).getOriginalValue().toString());
|
comparedColumns.add(column);
|
||||||
List<Diff> after = JsonDiff.jsonDiff(source, target);
|
|
||||||
|
|
||||||
StringBuilder addBuff = new StringBuilder();
|
|
||||||
StringBuilder removeBuff = new StringBuilder();
|
|
||||||
StringBuilder repBuff = new StringBuilder();
|
|
||||||
StringBuilder oldValue = new StringBuilder();
|
|
||||||
for (Diff item : after) {
|
|
||||||
if (item.getOperation().equals(Operation.ADD)) {
|
|
||||||
addBuff.append(item.getPath() + ":" + item.getValue()).append("\n");
|
|
||||||
}
|
|
||||||
if (item.getOperation().equals(Operation.REMOVE)) {
|
|
||||||
removeBuff.append(item.getPath() + ":" + item.getValue()).append("\n");
|
|
||||||
}
|
|
||||||
if (item.getOperation().equals(Operation.REPLACE)) {
|
|
||||||
repBuff.append(item.getPath() + ":" + item.getValue()).append("\n");
|
|
||||||
oldValue.append(item.getPath() + ":" + item.getSrcValue()).append("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
StringBuilder newValue = new StringBuilder();
|
|
||||||
if (addBuff != null && addBuff.toString().length() > 0) {
|
|
||||||
newValue.append("添加:\n").append(addBuff).append("\n");
|
|
||||||
}
|
|
||||||
if (removeBuff != null && removeBuff.toString().length() > 0) {
|
|
||||||
newValue.append("移除:\n").append(removeBuff).append("\n");
|
|
||||||
}
|
|
||||||
if (repBuff != null && repBuff.toString().length() > 0) {
|
|
||||||
newValue.append("修改:\n").append(repBuff).append("\n");
|
|
||||||
}
|
|
||||||
DetailColumn column = new DetailColumn();
|
|
||||||
BeanUtils.copyBean(column, originalColumns.get(i));
|
|
||||||
if (oldValue != null && oldValue.length() > 0) {
|
|
||||||
column.setOriginalValue(oldValue);
|
|
||||||
}
|
|
||||||
column.setNewValue(newValue);
|
|
||||||
comparedColumns.add(column);
|
|
||||||
} else {
|
|
||||||
DetailColumn column = new DetailColumn();
|
|
||||||
BeanUtils.copyBean(column, originalColumns.get(i));
|
|
||||||
column.setNewValue(newColumns.get(i).getOriginalValue());
|
|
||||||
comparedColumns.add(column);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
"json-bigint": "^1.0.0",
|
"json-bigint": "^1.0.0",
|
||||||
"json-schema-faker": "^0.5.0-rcv.32",
|
"json-schema-faker": "^0.5.0-rcv.32",
|
||||||
"json5": "^2.1.3",
|
"json5": "^2.1.3",
|
||||||
|
"jsondiffpatch": "^0.4.1",
|
||||||
"jsoneditor": "^9.1.2",
|
"jsoneditor": "^9.1.2",
|
||||||
"jsonpath": "^1.1.0",
|
"jsonpath": "^1.1.0",
|
||||||
"jspdf": "^2.1.1",
|
"jspdf": "^2.1.1",
|
||||||
|
|
|
@ -63,7 +63,7 @@
|
||||||
infoVisible: false,
|
infoVisible: false,
|
||||||
loading: false,
|
loading: false,
|
||||||
details: [],
|
details: [],
|
||||||
linkDatas: ["prerequisite", "steps", "remark", "request", "response", "scenarioDefinition", "loadConfiguration", "advancedConfiguration"],
|
linkDatas: ["prerequisite", "steps", "remark", "request", "response", "scenarioDefinition","tags", "loadConfiguration", "advancedConfiguration"],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
|
@ -11,27 +11,9 @@
|
||||||
</div>
|
</div>
|
||||||
<div style="overflow: auto">
|
<div style="overflow: auto">
|
||||||
<p class="tip">{{ this.$t('report.test_log_details') }} </p>
|
<p class="tip">{{ this.$t('report.test_log_details') }} </p>
|
||||||
<el-row style="background:#F8F8F8">
|
|
||||||
<el-col :span="12">
|
|
||||||
{{$t('operating_log.before_change')}}
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
{{$t('operating_log.after_change')}}
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="12">
|
<pre v-html="getDiff(detail.originalValue,detail.newValue)"></pre>
|
||||||
<div style="width: 400px;overflow: auto">
|
<!--</el-col>-->
|
||||||
<pre v-if="formatData.indexOf(detail.columnName)!==-1">{{ detail.originalValue }}</pre>
|
|
||||||
<div v-else>{{ detail.originalValue }}</div>
|
|
||||||
</div>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<div style="width: 400px;overflow: auto">
|
|
||||||
<pre v-if="formatData.indexOf(detail.columnName)!==-1">{{ detail.newValue }}</pre>
|
|
||||||
<div v-else>{{ detail.newValue }}</div>
|
|
||||||
</div>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -39,6 +21,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
const jsondiffpatch = require('jsondiffpatch');
|
||||||
|
const formattersHtml = jsondiffpatch.formatters.html;
|
||||||
export default {
|
export default {
|
||||||
name: "MsHistoryDetail",
|
name: "MsHistoryDetail",
|
||||||
components: {},
|
components: {},
|
||||||
|
@ -49,10 +33,14 @@
|
||||||
return {
|
return {
|
||||||
infoVisible: false,
|
infoVisible: false,
|
||||||
detail: {},
|
detail: {},
|
||||||
formatData:["loadConfiguration","advancedConfiguration","config","variables","tags","customFields","steps","scenarioDefinition","request","response"],
|
formatData: ["loadConfiguration", "advancedConfiguration", "config", "variables", "tags", "customFields", "steps", "scenarioDefinition", "request", "response"],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
getDiff(v1, v2) {
|
||||||
|
let delta = jsondiffpatch.diff(v1, v2);
|
||||||
|
return formattersHtml.format(delta, v1);
|
||||||
|
},
|
||||||
handleClose() {
|
handleClose() {
|
||||||
this.infoVisible = false;
|
this.infoVisible = false;
|
||||||
},
|
},
|
||||||
|
@ -68,6 +56,8 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
@import "~jsondiffpatch/dist/formatters-styles/html.css";
|
||||||
|
@import "~jsondiffpatch/dist/formatters-styles/annotated.css";
|
||||||
|
|
||||||
.tip {
|
.tip {
|
||||||
padding: 3px 5px;
|
padding: 3px 5px;
|
||||||
|
|
|
@ -17,17 +17,16 @@
|
||||||
<div v-if="detail && detail.details && detail.details.columns" style="margin-left: 20px">
|
<div v-if="detail && detail.details && detail.details.columns" style="margin-left: 20px">
|
||||||
<el-table :data="detail.details.columns">
|
<el-table :data="detail.details.columns">
|
||||||
<el-table-column prop="columnTitle" :label="$t('operating_log.change_field')" width="150px" show-overflow-tooltip/>
|
<el-table-column prop="columnTitle" :label="$t('operating_log.change_field')" width="150px" show-overflow-tooltip/>
|
||||||
<el-table-column prop="originalValue" :label="$t('operating_log.before_change')" width="400px" show-overflow-tooltip>
|
<!--<el-table-column prop="originalValue" :label="$t('operating_log.before_change')" width="400px">-->
|
||||||
<template v-slot:default="scope">
|
<!--<template v-slot:default="scope">-->
|
||||||
<span v-if="timeDates.indexOf(scope.row.columnName)!==-1">{{ scope.row.originalValue | timestampFormatDate }}</span>
|
<!--<span v-if="timeDates.indexOf(scope.row.columnName)!==-1">{{ scope.row.originalValue | timestampFormatDate }}</span>-->
|
||||||
<pre v-else>{{ scope.row.originalValue }}</pre>
|
<!--<div v-else>{{ scope.row.originalValue }}</div>-->
|
||||||
|
<!--</template>-->
|
||||||
</template>
|
<!--</el-table-column>-->
|
||||||
</el-table-column>
|
<el-table-column prop="newValue" :label="$t('operating_log.change_content')">
|
||||||
<el-table-column prop="newValue" :label="$t('operating_log.after_change')" width="400px" show-overflow-tooltip>
|
|
||||||
<template v-slot:default="scope">
|
<template v-slot:default="scope">
|
||||||
<span v-if="timeDates.indexOf(scope.row.columnName)!==-1">{{ scope.row.newValue | timestampFormatDate }}</span>
|
<span v-if="timeDates.indexOf(scope.row.columnName)!==-1">{{ scope.row.newValue | timestampFormatDate }}</span>
|
||||||
<pre v-else>{{ scope.row.newValue }}</pre>
|
<pre v-html="getDiff(scope.row.originalValue,scope.row.newValue)" v-else></pre>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
@ -48,7 +47,6 @@
|
||||||
{{n.columnTitle}}:{{n.originalValue}}
|
{{n.columnTitle}}:{{n.originalValue}}
|
||||||
</pre>
|
</pre>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -57,6 +55,9 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
const jsondiffpatch = require('jsondiffpatch');
|
||||||
|
const formattersHtml = jsondiffpatch.formatters.html;
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "MsLogDetail",
|
name: "MsLogDetail",
|
||||||
components: {},
|
components: {},
|
||||||
|
@ -66,6 +67,8 @@
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
infoVisible: false,
|
infoVisible: false,
|
||||||
|
d1: "",
|
||||||
|
d2: "",
|
||||||
detail: {},
|
detail: {},
|
||||||
LOG_TYPE: [
|
LOG_TYPE: [
|
||||||
{id: 'CREATE', label: this.$t('api_test.definition.request.create_info')},
|
{id: 'CREATE', label: this.$t('api_test.definition.request.create_info')},
|
||||||
|
@ -122,10 +125,18 @@
|
||||||
handleClose() {
|
handleClose() {
|
||||||
this.infoVisible = false;
|
this.infoVisible = false;
|
||||||
},
|
},
|
||||||
|
getDiff(v1, v2) {
|
||||||
|
let delta = jsondiffpatch.diff(v1, v2);
|
||||||
|
return formattersHtml.format(delta, v1);
|
||||||
|
},
|
||||||
getDetails(id) {
|
getDetails(id) {
|
||||||
this.result = this.$get("/operating/log/get/" + id, response => {
|
this.result = this.$get("/operating/log/get/" + id, response => {
|
||||||
let data = response.data;
|
let data = response.data;
|
||||||
this.detail = data;
|
this.detail = data;
|
||||||
|
//let delta = jsondiffpatch.diff(this.d1, this.d2);/
|
||||||
|
//document.getElementById('visual').innerHTML = formattersHtml.format(delta, this.d1);
|
||||||
|
// self-explained json
|
||||||
|
//document.getElementById('annotated').innerHTML = jsondiffpatch.formatters.annotated.format(delta, this.d1);
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
open(id) {
|
open(id) {
|
||||||
|
@ -140,6 +151,8 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
@import "~jsondiffpatch/dist/formatters-styles/html.css";
|
||||||
|
@import "~jsondiffpatch/dist/formatters-styles/annotated.css";
|
||||||
|
|
||||||
.tip {
|
.tip {
|
||||||
padding: 3px 5px;
|
padding: 3px 5px;
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 0af67efb336b3f5f6718c7b2684de4d4985c0aee
|
Subproject commit e6cc6ba0e8264f4f3780448b60dc149aef8a2cbc
|
|
@ -817,7 +817,7 @@ export default {
|
||||||
wait_controller: "Wait controller",
|
wait_controller: "Wait controller",
|
||||||
if_controller: "If controller",
|
if_controller: "If controller",
|
||||||
loop_controller: "Loop Controller",
|
loop_controller: "Loop Controller",
|
||||||
transcation_controller:"Transcation controller",
|
transcation_controller: "Transcation controller",
|
||||||
scenario_import: "Scenario import",
|
scenario_import: "Scenario import",
|
||||||
customize_script: "Customize script",
|
customize_script: "Customize script",
|
||||||
customize_req: "Customize req",
|
customize_req: "Customize req",
|
||||||
|
@ -1830,5 +1830,6 @@ export default {
|
||||||
after_change: "After change",
|
after_change: "After change",
|
||||||
share: "Share",
|
share: "Share",
|
||||||
change_history: "Change history",
|
change_history: "Change history",
|
||||||
|
change_content: "Change content",
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1837,5 +1837,6 @@ export default {
|
||||||
after_change: "变更后",
|
after_change: "变更后",
|
||||||
share: "分享",
|
share: "分享",
|
||||||
change_history: "变更历史",
|
change_history: "变更历史",
|
||||||
|
change_content: "变更内容",
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1837,5 +1837,6 @@ export default {
|
||||||
after_change: "變更後",
|
after_change: "變更後",
|
||||||
share: "分享",
|
share: "分享",
|
||||||
change_history: "變更歷史",
|
change_history: "變更歷史",
|
||||||
|
change_content: "变更内容",
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue