public with sharing class NFM501Controller implements Queueable { //先定义 //add aws response public class AllData { public String code; public QLMData data; public String msg; } public class QLMData { public String cursorMark; public ListItem[] list1; } public class ListItem { public String[] ZhaoBiaoUnit; public String infoId; //public String extractProjName;// public String infoTitle; public String keywords; public String biddingType; public String infoQianlimaUrl; public String[] ZhaoRelationWay; public String isElectronic; public String xmNumber; public String tenderEndTime; public String areaProvince; public String[] ZhongBiaoUnit; public String[] moreZhongBiaoUnit;// add 2021/12/03 fxk public String allKeywords;// add 2021/12/06 fxk public String infoType; public String openBidingTime; public String[] AgentRelationWay; public String[] InfoFile; public AmountItem[] Budget; public String infoPublishTime; public String[] AgentRelationName; public String bidingEndTime; public AmountItem[] WinnerAmount; public String[] ZhongRelationWay; public String bidingAcquireTime; public String tenderBeginTime; public Target Target; public String areaCity; public String areaCountry; public String[] AgentUnit; public String projectId; public String[] ZhaoRelationName; public String[] ZhongRelationName; public String infoTypeSegment; //add aws pi start sushanhu 20220223 start public String[] AgentRelationWayEncrypted;//代理机构联系方式密文 public String[] AgentRelationNameEncrypted;//代理机构联系方式人密文 public String[] ZhongRelationWayEncrypted;//中标单位联系方式密文 public String[] ZhongRelationNameEncrypted;//中标单位联系人密文 public String[] ZhaoRelationNameEncrypted;//招标单位联系人密文 public String[] ZhaoRelationWayEncrypted;//招标单位联系方式密文 public String DataId;// AWS 存储凭据 //add aws pi start sushanhu 20220223 start } public class AmountItem { public String Amount; public String Unit; } public class Target { public String SumUnit; public String Sum; public TargetDetailsItem[] TargetDetails; } public class TargetDetailsItem { public String number1; public String priceUnit; public String tarKeyword; public String totalPrice; public String price; public String totalPriceUnit; public String name; public String model; public String brand; public String numberUnit; } public NFM501Controller() { } // 最大值为3,用来作为判断错误的条件(重发三次) public static Integer batch_retry_max_cnt = Integer.valueOf(System.Label.batch_retry_max_cnt); public void execute(QueueableContext context) { //1、检索IF转换表中,关于之前的cMark(游标) BatchIF_Transfer__c oldMark = [Select ID, Internal_Value__c FROM BatchIF_Transfer__c Where Table__c = 'QLMoldMark']; //检索rowData日志(当存在日志中的GroupNumber字段中的Mark与转换表存的Mark一致) List rowDataList = [select Id, Name, Log__c, ErrorLog__c, Log2__c, Log3__c, Log4__c, Log5__c, Log6__c, Log7__c, Log8__c, Log9__c, Log10__c, Log11__c, Log12__c, MessageGroupNumber__c from BatchIF_Log__c where RowDataFlg__c = true and MessageGroupNumber__c = :oldMark.Internal_Value__c ]; System.debug('-------1-------' + rowDataList); //如果没有rowdata日志,则创建日志 BatchIF_Log__c rowData = new BatchIF_Log__c(); if (rowDataList == null || rowDataList.size() == 0) { rowData.Type__c = 'NFM501'; rowData.RowDataFlg__c = true; rowData.MessageGroupNumber__c = oldMark.Internal_Value__c; insert rowData; System.debug('-------2-------'); //如果只存在一个日志,将其第一个日志赋值给rowdata日志 } else if (rowDataList.size() >= 1) { rowData = rowDataList[0]; System.debug('-------3-------'); } //如果存在两个日志, //else if(rowDataList.size() == 2){ // if(rowDataList[0].last_501__c){ // rowData =rowDataList[0]; // }else{ // rowData =rowDataList[1]; // } // } //创建一个iflog日志表,用来存报错信息 BatchIF_Log__c iflog = new BatchIF_Log__c(); iflog.Type__c = 'NFM501'; iflog.RowDataFlg__c = false; iflog.MessageGroupNumber__c = oldMark.Internal_Value__c; iflog.Log__c = ''; iflog.ErrorLog__c = ''; insert iflog; NFM501Controller.sendRequest( rowData.id, iflog.id, false); } @future(callout = true) public static void sendRequest(String rowDataid, String iflogid, boolean Manual_execution501) { BatchIF_Log__c rowData = [select Id, Name, Log__c, ErrorLog__c, Log2__c, Log3__c, Log4__c, Log5__c, Log6__c, Log7__c, Log8__c, Log9__c, Log10__c, Log11__c, Log12__c, MessageGroupNumber__c, retry_cnt__c from BatchIF_Log__c where id = : rowDataid ]; system.debug('-------4-------'); BatchIF_Log__c iflog = [select Id, Name, Log__c, ErrorLog__c, Log2__c, Log3__c, Log4__c, Log5__c, Log6__c, Log7__c, Log8__c, Log9__c, Log10__c, Log11__c, Log12__c, MessageGroupNumber__c, retry_cnt__c from BatchIF_Log__c where id = : iflogid ]; // 由于检索出来的rowData和iflog为空,则进行一下判断 iflog.Log__c = iflog.Log__c == null ? '' : iflog.Log__c; iflog.ErrorLog__c = iflog.ErrorLog__c == null ? '' : iflog.ErrorLog__c; rowData.Log__c = rowData.Log__c == null ? '' : rowData.Log__c; rowData.ErrorLog__c = rowData.ErrorLog__c == null ? '' : rowData.ErrorLog__c; System.debug('iflog:12345678' + iflog); // Savepoint sp = Database.setSavepoint(); try { String token; Datetime oldTime; // aaaaaaaa 这里检索需要换行,否则一行看不见 // 从转换表里检索token及其获取结束时间 BatchIF_Transfer__c oldTimeTran = [Select ID, NFM501_Gain_End_Time__c FROM BatchIF_Transfer__c Where Table__c = 'NFM501GainEndTime']; BatchIF_Transfer__c tokenTran = [Select ID, NFM501_Token__c FROM BatchIF_Transfer__c Where Table__c = 'NFM501Token']; BatchIF_Transfer__c oldMark = [Select ID, Internal_Value__c FROM BatchIF_Transfer__c Where Table__c = 'QLMoldMark']; System.debug('oldTimeTran=' + oldTimeTran.NFM501_Gain_End_Time__c + 'tokenTran=' + tokenTran.NFM501_Token__c); //1、 获取token(token每过两小时会失效重新获取,以下逻辑使token每30分钟自动获取一遍): token = tokenTran.NFM501_Token__c; oldTime = oldTimeTran.NFM501_Gain_End_Time__c ; Long timeslot; Datetime newTime = System.now(); // System.debug('++++1++++'+oldTime); // System.debug('++++2++++'+newTime); if (oldTime == null) { timeslot = 2800000; } else { timeslot = newTime.getTime() - oldTime.getTime(); } System.debug('++++1++++' + token + ' : ' + timeslot); if (string.isblank(token) || timeslot > 1800000) { System.debug('++++2++++' + token + ' : ' + timeslot); // NFMUtil.response response = NFMUtil.receiveToken(); //update to aws token sushanhu start 20220223 NFMUtil.response response=NFMUtil.getAwsToken(); //update to aws token sushanhu end 20220223 System.debug('++++response++++' + response); //判断rowdata中数据获取成功与否,如果失败重发三次,如果大于三次则手动操作 if (String.isBlank(response.responseBody)) { System.debug('response.responseBody:' + response.responseBody); iflog.ErrorLog__c = '501token:' + response.status; if (!Manual_execution501) { NFM501Controller.againSendRequest(iflog, 'retry_cnt__c', rowData); } // aaaaaaaa 既然是token 抓取失败,那么这里就不应该更新 return; } //获取token token = response.responseBody; System.debug('-------6-------' + token); //获取结束时间 oldTime = Datetime.now(); // 为转换表中重新附上新值 tokenTran.NFM501_Token__c = token; oldTimeTran.NFM501_Gain_End_Time__c = oldTime; } // //替换获取到数据中的关键字 // NFMUtil.response response = NFMUtil.getQLMData(NFMUtil.NFM501_ENDPOINT // + oldMark.Internal_Value__c + '/10', token); // // aaaaaaaa 这里顺序错了,肯定是应该先判断是不是因为http 报错,然后才是千里马的code解析 //update to aws start sushanhu 20220223 PIHelper.PIIntegration NFM501AWS =PIHelper.getPIIntegrationInfo('QLMNFM501'); NFMUtil.response response = NFMUtil.getAWSQLMData(NFM501AWS.newUrl+'cursorMark=' + oldMark.Internal_Value__c + '&pageSize=10', token); //update to aws sushanhu end 20220223 //http的报错处理(重发三遍) // if (String.isBlank(response.responseBody)) { System.debug('-------7-------'); // aaaaaaaa 报错原因写的不对 iflog.ErrorLog__c = '501Http报错信息:' + response.status; if (!Manual_execution501) { NFM501Controller.againSendRequest(iflog, 'retry_cnt__c', rowData); } update tokenTran; update oldTimeTran; return; } // aaaaaaaa 这里这个字段可以改名为NFM501Response 之类的,这样就有区分度了 // 解析后的code报错处理 String NFM501responseBody = response.responseBody; System.debug('-------------NFM501responseBody------------' + NFM501responseBody); //update to aws response sushanhu 20220223 start Map results = (Map) JSON.deserializeUntyped(NFM501responseBody); //String qlmResult =(String)results.get('object'); String qlmResult =JSON.serialize(results.get('object')); System.debug('-------------NFM501responseBody qlmResult------------' + qlmResult); // NFM501responseBody = NFM501responseBody.replaceAll('"list"', '"list1"').replaceAll('"number":', '"number1":'); NFM501responseBody = qlmResult.replaceAll('"list"', '"list1"').replaceAll('"number":', '"number1":'); //update to aws response sushanhu 20220223 end AllData getQLMData = (AllData) JSON.deserializeStrict(NFM501responseBody, AllData.class); System.debug('-------------8------------' + getQLMData); if (!getQLMData.code.equals('0')) { System.debug('-------99-------'); iflog.ErrorLog__c = '501解析:' + getQLMData.msg ; if (!Manual_execution501) { NFM501Controller.againSendRequest(iflog, 'retry_cnt__c', rowData); } update tokenTran; update oldTimeTran; return; } rowData = NFMUtil.QLMmakeRowData(NFM501responseBody, rowData); rowData.AWS_Transaction_Id__c = (String)results.get('txId');// add for pi susanhu 20220310 update rowData; system.debug('rowData---'+rowData); System.debug('======2221234======'); update tokenTran; update oldTimeTran; String newMark = getQLMData.data.cursorMark; //4、新旧mark对比,如果不相等重新接收数据,并把新mark存入转换表中,之后更新; if (!newMark.equals(oldMark.Internal_Value__c)) { System.debug('1234567'); oldMark.Internal_Value__c = newMark; update oldMark; if (!Test.isRunningTest()) { System.enqueueJob(new NFM501FutureController(rowData.id)); } NFM501Schedule2.assignOneMinute(); } else if (newMark.equals(oldMark.Internal_Value__c) || Test.isRunningTest()) { // 之前数据抓取完毕后,过十分钟后,整体抓取503附件 NFM503InfoFileSchedule.assignOneMinute(); // 12点自动抓取招投标数据 // NFM501Controller.TwoMarkEqualAgainSend(); } rowData.retry_cnt__c = 0; if (System.Test.isRunningTest()) { throw new ControllerUtil.myException('aaa'); } } catch (Exception ex) { // Database.rollback(sp); System.debug('rollback'); // System.debug(Logginglevel.ERROR, 'QLMData_' + rowData.MessageGroupNumber__c + ':' + ex.getMessage()); // System.debug(Logginglevel.ERROR, 'QLMData_' + rowData.MessageGroupNumber__c + ':' + ex.getStackTraceString()); // logstr += '\n' + ex.getMessage(); iflog.ErrorLog__c = '501抛出异常:' + ex.getMessage() + '\n' + ex.getStackTraceString() + '\n' + iflog.ErrorLog__c; if (!Manual_execution501) { NFM501Controller.NFM501againSendExceptionRequest(iflog, 'retry_cnt__c', rowData, '501抛出异常:' + ex.getMessage() + '\n' + ex.getStackTraceString() + '\n' + rowData.ErrorLog__c + '错误次数已经超过自动收信设定的最大次数,请手动收信'); } } update rowData; System.debug('+++++++5+++++++' + rowData); System.debug('+++++++3+++++++' + iflog.Log__c); System.debug('+++++++2+++++++' + iflog.ErrorLog__c); //如果存入信息超出限制,用省略号代替 if (iflog.Log__c.length() > 131072) { iflog.Log__c = iflog.Log__c.subString(0, 131065) + ' ...'; } if (iflog.ErrorLog__c.length() > 32768) { iflog.ErrorLog__c = iflog.ErrorLog__c.subString(0, 32760) + ' ...'; } upsert iflog; } public static void againSendRequest(BatchIF_Log__c iflog, String count, BatchIF_Log__c rowData ) { //判断rowdata中数据获取成功与否,如果失败重发三次,如果大于三次则手动操作 System.debug('-------9-------'); Integer rowDataStr = Integer.valueOf(rowData.get(count)); rowDataStr = 0; if (rowDataStr == null) rowDataStr = 0; if (rowDataStr < batch_retry_max_cnt) { rowDataStr++; NFM501Schedule2.assignOneMinute(); } if (rowDataStr >= batch_retry_max_cnt) { iflog.ErrorLog__c += '错误次数已经超过自动收信设定的最大次数,请手动收信'; rowData.ErrorLog__c += '错误次数已经超过自动收信设定的最大次数,请手动收信'; } upsert rowData; upsert iflog; rowData.put(count, rowDataStr); } public static void againSendExceptionRequest(BatchIF_Log__c iflog, String count, BatchIF_Log__c rowData, String errorStr ) { //判断rowdata中数据获取成功与否,如果失败重发三次,如果大于三次则手动操作 System.debug('=======9-------'); Integer rowDataStr = Integer.valueOf(rowData.get(count)); if (rowDataStr == null) { rowDataStr = 0; } if (rowDataStr < batch_retry_max_cnt) { rowDataStr++; LogAutoSendSchedule.assignOneMinute(); } if (rowDataStr >= batch_retry_max_cnt) { rowData.ErrorLog__c += errorStr; } rowData.put(count, rowDataStr); } public static void NFM501againSendExceptionRequest(BatchIF_Log__c iflog, String count, BatchIF_Log__c rowData, String errorStr ) { //判断rowdata中数据获取成功与否,如果失败重发三次,如果大于三次则手动操作 System.debug('=======9-------'); Integer rowDataStr = Integer.valueOf(rowData.get(count)); if (rowDataStr == null) { rowDataStr = 0; } if (rowDataStr < batch_retry_max_cnt) { rowDataStr++; NFM501Schedule2.assignOneMinute(); } if (rowDataStr >= batch_retry_max_cnt) { rowData.ErrorLog__c += errorStr; } rowData.put(count, rowDataStr); } // 12点自动抓取招投标数据 // public static void TwoMarkEqualAgainSend() { // DateTime now = System.now(); // if (now.hour() < 12) { // NFM501Schedule2.assignTwoMinute(); // } // } public static void test() { integer i = 0; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; } } //rowData中创建token ,时间字段的原因, // //把错误信息提出来做成公用方法 // // // token = b.access_token; // //解析从千里马数据库获取到的数据(解析成类形式) // QLMData getQLMData = (QLMData) JSON.deserializeStrict(responseBody2, QLMData.class); // if (getQLMData == null ) { // return; // } // BatchIF_Log__c rowData = NFMUtil.QLMsaveRowData( 'QLMData', getQLMData); // System.debug('----------1--------'+rowData); // if (String.isBlank(rowData.Log__c) == false){ // NFM501FutureController.execute('a001s000002LNiP'); // } //将cursormark存在IF转换表中,循环与之前的mark做对比,知道现在的与前一个mark相同,这说明数据全部获取完成 //1、检索IF转换表中,关于之前的cMark // BatchIF_Transfer__c oldMark = [Select ID, Internal_Value__c FROM BatchIF_Transfer__c Where Table__c = 'QLMoldMark']; // //2、取新获取的cMark // String newMark = getQLMData.cursorMark; // //3、将数据存到日志中() // iflog1.Log__c = response2.getBody(); // insert iflog1; // //4、新旧mark对比,如果不相等重新接收数据,并把新mark存入转换表中,之后更新; // if(newMark != oldMark.Internal_Value__c){ // System.enqueueJob(new NFM501Controller(token, oldTime)); // oldMark.Internal_Value__c = newMark; // update oldMark; // } // List infourlList = new List(); // for(ListItem u : getQLMData.list1){ // infourlList.add(u.infoQianlimaUrl); // } // //3、获取网页:记得使用1中获取的token,记得EndPoint 使用2中获取的网页 // Http http3 = new Http(); // HttpRequest req3 = new HttpRequest(); // req3.setHeader('Content-Type','application/x-www-form-urlencoded'); // req3.setHeader('open-authorization', 'Bearer'+token); // req3.setTimeout(120000); // req3.setEndpoint('http://cusdata.qianlima.com/test/v1/info/detailHtml?url='+infourlList); // req3.setMethod('GET'); // HTTPResponse response3 = http3.send(req3); // String responseBody3 = response3.getBody(); // //截切数据(使数据成为解析的格式) // Integer start1 = responseBody3.indexOf('