package com.qhyf.app.bl.service; import java.io.IOException; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import com.qhyf.app.bl.BlConstant; import com.qhyf.app.bl.base.controller.QhyfController; import com.qhyf.app.bl.base.service.QhyfService; import com.qhyf.app.bl.model.BizExternalInterfacesCallResume; import com.qhyf.app.bl.model.BizJdPaymentInfo; import com.qhyf.app.bl.security.RSAUtils; import club.newepoch.iweb.common.IwebCacheKit; import club.newepoch.persistent.db.common.Db; import club.newepoch.persistent.db.exception.ActiveRecordException; import club.newepoch.persistent.db.pojo.Record; import club.newepoch.utils.StringUtils; import net.sf.json.JSONObject; /** * 对外开放接口(金蝶)Service * * @author jpf */ public class KingdeeCallingInterfaceService extends QhyfService{ /** * 根据应用代码、应用密码获取token * @param QhyfController * @param appKey 应用代码(账号) * @param appSecret 应用密码(公钥) * @return returnJson 响应报文Json * @throws Exception */ public JSONObject getToken(String appKey, String appSecret) throws IOException, ActiveRecordException { // 设置接口返回json JSONObject returnJson = new JSONObject(); JSONObject data = new JSONObject(); // 根据应用账号在DB中查询是否存在 String appKeySql = "" + "select " + "app_name," + "app_key," + "app_secret," + "expire_time " + "from biz_external_interfaces_manage " + "where app_key = ? " + "and sys_status= 1 "; Record appKeyRecord = Db.findFirst(appKeySql, appKey); // 若不存在 if(appKeyRecord == null) { returnJson.put("errcode", "10002"); returnJson.put("errmsg", "参数【appKey】值不合法"); } else if(!appSecret.equals(appKeyRecord.getStr("appSecret"))) { // 若数据存在,但appSecret与DB数据不一致时 returnJson.put("errcode", "10002"); returnJson.put("errmsg", "参数【appSecret】值不合法"); } else { // appKey、appSecret验证通过时返回token // 随机生成token String token = StringUtils.randomUuid(); // 设置超时时间 String expireTime = appKeyRecord.getStr("expireTime"); // 设置日志 logger.info(String.format("【%s】调用保理系统获取访问令牌接口,token值为[%s],有效时间%s", appKeyRecord.getStr("appName"), token, expireTime)); // 往缓存中设置token,有效时间为3个小时 IwebCacheKit.use().put("easCache", token, appKey, Long.parseLong(expireTime)); // 设置token data.put("token", token); data.put("expireTime", expireTime); returnJson.put("data", data); // 设置返回码 0:调用成功 returnJson.put("errcode", "0"); returnJson.put("errmsg", ""); } return returnJson; } /** * 验证保理单传入数据,并保存保理单 * @param QhyfController * @param rsaParameter 传入报文 * @return returnJson 响应报文Json * @throws Exception */ public JSONObject paymentSave(String rsaParameter) throws Exception { // 设置接口返回json JSONObject returnJson = new JSONObject(); // 解析json获取参数对应的值 JSONObject paraObject = JSONObject.fromObject(rsaParameter); // 数据校验是否成功标识 boolean checkFlag = true; // errmsg信息 StringBuffer errmsgStr = new StringBuffer(); // 校验是否缺少参数 // 保理单号(资金计划编号) if (paraObject.get("baoliNo") == null || paraObject.get("baoliNo") == "") { errmsgStr.append("参数baoliNo不能为空;"); checkFlag = false; } // 单据日期(推送日期) if (paraObject.get("billDate") == null || paraObject.get("billDate") == "") { errmsgStr.append("参数billDate不能为空;"); checkFlag = false; } // 申请金额(可放款金额) if (paraObject.get("applyAmount") == null || paraObject.get("applyAmount") == "") { errmsgStr.append("参数applyAmount不能为空;"); checkFlag = false; } // 放款对象(收款人GUID) if (paraObject.get("payee") == null || paraObject.get("payee") == "") { errmsgStr.append("参数payee不能为空;"); checkFlag = false; } // 放款单位(GUID) if (paraObject.get("payProviderGUID") == null || paraObject.get("payProviderGUID") == "") { errmsgStr.append("参数payProviderGUID不能为空;"); checkFlag = false; } // 申请说明(申请主题) if (paraObject.get("applyDesc") == null || paraObject.get("applyDesc") == "") { errmsgStr.append("参数applyDesc不能为空;"); checkFlag = false; } // 业务合同号(地产项目编号) if (paraObject.get("contractCode") == null || paraObject.get("contractCode") == "") { errmsgStr.append("参数contractCode不能为空;"); checkFlag = false; } // 业务合同名称(地产项目名称) if (paraObject.get("contractName") == null || paraObject.get("contractName") == "") { errmsgStr.append("参数contractName不能为空;"); checkFlag = false; } // 申请编号 if (paraObject.get("applyCode") == null || paraObject.get("applyCode") == "") { errmsgStr.append("参数applyCode不能为空;"); checkFlag = false; } // 归属公司(商业、住开公司名称) if (paraObject.get("companyName") == null || paraObject.get("companyName") == "") { errmsgStr.append("参数companyName不能为空;"); checkFlag = false; } // 非空校验通过时 if(checkFlag) { // 单据日期(推送日期),日期格式校验 if(!isDate(paraObject.get("billDate").toString())){ errmsgStr.append("参数billDate不是合法的日期格式"); returnJson.put("errcode", "10002"); checkFlag = false; } // 申请金额(可放款金额),金额校验 if(!checkIntParamLength(paraObject.get("applyAmount").toString())){ errmsgStr.append("参数applyAmount不合法(只能是数字,且整数位不能大于20位,小数位不能超过2位)"); returnJson.put("errcode", "10002"); checkFlag = false; } } else { // 缺少参数 returnJson.put("errcode", "10001"); } // 校验通过时 if(checkFlag) { // 调用保存金蝶付款单数据表方法 saveJdPaymentInfo(paraObject); // 设置返回码 0:调用成功 returnJson.put("errcode", "0"); returnJson.put("errmsg", ""); }else { returnJson.put("errmsg", errmsgStr.toString()); } return returnJson; } /** * 验证传入数据并取消保理单 * @param QhyfController * @param rsaParameter 传入报文 * @return returnJson 响应报文Json * @throws Exception */ public JSONObject paymentCancel(String rsaParameter) throws Exception { // 设置接口返回json JSONObject returnJson = new JSONObject(); // 解析json获取参数对应的值 JSONObject paraObject = JSONObject.fromObject(rsaParameter); // 保理单号(资金计划编号) String baoliNo = null; Object baoliN = paraObject.get("baoliNo"); if (baoliN != null) { baoliNo = baoliN.toString(); // 金蝶付款单数据表,修改付款单状态为已取消 String sql = "select " + "uuid, " + "payment_status " + "from biz_jd_payment_info " + "where baoli_no = ? " + "and sys_status = 1"; Record record = Db.findFirst(sql, baoliNo); // 金蝶付款单数据表,修改付款单状态为已取消 BizJdPaymentInfo jdInfo = new BizJdPaymentInfo(); if (record != null) { if ("1".equals(record.getStr("paymentStatus")) ) { jdInfo.set("uuid", record.getStr("uuid")); // 设置更新者 jdInfo.set(BlConstant.FIELD_DB_UPDATE_USER_ID, BlConstant.FIELD_DB_CURRENT_SYSTEM_USER_ID); // 设置更新程序ID jdInfo.set(BlConstant.FIELD_DB_UPDATE_PROG_ID, this.getClass().getCanonicalName()); // 设置更新时间 jdInfo.set(BlConstant.FIELD_DB_UPDATE_SYS_TIME, new Date()); // 付款单状态 0:已取消 jdInfo.set("paymentStatus", "0"); this.merge(BizJdPaymentInfo.dao.getTable().getName(), jdInfo); } else { // 付款单状态已经为"0"的时候不操作数据 } // 设置返回码 0:调用成功 returnJson.put("errcode", "0"); returnJson.put("errmsg", ""); }else { returnJson.put("errcode", "10002"); returnJson.put("errmsg", String.format("参数值不合法(【%s】保理单还未传入保理系统)")); } } else { returnJson.put("errcode", "10001"); returnJson.put("errmsg", "缺少参数【baoliNo】"); } return returnJson; } /** * 保存接口调用履历 * @param QhyfController * @throws Exception */ public void updateHistory(QhyfController controller,String uuid,String appKey,String api, Date startTime,Date endTime,String apiSend,String apiReceive,String called,String errors) throws Exception{ // 更新保理系统对外接口调用履历表 BizExternalInterfacesCallResume history = new BizExternalInterfacesCallResume(); // 记录ID history.set("uuid", uuid); // 应用账号 history.set("appKey", appKey); // 接口名称 history.set("api", api); // 调用方法所在类 history.set("location", controller.getClass().getCanonicalName()); // 调用开始时间 history.set("startTime", startTime); // 调用结束时间 history.set("endTime", endTime); // 用时 history.set("callTime", endTime.getTime()- startTime.getTime()); // 接口发送报文 history.set("apiSend", apiSend); // 接口接收结果 history.set("apiReceive", apiReceive); // 是否调用成功 history.set("called", called); // 错误信息 history.set("errors", errors); // 设置创建者 history.set(BlConstant.FIELD_DB_CREATE_USER_ID, BlConstant.FIELD_DB_CURRENT_SYSTEM_USER_ID); // 设置新增程序ID history.set(BlConstant.FIELD_DB_CREATE_PROG_ID, this.getClass().getCanonicalName()); // 设置新增时间 history.set(BlConstant.FIELD_DB_CREATE_SYS_TIME, new Date()); this.merge(BizExternalInterfacesCallResume.dao.getTable().getName(), history); } /** * 保存付款单信息 * @param QhyfController * @throws Exception */ public void saveJdPaymentInfo(JSONObject paraObject) throws Exception{ // 金蝶付款单数据表 BizJdPaymentInfo jdInfo = new BizJdPaymentInfo(); // 操作程序和操作时间 String proName = this.getClass().getCanonicalName(); Date date = new Date(); // 是否执行merge boolean isMergePayment = false; String blNoSql = "SELECT " + " uuid, " + " baoli_no, " + " bill_date, " + " apply_amount, " + " payee, " + " pay_provider_guid, " + " apply_desc, " + " contract_code, " + " contract_name, " + " apply_code, " + " company_name, " + " payee_bank, " + " payee_account, " + " is_export_flag " + "FROM " + " biz_jd_payment_info " + "WHERE " + " baoli_no =? "+ "and sys_status= 1 "; Record blNoRecord = Db.findFirst(blNoSql, paraObject.get("baoliNo").toString()); if (blNoRecord != null) {// 数据库中存在数据 //调用方法, 金蝶数据与前海一方数据库有不同字段时,更新数据 if (comparekdDatas(paraObject, blNoRecord)) { // 更新,设置UUID jdInfo.set(BlConstant.FIELD_UUID, blNoRecord.get("uuid")); // 设置更新者 jdInfo.set(BlConstant.FIELD_DB_UPDATE_USER_ID, BlConstant.FIELD_DB_CURRENT_SYSTEM_USER_ID); // 设置更新程序ID jdInfo.set(BlConstant.FIELD_DB_UPDATE_PROG_ID, proName); // 设置更新时间 jdInfo.set(BlConstant.FIELD_DB_UPDATE_SYS_TIME, date); isMergePayment = true; }else{ // 全部相同的时候不操作数据 } } else {// 数据库中不存在数据 // 设置UUID jdInfo.set(BlConstant.FIELD_UUID, StringUtils.randomUuid()); // 设置创建者 jdInfo.set(BlConstant.FIELD_DB_CREATE_USER_ID, BlConstant.FIELD_DB_CURRENT_SYSTEM_USER_ID); // 设置新增程序ID jdInfo.set(BlConstant.FIELD_DB_CREATE_PROG_ID, proName); // 设置新增时间 jdInfo.set(BlConstant.FIELD_DB_CREATE_SYS_TIME, date); isMergePayment = true; } if (isMergePayment) { // 保理单号(资金计划编号) jdInfo.set("baoliNo", paraObject.get("baoliNo")); // 单据日期(推送日期) jdInfo.set("billDate", paraObject.get("billDate")); // 申请金额(可放款金额) jdInfo.set("applyAmount", paraObject.get("applyAmount")); // 放款对象(收款人GUID) jdInfo.set("payee", paraObject.get("payee")); // 放款单位(GUID) jdInfo.set("payProviderGuid", paraObject.get("payProviderGUID")); // 申请说明(申请主题) jdInfo.set("applyDesc", paraObject.get("applyDesc")); // 业务合同号(地产项目编号) jdInfo.set("contractCode", paraObject.get("contractCode")); // 业务合同名称(地产项目名称) jdInfo.set("contractName", paraObject.get("contractName")); // 申请编号 jdInfo.set("applyCode", paraObject.get("applyCode")); // 归属公司(商业、住开公司名称) jdInfo.set("companyName", paraObject.get("companyName")); // 收款人开户行名称 jdInfo.set("payeeBank", paraObject.get("payeeBank")); // 收款人账号 jdInfo.set("payeeAccount", paraObject.get("payeeAccount")); // 记录状态 jdInfo.set("sysStatus", BlConstant.SYS_STATUS_VALUE); this.merge(BizJdPaymentInfo.dao.getTable().getComment(), jdInfo); } } /** * 判断传入的付款单数据与前海一方数据库是否不一致 * 不一致返回true * 一致返回false * * @param paraObject 金蝶的传入值 * @param record 数据库的值 * @return boolean 是否不一致 * @throws ParseException */ private boolean comparekdDatas(JSONObject paraObject, Record blNoRecord) throws ParseException { // 保理单号(资金计划编号) if (!objToString(paraObject.get("baoliNo")).equals(objToString(blNoRecord.get("baoliNo")))) { return true; } // 时间转换 SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); Date date = toDate(objToString(paraObject.get("billDate"))); // 单据日期(推送日期) if (!String.valueOf(formatter.format(date)).equals(String.valueOf(formatter.format(blNoRecord.get("billDate"))))) { return true; } // 申请金额(可放款金额) if (Double.parseDouble(objToString(paraObject.get("applyAmount"))) != Double.parseDouble(objToString(blNoRecord.get("applyAmount")))) { return true; } // 放款对象(收款人GUID) if (!objToString(paraObject.get("payee")).equals(objToString(blNoRecord.get("payee")))) { return true; } // 放款单位(GUID) if (!objToString(paraObject.get("payProviderGUID")).equals(objToString(blNoRecord.get("payProviderGuid")))) { return true; } // 申请说明(申请主题) if (!objToString(paraObject.get("applyDesc")).equals(objToString(blNoRecord.get("applyDesc")))) { return true; } // 业务合同号(地产项目编号) if (!objToString(paraObject.get("contractCode")).equals(objToString(blNoRecord.get("contractCode")))) { return true; } // 业务合同名称(地产项目名称) if (!objToString(paraObject.get("contractName")).equals(objToString(blNoRecord.get("contractName")))) { return true; } // 申请编号 if (!objToString(paraObject.get("applyCode")).equals(objToString(blNoRecord.get("applyCode")))) { return true; } // 归属公司(商业、住开公司名称) if (!objToString(paraObject.get("companyName")).equals(objToString(blNoRecord.get("companyName")))) { return true; } // 收款人开户行名称 if (!objToString(paraObject.get("payeeBank")).equals(objToString(blNoRecord.get("payeeBank")))) { return true; } // 收款人账号 if (!objToString(paraObject.get("payeeAccount")).equals(objToString(blNoRecord.get("payeeAccount")))) { return true; } return false; } /** * RSA私钥解密 * @param appKey 应用账号 * @param body 密文 * @throws Exception */ public String rsaDecrypt(String appKey, String body) throws Exception { // 接口接收结果 String rsaParameter = null; // 根据应用账号appKey获取解密私钥 String appPrivateKeySql = "select " + "app_name," + "app_private_key " + "from biz_external_interfaces_manage " + "where app_key = ? " + "and sys_status = 1 "; Record privateKeyRecord = Db.findFirst(appPrivateKeySql, appKey); // 获取应用私钥 String privateKey = privateKeyRecord.getStr("appPrivateKey"); // 对传入报文进行解密 rsaParameter = RSAUtils.decryptByPrivateKey(body, privateKey); return rsaParameter; } /** * 金额校验 * @param param 需要校验的参数 * @param errorMsg 不满足时提示的错误信息 * @return isCheckThrough 是否满足校验规则 */ private boolean checkIntParamLength(String param) { boolean isCheckThrough = StringUtils.matchRegex(param, "^[0-9]{0,20}.[0-9]{0,2}$"); if (isCheckThrough) { return true; } else { return false; } } /** * 校验字符串是够满足日期格式 * @param str_input 日期字符串 * @return falg true/false * @throws Exception 格式化异常 */ private boolean isDate(String str_input) { boolean falg = false; if (!(str_input == null)) { String[] rDateFormat = {"yyyy/MM/dd", "yyyy-MM-dd", "yyyy.MM.dd", "yyyy-MM-dd HH:mm:ss"}; for (int i = 0; i < rDateFormat.length; i++) { SimpleDateFormat formatter = new SimpleDateFormat(rDateFormat[i]); // 设置lenient为false.否则SimpleDateFormat会比较宽松地验证日期,比如2007/02/29会被接受,并转换成2007/03/01 formatter.setLenient(false); try { formatter.format(formatter.parse(str_input)); // 是合法的日期格式这设置为true,退出循环 falg = true; break; } catch (Exception e) { // 不是合法的日期格式,不做处理 } } return falg; } return falg; } /** * 将字符串转化为合法的日期格式 * * @param str_input 日期字符串 * @return date Date * @throws Exception 格式化异常 */ private Date toDate(String str_input) { Date date = null; String[] rDateFormat = {"yyyy/MM/dd", "yyyy-MM-dd", "yyyy.MM.dd"}; for (int i = 0; i < rDateFormat.length; i++) { SimpleDateFormat formatter = new SimpleDateFormat(rDateFormat[i]); // 设置lenient为false.否则SimpleDateFormat会比较宽松地验证日期,比如2007/02/29会被接受,并转换成2007/03/01 formatter.setLenient(false); try { date = formatter.parse(str_input); break; } catch (Exception e) { // 不是合法的日期格式,不做处理 } } return date; } /** * 判断一字符串是否为json格式 * @param str_input 字符串 * @throws Exception 异常 */ public static boolean isJson(String content) { try { JSONObject.fromObject(content); return true; } catch (Exception e) { return false; } } /** * object转化为String的方法 */ private String objToString(Object obj) { String str = ""; if (obj != null) { str = obj.toString(); } return str; } }