PayBillToolUtil.java 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. package fi.cas.opplugin;
  2. import kd.bos.dataentity.entity.DynamicObject;
  3. import kd.bos.entity.EntityMetadataCache;
  4. import kd.bos.logging.Log;
  5. import kd.bos.logging.LogFactory;
  6. import kd.bos.orm.query.QFilter;
  7. import kd.bos.servicehelper.BusinessDataServiceHelper;
  8. import java.io.*;
  9. import java.math.RoundingMode;
  10. import java.net.Socket;
  11. import java.util.Calendar;
  12. import java.util.Date;
  13. import java.util.HashMap;
  14. import java.util.Map;
  15. import kd.bos.servicehelper.operation.OperationServiceHelper;
  16. import kd.bos.servicehelper.operation.SaveServiceHelper;
  17. import org.w3c.dom.Document;
  18. import org.w3c.dom.Element;
  19. import org.json.JSONObject;
  20. import org.json.XML;
  21. import javax.xml.parsers.DocumentBuilder;
  22. import javax.xml.parsers.DocumentBuilderFactory;
  23. import javax.xml.transform.OutputKeys;
  24. import javax.xml.transform.Transformer;
  25. import javax.xml.transform.TransformerFactory;
  26. import javax.xml.transform.dom.DOMSource;
  27. import javax.xml.transform.stream.StreamResult;
  28. public class PayBillToolUtil {
  29. public static final String ENTITY_NAME = "cas_paybill";
  30. protected static final Log log = LogFactory.getLog(PayBillToolUtil.class);
  31. public static String createSinglePaymentRequest(DynamicObject payBillEntity) {
  32. try {
  33. DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
  34. DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
  35. Document doc = dBuilder.newDocument();
  36. Element rootElement = doc.createElement("Message");
  37. doc.appendChild(rootElement);
  38. Element body = doc.createElement("Body");
  39. rootElement.appendChild(body);
  40. createElement(doc, body, "transcode", "BTSCO001");
  41. createElement(doc, body, "trxcode", "jfgx");//渠道交易代码
  42. createElement(doc, body, "channelcode", "经费共享");//发起渠道
  43. Calendar currentdate = Calendar.getInstance();
  44. createElement(doc, body, "channeldate", TypeUtils.date2String(currentdate.getTime(),"yyyyMMdd"));//发起渠道日期
  45. String channelserno = payBillEntity.get("billno")+"-"+payBillEntity.getInt("nckd_bbh");
  46. createElement(doc, body, "channelserno", channelserno);//发起渠道流水
  47. createElement(doc, body, "channeltime", currentdate.get(Calendar.HOUR)+""+currentdate.get(Calendar.MINUTE)+""+currentdate.get(Calendar.SECOND));
  48. createElement(doc, body, "brno", "");//交易发起机构,可为空,默认100800
  49. createElement(doc, body, "bustype", "");//业务类型,可为空,默认为0-汇兑
  50. createElement(doc, body, "buskind", "");//业务种类,可为空,默认为0-普通汇兑
  51. createElement(doc, body, "payeracctype", "1");//付款账户类型 0-对公账户 1-个人账户.待补充
  52. //付款账号
  53. DynamicObject payeracctbankEntity = BusinessDataServiceHelper.loadSingle(payBillEntity.getDynamicObject("payeracctbank").getPkValue(), "am_accountbank");
  54. String payeracc = payeracctbankEntity.getString("bankaccountnumber");
  55. String payername = payeracctbankEntity.getString("name");
  56. createElement(doc, body, "payeracc", payeracc);//付款账户
  57. createElement(doc, body, "payername", payername);//付款人名称
  58. createElement(doc, body, "realpayeracc", payeracc);//实际付款人账户
  59. createElement(doc, body, "realpayername", payername);//实际付款人名称
  60. createElement(doc, body, "payeeacc", payBillEntity.getString("payeebanknum"));//收款账号
  61. createElement(doc, body, "payeename", payBillEntity.getString("payeename"));//收款人名称
  62. createElement(doc, body, "amount", payBillEntity.getBigDecimal("actpayamt").setScale(2, RoundingMode.DOWN).toString());//金额
  63. createElement(doc, body, "feeflag", "0");//收费标志0-暂不收费 1-计费 2-按月计费
  64. createElement(doc, body, "postscript", "测试江西银行经费共享系统付款");
  65. DynamicObject skyhinfo = BusinessDataServiceHelper.loadSingle(payBillEntity.getDynamicObject("payeebank").getPkValue(), "bd_bebank");
  66. createElement(doc, body, "recvbank", skyhinfo.getString("union_number"));// 如果是跨行业务,需填写接收行号
  67. createElement(doc, body, "paysysid", "0");// 如果是跨行业务,需填写汇路
  68. TransformerFactory transformerFactory = TransformerFactory.newInstance();
  69. Transformer transformer = transformerFactory.newTransformer();
  70. // 指定编码格式为GBK
  71. transformer.setOutputProperty(OutputKeys.ENCODING, "GBK");
  72. transformer.setOutputProperty(OutputKeys.INDENT, "yes");
  73. DOMSource source = new DOMSource(doc);
  74. StringWriter writer = new StringWriter();
  75. StreamResult result = new StreamResult(writer);
  76. transformer.transform(source, result);
  77. return writer.toString();
  78. } catch (Exception e) {
  79. e.printStackTrace();
  80. return null;
  81. }
  82. }
  83. private static void createElement(Document doc, Element parent, String name, String value) {
  84. Element element = doc.createElement(name);
  85. element.appendChild(doc.createTextNode(value));
  86. parent.appendChild(element);
  87. }
  88. /**
  89. * 支付单同步
  90. * @params billEntities
  91. * @returns 返回报错信息
  92. *
  93. */
  94. public static String payBillForCBSSync(DynamicObject[] billEntities) {
  95. StringBuffer errMsg = new StringBuffer();
  96. //获取接口链接等信息
  97. DynamicObject jkpzxx = BusinessDataServiceHelper.loadSingle("nckd_jkpzxx",new QFilter[]{new QFilter("number","=","paytozfqz")});
  98. String servername = jkpzxx.getString("nckd_servername");
  99. String port = jkpzxx.getString("nckd_port");
  100. for (DynamicObject dataEntity : billEntities) {
  101. boolean isSuccess = false;
  102. boolean isZFQZ = true;
  103. Map<String, String> qzObject = new HashMap<>();
  104. DynamicObject payBillEntity = BusinessDataServiceHelper.loadSingle(dataEntity.getPkValue(), ENTITY_NAME);
  105. String cbsUrlBill ="";
  106. /**
  107. * 判断是否可以走前置支付
  108. * 1、付款单为审核状态
  109. * 2、支付状态为未支付
  110. * 3、版本号>=1时,必须等于付款次数
  111. */
  112. String billNum = payBillEntity.getString("billno");
  113. String billstatusString = payBillEntity.getString("billstatus");
  114. String paystatus = payBillEntity.getString("nckd_paystatus");
  115. int bbh = payBillEntity.getInt("nckd_bbh");
  116. int fkcs = payBillEntity.getInt("nckd_fkcs");
  117. if (!"C".equals(billstatusString)) {
  118. errMsg.append("单据号:").append(billNum).append(",付款单为审核状态,才能提交~\r\n");
  119. isZFQZ = false;
  120. }
  121. if (!"1".equals(paystatus) && !"".equals(paystatus)) {
  122. errMsg.append("单据号:").append(billNum).append(",付款单为未支付,才能提交~\r\n");
  123. isZFQZ = false;
  124. }
  125. if(bbh>=1 && bbh!=fkcs){
  126. errMsg.append("单据号:").append(billNum).append(",付款单版本号有误,请检查数据,或联系管理员~\r\n");
  127. isZFQZ = false;
  128. }
  129. if(payBillEntity.getDynamicObject("payeracctbank")==null) {
  130. errMsg.append("单据号:").append(billNum).append(",付款账户为空~\r\n");
  131. isZFQZ = false;
  132. }
  133. if(payBillEntity.getDynamicObject("payeebank")==null) {
  134. errMsg.append("单据号:").append(billNum).append(",收款账户为空~\r\n");
  135. isZFQZ = false;
  136. }
  137. //构建请求xml
  138. String bodyxml = createSinglePaymentRequest(payBillEntity);
  139. if(bodyxml==null){
  140. isZFQZ = false;
  141. errMsg.append("单据号:").append(billNum).append(",无法拼出正确的xml请求~\r\n");
  142. }
  143. if(!isZFQZ){
  144. continue;
  145. }
  146. log.info("单据号:"+billNum+"传入参数"+bodyxml);
  147. JSONObject cbsReturnJson =socketService(servername,port,bodyxml);
  148. log.info("单据号:"+billNum+"返回参数"+cbsReturnJson.toString());
  149. //存入日志表
  150. savelog(payBillEntity,bodyxml,cbsReturnJson.toString());
  151. if(cbsReturnJson==null){
  152. isSuccess = false;
  153. errMsg.append("单据号:").append(billNum).append(",推送支付前置失败,");
  154. errMsg.append("错误号:").append("XXXXXX");
  155. errMsg.append(",错误原因:").append("接口无法连通,未获取到返回结果");
  156. errMsg.append("\r\n");
  157. }else{
  158. String errcode =cbsReturnJson.getString("errorcode");
  159. if ("FIN0000".equals(errcode)) {//已受理,不代表支付成功
  160. isSuccess = true;
  161. errMsg.append("单据号:").append(billNum).append(",推送支付前置成功!");
  162. payBillEntity.set("nckd_fkcs", fkcs+1);//付款次数+1
  163. payBillEntity.set("nckd_sbyy",cbsReturnJson.getString("errormsg"));//错误信息
  164. String zfstatus = cbsReturnJson.getString("status");
  165. if("S".equals(zfstatus)){//成功
  166. payBillEntity.set("nckd_paystatus",3);
  167. }else if("U".equals(zfstatus)){//在途
  168. payBillEntity.set("nckd_paystatus",2);//支付中
  169. }else if("F".equals(zfstatus)){//失败
  170. payBillEntity.set("nckd_paystatus",4);//支付失败
  171. }
  172. } else {
  173. isSuccess = false;
  174. errMsg.append("单据号:").append(billNum).append(",推送支付前置失败,");
  175. errMsg.append("错误号:").append(errcode);
  176. errMsg.append(",错误原因:").append(cbsReturnJson.getString("errormsg"));
  177. errMsg.append("\r\n");
  178. }
  179. }
  180. ////返回日志处理
  181. System.out.println("调用支付前置接口返回值:" + cbsReturnJson.toString());
  182. if (isSuccess) {
  183. SaveServiceHelper.update(new DynamicObject[]{payBillEntity});
  184. }
  185. }
  186. return errMsg.toString();
  187. }
  188. public static void savelog(DynamicObject payBillEntity,String qqbw,String fhbw){
  189. try {
  190. DynamicObject logInfo = new DynamicObject( EntityMetadataCache.getDataEntityType("nckd_zfjkdyrz"));
  191. String channelserno = payBillEntity.get("billno")+"-"+payBillEntity.getInt("nckd_bbh");
  192. logInfo.set("number",channelserno);
  193. logInfo.set("name",payBillEntity.get("billno")+"付款日志");
  194. logInfo.set("status","A");
  195. logInfo.set("nckd_billno",payBillEntity.get("billno"));
  196. logInfo.set("nckd_payid",payBillEntity.getPkValue()+"");
  197. logInfo.set("nckd_qqbw",qqbw);
  198. logInfo.set("nckd_fhbw",fhbw);
  199. logInfo.set("nckd_djlx","1");
  200. OperationServiceHelper.executeOperate("save","nckd_zfjkdyrz",new DynamicObject[]{logInfo});
  201. }catch (Exception e){
  202. log.info("保存日志报错"+e.getMessage());
  203. }
  204. }
  205. public static JSONObject socketService(String serverName,String port,String xmlData){
  206. try {
  207. Socket client = new Socket(serverName,TypeUtils.nullToInt(port));
  208. int messageLength = xmlData.getBytes("GBK").length;
  209. String header = String.format("%08dXMLBTSCO001%%%%%%%%%%%%%%%%%%%%%%%%", messageLength);
  210. String fullMessage = header + xmlData;
  211. OutputStream outToServer = client.getOutputStream();
  212. PrintWriter out = new PrintWriter(new OutputStreamWriter(outToServer, "GBK"), true);
  213. out.println(fullMessage);
  214. InputStream inFromServer = client.getInputStream();
  215. BufferedReader in = new BufferedReader(new InputStreamReader(inFromServer, "GBK"));
  216. StringBuilder responseBuilder = new StringBuilder();
  217. String line;
  218. while ((line = in.readLine()) != null) {
  219. responseBuilder.append(line);
  220. }
  221. String responseJson = responseBuilder.toString();
  222. if(responseJson.indexOf("<?xml")>0){
  223. int index = responseJson.indexOf("<?xml");
  224. responseJson.substring(index);
  225. }
  226. JSONObject jsonObject = XML.toJSONObject(responseJson);
  227. client.close();
  228. return jsonObject;
  229. } catch (IOException e) {
  230. e.printStackTrace();
  231. log.info(e.getMessage());
  232. }
  233. return null;
  234. }
  235. }