package fi.cas.opplugin; import kd.bos.dataentity.entity.DynamicObject; import kd.bos.entity.EntityMetadataCache; import kd.bos.logging.Log; import kd.bos.logging.LogFactory; import kd.bos.orm.query.QFilter; import kd.bos.servicehelper.BusinessDataServiceHelper; import java.io.*; import java.math.RoundingMode; import java.net.Socket; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.Map; import kd.bos.servicehelper.operation.OperationServiceHelper; import kd.bos.servicehelper.operation.SaveServiceHelper; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.json.JSONObject; import org.json.XML; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; public class PayBillToolUtil { public static final String ENTITY_NAME = "cas_paybill"; protected static final Log log = LogFactory.getLog(PayBillToolUtil.class); public static String createSinglePaymentRequest(DynamicObject payBillEntity) { try { DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); Document doc = dBuilder.newDocument(); Element rootElement = doc.createElement("Message"); doc.appendChild(rootElement); Element body = doc.createElement("Body"); rootElement.appendChild(body); createElement(doc, body, "transcode", "BTSCO001"); createElement(doc, body, "trxcode", "jfgx");//渠道交易代码 createElement(doc, body, "channelcode", "经费共享");//发起渠道 Calendar currentdate = Calendar.getInstance(); createElement(doc, body, "channeldate", TypeUtils.date2String(currentdate.getTime(),"yyyyMMdd"));//发起渠道日期 String channelserno = payBillEntity.get("billno")+"-"+payBillEntity.getInt("nckd_bbh"); createElement(doc, body, "channelserno", channelserno);//发起渠道流水 createElement(doc, body, "channeltime", currentdate.get(Calendar.HOUR)+""+currentdate.get(Calendar.MINUTE)+""+currentdate.get(Calendar.SECOND)); createElement(doc, body, "brno", "");//交易发起机构,可为空,默认100800 createElement(doc, body, "bustype", "");//业务类型,可为空,默认为0-汇兑 createElement(doc, body, "buskind", "");//业务种类,可为空,默认为0-普通汇兑 createElement(doc, body, "payeracctype", "1");//付款账户类型 0-对公账户 1-个人账户.待补充 //付款账号 DynamicObject payeracctbankEntity = BusinessDataServiceHelper.loadSingle(payBillEntity.getDynamicObject("payeracctbank").getPkValue(), "am_accountbank"); String payeracc = payeracctbankEntity.getString("bankaccountnumber"); String payername = payeracctbankEntity.getString("name"); createElement(doc, body, "payeracc", payeracc);//付款账户 createElement(doc, body, "payername", payername);//付款人名称 createElement(doc, body, "realpayeracc", payeracc);//实际付款人账户 createElement(doc, body, "realpayername", payername);//实际付款人名称 createElement(doc, body, "payeeacc", payBillEntity.getString("payeebanknum"));//收款账号 createElement(doc, body, "payeename", payBillEntity.getString("payeename"));//收款人名称 createElement(doc, body, "amount", payBillEntity.getBigDecimal("actpayamt").setScale(2, RoundingMode.DOWN).toString());//金额 createElement(doc, body, "feeflag", "0");//收费标志0-暂不收费 1-计费 2-按月计费 createElement(doc, body, "postscript", "测试江西银行经费共享系统付款"); DynamicObject skyhinfo = BusinessDataServiceHelper.loadSingle(payBillEntity.getDynamicObject("payeebank").getPkValue(), "bd_bebank"); createElement(doc, body, "recvbank", skyhinfo.getString("union_number"));// 如果是跨行业务,需填写接收行号 createElement(doc, body, "paysysid", "0");// 如果是跨行业务,需填写汇路 TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); // 指定编码格式为GBK transformer.setOutputProperty(OutputKeys.ENCODING, "GBK"); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); DOMSource source = new DOMSource(doc); StringWriter writer = new StringWriter(); StreamResult result = new StreamResult(writer); transformer.transform(source, result); return writer.toString(); } catch (Exception e) { e.printStackTrace(); return null; } } private static void createElement(Document doc, Element parent, String name, String value) { Element element = doc.createElement(name); element.appendChild(doc.createTextNode(value)); parent.appendChild(element); } /** * 支付单同步 * @params billEntities * @returns 返回报错信息 * */ public static String payBillForCBSSync(DynamicObject[] billEntities) { StringBuffer errMsg = new StringBuffer(); //获取接口链接等信息 DynamicObject jkpzxx = BusinessDataServiceHelper.loadSingle("nckd_jkpzxx",new QFilter[]{new QFilter("number","=","paytozfqz")}); String servername = jkpzxx.getString("nckd_servername"); String port = jkpzxx.getString("nckd_port"); for (DynamicObject dataEntity : billEntities) { boolean isSuccess = false; boolean isZFQZ = true; Map qzObject = new HashMap<>(); DynamicObject payBillEntity = BusinessDataServiceHelper.loadSingle(dataEntity.getPkValue(), ENTITY_NAME); String cbsUrlBill =""; /** * 判断是否可以走前置支付 * 1、付款单为审核状态 * 2、支付状态为未支付 * 3、版本号>=1时,必须等于付款次数 */ String billNum = payBillEntity.getString("billno"); String billstatusString = payBillEntity.getString("billstatus"); String paystatus = payBillEntity.getString("nckd_paystatus"); int bbh = payBillEntity.getInt("nckd_bbh"); int fkcs = payBillEntity.getInt("nckd_fkcs"); if (!"C".equals(billstatusString)) { errMsg.append("单据号:").append(billNum).append(",付款单为审核状态,才能提交~\r\n"); isZFQZ = false; } if (!"1".equals(paystatus) && !"".equals(paystatus)) { errMsg.append("单据号:").append(billNum).append(",付款单为未支付,才能提交~\r\n"); isZFQZ = false; } if(bbh>=1 && bbh!=fkcs){ errMsg.append("单据号:").append(billNum).append(",付款单版本号有误,请检查数据,或联系管理员~\r\n"); isZFQZ = false; } if(payBillEntity.getDynamicObject("payeracctbank")==null) { errMsg.append("单据号:").append(billNum).append(",付款账户为空~\r\n"); isZFQZ = false; } if(payBillEntity.getDynamicObject("payeebank")==null) { errMsg.append("单据号:").append(billNum).append(",收款账户为空~\r\n"); isZFQZ = false; } //构建请求xml String bodyxml = createSinglePaymentRequest(payBillEntity); if(bodyxml==null){ isZFQZ = false; errMsg.append("单据号:").append(billNum).append(",无法拼出正确的xml请求~\r\n"); } if(!isZFQZ){ continue; } log.info("单据号:"+billNum+"传入参数"+bodyxml); JSONObject cbsReturnJson =socketService(servername,port,bodyxml); log.info("单据号:"+billNum+"返回参数"+cbsReturnJson.toString()); //存入日志表 savelog(payBillEntity,bodyxml,cbsReturnJson.toString()); if(cbsReturnJson==null){ isSuccess = false; errMsg.append("单据号:").append(billNum).append(",推送支付前置失败,"); errMsg.append("错误号:").append("XXXXXX"); errMsg.append(",错误原因:").append("接口无法连通,未获取到返回结果"); errMsg.append("\r\n"); }else{ String errcode =cbsReturnJson.getString("errorcode"); if ("FIN0000".equals(errcode)) {//已受理,不代表支付成功 isSuccess = true; errMsg.append("单据号:").append(billNum).append(",推送支付前置成功!"); payBillEntity.set("nckd_fkcs", fkcs+1);//付款次数+1 payBillEntity.set("nckd_sbyy",cbsReturnJson.getString("errormsg"));//错误信息 String zfstatus = cbsReturnJson.getString("status"); if("S".equals(zfstatus)){//成功 payBillEntity.set("nckd_paystatus",3); }else if("U".equals(zfstatus)){//在途 payBillEntity.set("nckd_paystatus",2);//支付中 }else if("F".equals(zfstatus)){//失败 payBillEntity.set("nckd_paystatus",4);//支付失败 } } else { isSuccess = false; errMsg.append("单据号:").append(billNum).append(",推送支付前置失败,"); errMsg.append("错误号:").append(errcode); errMsg.append(",错误原因:").append(cbsReturnJson.getString("errormsg")); errMsg.append("\r\n"); } } ////返回日志处理 System.out.println("调用支付前置接口返回值:" + cbsReturnJson.toString()); if (isSuccess) { SaveServiceHelper.update(new DynamicObject[]{payBillEntity}); } } return errMsg.toString(); } public static void savelog(DynamicObject payBillEntity,String qqbw,String fhbw){ try { DynamicObject logInfo = new DynamicObject( EntityMetadataCache.getDataEntityType("nckd_zfjkdyrz")); String channelserno = payBillEntity.get("billno")+"-"+payBillEntity.getInt("nckd_bbh"); logInfo.set("number",channelserno); logInfo.set("name",payBillEntity.get("billno")+"付款日志"); logInfo.set("status","A"); logInfo.set("nckd_billno",payBillEntity.get("billno")); logInfo.set("nckd_payid",payBillEntity.getPkValue()+""); logInfo.set("nckd_qqbw",qqbw); logInfo.set("nckd_fhbw",fhbw); logInfo.set("nckd_djlx","1"); OperationServiceHelper.executeOperate("save","nckd_zfjkdyrz",new DynamicObject[]{logInfo}); }catch (Exception e){ log.info("保存日志报错"+e.getMessage()); } } public static JSONObject socketService(String serverName,String port,String xmlData){ try { Socket client = new Socket(serverName,TypeUtils.nullToInt(port)); int messageLength = xmlData.getBytes("GBK").length; String header = String.format("%08dXMLBTSCO001%%%%%%%%%%%%%%%%%%%%%%%%", messageLength); String fullMessage = header + xmlData; OutputStream outToServer = client.getOutputStream(); PrintWriter out = new PrintWriter(new OutputStreamWriter(outToServer, "GBK"), true); out.println(fullMessage); InputStream inFromServer = client.getInputStream(); BufferedReader in = new BufferedReader(new InputStreamReader(inFromServer, "GBK")); StringBuilder responseBuilder = new StringBuilder(); String line; while ((line = in.readLine()) != null) { responseBuilder.append(line); } String responseJson = responseBuilder.toString(); if(responseJson.indexOf("0){ int index = responseJson.indexOf("