package org.dromara.settlement.service.impl;

import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.DateUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.settlement.api.RemoteConfigService;
import org.dromara.settlement.api.domain.*;
import org.dromara.settlement.common.bank.jiaotong.JiaoTongConfig;
import org.dromara.settlement.common.bank.jiaotong.JiaoTongResponse;
import org.dromara.settlement.common.bank.jiaotong.JiaoTongUtil;
import org.dromara.settlement.common.file.FileUtils;
import org.dromara.settlement.common.file.SftpUtils;
import org.dromara.settlement.common.file.ZipUtils;
import org.dromara.settlement.domain.SysLog;
import org.dromara.settlement.mapper.SysLogMapper;
import org.dromara.settlement.mapper.TransactionLogMapper;
import org.redisson.api.RLock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.SftpException;

@Service
public class JitaoTongServiceImpl {
	private Logger log = LoggerFactory.getLogger(JitaoTongServiceImpl.class);

	@Autowired
	private RemoteConfigService wConfigService;// 配置

	@Autowired
	private TransactionLogMapper transactionLogDao;//交易记录dao

	@Autowired
	private SysLogMapper sysLogDao;// 日志

	private JiaoTongResponse request(long unitId, String funcode, StringBuilder body, boolean record) {
		return request(unitId, funcode, body, record, null);
	}

	private JiaoTongResponse request(long unitId, String funcode, StringBuilder body, boolean record, Long tranId) {
		JiaoTongResponse response = null;
		JiaoTongConfig config = getBankConfig(unitId);
		String reqid = DateUtils.parseDateToString("yyyyMMddHHmmssSSS", new Date());
		SysLog sysLog = new SysLog();
		if (record) {
			sysLog.setTranId(tranId);
		}
		sysLogDao.insert(sysLog);
		reqid = reqid + sysLog.getId();
		if (record) {
			sysLog.setReqid(reqid);
			sysLog.setRequestTime(new Date());
		}
		Result<String> requsetRtn = JiaoTongUtil.getInstance().request(config, funcode, reqid, body.toString());
		if (record && requsetRtn != null) {
			sysLog.setRequest(requsetRtn.getResult());
		}
		if (requsetRtn != null) {
			Result<JiaoTongResponse> responseRtn = JiaoTongUtil.getInstance().response(config, requsetRtn.getRtnData());
			if (record) {
				sysLog.setResponseTime(new Date());
			}
			if (responseRtn.hasError()) {
				log.error(responseRtn.getResult());
			}
			response = responseRtn.getRtnData();
			if (record && responseRtn != null) {
				sysLog.setResponse(responseRtn.getResult());
			}
		}
		if (sysLog.getId() != null) {
			if (record) {
				if (tranId != null) {
					sysLogDao.deleteByTranId(tranId, sysLog.getId());
				}
				sysLogDao.updateByPrimaryKeySelective(sysLog);
			} else
				sysLogDao.deleteByPrimaryKey(sysLog.getId());
		}
		return response;
	}

	private JiaoTongConfig getBankConfig(long unitId) {
		JiaoTongConfig config = new JiaoTongConfig();
		if (wConfigService != null && unitId > 0) {
			config.CorpNo = wConfigService.getItem(unitId, "jiaotong_corpno");
			config.UserNo = wConfigService.getItem(unitId, "jiaotong_userno");
			config.SUPERACC = wConfigService.getItem(unitId, "jiaotong_super_acc");
			config.URL = wConfigService.getItem(unitId, "jiaotong_api");
			config.PAYTYPE = wConfigService.getItem(unitId, "jiaotong_pay_type");
			config.CUSTNO = wConfigService.getItem(unitId, "jiaotong_cust_no");
			config.CALLBACKHOST = wConfigService.getItem(unitId, "jiaotong_callback_host");
			config.CALLBACKPORT = wConfigService.getItem(unitId, "jiaotong_callback_port");
			config.CALLBACKNAME = wConfigService.getItem(unitId, "jiaotong_callback_name");
			config.CALLBACKPASSWORD = wConfigService.getItem(unitId, "jiaotong_callback_password");
			config.SUPERACCNAME = wConfigService.getItem(unitId, "jiaotong_super_acc_name");
			if (StringUtils.isBlank(config.SUPERACCNAME)) {
				String key = "config:"+unitId;
				RedisUtils.deleteObject(key);
			}
			log.info("读取结算中心的账户配置（" + unitId + "）：" + config.CorpNo + "," + config.UserNo);
		}
		return config;
	}

	/**
	 * 创建交通银行云账户
	 * @author 张涛
	 * @date 2021年8月24日
	 * @param unitId 结算单位id
	 * @param code 云账户编号
	 * @param name 云账户名称
	 * @param prefix 云账户编号前缀
	 */
	public Account createAccount(long unitId, String code, String name, String prefix) {
		StringBuilder body = new StringBuilder();
		JiaoTongConfig config = getBankConfig(unitId);
		int total = 10;
        if(StringUtils.isNotEmpty(prefix)) {
        	total -= prefix.length();
        }
        if (code.length() < 10) {
			for (int i = code.length(); i < total; i++) {
				code = "0"+code;
			}
			if(StringUtils.isNotEmpty(prefix)) {
				code = prefix + code;
			}
		}
		body.append("<tranType>").append(1).append("</tranType>");
		body.append("<Acc>").append(config.SUPERACC).append("</Acc>");
		body.append("<superAcc>").append(config.SUPERACC).append("</superAcc>");
		body.append("<cusAccSeq>").append(code).append("</cusAccSeq>");
		body.append("<cloudAcc>").append(config.SUPERACC+"-"+code).append("</cloudAcc>");
		body.append("<cloudAccName>").append(config.SUPERACCNAME).append("</cloudAccName>");
		body.append("<alias>").append(name).append("</alias>");
		body.append("<certShared>").append(1).append("</certShared>");
		body.append("<sealShared>").append(1).append("</sealShared>");
		body.append("<sharedAcc>").append(config.SUPERACC).append("</sharedAcc>");
		body.append("<way>").append(1).append("</way>");
		body.append("<takeOutSign>").append(0).append("</takeOutSign>");
		body.append("<cdCloseCircle>").append(0).append("</cdCloseCircle>");
		body.append("<printReceipt>").append(1).append("</printReceipt>");
		body.append("<insideAccrual>").append(0).append("</insideAccrual>");
		JiaoTongResponse res = request(unitId, "710713", body, false);
		if (res != null && (res.getResultcode().equals("0000") || res.getResultcode().equals("0084"))) {
			Account account = new Account();
			account.setBankType("交通银行");
			account.setBankTypeName("交通银行");
			account.setBankCard(config.SUPERACC+"-"+code);
			account.setBalance(0l);
			return account;
		}
        return null;
	}

	/**
	 * 同步交通银行账户
	 *
	 * @author 张涛
	 * @date 2021年9月6日
	 * @param bankCard 银行卡号
	 * @return
	 */
	public AccountSyn synAccount(AccountSyn acc) {
		StringBuilder body = new StringBuilder();
		String curDate = DateUtils.getDate();
		String synDate = null;// 最近同步日期
		if (acc.getSynTime() != null) {
			synDate = DateUtils.parseDateToString(DateUtils.YYYY_MM_DD, acc.getSynTime());
		} else {
			synDate = curDate;
		}
		body.append("<accNo>").append(acc.getBankCard()).append("</accNo>");
		body.append("<dtlTyp>").append(2).append("</dtlTyp>");
		body.append("<startDate>").append(synDate.replace("-", "")).append("</startDate>");
		body.append("<endDate>").append(synDate.replace("-", "")).append("</endDate>");
		JiaoTongResponse res = request(acc.getUnitId(), "710714", body, false);
		if (res != null) {
			String record_num = "0";
			if(!res.getResultcode().equals("2018")) {//非无符合条件的记录
				if (!res.getResultcode().equals("0000") || StringUtils.isBlank(res.getData().elementText("serial_record"))) {
					throw new ServiceException(
							res != null && StringUtils.isNotBlank(res.getResultmsg()) ? res.getResultmsg() : "同步交通银行账户失败");
				}
				record_num = res.getData().elementText("record_num");
			}
			if (Integer.parseInt(record_num) > 0) {
				List<Map<String, String>> list = JiaoTongUtil.getInstance().getMutiAreaData(res.getData().elementText("serial_record"), Integer.parseInt(res.getData().elementText("field_num")));
				if (acc.getLogs() == null) {
					acc.setLogs(new ArrayList<AccountLog>());
				}
				Date curTime = new Date();
				for (Map<String, String> item : list) {
					String frmcod = item.containsKey("账号") ? item.get("账号") : "";
					if (frmcod.equals(acc.getBankCard())) {
						AccountLog log = new AccountLog();
						log.setAccId(acc.getId());
						log.setAddBy("系统");
						log.setAddTime(curTime);
						log.setBankCard(acc.getBankCard());
						log.setBankType(acc.getBankType());
						log.setRpyacc(item.containsKey("对方账号") ? item.get("对方账号") : null);
						log.setRpynam(item.containsKey("对方户名") ? item.get("对方户名") : null);
						String trxtim = item.get("交易时间");
						String trxdat = item.containsKey("交易日期") ? item.get("交易日期") : "";
						if (StringUtils.isNotBlank(trxdat)) {
							trxtim = trxdat.substring(0, 4) + "-" + trxdat.substring(4, 6) + "-"
									+ trxdat.substring(6, 8) + " " + trxtim.substring(0, 2) + ":"
									+ trxtim.substring(2, 4) + ":" + trxtim.substring(4, 6);
						} else {
							trxtim = curDate + " " + trxtim.substring(0, 2) + ":" + trxtim.substring(2, 4) + ":"
									+ trxtim.substring(4, 6);
						}
						log.setTranTime(
								DateUtils.parseStringToDate(DateUtils.YYYY_MM_DD_HH_MM_SS, trxtim));
						log.setTrxamt(new BigDecimal(item.get("交易金额")).multiply(new BigDecimal(100))
								.longValue());
						log.setTrxnbr(item.get("会计流水号"));
						String trxdir = item.get("借贷标志");
						String narinn = null;
						if (item.containsKey("传票业务摘要区")) {
							if (item.get("传票业务摘要区").indexOf("〉〉") != -1) {
								String[] trxtxtArr = item.get("传票业务摘要区").split("〉〉");
								narinn = trxtxtArr[0];
								log.setTrxtxt(trxtxtArr[trxtxtArr.length-1]);
							}else {
								log.setTrxtxt(item.get("传票业务摘要区"));
							}
							if (log.getTrxtxt().equals("代收小额支付业务手续费")) {
								//手续费的会计流水号与当笔交易相同，这里做兼容处理
								log.setTrxnbr(log.getTrxnbr()+"-1");
							}
						}
						if (trxdir.equals("D")) {
							log.setTrxamt(-log.getTrxamt());
							log.setTrxdir((short) 2);
						} else if (trxdir.equals("C")) {
							log.setTrxdir((short) 1);
							String narinnStr = item.containsKey("备用字段1") ? item.get("备用字段1") : null;
							if (StringUtils.isNotBlank(narinnStr)) {
								String[] narinnStrArr = narinnStr.split("#");
								if (narinnStrArr[0].equals("1") && narinnStrArr.length > 2) {//退汇
									log.setRefundDate(narinnStrArr[1].substring(0, 4) + "-" + narinnStrArr[1].substring(4, 6) + "-"
											+ narinnStrArr[1].substring(6, 8));
									log.setRefundTrxnbr(narinnStrArr[2]);
								}
							}
						}
						log.setNarinn(narinn);
						log.setBalance(acc.getBalance());
						log.setUnitId(acc.getUnitId());
						acc.getLogs().add(log);
						if (StringUtils.isNotBlank(acc.getTrxnbrs())) {
							acc.setTrxnbrs(acc.getTrxnbrs() + ",");
						}
						acc.setTrxnbrs(acc.getTrxnbrs() + "'" + log.getTrxnbr() + "'");
					}
				}
			}
			// 不是今天，或者当前没有同步完
			if (DateUtils.parseStringToDate(DateUtils.YYYY_MM_DD, synDate).getTime() < DateUtils.parseStringToDate(DateUtils.YYYY_MM_DD, curDate).getTime()) {
				//开始同步下一天的
				synDate = DateUtils.getEndDateByDays(synDate, 1);
				acc.setSynTime(DateUtils.parseStringToDate(DateUtils.YYYY_MM_DD, synDate));
				acc = synAccount(acc);
			}
			acc.setSynTime(new Date());
		}
		return acc;
	}

	/**
	 * 内部转账
	 * @author 张涛
	 * @date 2021年9月7日
	 * @param log
	 * @return
	 */
	public TransactionLog innerTransfer(TransactionLog log) {
		StringBuilder body = new StringBuilder();
		JiaoTongConfig config = getBankConfig(log.getUnitId());
		String cert_no = DateUtils.parseDateToString("yyyyMMddHHmmss", new Date())+log.getId();
		body.append("<cert_no>").append(cert_no).append("</cert_no>");
		body.append("<super_acc>").append(config.SUPERACC).append("</super_acc>");
		body.append("<sum>").append(1).append("</sum>");
		String amt = String.format("%.2f", log.getAmount() / 100.0);
		body.append("<sum_amt>").append(amt).append("</sum_amt>");
		body.append("<tran>");
		body.append("<rcd>");
		body.append("<pay_acno>").append(log.getSourceCard()).append("</pay_acno>");
		body.append("<pay_acname>").append(log.getSourceAccName()).append("</pay_acname>");
		body.append("<rcv_acno>").append(log.getTargetCard()).append("</rcv_acno>");
		body.append("<rcv_acname>").append(log.getTargetAccName()).append("</rcv_acname>");
		body.append("<bank_flag>").append(log.getBankType().equals("交通银行") ? 0 : 1).append("</bank_flag>");
		body.append("<rcv_bank_name>").append(log.getBankType()).append("</rcv_bank_name>");
		body.append("<amt>").append(amt).append("</amt>");
		body.append("<purpose>").append(log.getRemark()).append("</purpose>");
		body.append("<busi_no>").append(log.getOrderNo()).append("</busi_no>");
		body.append("</rcd>");
		body.append("</tran>");
		JiaoTongResponse res = request(log.getUnitId(), "710716", body, true, log.getId());
		if (res == null || !res.getResultcode().equals("0000") || StringUtils.isBlank(res.getData().elementText("ebank_batflw"))) {
			this.log.error(res != null && StringUtils.isNotBlank(res.getResultmsg()) ? res.getResultmsg() : "内部转账失败");
        	log.setResult((short)-1);
    		return log;
		}
		log.setSourceBankNo(res.getData().elementText("ebank_batflw"));
		log.setTargetBankNo(log.getSourceBankNo());
		log.setResult((short) 1);
		log.setReason("");
		return log;
	}

	/**
	 * 对私跨行转账
	 * @author 张涛
	 * @date 2021年9月7日
	 * @param log
	 * @param busiNo 代发协议编号
	 * @return
	 */
	public TransactionLog crossPersionTransfer(TransactionLog log,String busiNo) {
		StringBuilder body = new StringBuilder();
		JiaoTongConfig config = getBankConfig(log.getUnitId());
		String cert_no = DateUtils.parseDateToString("yyyyMMddHHmmss", new Date())+log.getId();
		body.append("<cert_no>").append(cert_no).append("</cert_no>");
		body.append("<pay_acno>").append(log.getSourceCard()).append("</pay_acno>");
		body.append("<type>").append(config.PAYTYPE).append("</type>");
		body.append("<sum>").append(1).append("</sum>");
		String amt = String.format("%.2f", log.getAmount() / 100.0);
		body.append("<sum_amt>").append(amt).append("</sum_amt>");
		body.append("<pay_month>").append(DateUtils.parseDateToString("yyyyMM", new Date())).append("</pay_month>");
		body.append("<busi_no>").append(busiNo).append("</busi_no>");
		body.append("<tran>");
		body.append("<rcd>");
		body.append("<card_no>").append(log.getTargetCard()).append("</card_no>");
		body.append("<acname>").append(log.getTargetAccName()).append("</acname>");
		body.append("<card_flag>").append(log.getBankType().equals("交通银行") ? "A" : "B").append("</card_flag>");
		body.append("<amt>").append(amt).append("</amt>");
		body.append("<busino>").append(log.getOrderNo()).append("</busino>");
		body.append("<busummary>").append(log.getOrderNo()+"〉〉"+log.getRemark()).append("</busummary>");
		body.append("</rcd>");
		body.append("</tran>");
		JiaoTongResponse res = request(log.getUnitId(), "330012", body, true, log.getId());
		if (res == null || !res.getResultcode().equals("0000") || StringUtils.isBlank(res.getData().elementText("ebank_batflw"))) {
			throw new ServiceException(
					res != null && StringUtils.isNotBlank(res.getResultmsg()) ? res.getResultmsg() : "代发转账失败");
		}
		log.setSourceBankNo(res.getData().elementText("ebank_batflw"));
		log.setTargetBankNo(log.getSourceBankNo());
		log.setResult((short) 1);
		log.setReason("");
		return log;
	}

	/**
	 * 转账
	 *
	 * @author 张涛
	 * @date 2021年9月7日
	 * @param log
	 * @return
	 */
	public TransactionLog transfer(TransactionLog log) {
		StringBuilder body = new StringBuilder();
		JiaoTongConfig config = getBankConfig(log.getUnitId());
		String cert_no = DateUtils.parseDateToString("yyyyMMddHHmmss", new Date())+log.getId();
		body.append("<cert_no>").append(cert_no).append("</cert_no>");
		body.append("<super_acc>").append(config.SUPERACC).append("</super_acc>");
		body.append("<sum>").append(1).append("</sum>");
		String amt = String.format("%.2f", log.getAmount() / 100.0);
		body.append("<sum_amt>").append(amt).append("</sum_amt>");
		body.append("<tran>");
		body.append("<rcd>");
		body.append("<pay_acno>").append(log.getSourceCard()).append("</pay_acno>");
		body.append("<pay_acname>").append(log.getSourceAccName()).append("</pay_acname>");
		body.append("<rcv_acno>").append(log.getTargetCard()).append("</rcv_acno>");
		body.append("<rcv_acname>").append(log.getTargetAccName()).append("</rcv_acname>");
		body.append("<bank_flag>").append(log.getBankType().equals("交通银行") ? 0 : 1).append("</bank_flag>");
		body.append("<rcv_bank_name>").append(log.getBankType()).append("</rcv_bank_name>");
		body.append("<amt>").append(amt).append("</amt>");
		body.append("<purpose>").append(log.getRemark()).append("</purpose>");
		body.append("<busi_no>").append(log.getOrderNo()).append("</busi_no>");
		body.append("</rcd>");
		body.append("</tran>");
		JiaoTongResponse res = request(log.getUnitId(), "710716", body, true, log.getId());
		if (res == null || !res.getResultcode().equals("0000") || StringUtils.isBlank(res.getData().elementText("ebank_batflw"))) {
			throw new ServiceException(
					res != null && StringUtils.isNotBlank(res.getResultmsg()) ? res.getResultmsg() : "转账失败");
		}
		log.setSourceBankNo(res.getData().elementText("ebank_batflw"));
		log.setTargetBankNo(log.getSourceBankNo());
		log.setResult((short) 1);
		log.setReason("");
		return log;
	}

	/**
	 * 同步对私银行账户交易结果
	 * @author 张涛
	 * @date 2021年9月7日
	 * @param log
	 * @return
	 */
	public TransactionLog synPersionTransfer(TransactionLog log) {
		StringBuilder body = new StringBuilder();
		body.append("<ogl_serial_no>").append(log.getSourceBankNo()).append("</ogl_serial_no>");
		body.append("<query_flag>").append(2).append("</query_flag>");
		body.append("<query_type>").append("A").append("</query_type>");
		JiaoTongResponse res = request(log.getUnitId(), "310404", body, false, log.getId());
		if (res != null) {
			if (!res.getResultcode().equals("0000") || StringUtils.isBlank(res.getData().elementText("serial_record"))) {
				throw new ServiceException(
						res != null && StringUtils.isNotBlank(res.getResultmsg()) ? res.getResultmsg() : "同步交通银行对私交易结果失败");
			}
			String record_num = res.getData().elementText("record_num");
			if (Integer.parseInt(record_num) > 0) {
				List<Map<String, String>> list = JiaoTongUtil.getInstance().getMutiAreaData(res.getData().elementText("serial_record"), Integer.parseInt(res.getData().elementText("field_num")));
				if (list.size() > 0 && list.get(0).containsKey("状态")) {
					if (list.get(0).get("状态").equals("F")) {
						log.setResult((short) 2);
						log.setTranTime(new Date());
					}else if (list.get(0).get("状态").equals("E")) {
						log.setResult((short) 3);
						if(list.get(0).containsKey("错误原因")) {
							log.setReason(list.get(0).get("错误原因"));
						}
						log.setTranTime(new Date());
					}

				}
			}
		}
		return log;
	}

	/**
	 * 同步内部交易结果
	 *
	 * @author 张涛
	 * @date 2021年9月7日
	 * @param log
	 * @return
	 */
	public TransactionLog synInnerTransfer(TransactionLog log) {
		StringBuilder body = new StringBuilder();
		body.append("<ebank_batflw>").append(log.getSourceBankNo()).append("</ebank_batflw>");
		body.append("<query_flag>").append(2).append("</query_flag>");
		JiaoTongResponse res = request(log.getUnitId(), "710717", body, false, log.getId());
		if (res != null) {
			if (!res.getResultcode().equals("0000") || StringUtils.isBlank(res.getData().elementText("serial_record"))) {
				throw new ServiceException(
						res != null && StringUtils.isNotBlank(res.getResultmsg()) ? res.getResultmsg() : "同步交通银行交易结果失败");
			}
			String record_num = res.getData().elementText("record_num");
			if (Integer.parseInt(record_num) > 0) {
				List<Map<String, String>> list = JiaoTongUtil.getInstance().getMutiAreaData(res.getData().elementText("serial_record"), Integer.parseInt(res.getData().elementText("field_num")));
				if (list.size() > 0 && list.get(0).containsKey("交易状态")) {
					if (list.get(0).get("交易状态").equals("0")) {
						log.setResult((short) 2);
						log.setTranTime(new Date());
					}else if (list.get(0).get("交易状态").equals("3")) {
						log.setResult((short) -1);
						if(list.get(0).containsKey("备用字段1")) {
							log.setReason(list.get(0).get("备用字段1"));
						}
						log.setTranTime(new Date());
					}

				}
			}
		}
		return log;
	}

	/**
	 * 同步交易结果
	 *
	 * @author 张涛
	 * @date 2021年9月7日
	 * @param log
	 * @return
	 */
	public TransactionLog synTransfer(TransactionLog log) {
		StringBuilder body = new StringBuilder();
		body.append("<ebank_batflw>").append(log.getSourceBankNo()).append("</ebank_batflw>");
		body.append("<query_flag>").append(2).append("</query_flag>");
		JiaoTongResponse res = request(log.getUnitId(), "710717", body, false, log.getId());
		if (res != null) {
			if (!res.getResultcode().equals("0000") || StringUtils.isBlank(res.getData().elementText("serial_record"))) {
				throw new ServiceException(
						res != null && StringUtils.isNotBlank(res.getResultmsg()) ? res.getResultmsg() : "同步交通银行交易结果失败");
			}
			String record_num = res.getData().elementText("record_num");
			if (Integer.parseInt(record_num) > 0) {
				List<Map<String, String>> list = JiaoTongUtil.getInstance().getMutiAreaData(res.getData().elementText("serial_record"), Integer.parseInt(res.getData().elementText("field_num")));
				if (list.size() > 0 && list.get(0).containsKey("交易状态")) {
					if (list.get(0).get("交易状态").equals("0")) {
						log.setResult((short) 2);
						log.setTranTime(new Date());
					}else if (list.get(0).get("交易状态").equals("3")) {
						log.setResult((short) 3);
						if(list.get(0).containsKey("备用字段1")) {
							log.setReason(list.get(0).get("备用字段1"));
						}
						log.setTranTime(new Date());
					}

				}
			}
		}
		return log;
	}

	/**
	 * 获取交易回置单
	 *
	 * @author 张涛
	 * @date 2021年9月16日
	 * @param log
	 * @return
	 * @throws IOException
	 * @throws SftpException
	 */
	public String getTransferCallback(TransactionLog log) throws IOException, InterruptedException {
		String callBackFile = "";
		String synDate = DateUtils.parseDateToString(DateUtils.YYYYMMDD,log.getTranTime());
		String lockKey = "jiaotongback:"+log.getUnitId()+":"+synDate;
        RLock lock = RedisUtils.getClient().getLock(lockKey);
        if(lock.tryLock(1000*60*30, TimeUnit.MILLISECONDS)) {
			JiaoTongConfig config = getBankConfig(log.getUnitId());
			String uploadPhyPath = wConfigService.getUploadPhyPath(log.getUnitId())+"/";
			String flName = config.CUSTNO+"_"+synDate+".zip";
			String saveFile = uploadPhyPath + flName;
			File saveFileObj = new File(saveFile);
			if(!saveFileObj.exists()) {
				saveFileObj = null;
				SftpUtils sftpUtils = new SftpUtils();
				ChannelSftp sftp = null;
				try {
					String directory = "/";
					sftp = sftpUtils.connect(config.CALLBACKHOST, Integer.parseInt(config.CALLBACKPORT), config.CALLBACKNAME, config.CALLBACKPASSWORD);
					if (sftpUtils.isExist(directory, flName, sftp)) {
						if(sftpUtils.download(directory, flName, saveFile, sftp)) {
							saveFileObj = new File(saveFile);
							sftpUtils.delete(directory, flName, sftp);
						}
					}
				} catch (Exception e) {
					// TODO 自动生成的 catch 块
					this.log.error("下载交通银行交易回置单文件出错（"+flName+"）：",e);
				} finally {
					sftpUtils.disconnect(config.CALLBACKHOST, sftp);
				}
			}
			if (saveFileObj != null) {
				String descDir = saveFile.substring(0,saveFile.lastIndexOf("."))+"/";
				ZipUtils.unZipFiles(saveFile, descDir);
				File dir = new File(descDir);
				File[] files = dir.listFiles(); // 该文件目录下文件全部放入数组
		        if (files != null) {
		        	String uploadNetPath = wConfigService.getUploadNetPath(log.getUnitId());
		        	//回执单列表
		        	Map<String,TransactionLog> callBackFileList = new HashMap<String,TransactionLog>();
		            for (int i = 0,len = files.length; i < len; i++) {
		            	String fileName = files[i].getName();
		                if (files[i].isFile() && fileName.endsWith(".zip")) { // 判断是文件
		                    String fileDir = descDir + fileName.substring(0,fileName.lastIndexOf("."))+"/";
		                    ZipUtils.unZipFiles(descDir+fileName, fileDir);
		                    String payListFile = fileDir + fileName.substring(0,fileName.lastIndexOf("."))+".txt";
		                    List<Map<String, String>> payList = JiaoTongUtil.getInstance().getMutiAreaData(FileUtils.readTxtFile(payListFile,"|"), 12);
		                    for (Map<String, String> pay : payList) {
								if (pay.get("!借贷标志").equals("!借方")) {
									String key = pay.get("!会计流水号").substring(1);
									//主账户下的回执单：代发的收款人是真实收款人
									//云账户下的回执单：代发的收款人是主账户
									//会计流水号不存在，或属于主账户下的回执单（同一会计流水号会存在多个账户文件夹中)
									String payReceipt = fileDir.replace(uploadPhyPath, uploadNetPath)+pay.get("回单日期")+"_"+pay.get("!回单编号").substring(1)+"_"+key+".pdf";
									if (!callBackFileList.containsKey(key)) {
										TransactionLog callBack = new TransactionLog();
										callBack.setTargetBankNo(key);
										callBack.setPayReceipt(payReceipt);
										callBackFileList.put(key, callBack);
									}else if (callBackFileList.containsKey(key) && fileName.indexOf("-") == -1) {
										callBackFileList.get(key).setPayReceipt(payReceipt);
									}
								}
							}
		                }
		            }
		            transactionLogDao.updatePayReceipt("交通银行", new ArrayList<TransactionLog>(callBackFileList.values()));
		            if (callBackFileList.containsKey(log.getTargetBankNo())) {
		            	callBackFile = callBackFileList.get(log.getTargetBankNo()).getPayReceipt();
					}
		        }
			}
            lock.unlock();
		}
		return callBackFile;
	}

	/**
	 * 获取交易流水号
	 *
	 * @author 张涛
	 * @date 2021年9月22日
	 * @param log
	 * @param trsseq 断点续传编号
	 * @return
	 */
	public String getTransferBankNo(TransactionLog log) {
		String result = "";
		if(log.getTranTime() != null) {
			StringBuilder body = new StringBuilder();
			//同步到结果的日期（结束日期）
			String synDate = DateUtils.parseDateToString(DateUtils.YYYY_MM_DD, log.getTranTime());
			//开始日期（解决同步到结果的日期与银行出结果的时间差问题）
			String startDate = DateUtils.parseDateToString(DateUtils.YYYY_MM_DD, DateUtils.addOneHour(log.getTranTime(), -1));
			body.append("<accNo>").append(log.getSourceCard()).append("</accNo>");
			body.append("<dtlTyp>").append(2).append("</dtlTyp>");
			body.append("<startDate>").append(startDate.replace("-", "")).append("</startDate>");
			body.append("<endDate>").append(synDate.replace("-", "")).append("</endDate>");
			JiaoTongResponse res = request(log.getUnitId(), "710714", body, false);
			if (res != null) {
				if (!res.getResultcode().equals("0000") || StringUtils.isBlank(res.getData().elementText("serial_record"))) {
					throw new ServiceException(
							res != null && StringUtils.isNotBlank(res.getResultmsg()) ? res.getResultmsg() : "同步交通银行交易流水号失败");
				}
				String record_num = res.getData().elementText("record_num");
				if (Integer.parseInt(record_num) > 0) {
					List<Map<String, String>> list = JiaoTongUtil.getInstance().getMutiAreaData(res.getData().elementText("serial_record"), Integer.parseInt(res.getData().elementText("field_num")));
					for (Map<String, String> item : list) {
						String frmcod = item.containsKey("账号") ? item.get("账号") : "";
						if (frmcod.equals(log.getSourceCard())) {
							String narinn = null;
							if (item.get("传票业务摘要区").indexOf("〉〉") != -1) {
								narinn = item.get("传票业务摘要区").split("〉〉")[0];
							}
							if (StringUtils.isNotBlank(narinn) && narinn.equals(log.getOrderNo())) {
								result = item.get("会计流水号");
								break;
							}
						}
					}
				}
			}
		}
		return result;
	}
}
