diff --git a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/apijson/StringUtil.js b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/apijson/StringUtil.js
index dfe8f0d..12f1378 100644
--- a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/apijson/StringUtil.js
+++ b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/apijson/StringUtil.js
@@ -153,6 +153,55 @@ var StringUtil = {
return s.toLowerCase();
},
+ getTableName: function(s) {
+ s = StringUtil.trim(s);
+ var keys = s.split('_');
+ if (keys.length > 1) {
+ return keys[keys.length - 2];
+ }
+
+ var hasBig = false;
+ var lastInd = -1;
+ for (var i = s.length - 1; i >= 0; i--) {
+ var c = s.substring(i, i + 1);
+ var isBig = /[A-Z]/.test(c)
+ if (lastInd >= 1 && (isBig || i <= 0)) {
+ return s.substring(i, lastInd + 1);
+ }
+
+ if (hasBig && lastInd < 0 && ! isBig) {
+ lastInd = i;
+ }
+ hasBig = hasBig || isBig
+ }
+
+ return '';
+ },
+ getColumnName: function(s) {
+ s = StringUtil.trim(s);
+ var keys = s.split('_');
+ if (keys.length > 1) {
+ return keys[keys.length - 1];
+ }
+
+ var hasBig = false;
+ var lastInd = -1;
+ for (var i = s.length - 1; i >= 0; i--) {
+ var c = s.substring(i, i + 1);
+ var isBig = /[A-Z]/.test(c)
+ if (lastInd >= 0 && (isBig != hasBig || i <= 0)) {
+ return s.substring(lastInd + (isBig ? 0 : 1));
+ }
+
+ if (hasBig && lastInd < 0 && ! isBig) {
+ lastInd = i;
+ }
+ hasBig = hasBig || isBig
+ }
+
+ return s;
+ },
+
split: function (s, separator, trim) {
if (StringUtil.isEmpty(s, trim)) {
return null;
diff --git a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/index.html b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/index.html
index f72eb8f..0d03688 100755
--- a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/index.html
+++ b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/index.html
@@ -686,7 +686,7 @@
-
+
diff --git a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/js/main.js b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/js/main.js
index f5b5cb0..04f1bc5 100755
--- a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/js/main.js
+++ b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/api/js/main.js
@@ -3452,7 +3452,11 @@ https://github.com/Tencent/APIJSON/issues
this.isRandomSubListShow = false;
} else if (StringUtil.isEmpty(vRandom.value, true)) {
var req = this.getRequest(vInput.value, {})
- vRandom.value = StringUtil.trim(this.newRandomConfig(null, '', req, Math.random() >= 0.5, Math.random() >= 0.3, Math.random() >= 0.8))
+ if (this.isChainShow) {
+ vRandom.value = StringUtil.trim(this.newRandomConfig(null, '', req))
+ } else {
+ vRandom.value = StringUtil.trim(this.newRandomConfig(null, '', req, Math.random() >= 0.5, Math.random() >= 0.3, Math.random() >= 0.8))
+ }
} else {
this.showExport(true, true, true)
}
@@ -3466,6 +3470,8 @@ https://github.com/Tencent/APIJSON/issues
return ''
}
+ var isChainShow = this.isChainShow;
+
var config = ''
var childPath = path == null || path == '' ? key : path + '/' + key
var prefix = childPath + ': '
@@ -3556,6 +3562,9 @@ https://github.com/Tencent/APIJSON/issues
var cfg = this.newRandomConfig(childPath, k, v, isRand, isBad, noDeep, isConst)
if (StringUtil.isNotEmpty(cfg, true)) {
+ if (k != null && k.toLowerCase() == 'id') {
+ return cfg
+ }
config += '\n' + cfg
}
}
@@ -3571,7 +3580,224 @@ https://github.com/Tencent/APIJSON/issues
return config
}
- if (typeof value == 'boolean') {
+ // FIXME 似乎加了自动生成场景传参配置后,空配置时点击 + 添加配置后,切换用例列表会卡死
+ if (isChainShow && StringUtil.isNotEmpty(key, true) && (typeof value != 'string' || ! key.endsWith('@'))) {
+ var keys = StringUtil.split(path, '/');
+ var table = keys == null ? '' : keys[keys.length - 1];
+ var isAPIJSONArray = childPath.indexOf('[]') >= 0;
+ var isId = key.toLowerCase() == 'id';
+ var isList = isAPIJSONArray || childPath.toLowerCase().indexOf('list') >= 0;
+ var isRestful = ! JSONObject.isAPIJSONPath(this.getMethod());
+
+ var tbl = StringUtil.getTableName(key)
+ tbl = StringUtil.firstCase(tbl, true)
+ var col = StringUtil.getColumnName(key)
+ col = StringUtil.firstCase(col, false)
+
+ var ks = keys == null ? [] : keys.slice(0, keys.length - 1)
+ ks.push(tbl)
+ var p = ks.join('/')
+ var cp = StringUtil.isNotEmpty(tbl) ? childPath : (StringUtil.isEmpty(p) ? '' : p + '/') + col
+ var kp = StringUtil.isEmpty(p) ? path : p;
+ var fd = StringUtil.isEmpty(kp) ? '' : kp + '/';
+
+ var ctxKey = StringUtil.isNotEmpty(tbl) ? key : StringUtil.firstCase(table, false) + StringUtil.firstCase(key, true)
+ var ctxPutPfx = ctxKey + ': '
+ var camelIdKey = StringUtil.firstCase((tbl || table) + 'Id');
+ var snakeIdKey = (tbl || table).toLowerCase() + '_id';
+
+ if (isList) {
+ if (isId) {
+ config += prefix + 'PRE_ARG("' + camelIdKey + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_ARG("' + snakeIdKey + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("' + cp + '")';
+ if (isRestful) {
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/' + cp + '")';
+ if (key != cp) {
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/' + key + '")';
+ }
+ }
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_ARG("' + camelIdKey + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_ARG("' + snakeIdKey + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'CTX_GET("' + camelIdKey + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'CTX_GET("' + snakeIdKey + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("' + camelIdKey + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("' + snakeIdKey + '")';
+ if (isRestful && ! isAPIJSONArray) {
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/' + camelIdKey + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/' + snakeIdKey + '")';
+ }
+ }
+ else if (StringUtil.isIdKey(key)) {
+ config += prefix + 'PRE_ARG("' + key + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_ARG("id")';
+ if (key != cp) {
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_ARG("' + cp + '")';
+ }
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("' + cp + '")';
+
+ var idKey = key.toLowerCase().startsWith(table.toLowerCase()) ? key : "id";
+ if (isRestful && ! isAPIJSONArray) {
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/' + cp + '")';
+ if (key != cp) {
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/' + key + '")';
+ }
+
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/list/0/' + key + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/list/0/id")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/0/' + key + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/0/id")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/' + key + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/id")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("list/0/' + key + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("list/0/id")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/list/0/' + fd + 'id")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/list/0/' + (tbl || table) + '/' + (col || key) + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/0/' + fd + 'id")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/0/' + (tbl || table) + '/' + (col || key) + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/' + fd + 'id")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/' + (tbl || table) + '/' + (col || key) + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/list/0/' + fd + 'id")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/list/0/' + (tbl || table) + '/' + (col || key) + '")';
+ } else {
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("[]/0/' + key + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("[]/0/id")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("' + fd + (col || key) + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("' + fd + 'id")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("' + (path || '') + '[]/0/' + key + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("' + (path || '') + '[]/0/id")';
+ }
+ }
+ else {
+ config += StringUtil.isEmpty(cp) ? '' : prefix + 'PRE_DATA("' + cp + '", get4Path(req,"' + childPath + '",null))';
+ config += (StringUtil.isEmpty(cp) ? '' : '\n// 可替代上面的 ') + prefix + 'PRE_DATA("' + cp + '", get4Path(req,"' + childPath + '"))';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("' + cp + '")';
+ if (isRestful && ! isAPIJSONArray) {
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/' + cp + '")';
+ if (key != cp) {
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/' + key + '")';
+ if (StringUtil.isNotEmpty(col)) {
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/' + (StringUtil.isEmpty(tbl) ? '' : tbl + '/') + col + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/' + col + '")';
+ }
+ }
+ }
+ }
+
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_ARG("' + childPath + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_ARG("' + cp + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'CTX_GET("' + ctxKey + '")';
+ if (key != childPath) {
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_ARG("' + key + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'CTX_GET("' + ctxKey + '")';
+ }
+ } else {
+ if (isId) {
+ if (isRestful) {
+ config += prefix + 'PRE_DATA("' + 'data/list/0/' + camelIdKey + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("' + 'data/0/' + snakeIdKey + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("' + 'list/0/' + camelIdKey + '")';
+ } else {
+ config += prefix + 'PRE_DATA("' + kp + '[]/0/' + camelIdKey + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("' + kp + '[]/0/' + snakeIdKey + '")';
+ }
+
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("' + camelIdKey + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("' + snakeIdKey + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("' + cp + '")';
+ if (isRestful) {
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/' + cp + '")';
+ if (key != cp) {
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/' + key + '")';
+ }
+ }
+ config += '\n// 可替代上面的 ' + prefix + 'CTX_GET("' + camelIdKey + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'CTX_GET("' + snakeIdKey + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("' + (StringUtil.isEmpty(path) ? '' : path + '/') + camelIdKey + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("' + (StringUtil.isEmpty(path) ? '' : path + '/') + snakeIdKey + '")';
+ }
+ else if (StringUtil.isIdKey(key)) {
+ if (isRestful) {
+ config += prefix + 'PRE_DATA("data/list/0/id")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/0/id")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("list/0/id")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/list/0/' + fd + 'id")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/0/' + fd + 'id")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/list/0/' + fd + 'id")';
+ } else {
+ config += prefix + 'PRE_DATA("[]/0/' + (StringUtil.isEmpty(p) ? '' : kp + '/') + 'id")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("[]/0/' + fd + (col || key) + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("[]/0/' + fd + 'id")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("' + kp + '[]/0/' + (col || key) + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("' + kp + '[]/0/id")';
+ }
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("' + cp + '")';
+ if (isRestful) {
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/' + cp + '")';
+ if (key != cp) {
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/' + (col || key) + '")';
+ }
+ }
+ config += '\n// 可替代上面的 ' + prefix + 'CTX_GET("' + ctxKey + '")';
+ if (isRestful) {
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/id")';
+ }
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("id")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("' + fd + 'id")';
+ if (isRestful) {
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/' + fd + 'id")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/id")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/' + fd + 'id")';
+ }
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("' + fd + 'id")';
+ }
+ else {
+ config += prefix + 'PRE_DATA("' + cp + '", get4Path(req,"' + key + '",null))';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("' + cp + '")';
+ if (isRestful) {
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/' + cp + '")';
+ if (key != cp) {
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/' + key + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("' + key + '")';
+ }
+ } else {
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("' + key + '")';
+ }
+ }
+
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_ARG("' + childPath + '")';
+ if (key != childPath) {
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_ARG("' + key + '")';
+ }
+
+ if (isRestful) {
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/' + cp + '")';
+ }
+ config += '\n// 可替代上面的 ' + prefix + 'CTX_GET("' + ctxKey + '")';
+ if (isRestful) {
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/list/0/' + cp + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("data/0/' + cp + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("list/0/' + cp + '")';
+ config += '\n// 可替代上面的 ' + ctxPutPfx + 'CTX_PUT("[]/0/' + cp + '", "PRE_DATA")';
+ config += '\n// 可替代上面的 ' + ctxPutPfx + 'CTX_PUT("data/0/' + cp + '", "PRE_DATA")';
+ config += '\n// 可替代上面的 ' + ctxPutPfx + 'CTX_PUT("list/0'/ + cp + '", "PRE_DATA")';
+ } else {
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("[]/0/' + cp + '")';
+ config += '\n// 可替代上面的 ' + prefix + 'PRE_DATA("' + kp + '[]/0/' + (col || key) + '")';
+ config += '\n// 可替代上面的 ' + ctxPutPfx + 'CTX_PUT("' + kp + '[]/0/' + (col || key) + '", "PRE_DATA")';
+ config += '\n// 可替代上面的 ' + ctxPutPfx + 'CTX_PUT("[]/0/' + cp + '", "PRE_DATA")';
+ }
+ }
+
+ config += '\n// 可替代上面的 ' + ctxPutPfx + 'CTX_PUT("' + key + '", App.getCurrentAccount())';
+ config += '\n// 可替代上面的 ' + ctxPutPfx + 'CTX_PUT("' + cp + '", "PRE_DATA")';
+ config += '\n// 可替代上面的 ' + ctxPutPfx + 'CTX_PUT("' + childPath + '", "PRE_ARG")';
+ if (key != childPath) {
+ config += '\n// 可替代上面的 ' + ctxPutPfx + 'CTX_PUT("' + key + '", "PRE_DATA")';
+ config += '\n// 可替代上面的 ' + ctxPutPfx + 'CTX_PUT("' + key + '", "PRE_ARG")';
+ }
+ }
+ else if (typeof value == 'boolean') {
if (isBad) {
return prefix + (isRand ? 'RANDOM_BAD_BOOL' : 'ORDER_BAD_BOOL' + offset) + '()'
}
@@ -5208,6 +5434,8 @@ https://github.com/Tencent/APIJSON/issues
var groupName = group.groupName
var isAdd = true
+ var reqObj = this.testCases == null || this.testCases.length <= 0 ? null : this.getRequest()
+ var config = reqObj == null ? '' : StringUtil.trim(this.newRandomConfig(null, '', reqObj))
this.request(true, REQUEST_TYPE_POST, REQUEST_TYPE_JSON, this.server + '/post', {
Chain: {
'rank': this.formatDateTime(StringUtil.isEmpty(nextRank, true) ? null : new Date(new Date(nextRank).getTime() - 10)),
@@ -5216,6 +5444,13 @@ https://github.com/Tencent/APIJSON/issues
'documentId': item.id,
'documentName': item.name
},
+ Random: {
+ toId: 0,
+ documentId: item.id,
+ count: 1,
+ name: '参数传递 ' + App.formatDateTime(),
+ config: config
+ },
tag: 'Chain'
}, {}, function (url, res, err) {
App.onResponse(url, res, err)
@@ -7305,7 +7540,7 @@ https://github.com/Tencent/APIJSON/issues
}
axios.interceptors.request.use(function (config) {
- config.metadata = { startTime: new Date().getTime()}
+ config.metadata = { isChainShow: App.isChainShow, startTime: new Date().getTime() }
return config;
}, function (error) {
return Promise.reject(error);
@@ -8201,7 +8436,7 @@ Content-Type: ` + contentType) + (StringUtil.isEmpty(headerStr, true) ? '' : hea
var methods = this.methods
var types = this.types
- //修改 Document
+ // Document
this.request(true, REQUEST_TYPE_POST, REQUEST_TYPE_JSON, this.server + '/get', {
format: false,
'Document[]': {
@@ -8834,8 +9069,10 @@ Content-Type: ` + contentType) + (StringUtil.isEmpty(headerStr, true) ? '' : hea
return;
}
- var time = res.config == null || res.config.metadata == null ? 0 : (res.config.metadata.startTime || 0)
- if (time < this.lastDocReqTime) {
+ var config = res.config
+ var metadata = config == null ? null : config.metadata
+ var time = metadata == null ? 0 : (metadata.startTime || 0)
+ if (time < this.lastDocReqTime || (metadata != null && metadata.isChainShow != null && metadata.isChainShow != this.isChainShow)) {
return
}