1
1
package com .xiaoju .framework .service .impl ;
2
2
3
+ import com .fasterxml .jackson .databind .JsonNode ;
4
+ import com .fasterxml .jackson .databind .ObjectMapper ;
5
+ import com .fasterxml .jackson .databind .node .ArrayNode ;
6
+ import com .fasterxml .jackson .databind .node .JsonNodeFactory ;
7
+ import com .fasterxml .jackson .databind .node .ObjectNode ;
8
+ import com .flipkart .zjsonpatch .JsonDiff ;
9
+ import com .flipkart .zjsonpatch .JsonPatch ;
3
10
import com .xiaoju .framework .entity .persistent .CaseBackup ;
4
11
import com .xiaoju .framework .mapper .CaseBackupMapper ;
5
12
import com .xiaoju .framework .service .CaseBackupService ;
8
15
import org .slf4j .LoggerFactory ;
9
16
import org .springframework .stereotype .Service ;
10
17
import org .springframework .transaction .annotation .Transactional ;
18
+ import java .util .regex .Matcher ;
19
+ import java .util .regex .Pattern ;
11
20
12
21
import javax .annotation .Resource ;
13
- import java .util .Date ;
14
- import java .util .List ;
22
+ import java .io .IOException ;
23
+ import java .lang .reflect .Field ;
24
+ import java .util .*;
25
+
26
+ import static com .flipkart .zjsonpatch .DiffFlags .ADD_EXPLICIT_REMOVE_ADD_ON_REPLACE ;
27
+ import static com .flipkart .zjsonpatch .DiffFlags .ADD_ORIGINAL_VALUE_ON_REPLACE ;
15
28
16
29
/**
17
30
* 备份记录
@@ -33,12 +46,19 @@ public synchronized CaseBackup insertBackup(CaseBackup caseBackup) {
33
46
List <CaseBackup > caseBackups = caseBackupMapper .selectByCaseId (caseBackup .getCaseId (), null , null );
34
47
35
48
// 如果当前已有,则直接返回
36
- // todo: 此处应该是比较json或者base字段信息,此处可能存在json字段位置不一致导致的字符串不一致问题。
37
- if (caseBackups .size () > 0 &&
38
- caseBackups .get (0 ).getCaseContent ().equals (caseBackup .getCaseContent ()) &&
39
- caseBackups .get (0 ).getRecordContent ().equals (caseBackup .getRecordContent ())) {
40
- LOGGER .info ("当前内容已经保存过了,不再重复保存。" );
41
- return caseBackups .get (0 );
49
+ // todo 此处还是用版本信息控制更加合理
50
+ ObjectMapper jsonMapper = new ObjectMapper ();
51
+ try {
52
+ if (caseBackups .size () > 0 &&
53
+ JsonDiff .asJson (jsonMapper .readTree (caseBackups .get (0 ).getCaseContent ()),
54
+ jsonMapper .readTree (caseBackup .getCaseContent ())).size () == 0 &&
55
+ JsonDiff .asJson (jsonMapper .readTree (caseBackups .get (0 ).getRecordContent ()),
56
+ jsonMapper .readTree (caseBackup .getRecordContent ())).size () == 0 ) {
57
+ LOGGER .info ("当前内容已经保存过了,不再重复保存。" );
58
+ return caseBackups .get (0 );
59
+ }
60
+ } catch (IOException e ) {
61
+ LOGGER .info ("json转换异常. 数据继续备份" , e );
42
62
}
43
63
44
64
int ret = caseBackupMapper .insert (caseBackup );
@@ -53,9 +73,127 @@ public synchronized CaseBackup insertBackup(CaseBackup caseBackup) {
53
73
return caseBackup ;
54
74
}
55
75
76
+ @ Override
77
+ public JsonNode getCaseDiff (Long backupId2 , Long backupId1 ) {
78
+ ObjectMapper jsonMapper = new ObjectMapper ();
79
+ CaseBackup caseBackup1 = caseBackupMapper .selectByBackupId (backupId1 );
80
+ CaseBackup caseBackup2 = caseBackupMapper .selectByBackupId (backupId2 );
81
+
82
+ try {
83
+ JsonNode content1 = jsonMapper .readTree (caseBackup1 .getCaseContent ());
84
+ JsonNode content2 = jsonMapper .readTree (caseBackup2 .getCaseContent ());
85
+ ArrayNode patches = (ArrayNode ) JsonDiff .asJson (content1 , content2 , EnumSet .of (ADD_ORIGINAL_VALUE_ON_REPLACE ));
86
+
87
+ JsonNodeFactory FACTORY = JsonNodeFactory .instance ;
88
+ ArrayNode patchesNew = FACTORY .arrayNode ();
89
+ ObjectNode retJson = FACTORY .objectNode ();
90
+ Iterator <JsonNode > it = patches .elements ();
91
+
92
+ while (it .hasNext ()) {
93
+ JsonNode element = it .next ();
94
+ String op = element .get ("op" ).textValue ();
95
+ if (op .equals ("replace" )) {
96
+ if (element .get ("path" ).textValue ().endsWith ("base" )) {
97
+ continue ;
98
+ }
99
+ ObjectNode node1 = element .deepCopy ();
100
+
101
+ if (!element .get ("path" ).textValue ().endsWith ("image" ) && !element .get ("path" ).textValue ().contains ("imageSize" )) {
102
+ node1 .remove ("value" );
103
+ node1 .put ("value" , "旧内容:" + element .get ("fromValue" ).textValue () + "\n 新内容:" + element .get ("value" ).textValue ());
104
+ }
105
+ patchesNew .add (node1 );
106
+ ObjectNode node2 = FACTORY .objectNode ();
107
+ node2 .put ("op" , "add" );
108
+ String srcPath = element .get ("path" ).textValue ();
109
+
110
+ node2 .put ("path" , srcPath .substring (0 , srcPath .lastIndexOf ('/' )) + "/background" );
111
+ node2 .put ("value" , "#d6f0ff" );
112
+ patchesNew .add (node2 );
113
+ } else if (op .equals ("add" )) {
114
+ ObjectNode node1 = element .deepCopy ();
115
+ traverse (node1 , "add" );
116
+
117
+ patchesNew .add (node1 );
118
+
119
+ } else if (op .equals ("remove" )) {
120
+ patchesNew .add (element );
121
+ ObjectNode node1 = element .deepCopy ();
122
+ node1 .remove ("op" );
123
+ node1 .put ("op" , "add" );
124
+ traverse (node1 , "remove" );
125
+ patchesNew .add (node1 );
126
+
127
+ } else {
128
+ LOGGER .info ("op is: " + element .toString ());
129
+ }
130
+ }
131
+ JsonNode target = JsonPatch .apply ((JsonNode ) patchesNew , content1 );
132
+
133
+ retJson .set ("content" , target );
134
+ ArrayNode cardJson = FACTORY .arrayNode ();
135
+ ObjectNode backup1 = FACTORY .objectNode ();
136
+ backup1 .put ("user" , caseBackup1 .getCreator ());
137
+ backup1 .put ("time" , caseBackup1 .getGmtCreated ().toString ());
138
+ ObjectNode backup2 = FACTORY .objectNode ();
139
+ backup2 .put ("user" , caseBackup2 .getCreator ());
140
+ backup2 .put ("time" , caseBackup2 .getGmtCreated ().toString ());
141
+ cardJson .add (backup1 );
142
+ cardJson .add (backup2 );
143
+
144
+ retJson .set ("backupinfo" , cardJson );
145
+
146
+ return retJson ;
147
+
148
+ } catch (Exception e ) {
149
+ LOGGER .error ("json mapper read tree exception. " , e );
150
+ return null ;
151
+ }
152
+
153
+ }
154
+
155
+ private void traverse (JsonNode node , String op ) {
156
+ Iterator <JsonNode > iterator = node .iterator ();
157
+
158
+ while (iterator .hasNext ()) {
159
+ JsonNode n = iterator .next ();
160
+ if (n .size () > 0 ) {
161
+ if (n .has ("id" )) {
162
+ if (op .equals ("add" )) {
163
+ ((ObjectNode ) n ).put ("background" , "#ddfade" );
164
+ } else {
165
+ ((ObjectNode ) n ).put ("background" , "#ffe7e7" );
166
+ }
167
+ }
168
+ traverse (n , op );
169
+ } else {
170
+ // System.out.println(n.toString());
171
+ }
172
+ }
173
+
174
+ }
56
175
@ Override
57
176
public List <CaseBackup > getBackupByCaseId (Long caseId , String beginTime , String endTime ) {
58
- return caseBackupMapper .selectByCaseId (caseId , transferTime (beginTime ), transferTime (endTime ));
177
+ List <CaseBackup > backupsSrc = caseBackupMapper .selectByCaseId (caseId , transferTime (beginTime ), transferTime (endTime ));
178
+ List <CaseBackup > backups = new ArrayList <>();
179
+ String pattern = "\" base\" :(\\ d+).*" ;
180
+ Pattern r = Pattern .compile (pattern );
181
+ Integer compareVersion = 0 ;
182
+ for (CaseBackup cb :backupsSrc ) {
183
+ Matcher m = r .matcher (cb .getCaseContent ());
184
+ if (m .find ()) {
185
+ Integer currentVersion = Integer .valueOf (m .group (1 ));
186
+ if (!currentVersion .equals (compareVersion )) {
187
+ backups .add (cb );
188
+ compareVersion = currentVersion ;
189
+ } else {
190
+ LOGGER .error ("base信息一致。过滤信息。base: " + currentVersion );
191
+ }
192
+ } else {
193
+ LOGGER .error ("未找到base信息。用例内容是:" + cb .getCaseContent ());
194
+ }
195
+ }
196
+ return backups ;
59
197
}
60
198
61
199
@ Override
0 commit comments