|
@@ -2,22 +2,22 @@
|
|
|
input = INPUT;
|
|
|
output = {};
|
|
|
|
|
|
-try{
|
|
|
- input = decodeURIComponent( input );
|
|
|
-} catch(e){}
|
|
|
-try{
|
|
|
+try {
|
|
|
+ input = decodeURIComponent(input);
|
|
|
+} catch (e) { }
|
|
|
+try {
|
|
|
input = base64.decode(input);
|
|
|
-} catch(e){}
|
|
|
-try{
|
|
|
+} catch (e) { }
|
|
|
+try {
|
|
|
input = JSON.parse(input);
|
|
|
input = JSON.parse(input); // 解析可能存在的重复编码
|
|
|
-}catch(e){}
|
|
|
+} catch (e) { }
|
|
|
|
|
|
// 环境配置参数,配置定义在etcd:/matrix/data/api/cfg.json
|
|
|
cfg = {}
|
|
|
-try{
|
|
|
- cfg.env = "prod";//JSON.parse(etcd.get("/api/cfg.json"));
|
|
|
-}catch(e){}
|
|
|
+try {
|
|
|
+ cfg.env = "test";//JSON.parse(etcd.get("/api/cfg.json"));
|
|
|
+} catch (e) { }
|
|
|
|
|
|
/*
|
|
|
{"kpi_key":"kpi.IBPS.101.sendnode-recvnode-ratio","timestamp":1669087620,"value":0.9967} 网银应答率
|
|
@@ -43,161 +43,198 @@ try{
|
|
|
{"kpi_key":"kpi.HVPS.MachinAvgDealTime","timestamp":1669087680,"value":1645.3793} 大额处理时间
|
|
|
{"kpi_key":"kpi.HVPS.FailCount","timestamp":1669087680,"value":0} 大额失败笔数
|
|
|
|
|
|
-*/
|
|
|
-function getDataFromOmdb(type,tms,tme){
|
|
|
-
|
|
|
+*/
|
|
|
+function getDataFromOmdb(type, tms, tme) {
|
|
|
+
|
|
|
var data = [];
|
|
|
var kpiDef = [
|
|
|
- {"kpi_key":"kpi.IBPS.101.sendnode-recvnode-ratio", title: "网银应答率", "name": "RR" },
|
|
|
- {"kpi_key":"kpi.IBPS.SuccPer", "title":"网银成功率", "name":"RS"},
|
|
|
- {"kpi_key":"kpi.IBPS.TransCount", "title":"网银交易量", "name":"RV"},
|
|
|
- {"kpi_key":"kpi.IBPS.MachinAvgDealTime", "title":"网银处理时间", "name":"RD"},
|
|
|
- {"kpi_key":"kpi.IBPS.FailCount", "title":"网银失败笔数", "name":"FV"},
|
|
|
-
|
|
|
- {"kpi_key":"kpi.FXCC.SuccPer", "title":"外币成功率", "name":"RS"},
|
|
|
- {"kpi_key":"kpi.FXCC.TransCount", "title":"外币交易量", "name":"RV"},
|
|
|
- {"kpi_key":"kpi.FXCC.MachinAvgDealTime", "title":"外币处理时间", "name":"RD"},
|
|
|
- {"kpi_key":"kpi.FXCC.FailCount", "title":"外币失败笔数", "name":"FV"},
|
|
|
-
|
|
|
- {"kpi_key":"kpi.BEPS.SuccPer", "title":"小额成功率", "name":"RS"},
|
|
|
- {"kpi_key":"kpi.BEPS.TransCount", "title":"小额交易量", "name":"RV"},
|
|
|
- {"kpi_key":"kpi.BEPS.MachinAvgDealTime", "title":"小额处理时间", "name":"RD"},
|
|
|
- {"kpi_key":"kpi.BEPS.FailCount", "title":"小额失败笔数", "name":"FV"},
|
|
|
-
|
|
|
- {"kpi_key":"kpi.HVPS.SuccPer", "title":"大额成功率", "name":"RS"},
|
|
|
- {"kpi_key":"kpi.HVPS.TransCount", "title":"大额交易量", "name":"RV"},
|
|
|
- {"kpi_key":"kpi.HVPS.MachinAvgDealTime", "title":"大额处理时间", "name":"RD"},
|
|
|
- {"kpi_key":"kpi.HVPS.FailCount", "title":"大额失败笔数", "name":"FV"}];
|
|
|
- var kpiGroup = _.groupBy(kpiDef,function(v){ return v.kpi_key.split(".")[1]; });
|
|
|
-
|
|
|
- if(!kpiGroup[type]) return [];
|
|
|
-
|
|
|
- var kpiObj = {"RR":100, "RS":100, "RV":0, "RD":0, "FV":0};
|
|
|
-
|
|
|
- kpiGroup[type].forEach(function(v){
|
|
|
-
|
|
|
+ { "kpi_key": "kpi.IBPS.101.sendnode-recvnode-ratio", title: "网银应答率", "name": "RR" },
|
|
|
+ { "kpi_key": "kpi.IBPS.SuccPer", "title": "网银成功率", "name": "RS" },
|
|
|
+ { "kpi_key": "kpi.IBPS.TransCount", "title": "网银交易量", "name": "RV" },
|
|
|
+ { "kpi_key": "kpi.IBPS.MachinAvgDealTime", "title": "网银处理时间", "name": "RD" },
|
|
|
+ { "kpi_key": "kpi.IBPS.FailCount", "title": "网银失败笔数", "name": "FV" },
|
|
|
+
|
|
|
+ { "kpi_key": "kpi.FXCC.SuccPer", "title": "外币成功率", "name": "RS" },
|
|
|
+ { "kpi_key": "kpi.FXCC.TransCount", "title": "外币交易量", "name": "RV" },
|
|
|
+ { "kpi_key": "kpi.FXCC.MachinAvgDealTime", "title": "外币处理时间", "name": "RD" },
|
|
|
+ { "kpi_key": "kpi.FXCC.FailCount", "title": "外币失败笔数", "name": "FV" },
|
|
|
+
|
|
|
+ { "kpi_key": "kpi.BEPS.SuccPer", "title": "小额成功率", "name": "RS" },
|
|
|
+ { "kpi_key": "kpi.BEPS.TransCount", "title": "小额交易量", "name": "RV" },
|
|
|
+ { "kpi_key": "kpi.BEPS.MachinAvgDealTime", "title": "小额处理时间", "name": "RD" },
|
|
|
+ { "kpi_key": "kpi.BEPS.FailCount", "title": "小额失败笔数", "name": "FV" },
|
|
|
+
|
|
|
+ { "kpi_key": "kpi.HVPS.SuccPer", "title": "大额成功率", "name": "RS" },
|
|
|
+ { "kpi_key": "kpi.HVPS.TransCount", "title": "大额交易量", "name": "RV" },
|
|
|
+ { "kpi_key": "kpi.HVPS.MachinAvgDealTime", "title": "大额处理时间", "name": "RD" },
|
|
|
+ { "kpi_key": "kpi.HVPS.FailCount", "title": "大额失败笔数", "name": "FV" }];
|
|
|
+ var kpiGroup = _.groupBy(kpiDef, function (v) { return v.kpi_key.split(".")[1]; });
|
|
|
+
|
|
|
+ if (!kpiGroup[type]) return [];
|
|
|
+
|
|
|
+ var kpiObj = { "RR": 100, "RS": 100, "RV": 0, "RD": 0, "FV": 0 };
|
|
|
+
|
|
|
+ kpiGroup[type].forEach(function (v) {
|
|
|
+
|
|
|
var comp = _.template("select id,stats.find(name='<%= name %>').time('<%=tms %>','<%= tme%>') from /cncc/entity/biz where name='<%=bizname%>'");
|
|
|
-
|
|
|
+
|
|
|
var mql = comp({
|
|
|
name: v.kpi_key,
|
|
|
- tms: new Date(tms - 3600*8*1000).toLocaleString(),
|
|
|
- tme: new Date(tme - 3600*8*1000 + 60000).toLocaleString(),
|
|
|
+ tms: new Date(tms - 3600 * 8 * 1000).toLocaleString(),
|
|
|
+ tme: new Date(tme - 3600 * 8 * 1000 + 60000).toLocaleString(),
|
|
|
bizname: type
|
|
|
})
|
|
|
webcontext.admin(true);
|
|
|
var res = odb.mql(mql).data[0].stats;
|
|
|
-
|
|
|
- if(_.isEmpty(res)) return;
|
|
|
-
|
|
|
+
|
|
|
+ if (_.isEmpty(res)) return;
|
|
|
+
|
|
|
var o = {};
|
|
|
o[v.name] = res[0][2];
|
|
|
-
|
|
|
+
|
|
|
_.extend(kpiObj, o);
|
|
|
})
|
|
|
-
|
|
|
+
|
|
|
data.push(_.extend({
|
|
|
- type: type,
|
|
|
- time : new Date(tms)},kpiObj)
|
|
|
- );
|
|
|
+ type: type,
|
|
|
+ time: new Date(tms)
|
|
|
+ }, kpiObj)
|
|
|
+ );
|
|
|
return data;
|
|
|
}
|
|
|
|
|
|
// 函数定义
|
|
|
// 从ODB获取数据
|
|
|
-function getData(type, tms, tme){
|
|
|
+function getData(type, tms, tme) {
|
|
|
var data = [];
|
|
|
- // TODO: 从ODB获取数据
|
|
|
- if( cfg.env == "test"){
|
|
|
- // 从测试模拟数据
|
|
|
- for (var t = tms; t <= tme; t += 60 * 1000){
|
|
|
- data.push({
|
|
|
- type: type,
|
|
|
- time : new Date(t),
|
|
|
- RV: parseInt(Math.random() * 500 + 1000), // 交易量
|
|
|
- RS: Math.random() * 5 + 95, // 系统成功率
|
|
|
- RD: parseInt(Math.random() * 500 + 100), // 平均响应时间
|
|
|
- RR: Math.random() * 5 + 95, // 交易响应率
|
|
|
- FV: parseInt(Math.random() * 10) // 失败笔数
|
|
|
- });
|
|
|
- }
|
|
|
- }else{
|
|
|
+ try {
|
|
|
+ // 从ODB获取数据
|
|
|
data = getDataFromOmdb(type, tms, tme);
|
|
|
+ return data
|
|
|
+ } catch (e) {
|
|
|
+ if (cfg.env == "test") {
|
|
|
+ // 从测试模拟数据
|
|
|
+ for (var t = tms; t <= tme; t += 60 * 1000) {
|
|
|
+ data.push({
|
|
|
+ type: type,
|
|
|
+ time: new Date(t),
|
|
|
+ RV: parseInt(Math.random() * 500 + 1000), // 交易量
|
|
|
+ RS: Math.random() * 5 + 95, // 系统成功率
|
|
|
+ RD: parseInt(Math.random() * 500 + 100), // 平均响应时间
|
|
|
+ RR: Math.random() * 5 + 95, // 交易响应率
|
|
|
+ FV: parseInt(Math.random() * 10) // 失败笔数
|
|
|
+ });
|
|
|
+ }
|
|
|
+ return data
|
|
|
+ }
|
|
|
+ throw(e)
|
|
|
}
|
|
|
- OUTPUT = data;
|
|
|
- return data;
|
|
|
};
|
|
|
|
|
|
+//对浮点数格式化,防止出现0.99999998的现象(f为浮点数,size中保留小数位数)
|
|
|
+function floatRound(f, size) {
|
|
|
+ var tf = f * Math.pow(10, size);
|
|
|
+ tf = Math.round(tf + 0.000000001);
|
|
|
+ tf = tf / Math.pow(10, size);
|
|
|
+ return tf;
|
|
|
+}
|
|
|
+//格式化浮点数字符串,保证其有给定的小数位数。其中f是浮点数的字符串常量,size是保留小数位数
|
|
|
+function floatFormat(f, size) {
|
|
|
+ var tf = floatRound(f, size);
|
|
|
+ var sf = "" + tf;
|
|
|
+ aa = sf.split("");
|
|
|
+ var varchar = "";
|
|
|
+ var num = 0, k = 0; //num是已得小数点位数,K用来作是否到小数点控制
|
|
|
+ for (var i = 0; i < aa.length; i++) {
|
|
|
+ varchar += aa[i];
|
|
|
+ if (aa[i] == ".") {
|
|
|
+ k = 1;
|
|
|
+ }
|
|
|
+ if (k == 1) {
|
|
|
+ num++;
|
|
|
+ if (num > size) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ num--;
|
|
|
+ //如果位数不够,则补0
|
|
|
+ for (; num < size; num++) {
|
|
|
+ varchar += "0";
|
|
|
+ }
|
|
|
+ return varchar;
|
|
|
+}
|
|
|
|
|
|
// 格式化数据
|
|
|
-function formatData(data){
|
|
|
- if(data.length == 0){
|
|
|
- // 无数据返回 {}
|
|
|
- return {};
|
|
|
- }
|
|
|
- for(var i = 0; i < data.length; i++){
|
|
|
- data[i].time = data[i].time.toJSON().replace(/[TZ]/mg," ").substring(0,16); // 时间格式: yyyy-MM-dd HH:mm
|
|
|
- data[i].RV = "" + parseInt(data[i].RV);//parseInt(data[i].RV); // 交易量
|
|
|
- data[i].RS = "" + parseInt(data[i].RS * 10000) / 100;//parseInt(data[i].RS * 100) / 100; // 系统成功率,四舍五入保留2位小数,系统成功率 <= 100
|
|
|
- data[i].RD = "" + parseInt(data[i].RD);//parseInt(data[i].RD); // 平均响应时间,单位ms, 四舍五入取整
|
|
|
- data[i].RR = "" + parseInt(data[i].RR * 10000) / 100;//parseInt(data[i].RR); // 交易响应率,四舍五入保留2位小数,系统成功率 <= 100
|
|
|
- data[i].FV = "" + parseInt(data[i].FV);//parseInt(data[i].FV); // 失败笔数, 1分钟统计周期内,失败交易笔数
|
|
|
- }
|
|
|
- if(data.length == 1){
|
|
|
- // 单条数据直接返回对象
|
|
|
- data = data[0];
|
|
|
- }
|
|
|
- return data;
|
|
|
+function formatData(data) {
|
|
|
+ if (data.length == 0) {
|
|
|
+ // 无数据返回 {}
|
|
|
+ return {};
|
|
|
+ }
|
|
|
+ for (var i = 0; i < data.length; i++) {
|
|
|
+ data[i].time = data[i].time.toJSON().replace(/[TZ]/mg, " ").substring(0, 16); // 时间格式: yyyy-MM-dd HH:mm
|
|
|
+ data[i].RV = "" + parseInt(data[i].RV);//parseInt(data[i].RV); // 交易量
|
|
|
+ data[i].RS = floatFormat(parseInt(data[i].RS * 10000) / 100, 2);//parseInt(data[i].RS * 100) / 100; // 系统成功率,四舍五入保留2位小数,系统成功率 <= 100
|
|
|
+ data[i].RD = "" + parseInt(data[i].RD);//parseInt(data[i].RD); // 平均响应时间,单位ms, 四舍五入取整
|
|
|
+ data[i].RR = floatFormat(parseInt(data[i].RR * 10000) / 100, 2);//parseInt(data[i].RR); // 交易响应率,四舍五入保留2位小数,系统成功率 <= 100
|
|
|
+ data[i].FV = "" + parseInt(data[i].FV);//parseInt(data[i].FV); // 失败笔数, 1分钟统计周期内,失败交易笔数
|
|
|
+ }
|
|
|
+ if (data.length == 1) {
|
|
|
+ // 单条数据直接返回对象
|
|
|
+ data = data[0];
|
|
|
+ }
|
|
|
+ return data;
|
|
|
}
|
|
|
|
|
|
// 解析时间字符串,格式为:yyyyMMddHHmm
|
|
|
-function parseTime(ymdhm){
|
|
|
- try{
|
|
|
- if(!/^\d{12}$/.test(ymdhm) ){
|
|
|
+function parseTime(ymdhm) {
|
|
|
+ try {
|
|
|
+ if (!/^\d{12}$/.test(ymdhm)) {
|
|
|
throw ("format error")
|
|
|
}
|
|
|
-
|
|
|
- var d = new Date( parseInt(ymdhm.substring(0,4)), parseInt(ymdhm.substring(4,6)) - 1, parseInt(ymdhm.substring(6,8)), parseInt(ymdhm.substring(8,10)), parseInt(ymdhm.substring(10,12)) );
|
|
|
+
|
|
|
+ var d = new Date(parseInt(ymdhm.substring(0, 4)), parseInt(ymdhm.substring(4, 6)) - 1, parseInt(ymdhm.substring(6, 8)), parseInt(ymdhm.substring(8, 10)), parseInt(ymdhm.substring(10, 12)));
|
|
|
d.setMinutes(d.getMinutes() - d.getTimezoneOffset());
|
|
|
return d;
|
|
|
}
|
|
|
- catch(e){
|
|
|
+ catch (e) {
|
|
|
throw ("时间格式错误,正确格式是yyyyMMddHHmm");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 主执行阶段
|
|
|
-try{
|
|
|
+try {
|
|
|
// 参数检查
|
|
|
var type = input.type;
|
|
|
- if(!type){
|
|
|
- throw("必须指定参数 type, 如:HVPS,BEPS,IBPS,FXPS");
|
|
|
+ if (!type) {
|
|
|
+ throw ("必须指定参数 type, 如:HVPS,BEPS,IBPS,FXPS");
|
|
|
}
|
|
|
var starttime = input.time;
|
|
|
- if(!starttime){
|
|
|
+ if (!starttime) {
|
|
|
throw ("必须指定参数time,格式为:yyyyMMddHHmm");
|
|
|
}
|
|
|
var endtime = input.endtime; // 可选参数,指定结束时间,可以获取一段时间的数据
|
|
|
- if(!endtime){
|
|
|
- endtime = input.time;
|
|
|
+ if (!endtime) {
|
|
|
+ endtime = input.time;
|
|
|
}
|
|
|
// 参数解析
|
|
|
- var tms = parseTime("" +starttime).getTime();
|
|
|
- var tme = parseTime("" +endtime).getTime();
|
|
|
-
|
|
|
+ var tms = parseTime("" + starttime).getTime();
|
|
|
+ var tme = parseTime("" + endtime).getTime();
|
|
|
+
|
|
|
// 数据获取
|
|
|
var data = getData(type, tms, tme);
|
|
|
-
|
|
|
+
|
|
|
// 数据格式化
|
|
|
data = formatData(data);
|
|
|
// 数据输出
|
|
|
output.data = data;
|
|
|
}
|
|
|
-catch(e){
|
|
|
+catch (e) {
|
|
|
// 错误信息输出处理,抛出ok表示正常结束
|
|
|
- if(e != "ok"){
|
|
|
- if( typeof (e) == "object"){
|
|
|
+ if (e != "ok") {
|
|
|
+ if (typeof (e) == "object") {
|
|
|
output.error = e;
|
|
|
- } else if( typeof (e) == "string"){
|
|
|
+ } else if (typeof (e) == "string") {
|
|
|
output.error = "错误:" + e;
|
|
|
} else {
|
|
|
output.error = JSON.stringify(e);
|