Skip to content

Commit 4374c89

Browse files
committed
零代码断言:新增支持自动断言 搜索、排序、数量限制
1 parent eab6d78 commit 4374c89

3 files changed

Lines changed: 189 additions & 15 deletions

File tree

‎APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/apijson/JSONResponse.js‎

Lines changed: 152 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -467,8 +467,10 @@ var JSONResponse = {
467467
COMPARE_KEY_MORE: 1,
468468
COMPARE_VALUE_MORE: 2,
469469
COMPARE_EQUAL_EXCEPTION: 3,
470+
COMPARE_SORT_CHANGE: 4, // FIXME 不重复,后面都额外加判断?
470471
COMPARE_LENGTH_CHANGE: 4,
471472
COMPARE_VALUE_CHANGE: 5,
473+
COMPARE_FILTER_CHANGE: 5, // FIXME 不重复,后面都额外加判断?
472474
COMPARE_VALUE_EMPTY: 6,
473475
COMPARE_KEY_LESS: 7,
474476
COMPARE_FORMAT_CHANGE: 8,
@@ -907,7 +909,7 @@ var JSONResponse = {
907909
3-缺少字段/整数变小数,黄色;
908910
4-类型/code 改变,红色;
909911
*/
910-
compareWithStandard: function(target, real, folder, exceptKeys, ignoreTrend, callback) {
912+
compareWithStandard: function(target, real, folder, exceptKeys, ignoreTrend, preReal, reqSearches, reqSorts, reqLimits, callback) {
911913
folder = folder == null ? '' : folder;
912914

913915
if (target == null) {
@@ -1011,6 +1013,64 @@ var JSONResponse = {
10111013
max.code -= 1;
10121014
}
10131015

1016+
var isStr = type == 'string'
1017+
var isNum = (! isStr) && CodeUtil.isTypeMatch('number', type);
1018+
preReal = preReal != null ? preReal : (isNum ? 0 : (isStr ? '' : preReal));
1019+
1020+
var keys = StringUtil.splitPath(folder, false);
1021+
var key = StringUtil.isEmpty(keys) ? '' : (keys[keys.length - 1] || '');
1022+
1023+
var reqSearchObj = reqSearches == null || max.code >= JSONResponse.COMPARE_FILTER_CHANGE || ! isStr ? null : reqSearches[key];
1024+
var reqSearch = reqSearchObj == null ? null : reqSearchObj.same;
1025+
if (StringUtil.isNotEmpty(reqSearch) && ! real.includes(reqSearch)) {
1026+
log('compareWithStandard StringUtil.isNotEmpty(reqSearch) && ! real.includes(reqSearch) >> return COMPARE_FILTER_CHANGE');
1027+
max = {
1028+
code: JSONResponse.COMPARE_FILTER_CHANGE,
1029+
msg: '未包含传参 ' + (StringUtil.isEmpty(reqSearchObj.path) ? '' : reqSearchObj.path + ' 筛选 ') + reqSearch,
1030+
path: folder,
1031+
value: real
1032+
};
1033+
}
1034+
1035+
var same = max.code >= JSONResponse.COMPARE_FILTER_CHANGE || ! isStr ? null : target.same;
1036+
if (StringUtil.isNotEmpty(same) && ! real.includes(same)) {
1037+
log('compareWithStandard StringUtil.isNotEmpty(same) && ! real.includes(same) >> return COMPARE_FILTER_CHANGE');
1038+
max = {
1039+
code: JSONResponse.COMPARE_FILTER_CHANGE,
1040+
msg: '未包含 ' + same,
1041+
path: folder,
1042+
value: real
1043+
};
1044+
}
1045+
1046+
var notCmpSort = reqSorts == null || max.code >= JSONResponse.COMPARE_SORT_CHANGE || ! (isStr || isNum)
1047+
var reqSortObj = notCmpSort ? null : reqSorts[key];
1048+
var reqSort = reqSortObj == null ? null : reqSortObj.sort;
1049+
1050+
var sort = notCmpSort ? null : target.sort;
1051+
if (StringUtil.isNotEmpty(reqSort) || StringUtil.isNotEmpty(sort)) {
1052+
var srt = (real === preReal ? '=' : (real > preReal ? '>' : '<'));
1053+
1054+
if (! reqSort.includes(srt)) {
1055+
log('compareWithStandard StringUtil.isNotEmpty(reqSort) && ! ' + reqSort + '.includes(' + srt + ') >> return COMPARE_SORT_CHANGE');
1056+
max = {
1057+
code: JSONResponse.COMPARE_SORT_CHANGE,
1058+
msg: '排序 ' + srt + ' 不符合传参 ' + (StringUtil.isEmpty(reqSortObj.path) ? '' : reqSortObj.path + ' ') + reqSort,
1059+
path: folder,
1060+
value: real
1061+
};
1062+
}
1063+
1064+
if (max.code < JSONResponse.COMPARE_SORT_CHANGE && ! sort.includes(srt)) {
1065+
log('compareWithStandard StringUtil.isNotEmpty(sort) && ! ' + sort + '.includes(' + srt + ') >> return COMPARE_SORT_CHANGE');
1066+
max = {
1067+
code: JSONResponse.COMPARE_SORT_CHANGE,
1068+
msg: '排序 ' + sort + ' 变成 ' + srt,
1069+
path: folder,
1070+
value: real
1071+
};
1072+
}
1073+
}
10141074

10151075
var each;
10161076

@@ -1020,7 +1080,7 @@ var JSONResponse = {
10201080
for (var i = 0; i < real.length; i ++) { //检查real的每一项
10211081
log('compareWithStandard for i = ' + i + ' >> ');
10221082

1023-
each = JSONResponse.compareWithStandard(firstVal, real[i], JSONResponse.getAbstractPath(folder, i), exceptKeys, ignoreTrend);
1083+
each = JSONResponse.compareWithStandard(firstVal, real[i], JSONResponse.getAbstractPath(folder, i), exceptKeys, ignoreTrend, i <= 0 ? null : real[i - 1], reqSearches, reqSorts, reqLimits);
10241084

10251085
if (max.code < each.code) {
10261086
max = each;
@@ -1055,7 +1115,8 @@ var JSONResponse = {
10551115
}
10561116
log('compareWithStandard for tk = ' + tk + ' >> ');
10571117

1058-
each = JSONResponse.compareWithStandard(firstVal[tk], real[tk], JSONResponse.getAbstractPath(folder, tk), exceptKeys);
1118+
each = JSONResponse.compareWithStandard(firstVal[tk], real[tk], JSONResponse.getAbstractPath(folder, tk), exceptKeys
1119+
, ignoreTrend, JSONResponse.isObject(preReal) ? preReal[tk] : null, reqSearches, reqSorts, reqLimits);
10591120
if (max.code < each.code) {
10601121
max = each;
10611122
}
@@ -1105,7 +1166,14 @@ var JSONResponse = {
11051166
else if (format instanceof Array == false && format instanceof Object) {
11061167
try {
11071168
var realObj = parseJSON(real);
1108-
var result = JSONResponse.compareWithStandard(format, realObj, folder, exceptKeys, ignoreTrend);
1169+
var preRealObj = null;
1170+
try { // FIXME 是否暴露?
1171+
preRealObj = parseJSON(preReal);
1172+
} catch (e) {
1173+
log(e);
1174+
}
1175+
1176+
var result = JSONResponse.compareWithStandard(format, realObj, folder, exceptKeys, ignoreTrend, preRealObj); // , reqSearches, reqSorts, reqLimits); // TODO: 是否必要在字符串里再解析排序?
11091177
if (guess == true) {
11101178
result.code -= 1;
11111179
}
@@ -1119,10 +1187,9 @@ var JSONResponse = {
11191187
}
11201188
}
11211189

1122-
var isNum = CodeUtil.isTypeMatch('number', type);
11231190
var ignore = false;
11241191
var isFolderMeaningful = StringUtil.isNotEmpty(folder) && ! StringUtil.isNumber(folder);
1125-
if (isFolderMeaningful && (isNum || type == 'string')) {
1192+
if (isFolderMeaningful && (isNum || isStr)) {
11261193
if (JSONResponse.IGNORE_KEYS.includes(folder)) {
11271194
ignore = true;
11281195
} else if (folder.includes('/')) {
@@ -1201,6 +1268,15 @@ var JSONResponse = {
12011268
var realLength = JSONResponse.getLength(real);
12021269
log('compareWithStandard realLength = ' + realLength + ' >> ');
12031270

1271+
var reqLimitObj = reqLimits == null || type !== 'array' ? null : reqLimits[key];
1272+
var reqLimit = reqLimitObj == null ? null : reqLimitObj.limit;
1273+
if (Number.isSafeInteger(reqLimit) && reqLimit > 0 && reqLimit < realLength) {
1274+
max.code = JSONResponse.COMPARE_LENGTH_CHANGE;
1275+
max.msg = '长度 ' + realLength + ' > 传参限制 ' + reqLimit + ' 个 ' + StringUtil.get(reqLimitObj.path);
1276+
max.path = folder;
1277+
max.value = realLength;
1278+
}
1279+
12041280
if (realLength != null && JSONResponse.isValueCorrect(target.lengthLevel, target.lengths, realLength) != true) {
12051281
var lengths = target.lengths
12061282
var maxVal = lengths == null || lengths.length <= 0 ? null : lengths[0];
@@ -1441,7 +1517,7 @@ var JSONResponse = {
14411517

14421518
/**更新测试标准,通过原来的标准与最新的数据合并来实现
14431519
*/
1444-
updateStandard: function(target, real, exceptKeys, ignoreTrend, key) {
1520+
updateStandard: function(target, real, exceptKeys, ignoreTrend, folder, key, preReal) {
14451521
if (target instanceof Array) { // JSONArray
14461522
throw new Error("Standard 语法错误,不应该有 array!");
14471523
}
@@ -1577,6 +1653,8 @@ var JSONResponse = {
15771653
return target;
15781654
}
15791655

1656+
var fd = JSONResponse.getAbstractPath(folder, key);
1657+
15801658
log('updateStandard type = target.type = ' + type + ' >>');
15811659
if (type == null || CodeUtil.isTypeMatch(target.type, rtype) != true) { //强制用real的类型替代
15821660
type = target.type = rtype;
@@ -1598,6 +1676,9 @@ var JSONResponse = {
15981676
valueLevel = target.valueLevel = 0;
15991677
}
16001678

1679+
var sort = target.sort;
1680+
var same = target.same;
1681+
16011682
if (type == 'array') {
16021683
log('updateStandard type == array >> ');
16031684

@@ -1609,19 +1690,49 @@ var JSONResponse = {
16091690
}
16101691

16111692
var child = values[0];
1612-
for (var i = 0; i < real.length; i ++) {
1693+
var len = real.length;
1694+
for (var i = 0; i < len; i ++) {
1695+
var v = real[i];
16131696
log('updateStandard for i = ' + i + '; child = '
1614-
+ JSON.stringify(child, null, ' ') + ';\n real[i] = ' + JSON.stringify(real[i], null, ' ') + ' >>');
1697+
+ JSON.stringify(child, null, ' ') + ';\n real[i] = ' + JSON.stringify(v, null, ' ') + ' >>');
1698+
if (i === 0 && len >= 2 && (sort !== '' || same !== '')) {
1699+
var isStr = JSONResponse.isString(v);
1700+
var isNum = (! isStr) && JSONResponse.isNumber(v);
1701+
if (isStr || (isNum && sort !== '')) {
1702+
var last = null;
1703+
for (let j = len - 1; j > 2; j--) {
1704+
last = real[len - 1];
1705+
if ((JSONResponse.isNumber(last) && last !== 0) || (JSONResponse.isString(last) && last !== '')) {
1706+
break
1707+
}
1708+
}
1709+
1710+
if (last == null) {
1711+
last = isNum ? 0 : '';
1712+
}
1713+
var first = v != null ? v : (isNum ? 0 : '');
1714+
1715+
if (sort !== '') { // >, >=, ''; <, <=, ''; =, >=, ''; =, <=, ''
1716+
var srt = (last === first ? '=' : (last > first ? '>' : '<'));
1717+
target.sort = sort = sort == null || srt === sort ? srt : (sort.includes(srt) ? sort : (srt === '=' ? sort + '=' : ''));
1718+
}
16151719

1616-
child = JSONResponse.updateStandard(child, real[i], exceptKeys, true, key == null ? 'item' : key + 'Item'); //FIXME ignoreTrend 固定取 true 导致批量创建后多个 id [1,2,3] -> [3,4,5] 漏报趋势异常
1720+
if (isStr && same !== '' && StringUtil.isNotEmpty(first) && StringUtil.isNotEmpty(last)) {
1721+
var sm = StringUtil.longestSubstr(first, last);
1722+
target.same = same = StringUtil.longestSubstr(same, sm);
1723+
}
1724+
}
1725+
}
1726+
1727+
child = JSONResponse.updateStandard(child, v, exceptKeys, true, fd, '' + i, i <= 0 ? null : real[i - 1]); //FIXME ignoreTrend 固定取 true 导致批量创建后多个 id [1,2,3] -> [3,4,5] 漏报趋势异常
16171728
}
16181729
if (child == null) {
16191730
log('updateStandard child == null >> child = {}');
16201731
child = {} //啥都确定不了,level为null默认用0替代
16211732
}
16221733

16231734
values = [child];
1624-
target = JSONResponse.setValue(target, real.length, lengthLevel == null ? 1 : lengthLevel, lengths, true, true);
1735+
target = JSONResponse.setValue(target, len, lengthLevel == null ? 1 : lengthLevel, lengths, true, true);
16251736
target = JSONResponse.setValue(target, null, valueLevel, values, false, ignoreTrend);
16261737
}
16271738
else if (type == 'object') {
@@ -1660,15 +1771,34 @@ var JSONResponse = {
16601771
continue
16611772
}
16621773

1774+
var fv = firstVal[k];
1775+
var rv = real[k];
16631776
log('updateStandard for k in real = ' + k + '; firstVal[k] = '
1664-
+ JSON.stringify(firstVal[k], null, ' ') + ';\n real[k] = ' + JSON.stringify(real[k], null, ' ') + ' >>');
1665-
firstVal[k] = JSONResponse.updateStandard(firstVal[k], real[k], exceptKeys, ignoreTrend, k);
1777+
+ JSON.stringify(fv, null, ' ') + ';\n real[k] = ' + JSON.stringify(rv, null, ' ') + ' >>');
1778+
firstVal[k] = JSONResponse.updateStandard(fv, rv, exceptKeys, ignoreTrend, fd, k, JSONResponse.isObject(preReal) ? preReal[k] : null);
16661779
}
16671780

16681781
target.values = values;
16691782
}
16701783
else {
1671-
log('updateStandard type == other >> ');
1784+
log('updateStandard type == ' + type + ' >> ');
1785+
if (StringUtil.isNumber(key) && key >= '1' && (sort !== '' || same !== '') && type === JSONResponse.getType(preReal)) {
1786+
var isStr = JSONResponse.isString(real);
1787+
var isNum = (! isStr) && JSONResponse.isNumber(real);
1788+
if (isStr || (isNum && sort !== '')) {
1789+
if (sort !== '') { // >, >=, ''; <, <=, ''; =, >=, ''; =, <=, ''
1790+
preReal = preReal != null ? preReal : (isNum ? 0 : (isStr ? '' : preReal));
1791+
var srt = (real === preReal ? '=' : (real > preReal ? '>' : '<'));
1792+
target.sort = sort = sort == null || srt === sort ? srt : (sort.includes(srt) ? sort : (srt === '=' ? sort + '=' : ''));
1793+
}
1794+
1795+
if (isStr && same !== '' && StringUtil.isNotEmpty(real)) {
1796+
var sm = StringUtil.isEmpty(same) ? real : StringUtil.longestSubstr(real, same); // preReal);
1797+
target.same = same = sm; // StringUtil.longestSubstr(same, sm);
1798+
}
1799+
}
1800+
}
1801+
16721802
if (type == 'string') {
16731803
var format = target.format;
16741804
try {
@@ -1708,7 +1838,14 @@ var JSONResponse = {
17081838
log(e)
17091839
try {
17101840
var realObj = parseJSON(real);
1711-
var format2 = JSONResponse.updateStandard(target.format, realObj, exceptKeys, ignoreTrend, key);
1841+
var preRealObj = null;
1842+
try {
1843+
preRealObj = parseJSON(preReal);
1844+
} catch (e2) {
1845+
log(e2)
1846+
}
1847+
1848+
var format2 = JSONResponse.updateStandard(target.format, realObj, exceptKeys, ignoreTrend, folder, key, preRealObj);
17121849
if (format2 != null) {
17131850
target.format = format2;
17141851
}

‎APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/apijson/StringUtil.js‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,41 @@ var StringUtil = {
878878
}
879879

880880
return StringUtil.trim(newStr);
881+
},
882+
883+
longestSubstr: function(str1, str2, trim) {
884+
if (! str1 || ! str2) {
885+
return "";
886+
}
887+
888+
let m = StringUtil.length(str1, trim);
889+
let n = StringUtil.length(str2, trim);
890+
891+
// 创建一个二维数组,dp[i][j] 记录以 str1[i-1] 和 str2[j-1] 结尾的公共子串长度
892+
let dp = Array.from(Array(m + 1), () => Array(n + 1).fill(0));
893+
894+
let maxLength = 0; // 记录最长公共子串的长度
895+
let endIndex = 0; // 记录最长公共子串在 str1 中结束的位置
896+
897+
for (let i = 1; i <= m; i++) {
898+
for (let j = 1; j <= n; j++) {
899+
// 如果当前字符相等
900+
if (str1[i - 1] === str2[j - 1]) {
901+
dp[i][j] = dp[i - 1][j - 1] + 1;
902+
903+
// 更新最大长度和结束索引
904+
if (dp[i][j] > maxLength) {
905+
maxLength = dp[i][j];
906+
endIndex = i; // 这里的 i 是基于 1 的索引,对应 str1 的 endIndex
907+
}
908+
} else {
909+
dp[i][j] = 0; // 不连续则清零
910+
}
911+
}
912+
}
913+
914+
// 根据结束索引和最大长度,从 str1 中截取出最长公共子串
915+
return str1.substring(endIndex - maxLength, endIndex);
881916
}
882917

883918
};

‎APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/js/main.js‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12682,8 +12682,10 @@ Content-Type: ` + contentType) + (StringUtil.isEmpty(headerStr, true) ? '' : hea
1268212682
it.compareColor = 'green'
1268312683
it.hintMessage = '新增字段/新增值 等'
1268412684
break;
12685+
case JSONResponse.COMPARE_SORT_CHANGE:
1268512686
case JSONResponse.COMPARE_LENGTH_CHANGE:
1268612687
case JSONResponse.COMPARE_VALUE_CHANGE:
12688+
case JSONResponse.COMPARE_FILTER_CHANGE:
1268712689
it.compareColor = 'blue'
1268812690
it.hintMessage = '值改变 等'
1268912691
break;

0 commit comments

Comments
 (0)