欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

中信银行银企直连对接项目

程序员文章站 2024-01-01 15:37:22
...

中信银行银企直连对接项目

1. 项目介绍

小猫停车场管理后台,将停车缴费和月卡续费的钱,通过对接中信银行银企直连系统将钱款转账给各个停车场账户。

2.拓扑图

中信银行银企直连对接项目

3.部分代码

3.1.云端代码实现

控制层 BillController

package com.mallparking.controller;

import java.text.ParseException;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.mallparking.mongo.model.AccountingBill;
import com.mallparking.mongo.model.MongoParking;
import com.mallparking.mongo.model.OperateBill;
import com.mallparking.mongo.model.ParkBill;
import com.mallparking.service.BillService;

/**
 *
 * @ClassName: BillController
 * @Description: 根据账单转账控制器
 * @author 郭鹏远
 * @date 2017年4月20日
 * @version v1.0
 *
 */
@RestController
@RequestMapping("/bill")
public class BillController {

    Logger logger = LoggerFactory.getLogger(BillController.class);

    @Autowired
    private BillService billService;

    // -------------------- 根据停车账单编号查询停车账单实体 ------------------------------
    @SuppressWarnings("unchecked")
    @RequestMapping(value = "/find/billnos", method = RequestMethod.POST)
    public ParkBill[] findByBillNos(@RequestBody Map<String, Object> map) {
        List<String> billNos = (List<String>) map.get("billNos");
        logger.info(">>>>>>>>>>开始停车账单编号查询停车账单实体,请求参数billNos为:");
        for (String billNo : billNos) {
            logger.info("-----billNo:" + billNo);
        }
        // 记录开始时间
        long beginTime = System.currentTimeMillis();
        ParkBill[] parkBills = billService.findEntitys(billNos);
        logger.info(">>>>>>>>>>完成停车账单编号查询停车账单实体,耗时[" + (System.currentTimeMillis() - beginTime) + "]ms");
        return parkBills;
    }

    // -------------------- 根据停车账单实体数组进行更新 ----------------------------------
    @RequestMapping(value = "/update/parkbills", method = RequestMethod.POST)
    public void updateByEntity(@RequestBody Map<String, Object> map) {
        String parkBillStr = (String) map.get("parkBills");
        logger.info(">>>>>>>>>>开始停车账单实体更新请求,请求参数parkBillStr为:"+parkBillStr);
        // 记录开始时间
        long beginTime = System.currentTimeMillis();
        try {
            billService.updatePrk(parkBillStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        logger.info(">>>>>>>>>>完成停车账单实体更新请求,耗时[" + (System.currentTimeMillis() - beginTime) + "]ms");
    }

    // -------------------- 根据客户流水号查询停车账单实体 ----------------------------------
    @RequestMapping(value = "/find/client", method = RequestMethod.POST)
    public ParkBill findByBillNosByClient(@RequestBody Map<String, Object> map) {
        String clientId = (String) map.get("clientId");
        logger.info(">>>>>>>>>>开始根据客户流水号查询停车账单实体,请求参数为[" + clientId + "]");
        // 记录开始时间
        long beginTime = System.currentTimeMillis();
        ParkBill parkBill = billService.findEntityOne(clientId);
        logger.info(">>>>>>>>>>完成根据客户流水号查询停车账单实体,耗时[" + (System.currentTimeMillis() - beginTime) + "]ms");
        return parkBill;
    }

    // -------------------- 根据每天月卡运营账单编号查询账单实体 ------------------------------
    @SuppressWarnings("unchecked")
    @RequestMapping(value = "/find/billnos/operate", method = RequestMethod.POST)
    public OperateBill[] findByOperateBillNos(@RequestBody Map<String, Object> map) {
        List<String> billNos = (List<String>) map.get("billNos");
        logger.info(">>>>>>>>>>开始每天月卡运营账单编号查询账单实体,请求参数billNos为:");
        for (String billNo : billNos) {
            logger.info("-----billNo:" + billNo);
        }
        // 记录开始时间
        long beginTime = System.currentTimeMillis();
        OperateBill[] operateBills = billService.findOperateEntitys(billNos);
        logger.info(">>>>>>>>>>完成每天月卡运营账单编号查询账单实体,耗时[" + (System.currentTimeMillis() - beginTime) + "]ms");
        return operateBills;
    }

    // -------------------- 根据每天月卡运营账单实体组进行更新 ----------------------------------
    @RequestMapping(value = "/update/operatebills", method = RequestMethod.POST)
    public void updateByOperateEntity(@RequestBody Map<String, Object> map) {
        String operateBillStr = (String) map.get("operateBills");
        logger.info(">>>>>>>>>>开始每天月卡运营账单实体更新请求,请求参数operateBillStr为:" + operateBillStr);
        // 记录开始时间
        long beginTime = System.currentTimeMillis();
        try {
            billService.updateOpe(operateBillStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        logger.info(">>>>>>>>>>完成每天月卡运营账单实体更新请求,耗时[" + (System.currentTimeMillis() - beginTime) + "]ms");
    }

    // -------------------- 根据月卡账单编号查询账单实体 ------------------------------
    @SuppressWarnings("unchecked")
    @RequestMapping(value = "/find/billnos/accounting", method = RequestMethod.POST)
    public AccountingBill[] findByAccountingBillNos(@RequestBody Map<String, Object> map) {
        List<String> billNos = (List<String>) map.get("billNos");
        logger.info(">>>>>>>>>>开始月卡账单编号查询账单实体,请求参数billNos为:");
        for (String billNo : billNos) {
            logger.info("-----billNo:" + billNo);
        }
        // 记录开始时间
        long beginTime = System.currentTimeMillis();
        AccountingBill[] accountingBills = billService.findAccountingEntitys(billNos);
        logger.info(">>>>>>>>>>完成月卡账单编号查询账单实体,耗时[" + (System.currentTimeMillis() - beginTime) + "]ms");
        return accountingBills;
    }

    // -------------------- 根据月卡账单实体组进行更新 ----------------------------------
    @RequestMapping(value = "/update/accountingbills", method = RequestMethod.POST)
    public void updateByAccountingEntity(@RequestBody Map<String, Object> map) {
        String accountingBillStr = (String) map.get("accountingBills");
        logger.info(">>>>>>>>>>开始月卡账单实体更新请求,请求参数accountingBillStr为:" + accountingBillStr);
        // 记录开始时间
        long beginTime = System.currentTimeMillis();
        billService.updateAcc(accountingBillStr);
        logger.info(">>>>>>>>>>完成月卡账单实体更新请求,耗时[" + (System.currentTimeMillis() - beginTime) + "]ms");
    }

    // -------------------- 根据客户流水号查询月卡账单实体 ----------------------------------
    @RequestMapping(value = "/find/client/accounting", method = RequestMethod.POST)
    public AccountingBill findByAccountingBillNosByClientId(@RequestBody Map<String, Object> map) {
        String clientId = (String) map.get("clientId");
        logger.info(">>>>>>>>>>开始根据客户流水号查询月卡账单实体,请求参数为[" + clientId + "]");
        // 记录开始时间
        long beginTime = System.currentTimeMillis();
        AccountingBill accountingBill = billService.findAccountingEntityOne(clientId);
        logger.info(">>>>>>>>>>完成根据客户流水号查询月卡账单实体,耗时[" + (System.currentTimeMillis() - beginTime) + "]ms");
        return accountingBill;
    }

    // -------------------- 根据小猫用户smallId查询MongoParking实体
    // -------------------------
    @RequestMapping(value = "/find/mongoparking", method = RequestMethod.POST)
    public MongoParking findBySmallId(@RequestBody Map<String,Object> map) {
        String smallId = (String) map.get("smallId");
        logger.info(">>>>>>>>>>开始根据客户流水号查询MongoParking实体,请求参数为[" + smallId + "]");
        // 记录开始时间
        long beginTime = System.currentTimeMillis();
        MongoParking mongoParking = billService.findMongoParking(smallId);
        logger.info(">>>>>>>>>>完成根据客户流水号查询MongoParking实体,耗时[" + (System.currentTimeMillis() - beginTime) + "]ms");
        return mongoParking;
    }

    // -------------------- 根据账单编号billNo设置MobileMember实体的属性OrderPayStat为true
    // -------------------------
    @SuppressWarnings("unchecked")
    @RequestMapping(value = "/set/orderpaystat", method = RequestMethod.POST)
    public void setOrderPayStat(@RequestBody Map<String, Object> map) {
        List<String> billNos = (List<String>) map.get("billNos");
        logger.info(">>>>>>>>>>开始根据账单编号billNo设置MobileMember实体的属性OrderPayStat为true,传入参数billNos为:");
        for (String billNo : billNos) {
            logger.info("-----billNo:" + billNo);
        }
        // 记录开始时间
        long beginTime = System.currentTimeMillis();
        billService.setStatus(billNos);
        logger.info(">>>>>>>>>>完成根据账单编号billNo设置MobileMember实体的属性OrderPayStat为true,耗时["
                + (System.currentTimeMillis() - beginTime) + "]ms");

    }

    // -------------------- 根据传入参数(操作人+账单编号)创建结算操作记录表数据
    // -------------------------
    @RequestMapping(value = "/create/monthcardpayrecord", method = RequestMethod.POST)
    public void createMonthCardPayRecord(@RequestBody Map<String, Object> map) {
        @SuppressWarnings("unchecked")
        List<String> billNos = (List<String>) map.get("billNos");
        String operationPerson = (String) map.get("operationPerson");
        logger.info(">>>>>>>>>>开始根据传入参数(操作人+账单编号)创建结算操作记录表数据");
        logger.info("-----传入参数billNos:");
        for (String billNo : billNos) {
            logger.info("-----billNo:" + billNo);
        }
        logger.info("-----传入参数operationPerson:" + operationPerson);
        // 记录开始时间
        long beginTime = System.currentTimeMillis();
        billService.createPayRecord(billNos, operationPerson);
        logger.info(
                ">>>>>>>>>>完成根据传入参数(操作人+账单编号)创建结算操作记录表数据,耗时[" + (System.currentTimeMillis() - beginTime) + "]ms");
    }
    // -------------------- 根据传入参数(操作人+账单编号)删除结算操作记录表中一条记录 -------------------------
    @SuppressWarnings("unchecked")
    @RequestMapping(value="/delete/monthcardpayrecord",method = RequestMethod.POST)
    public void deleteMonthCardPayRecord(@RequestBody Map<String,Object> map){
        List<String> billNos =(List<String>) map.get("billNos");
        String operationPerson = (String) map.get("operationPerson");
        logger.info(">>>>>>>>>>开始根据传入参数(操作人+账单编号)删除结算操作记录表中一条记录");
        logger.info("-----传入参数billNos:");
        for (String billNo : billNos) {
            logger.info("-----billNo:" + billNo);
        }
        logger.info("-----传入参数operationPerson:" + operationPerson);
        // 记录开始时间
        long beginTime = System.currentTimeMillis();
        billService.deletePayRecord(billNos, operationPerson);
        logger.info(">>>>>>>>>>完成根据传入参数(操作人+账单编号)删除结算操作记录表中一条记录,耗时["
                + (System.currentTimeMillis() - beginTime) + "]ms");
    }

    // -------------------- 根据传入参数(操作人+账单编号)更新结算操作记录表status为true
    // -------------------------
    @SuppressWarnings("unchecked")
    @RequestMapping(value = "/set/monthcardpayrecord", method = RequestMethod.POST)
    public void setMonthCardPayRecord(@RequestBody Map<String, Object> map) {
        List<String> billNos = (List<String>) map.get("billNos");
        String operationPerson = (String) map.get("operationPerson");
        logger.info(">>>>>>>>>>开始根据传入参数(操作人+账单编号)更新结算操作记录表status为true");
        logger.info("-----传入参数billNos:");
        for (String billNo : billNos) {
            logger.info("-----billNo:" + billNo);
        }
        logger.info("-----传入参数operationPerson:" + operationPerson);
        // 记录开始时间
        long beginTime = System.currentTimeMillis();
        billService.setPayRecord(billNos, operationPerson);
        logger.info(">>>>>>>>>>完成根据传入参数(操作人+账单编号)更新结算操作记录表status为true,耗时["
                + (System.currentTimeMillis() - beginTime) + "]ms");
    }

}

业务层 BillServiceImpl

package com.mallparking.service.impl;


import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import com.mallparking.mongo.dao.AccountingBillDAO;
import com.mallparking.mongo.dao.MonthCardPayRecordDAO;
import com.mallparking.mongo.dao.OperateBillDAO;
import com.mallparking.mongo.dao.ParkBillDAO;
import com.mallparking.mongo.dao.ParkingDAO;
import com.mallparking.mongo.model.AccountingBill;
import com.mallparking.mongo.model.MobileMember;
import com.mallparking.mongo.model.MongoParking;
import com.mallparking.mongo.model.MonthCardPayRecord;
import com.mallparking.mongo.model.OperateBill;
import com.mallparking.mongo.model.ParkBill;
import com.mallparking.service.BillService;

/**
 * 
 * @ClassName: BillServiceImpl
 * @Description: 转账及查询业务实现
 * @author 郭鹏远
 * @date 2017年4月21日
 * @version V1.0
 *
 */
@Service("billService")
public class BillServiceImpl implements BillService {

    Logger logger = LoggerFactory.getLogger(BillServiceImpl.class);
    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
    DecimalFormat df = new DecimalFormat("0000");

    @Autowired
    private ParkBillDAO parkBillDAO;

    @Autowired
    private AccountingBillDAO accountingBillDAO;

    @Autowired
    private OperateBillDAO operateBillDAO;

    @Autowired
    private ParkingDAO parkingDAO;

    @Autowired
    private MonthCardPayRecordDAO monthCardPayRecordDAO;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public ParkBill[] findEntitys(List<String> billNos){
        ParkBill[] parkBills = parkBillDAO.findByBillNoIn(billNos);
        return parkBills;   
    }

    @Override
    public ParkBill findEntityOne(String clientId){
        ParkBill parkBill = parkBillDAO.findByClientId(clientId);
        return parkBill;
    }

    @SuppressWarnings("unchecked")
    @Override
    public void updatePrk(String parkBillStr) throws ParseException{
        Map<String,Object> map = getMapByXml(parkBillStr);
        logger.info("-----map:"+map);
        List<Map<String,Object>> lists = (List<Map<String, Object>>) map.get("list");
        for (Map<String, Object> entity : lists) {
            ParkBill parkBillFind = parkBillDAO.findByBillNo((String)entity.get("billNo"));
            parkBillFind.setPaystate((String)entity.get("paystate"));
            parkBillFind.setBatNo((String)entity.get("batNo"));
            parkBillFind.setIsSettle(entity.get("isSettle").equals("true")?true:false);
            parkBillFind.setStatus(entity.get("status").equals("1")?1:0);
            parkBillFind.setReceipt((String)entity.get("receipt"));
            parkBillFind.setClientId((String)entity.get("clientId"));
            if(entity.get("settleDate")!=null){
                parkBillFind.setSettleDate(sdf.parse((String)entity.get("settleDate")));
            }           
            parkBillDAO.save(parkBillFind);
        }       
    }

    @Override
    public MongoParking findMongoParking(String smallId){
        MongoParking mongoParking = parkingDAO.findBySmallId(smallId);
        return mongoParking;
    }

    @SuppressWarnings("unchecked")
    @Override
    public void updateAcc(String accountingBillStr) {
        Map<String,Object> map = getMapByXml(accountingBillStr);
        List<Map<String,Object>> lists = (List<Map<String, Object>>) map.get("list");
        for (Map<String, Object> entity : lists) {
            AccountingBill accountingBillFind = accountingBillDAO.findByBillNo((String)entity.get("billNo"));
            accountingBillFind.setPaystate((String)entity.get("paystate"));
            accountingBillFind.setBatNo((String)entity.get("batNo"));
            accountingBillFind.setStatus(entity.get("status").equals("1")?1:0);
            accountingBillFind.setReceipt((String)entity.get("receipt"));
            accountingBillFind.setClientId((String)entity.get("clientId"));
            accountingBillDAO.save(accountingBillFind);
        }
    }

    @Override
    public AccountingBill[] findAccountingEntitys(List<String> billNos) {
        AccountingBill[] accountingBills = accountingBillDAO.findByBillNoIn(billNos);
        return accountingBills;
    }

    @Override
    public AccountingBill findAccountingEntityOne(String clientId) {
        AccountingBill accountingBill = accountingBillDAO.findByClientId(clientId);
        return accountingBill;
    }

    @SuppressWarnings("unchecked")
    @Override
    public void updateOpe(String operateBillStr) throws ParseException {
        Map<String,Object> map = getMapByXml(operateBillStr);
        List<Map<String,Object>> lists = (List<Map<String, Object>>) map.get("list");
        for(Map<String,Object> entity:lists){
            OperateBill operateBillFind = operateBillDAO.findByBillNo((String)entity.get("billNo"));
            operateBillFind.setPaystate((String)entity.get("paystate"));
            operateBillFind.setBatNo((String)entity.get("batNo"));
            operateBillFind.setIsSettle(entity.get("isSettle").equals("true")?true:false);
            operateBillFind.setStatus(entity.get("status").equals("1")?1:0);
            operateBillFind.setReceipt((String)entity.get("receipt"));
            operateBillFind.setClientId((String)entity.get("clientId"));
            if(entity.get("settleDate")!=null){
                operateBillFind.setSettleDate(sdf.parse((String)entity.get("settleDate")));
            }

            operateBillDAO.save(operateBillFind);
        }
    }

    @Override
    public OperateBill[] findOperateEntitys(List<String> billNos) {
        OperateBill[] operateBills = operateBillDAO.findByBillNoIn(billNos);
        return operateBills;
    }

    @Override
    public void setStatus(List<String> billNos) {
        for(String billNo:billNos){
            mongoTemplate.updateFirst(new Query(Criteria.where("outTradeNo").is(billNo)), new Update().set("orderPayStat", true), MobileMember.class);
        }

    }

    @Override
    public void createPayRecord(List<String>billNos,String operationPerson) {
        for(String billNo:billNos){
            if(monthCardPayRecordDAO.findByBillNo(billNo)==null){
                MonthCardPayRecord record = new MonthCardPayRecord();
                record.setBillNo(billNo);
                record.setOperationPerson(operationPerson);
                record.setPayTime(new Date());
                record.setStatus(false);
                monthCardPayRecordDAO.save(record);

            }
        }

    }
    @Override
    public void deletePayRecord(List<String>billNos,String operationPerson) {
        for(String billNo:billNos){
            MonthCardPayRecord record = monthCardPayRecordDAO.findByBillNo(billNo);
            if(record!=null){
                monthCardPayRecordDAO.deleteByBillNo(billNo);
            }

        }

    }

    @Override
    public void setPayRecord(List<String> billNos,String operationPerson) {
        MonthCardPayRecord record =null;
        for(String billNo:billNos){
            record = monthCardPayRecordDAO.findByBillNo(billNo);
            if(record!=null){
                record.setStatus(true);
                monthCardPayRecordDAO.save(record);
            }           
        }
    }

    // 将收到的XML字符串转化为MAP
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static Map<String, Object> getMapByXml(String xml) {
        Map<String, Object> returnMap = new HashMap<String, Object>();
        Document document = null;
        try {
            document = DocumentHelper.parseText(xml);
        } catch (DocumentException e) {
            // throw new CiticDirectException(e);
        }
        Element infoElement = (Element) document.getRootElement();
        Iterator rootIter = infoElement.elementIterator();
        while (rootIter.hasNext()) {
            Element element = (Element) rootIter.next();
            // System.out.println(element.getName());
            if (element.getName().equals("list")) {
                List<Map<String, Object>> list = new ArrayList();
                Iterator rowIter = element.elementIterator();
                while (rowIter.hasNext()) {
                    Map<String, Object> map = new HashMap<String, Object>();
                    Element rowEle = (Element) rowIter.next();
                    Iterator resIter = rowEle.elementIterator();
                    while (resIter.hasNext()) {
                        Element resEle = (Element) resIter.next();
                        map.put(resEle.getName(), resEle.getText());
                    }
                    list.add(map);
                }
                returnMap.put("list", list);
            } else {
                returnMap.put(element.getName(), element.getText());
            }
        }
        return returnMap;
    }

}// end class

3.2.本地服务实现

控制层实现 BillController

package com.mallparking.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.mallparking.exception.CiticConnectException;
import com.mallparking.model.BillParam;
import com.mallparking.model.QueryParam;
import com.mallparking.service.BillService;
import com.mallparking.utils.Constant;

/**
 *
 * @ClassName: BillController
 * @Description: 根据账单转账控制器
 * @author 郭鹏远
 * @date 2017年4月20日
 * @version v1.0
 *
 */
@RestController
@RequestMapping("/bill")
public class BillController {

    Logger logger = LoggerFactory.getLogger(BillController.class);

    @Autowired
    private BillService billService;

    // ------------------- 停车账单转账请求 -------------------------------------------
    @RequestMapping(value = "/transfer/parkbill", method = RequestMethod.POST)
    public Map<String, Object> parkBillTransfer(@RequestBody BillParam billParam) {

        List<String> billNos = billParam.getBillNos();
        String operationPerson = billParam.getOperationPerson();
        logger.info("开始处理停车账单转账请求,传入的账单号为[" + billNos.toString() + "],传入的操作人为[" + operationPerson + "]");

        // 记录开始时间
        long beginTime = System.currentTimeMillis();
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("flag", Constant.RESPONSE_FLAG_FAILED);

        // Step1 - 检查参数是否合法(非空)
        for (String billNo : billNos) {
            if (billNo == null) {
                map.put("msg", "提交失败");
                return map;
            }
        }

        // Step2 - 调用service层方法
        try {
            Map<String, Object> result = billService.transferPark(billParam);
            map.putAll(result);
        } catch (CiticConnectException e) {
            e.printStackTrace();
            map.put("msg", "银企直联系统异常");
        } catch (Exception e) {
            e.printStackTrace();
            map.put("msg", "服务器异常");
        }
        logger.info("完成停车账单转账请求,耗时[" + (System.currentTimeMillis() - beginTime) + "]ms");
        return map;
    }

    // ------------------- 停车账单转账查询请求
    // --------------------------------------------
    @SuppressWarnings("unchecked")
    @RequestMapping(value = "/query/parkbill", method = RequestMethod.POST)
    public Map<String, Object> parkBillQuery(@RequestBody QueryParam queryParam) {
        String operationPerson = queryParam.getOperationPerson();
        Map<String, Object> queryMaps = queryParam.getQueryMaps();
        logger.info("开始停车账单转账查询请求,传入的操作人为[" + operationPerson + "]");
        // 开始时间
        long beginTime = System.currentTimeMillis();
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("flag", Constant.RESPONSE_FLAG_FAILED);


        // Step1 - 检查参数是否合法(非空)
        if(queryMaps == null){
            map.put("msg", "提交失败");
            return map;
        }       
        for (Map.Entry<String, Object> entry : queryMaps.entrySet()) {
            logger.info("传入的批次号:" + entry.getKey() + ",传入批次号对应的账单编号:" + entry.getValue());
            for (String billNo : (List<String>) entry.getValue()) {
                if (billNo == null) {
                    map.put("msg", "提交失败");
                    return map;
                }
            }
        }
        // Step2 - 调用service层方法
        try {
            Map<String, Object> result = billService.queryPark(queryParam);
            map.putAll(result);
        } catch (CiticConnectException e) {
            e.printStackTrace();
            map.put("msg", "银企直联系统异常");
        } catch (Exception e) {
            e.printStackTrace();
            map.put("msg", "服务器异常");
        }
        logger.info("完成停车账单交易查询请求,耗时[" + (System.currentTimeMillis() - beginTime) + "]ms");
        return map;
    }

    // ------------------- 月卡账单转账请求 -------------------------------------------
    @RequestMapping(value = "/transfer/accountingbill", method = RequestMethod.POST)
    public Map<String, Object> accountingBillTransfer(@RequestBody BillParam billParam) {
        List<String> billNos = billParam.getBillNos();
        String operationPerson = billParam.getOperationPerson();
        logger.info("开始月卡账单转账查询请求,传入的账单号为[" + billNos.toString() + "],传入的操作人为[" + operationPerson + "]");

        // 记录开始时间
        long beginTime = System.currentTimeMillis();
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("flag", Constant.RESPONSE_FLAG_FAILED);

        // Step1 - 检查参数是否合法(非空)
        for (String billNo : billNos) {
            if (billNo == null) {
                map.put("msg", "提交失败");
                return map;
            }
        }
        // Step2 - 调用service层方法
        try {
            Map<String, Object> result = billService.transferAccounting(billParam);
            map.putAll(result);
        } catch (CiticConnectException e) {
            e.printStackTrace();
            map.put("msg", "银企直联系统异常");
        } catch (Exception e) {
            e.printStackTrace();
            map.put("msg", "服务器异常");
        }
        logger.info("完成月卡账单转账请求,耗时[" + (System.currentTimeMillis() - beginTime) + "]ms");
        return map;
    }

    @SuppressWarnings("unchecked")
    @RequestMapping(value = "/query/accountingbill", method = RequestMethod.POST)
    public Map<String, Object> accountingBillQuery(@RequestBody QueryParam queryParam) {

        String operationPerson = queryParam.getOperationPerson();
        Map<String, Object> queryMaps = queryParam.getQueryMaps();
        logger.info("开始月卡账单转账查询请求,传入的操作人为[" + operationPerson + "]");
        // 开始时间
        long beginTime = System.currentTimeMillis();
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("flag", Constant.RESPONSE_FLAG_FAILED);
        // Step1 - 检查参数是否合法(非空)
        if(queryMaps == null){
            map.put("msg", "提交失败");
            return map;
        }
        for (Map.Entry<String, Object> entry : queryMaps.entrySet()) {
            logger.info("传入的批次号:" + entry.getKey() + ",传入批次号对应的账单编号:" + entry.getValue());          
            for (String billNo : (List<String>) entry.getValue()) {
                if (billNo == null) {
                    map.put("msg", "提交失败");
                    return map;
                }
            }
        }
        // Step2 - 调用service层方法
        try {
            Map<String, Object> result = billService.queryAccounting(queryParam);
            map.putAll(result);
        } catch (CiticConnectException e) {
            e.printStackTrace();
            map.put("msg", "银企直联系统异常");
        } catch (Exception e) {
            e.printStackTrace();
            map.put("msg", "服务器异常");
        }
        logger.info("完成停车账单交易查询请求,耗时[" + (System.currentTimeMillis() - beginTime) + "]ms");
        return map;
    }

}

业务层 BillServiceImpl

package com.mallparking.service;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import com.mallparking.config.CiticBankConfig;
import com.mallparking.model.MongoParking;
import com.mallparking.model.OperateBill;
import com.mallparking.model.BillParam;
import com.mallparking.model.AccountingBill;
import com.mallparking.model.ParkBill;
import com.mallparking.model.QueryParam;
import com.mallparking.service.BillService;
import com.mallparking.utils.Constant;
import com.mallparking.utils.Encry_MD5;
import com.mallparking.utils.HttpPost;

/**
 * 
 * @ClassName: BillServiceImpl
 * @Description: 转账及查询业务实现
 * @author 郭鹏远
 * @date 2017年4月21日
 * @version V1.0
 *
 */
@Service("billService")
public class BillServiceImpl implements BillService {

    Logger logger = LoggerFactory.getLogger(BillServiceImpl.class);
    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
    DecimalFormat df = new DecimalFormat("0000");

    @Autowired
    private CiticBankConfig citic;

    private RestTemplate restTemplate = new RestTemplate();

    @SuppressWarnings("unchecked")
    @Override
    public Map<String, Object> transferPark(BillParam param) throws Exception {
        logger.info("----------测试:名字[" + citic.getName() + "]付款帐号[" + citic.getPayaccount() + "]");
        logger.info("----------测试:本地[" + citic.getUrl() + "]云端[" + citic.getSerurl() + "]");
        logger.info("----------开始停车账单转账请求提交----------");
        // 开始时间
        long beginTime = System.currentTimeMillis();
        // xml解析成的map
        Map<String, Object> map = new HashMap<String, Object>();
        // 返回结果
        Map<String, Object> result = new HashMap<String, Object>();
        // 停车单批次账单:0:成功 1:失败
        List<ParkBill>[] results = new ArrayList[2];
        // 停车总批次账单: 0: 成功 1: 失败
        List<ParkBill>[] resultAll = new ArrayList[2];
        resultAll[0] = new ArrayList<ParkBill>();
        resultAll[1] = new ArrayList<ParkBill>();
        // 账单编号:0:成功 1:失败
        List<String>[] billData = new ArrayList[2];
        billData[0] = new ArrayList<String>();
        billData[1] = new ArrayList<String>();

        // Step 1 - 获取传入参数Param中的所有信息(billNo,operationPerson)
        // Step 1.1 - 得到账单编号billNos
        List<String> billNos = param.getBillNos();
        logger.info("----------账单编号:" + billNos.toString());
        // Step 1.2 - 得到操作人operationPerson
        String operationPerson = param.getOperationPerson();

        // Step 2 - 根据账单编号数组生成批量提交xml
        // Step 2.1 - 访问云端数据,根据账单编号数组得到所有的账单信息
        Map<String, Object> postMapPrk = getPostMapByBillNos(billNos);
        ParkBill[] parkBillsNew = restTemplate.postForObject(citic.getSerurl() + "/bill/find/billnos", postMapPrk,
                ParkBill[].class);
        // Step 2.2 - 分批处理,将结果存储在ParkBill二维数组中
        ParkBill[][] parks = getBatch(parkBillsNew, 20);

        // Step 3 - 每批进行处理(发送,解析)
        for (ParkBill[] temp : parks) {
            // Step 3.1 - 对每一批次进行去除空值的操作,因最后一组数组可能存在null
            List<ParkBill> tmp = new ArrayList<ParkBill>();
            for (ParkBill parkBill : temp) {
                if (parkBill != null)
                    tmp.add(parkBill);
            }
            temp = tmp.toArray(new ParkBill[] {});
            // Step 3.2 - 生成停车账单支付批量提交sendXml
            logger.info("----------开始生成停车账单支付批量提交的xml报文----------");
            //System.out.println(temp.toString());
            for(ParkBill prkBill:temp){
                System.out.println(prkBill.toString());
            }
            String sendXml = genParkBillStr(temp);
            logger.info("----------开始发送停车账单支付批量提交请求----------");
            long beginTime1 = System.currentTimeMillis();
            String recXml = HttpPost.getInstance(citic.getUrl()).postRequest(sendXml);
            logger.info("----------发送停车账单支付批量提交请求成功,耗时[" + (System.currentTimeMillis() - beginTime1) + "]ms----------");
            // Step 3.3 - 根据提交返回状态决定流程
            logger.info("----------开始解析xml----------");
            map = getMapByXml(recXml);
            logger.info("----------解析成功,解析后的map为:[" + map + "]");
            String statusAll = (String) map.get("status");
            String statusText = (String) map.get("statusText");
            logger.info("----------查询过程状态,statusAll[" + statusAll + "],statusText[" + statusText + "]");
            // Step 3.4 - 过程成功,进行逻辑处理(调用handle)
            if ("AAAAAAA".equals(statusAll)) {
                results = handle(map, temp);
            } else {
                logger.info("----------本批查询过程不成功,状态:" + statusAll + "----------");
            }
            // Step 3.5 - 将每批次结果汇总
            if (results[0] != null)
                resultAll[0].addAll(results[0]);
            if (results[1] != null)
                resultAll[1].addAll(results[1]);
        }
        // Step 4 - 后期结果处理及数据处理
        // Step 4.1 - 由实体得到账单编号
        if (resultAll[0] != null) {
            for (ParkBill tmp : resultAll[0])
                billData[0].add(tmp.getBillNo());
        }
        if (resultAll[1] != null) {
            for (ParkBill tmp : resultAll[1])
                billData[1].add(tmp.getBillNo());
        }
        // Step 4.2 - 返回结果处理
        if (resultAll[0].size() == 0 && resultAll[1].size() == 0) {
            // a:过程失败
            result.put("sucData", billData[0].toString());
            result.put("errData", billData[1].toString());
            result.put("info", "过程失败");
            result.put("msg", "过程失败");
        } else if (resultAll[0].size() != 0 && resultAll[1].size() == 0) {
            // b: 全部成功
            result.put("sucData", billData[0].toString());
            result.put("errData", billData[1].toString());
            result.put("msg", "提交成功");
        } else {
            // c:部分失败或者全部失败
            result.put("sucData", billData[0].toString());
            result.put("errData", billData[1].toString());
            result.put("msg", "提交失败");
        }
        // Step 4.3 - 对成功的billNo进行创建monthCardPayRecord操作
        // 传入给云端的Param
        BillParam paramNew = new BillParam();
        paramNew.setBillNos(billData[0]);
        paramNew.setOperationPerson(operationPerson);
        if (billData[0] != null) {
            Map<String, Object> postMapCreatePayRecord = getPostMapByBillParam(paramNew);
            restTemplate.postForObject(citic.getSerurl() + "/bill/create/monthcardpayrecord", postMapCreatePayRecord,
                    Boolean.class);
        }
        // Step 4.4 - 进行数据的保存及更新
        if (resultAll[0] != null) {
            Map<String, Object> postMapPrkSaveSuc = getPostMapByPrk(resultAll[0]);
            restTemplate.postForObject(citic.getSerurl() + "/bill/update/parkbills", postMapPrkSaveSuc, Boolean.class);
        }
        if (resultAll[1] != null) {
            Map<String, Object> postMapPrkSaveErr = getPostMapByPrk(resultAll[1]);
            restTemplate.postForObject(citic.getSerurl() + "/bill/update/parkbills", postMapPrkSaveErr, Boolean.class);
        }
        logger.info("----------完成停车账单转账请求提交请求,耗时[" + (System.currentTimeMillis() - beginTime) + "]ms");
        return result;
    }

    @SuppressWarnings("unchecked")
    @Override
    public Map<String, Object> queryPark(QueryParam param) throws Exception {
        logger.info("----------开始停车账单支付批量查询----------");
        // 开始时间
        long beginTime1 = System.currentTimeMillis();
        // xml解析成的map
        Map<String, Object> map = new HashMap<String, Object>();
        // 函数返回结果
        Map<String, Object> result = new HashMap<String, Object>();
        // 停车单批次账单:0:成功 1:失败 2:正在处理中
        List<ParkBill>[] results = new List[3];
        results[0] = new ArrayList<ParkBill>();
        results[1] = new ArrayList<ParkBill>();
        results[2] = new ArrayList<ParkBill>();
        // 停车总批次账单:0:成功 1:失败 2:正在处理中
        List<ParkBill>[] resultAll = new List[3];
        resultAll[0] = new ArrayList<ParkBill>();
        resultAll[1] = new ArrayList<ParkBill>();
        resultAll[2] = new ArrayList<ParkBill>();
        // 账单编号:0:成功 1:失败 2:正在处理中
        List<String>[] billData = new ArrayList[3];
        billData[0] = new ArrayList<String>();
        billData[1] = new ArrayList<String>();
        billData[2] = new ArrayList<String>();

        // Step 1 - 获取传入参数Param中的所有信息(billNo,operationPerson)
        // Step 1.1 - 得到操作人operationPerson
        String operationPerson = param.getOperationPerson();
        Map<String, Object> queryMaps = param.getQueryMaps();
        // 分批处理
        for (Map.Entry<String, Object> entry : queryMaps.entrySet()) {
            String batNo = entry.getKey();
            List<String> billNos = (List<String>) entry.getValue();
            logger.info("----------批次号:" + batNo);
            logger.info("----------账单编号:" + billNos.toString());

            // Step 2 - 生成停车账单支付批量查询sendXmlQuery
            logger.info("----------开始生成停车账单支付批量查询的xml报文----------");
            String sendXmlQuery = genParkBillQuery(batNo);

            // Step 3 - 发送批量查询请求,并对结果进行解析
            // Step 3.1 - 发送批量查询请求,得到查询返回状态
            logger.info("----------开始发送停车账单支付批量查询请求----------");
            long beginTime = System.currentTimeMillis();
            String recXmlQuery = HttpPost.getInstance(citic.getUrl()).postRequest(sendXmlQuery);
            logger.info("----------发送停车账单支付批量查询请求成功,耗时[" + (System.currentTimeMillis() - beginTime) + "]ms----------");
            // Step 3.2 - 根据提交返回状态决定流程
            logger.info("----------开始解析xml----------");
            map = getMapByXml(recXmlQuery);
            logger.info("----------解析成功,解析后的map为:[" + map + "]");
            String statusAll = (String) map.get("status");
            String statusText = (String) map.get("statusText");
            logger.info("----------查询过程状态,statusAll[" + statusAll + "],statusText[" + statusText + "]");
            // Step 3.3 - 过程成功,进行逻辑处理(调用queryHandlePark)
            if ("AAAAAAA".equals(statusAll)) {
                results = queryHandlePark(map, billNos);
            } else {
                logger.info("----------本批查询过程不成功,状态:" + statusAll + "----------");
            }
            // Step 3.4 - 将每批次结果汇总
            if (results[0] != null)
                resultAll[0].addAll(results[0]);
            if (results[1] != null)
                resultAll[1].addAll(results[1]);
            if (results[2] != null)
                resultAll[2].addAll(results[2]);
        }

        // Step 4 - 汇总结果整体处理
        // Step 4.1 - 由实体得到账单编号
        if (resultAll[0] != null)
            for (ParkBill tmp : resultAll[0])
                billData[0].add(tmp.getBillNo());
        if (resultAll[1] != null)
            for (ParkBill tmp : resultAll[1])
                billData[1].add(tmp.getBillNo());
        if (resultAll[2] != null) {
            for (ParkBill tmp : resultAll[2])
                billData[2].add(tmp.getBillNo());
        }
        // Step 4.2 - 对于交易成功的账单,将表monthcardpayrecords中status改为true
        // 传入云端的参数Param
        BillParam paramNewSuc = new BillParam();
        paramNewSuc.setBillNos(billData[0]);
        paramNewSuc.setOperationPerson(operationPerson);
        if (billData[0] != null) {
            Map<String, Object> postMapSetPayRecord = getPostMapByBillParam(paramNewSuc);
            restTemplate.postForObject(citic.getSerurl() + "/bill/set/monthcardpayrecord", postMapSetPayRecord,
                    Boolean.class);
        }
        // Step 4.3 - 对于交易失败的账单,删除表monthcardpayrecords中数据
        // 传入云端的参数Param
        BillParam paramNewErr = new BillParam();
        paramNewErr.setBillNos(billData[1]);
        paramNewErr.setOperationPerson(operationPerson);
        if (billData[1] != null) {
            Map<String, Object> postMapSetPayRecord = getPostMapByBillParam(paramNewErr);
            restTemplate.postForObject(citic.getSerurl() + "/bill/delete/monthcardpayrecord", postMapSetPayRecord,
                    Boolean.class);
        }
        // Step 4.4 - result返回值处理
        if (resultAll[1].size() == 0 && resultAll[0].size() == 0 && resultAll[2].size() == 0) {
            // a:过程失败
            result.put("msg", "过程失败");
            result.put("info", "全部查询过程失败");
            result.put("sucData", billData[0].toString());
            result.put("errData", billData[1].toString());
            result.put("proData", billData[2].toString());
        } else if (resultAll[0].size() != 0 && resultAll[1].size() == 0 && resultAll[2].size() == 0) {
            // b:过程成功并且查询成功
            result.put("flag", Constant.RESPONSE_FLAG_SUCCESS);
            result.put("msg", "查询成功");
            result.put("sucData", billData[0].toString());
            result.put("errData", billData[1].toString());
            result.put("proData", billData[2].toString());
        } else if (resultAll[2].size() != 0) {
            // c:过程成功并且有正在处理中
            result.put("msg", "正在处理中");
            result.put("sucData", billData[0].toString());
            result.put("errData", billData[1].toString());
            result.put("proData", billData[2].toString());
        } else {
            // d:过程成功并且查询失败
            result.put("msg", "查询失败");
            result.put("sucData", billData[0].toString());
            result.put("errData", billData[1].toString());
            result.put("proData", billData[2].toString());
        }
        // Step 4.4 - 进行数据的保存及更新
        if (resultAll[0] != null) {
            Map<String, Object> postMapPrkSaveSuc = getPostMapByPrk(resultAll[0]);
            restTemplate.postForObject(citic.getSerurl() + "/bill/update/parkbills", postMapPrkSaveSuc, Boolean.class);
        }
        if (resultAll[1] != null) {
            Map<String, Object> postMapPrkSaveErr = getPostMapByPrk(resultAll[1]);
            restTemplate.postForObject(citic.getSerurl() + "/bill/update/parkbills", postMapPrkSaveErr, Boolean.class);
        }
        // resultAll[2]未进行更新不用处理
        logger.info("----------完成停车账单支付批量查询请求,耗时[" + (System.currentTimeMillis() - beginTime1) + "]ms----------");
        return result;
    }

    @SuppressWarnings("unchecked")
    @Override
    public Map<String, Object> transferAccounting(BillParam param) throws Exception {
        logger.info("----------测试:名字[" + citic.getName() + "]付款帐号[" + citic.getPayaccount() + "]");
        logger.info("----------开始月卡账单转账请求提交----------");
        // 开始时间
        long beginTime = System.currentTimeMillis();
        // xml解析成的map
        Map<String, Object> map = new HashMap<String, Object>();
        // 返回结果
        Map<String, Object> result = new HashMap<String, Object>();
        // 单批次月卡账单 0:成功,1:失败
        List<AccountingBill>[] results = new ArrayList[2];
        // 总批次月卡账单 0:成功,1:失败
        List<AccountingBill>[] resultAll = new ArrayList[2];
        resultAll[0] = new ArrayList<AccountingBill>();
        resultAll[1] = new ArrayList<AccountingBill>();
        // 账单编号
        List<String>[] billData = new ArrayList[2];
        billData[0] = new ArrayList<String>();
        billData[1] = new ArrayList<String>();

        // Step 1 - 获取传入参数Param中的所有信息(billNo,operationPerson)
        // Step 1.1 - 得到账单编号billNos
        List<String> billNos = param.getBillNos();
        logger.info("----------账单编号:" + billNos.toString());
        // Step 1.2 - 得到操作人operationPerson
        String operationPerson = param.getOperationPerson();

        // Step 2 - 根据账单编号数组生成批量提交xml
        // Step 2.1 - 访问云端数据,根据账单编号数组得到所有的账单信息
        Map<String, Object> postMapAcc = getPostMapByBillNos(billNos);
        AccountingBill[] accountingBillsNew = restTemplate
                .postForObject(citic.getSerurl() + "/bill/find/billnos/accounting", postMapAcc, AccountingBill[].class);

        // Step 2.2 - 分批处理,将结果存储在AccountingBill二维数组中
        AccountingBill[][] bills = getBatch(accountingBillsNew, 20);

        // Step 3 - 每批进行处理(发送,解析)
        for (AccountingBill[] temp : bills) {
            // Step 3.1 - 对每一批次进行去除空值的操作 - 因最后一组数组可能存在null
            List<AccountingBill> tmp = new ArrayList<AccountingBill>();
            for (AccountingBill accountingBill : temp) {
                if (accountingBill != null)
                    tmp.add(accountingBill);
            }
            temp = tmp.toArray(new AccountingBill[] {});
            // Step 3.2 - 相关信息非空判断,生成停车账单支付批量提交sendXml
            logger.info("----------开始生成月卡账单支付批量提交的xml报文----------");
            String sendXml = genAccountingBillStr(temp);
            // Step 3.3 - 发送批量查询请求,得到查询返回状态
            logger.info("----------开始发送月卡账单支付批量提交请求----------");
            long beginTime1 = System.currentTimeMillis();
            String recXml = HttpPost.getInstance(citic.getUrl()).postRequest(sendXml);
            logger.info("----------发送月卡账单支付批量提交请求成功,耗时[" + (System.currentTimeMillis() - beginTime1) + "]ms----------");
            // Step 3.4 - 根据提交返回状态决定流程
            logger.info("----------开始解析xml----------");
            map = getMapByXml(recXml);
            logger.info("----------解析成功,解析后的map为:[" + map + "]");
            String statusAll = (String) map.get("status");
            String statusText = (String) map.get("statusText");
            logger.info("----------查询过程状态,statusAll[" + statusAll + "],statusText[" + statusText + "]");
            // Step 3.5 - 过程成功,进行逻辑处理(调用queryHandle)
            if ("AAAAAAA".equals(statusAll)) {
                results = handle(map, temp);
            } else {
                logger.info("----------本批查询过程不成功,状态:" + statusAll + "----------");
            }
            // Step 3.6 - 将每批次结果汇总
            if (results[0] != null)
                resultAll[0].addAll(results[0]);
            if (results[1] != null)
                resultAll[1].addAll(results[1]);
        }

        // Step 4 - 汇总结果处理及数据处理
        // Step 4.1 - 由实体得到账单编号
        if (resultAll[0] != null) {
            for (AccountingBill tmp : resultAll[0])
                billData[0].add(tmp.getBillNo());
        }
        if (resultAll[1] != null) {
            for (AccountingBill tmp : resultAll[1])
                billData[1].add(tmp.getBillNo());
        }
        // Step 4.2 - 返回结果处理
        if ((resultAll[1].size() == 0) && (resultAll[0].size() == 0)) {
            // a:过程失败
            result.put("sucData", billData[0].toString());
            result.put("errData", billData[1].toString());
            result.put("info", "过程失败");
            result.put("msg", "过程失败");
        } else if ((results[1].size() == 0) && (results[0].size() != 0)) {
            // b:过程成功并提交全部成功
            result.put("flag", Constant.RESPONSE_FLAG_SUCCESS);
            result.put("sucData", billData[0].toString());
            result.put("errData", billData[1].toString());
            result.put("msg", "提交成功");
        } else {
            // c:过程成功并提交失败(包括部分和全部)
            result.put("sucData", billData[0].toString());
            result.put("errData", billData[1].toString());
            result.put("msg", "提交失败");
        }
        // Step 4.3 - 同步每天月卡运营账单信息,并保存
        ArrayList<AccountingBill> lists = new ArrayList<AccountingBill>();
        if (resultAll[0] != null) {
            lists.addAll(resultAll[0]);
        }
        if (resultAll[1] != null) {
            lists.addAll(resultAll[1]);
        }
        if (lists != null) {
            Map<String, Object> postMapOpe = getPostMapByBillNos(billNos);
            OperateBill[] operateBills = restTemplate.postForObject(citic.getSerurl() + "/bill/find/billnos/operate",
                    postMapOpe, OperateBill[].class);
            for (AccountingBill aBill : lists) {
                for (OperateBill oBill : operateBills) {
                    if (oBill.getBillNo().equals(aBill.getBillNo())) {
                        oBill.setBatNo(aBill.getBatNo());
                        oBill.setClientId(aBill.getClientId());
                        oBill.setPaystate(aBill.getPaystate());
                    }
                }
            }
            // 保存每天月卡运营账单
            List<OperateBill> operatebills = new ArrayList<OperateBill>();
            operatebills = Arrays.asList(operateBills);
            Map<String, Object> postMapOpeSave = getPostMapByOpe(operatebills);
            restTemplate.postForObject(citic.getSerurl() + "/bill/update/operatebills", postMapOpeSave, Boolean.class);
        }
        // Step 4.4 - 对成功的billNo进行创建monthCardPayRecord操作
        BillParam paramNew = new BillParam();
        paramNew.setBillNos(billData[0]);
        paramNew.setOperationPerson(operationPerson);
        if (billData[0] != null) {
            Map<String, Object> mapPostCreatePayRecord = getPostMapByBillParam(paramNew);
            restTemplate.postForObject(citic.getSerurl() + "/bill/create/monthcardpayrecord", mapPostCreatePayRecord,
                    Boolean.class);
        }
        // Step 4.5 - 进行月卡账单数据的保存及更新
        if (resultAll[0] != null) {
            Map<String, Object> mapPostAccSaveSuc = getPostMapByAcc(resultAll[0]);
            restTemplate.postForObject(citic.getSerurl() + "/bill/update/accountingbills", mapPostAccSaveSuc,
                    Boolean.class);
        }
        if (resultAll[1] != null) {
            Map<String, Object> mapPostAccSaveErr = getPostMapByAcc(resultAll[1]);
            restTemplate.postForObject(citic.getSerurl() + "/bill/update/accountingbills", mapPostAccSaveErr,
                    Boolean.class);
        }
        logger.info("----------完成月卡账单转账请求提交请求,耗时[" + (System.currentTimeMillis() - beginTime) + "]ms");
        return result;
    }

    @SuppressWarnings("unchecked")
    @Override
    public Map<String, Object> queryAccounting(QueryParam param) throws Exception {
        logger.info("----------开始月卡账单支付批量查询----------");
        // 开始时间
        long beginTime = System.currentTimeMillis();
        // xml解析成的map
        Map<String, Object> map = new HashMap<String, Object>();
        // 返回结果
        Map<String, Object> result = new HashMap<String, Object>();
        // 月卡单批次账单:0:成功 1:失败 2:正在处理中
        List<AccountingBill>[] results = new List[3];
        // 月卡总批次账单:0:成功 1:失败 2:正在处理中
        List<AccountingBill>[] resultAll = new List[3];
        resultAll[0] = new ArrayList<AccountingBill>();
        resultAll[1] = new ArrayList<AccountingBill>();
        resultAll[2] = new ArrayList<AccountingBill>();
        // 账单编号:0:成功 1:失败 2:正在处理中
        List<String>[] billData = new ArrayList[3];
        billData[0] = new ArrayList<String>();
        billData[1] = new ArrayList<String>();
        billData[2] = new ArrayList<String>();
        // 所有账单编号
        List<String> billNoAll = new ArrayList<String>();

        // Step 1 - 获取传入参数Param中的所有信息(billNo,operationPerson)
        // Step 1.1 - 得到操作人operationPerson
        String operationPerson = param.getOperationPerson();
        Map<String, Object> queryMaps = param.getQueryMaps();
        // 分批处理
        for (Map.Entry<String, Object> entry : queryMaps.entrySet()) {
            String batNo = entry.getKey();
            List<String> billNos = (List<String>) entry.getValue();
            logger.info("----------批次号:" + batNo);
            logger.info("----------账单编号:" + billNos.toString());

            // Step 2 - 相关信息非空判断,生成月卡账单支付批量查询sendXmlQuery
            logger.info("----------开始生成月卡账单支付批量查询的xml报文----------");
            String sendXmlQuery = genAccountingBillQuery(batNo);

            // Step 3 - 发送批量查询请求,并对结果进行解析
            // Step 3.1 - 发送批量查询请求,得到查询返回状态
            logger.info("----------开始发送月卡账单支付批量查询请求----------");
            long beginTime1 = System.currentTimeMillis();
            String recXmlQuery = HttpPost.getInstance(citic.getUrl()).postRequest(sendXmlQuery);
            logger.info("----------发送月卡账单支付批量查询请求成功,耗时[" + (System.currentTimeMillis() - beginTime1) + "]ms----------");
            // Step 3.2 - 根据提交返回状态决定流程
            logger.info("----------开始解析xml----------");
            map = getMapByXml(recXmlQuery);
            logger.info("----------解析成功,解析后的map为:[" + map + "]");
            String statusAll = (String) map.get("status");
            String statusText = (String) map.get("statusText");
            logger.info("----------查询过程状态,statusAll[" + statusAll + "],statusText[" + statusText + "]");
            // Step 3.3 - 过程成功,进行逻辑处理(调用queryHandle)
            if ("AAAAAAA".equals(statusAll)) {
                results = queryHandleAccounting(map,billNos);
            } else {
                logger.info("----------本批查询过程不成功,状态:" + statusAll + "----------");
            }
            // Step 3.4 - 将每批次结果汇总
            if (results[0] != null)
                resultAll[0].addAll(results[0]);
            if (results[1] != null)
                resultAll[1].addAll(results[1]);
            if (results[2] != null)
                resultAll[2].addAll(results[2]);
            // 得到所有账单编号
            if (billNos!=null){
                billNoAll.addAll(billNos);
            }

        }

        // Step 4 - 汇总结果整体处理
        // Step 4.1 - 由实体得到账单编号
        if (resultAll[0] != null) {
            for (AccountingBill tmp : resultAll[0])
                billData[0].add(tmp.getBillNo());
        }
        if (resultAll[1] != null) {
            for (AccountingBill tmp : resultAll[1])
                billData[1].add(tmp.getBillNo());
        }
        if (resultAll[2] != null) {
            for (AccountingBill tmp : resultAll[2])
                billData[2].add(tmp.getBillNo());
        }
        // Step 4.2 - 根据成功的账单编号更新月卡操作记录中的OrderPayStat字段
        Map<String, Object> postMapSetOrderpaystat = getPostMapByBillNos(billData[0]);
        if (billData[0] != null) {
            restTemplate.postForObject(citic.getSerurl() + "/bill/set/orderpaystat", postMapSetOrderpaystat,
                    Boolean.class);
        }
        // Step 4.3 - result返回值处理
        if (resultAll[0].size() == 0 && resultAll[1].size() == 0 && resultAll[2].size() == 0) {
            // a:过程失败
            result.put("msg", "过程失败");
            result.put("info", "全部查询过程失败");
            result.put("sucData", billData[0].toString());
            result.put("errData", billData[1].toString());
            result.put("proData", billData[2].toString());
        } else if (resultAll[0].size() != 0 && resultAll[1].size() == 0 && resultAll[2].size() == 0) {
            // b:过程成功并且查询成功
            result.put("flag", Constant.RESPONSE_FLAG_SUCCESS);
            result.put("msg", "查询成功");
            result.put("sucData", billData[0].toString());
            result.put("errData", billData[1].toString());
            result.put("proData", billData[2].toString());
        } else if (resultAll[2].size() != 0) {
            // c:过程成功并且有正在处理中
            result.put("msg", "正在处理中");
            result.put("sucData", billData[0].toString());
            result.put("errData", billData[1].toString());
            result.put("proData", billData[2].toString());
        } else {
            // d:过程成功并且查询失败
            result.put("msg", "查询失败");
            result.put("sucData", billData[0].toString());
            result.put("errData", billData[1].toString());
            result.put("proData", billData[2].toString());
        }
        // Step 4.4 - 同步每天月卡运营账单信息,并保存
        ArrayList<AccountingBill> lists = new ArrayList<AccountingBill>();
        if (resultAll[1] != null) {
            lists.addAll(resultAll[1]);
        }
        if (resultAll[2] != null) {
            lists.addAll(resultAll[2]);
        }
        if (lists != null || resultAll[0] != null) {
            Map<String, Object> postMapOpe = getPostMapByBillNos(billNoAll);
            OperateBill[] operateBills = restTemplate.postForObject(citic.getSerurl() + "/bill/find/billnos/operate",
                    postMapOpe, OperateBill[].class);
            // 成功需设置isSettle=true
            if (resultAll[0] != null) {
                for (AccountingBill aBill : resultAll[0]) {
                    for (OperateBill oBill : operateBills) {
                        if (oBill.getBillNo().trim().equals(aBill.getBillNo().trim())) {
                            oBill.setBatNo(aBill.getBatNo());
                            oBill.setClientId(aBill.getClientId());
                            oBill.setPaystate(aBill.getPaystate());
                            oBill.setStatus(aBill.getStatus());
                            oBill.setReceipt(aBill.getReceipt());
                            oBill.setSettleDate(new Date());
                            oBill.setIsSettle(true);
                        }
                    }
                }
            }
            if (lists != null) {
                for (AccountingBill aBill : lists) {
                    for (OperateBill oBill : operateBills) {
                        if (oBill.getBillNo().trim().equals(aBill.getBillNo().trim())) {
                            oBill.setBatNo(aBill.getBatNo());
                            oBill.setClientId(aBill.getClientId());
                            oBill.setPaystate(aBill.getPaystate());
                            oBill.setStatus(aBill.getStatus());
                            oBill.setReceipt(aBill.getReceipt());
                        }
                    }
                }
            }
            // 保存每天月卡运营账单
            List<OperateBill> postListOpe = Arrays.asList(operateBills);
            Map<String, Object> postMapOpeSave = getPostMapByOpe(postListOpe);
            restTemplate.postForObject(citic.getSerurl() + "/bill/update/operatebills", postMapOpeSave, Boolean.class);
        }
        // Step 4.5 - 对于交易成功的账单,将表monthcardpayrecords中status改为true
        // 传入给云端接口的Param
        BillParam paramNewSuc = new BillParam();
        paramNewSuc.setBillNos(billData[0]);
        paramNewSuc.setOperationPerson(operationPerson);
        if (billData[0] != null) {
            Map<String, Object> postMapSetStatusTrue = getPostMapByBillParam(paramNewSuc);
            restTemplate.postForObject(citic.getSerurl() + "/bill/set/monthcardpayrecord", postMapSetStatusTrue,
                    Boolean.class);
        }
        // Step 4.6 - 对于交易失败的账单,删除表monthcardpayrecords中数据
        // 传入云端的参数Param
        BillParam paramNewErr = new BillParam();
        paramNewErr.setBillNos(billData[1]);
        paramNewErr.setOperationPerson(operationPerson);
        if (billData[1] != null) {
            Map<String, Object> postMapSetPayRecord = getPostMapByBillParam(paramNewErr);
            restTemplate.postForObject(citic.getSerurl() + "/bill/delete/monthcardpayrecord", postMapSetPayRecord,
                    Boolean.class);
        }
        // Step 4.7 - 进行数据的保存及更新
        if (resultAll[0] != null) {
            Map<String, Object> postMapAccSaveSuc = getPostMapByAcc(resultAll[0]);
            restTemplate.postForObject(citic.getSerurl() + "/bill/update/accountingbills", postMapAccSaveSuc,
                    Boolean.class);
        }
        if (resultAll[1] != null) {
            Map<String, Object> postMapAccSaveErr = getPostMapByAcc(resultAll[1]);
            restTemplate.postForObject(citic.getSerurl() + "/bill/update/accountingbills", postMapAccSaveErr,
                    Boolean.class);
        }
        // resultAll[2]未进行更新,可以不用处理
        logger.info("----------完成月卡账单支付批量查询请求,耗时[" + (System.currentTimeMillis() - beginTime) + "]ms----------");
        return result;
    }

    // 对提交过程成功返回报文进行处理,显示每条账单处理状态并作出相应提示,保存相关数据,
    // 返回包含成功的账单数组results[0]与包含失败的账单数组results[1]的List数组
    @SuppressWarnings("unchecked")
    public List<ParkBill>[] handle(Map<String, Object> map, ParkBill[] parkBills) throws Exception {
        // List<String> results = new ArrayList<String>();
        List<ParkBill>[] results = new List[2];
        // 保存成功的账单
        results[0] = new ArrayList<ParkBill>();
        // 保存失败的账单
        results[1] = new ArrayList<ParkBill>();
        // 解析批次号
        String batNo = (String) map.get("batNo");
        // 解析数量
        Integer sucTotalNum = Integer.parseInt((String) map.get("sucTotalNum"));
        Integer errTotalNum = Integer.parseInt((String) map.get("errTotalNum"));
        Integer totalNum = sucTotalNum + errTotalNum;
        logger.info("----------解析出总笔数:[" + totalNum + "]");
        // 解析所有账单于Map<String,Object> lists中
        List<Map<String, Object>> lists = new ArrayList<Map<String, Object>>();
        lists = (ArrayList<Map<String, Object>>) map.get("list");
        for (Map<String, Object> entity : lists) {
            // 单笔交易状态
            String status = (String) entity.get("status");
            // 单笔交易状态提示
            String statusTextOne = (String) entity.get("statusText");
            String clientID = (String) entity.get("clientID");

            // 根据clientID从parkBills数组中找到制定parkBillTmp(clientId=clientId)
            // ParkBill parkBillTmp =
            // restTemplate.postForObject(citic.getFindurlone(),clientID,ParkBill.class);
            ParkBill parkBillTmp = null;
            for (int i = 0; i < parkBills.length; i++) {
                if (clientID.equals(parkBills[i].getClientId()))
                    parkBillTmp = parkBills[i];
            }
            String billNo = parkBillTmp.getBillNo();
            if ("AAAAAAA".equals(status) || "AAAAAAE".equals(status)) {
                // a:单笔提交成功
                logger.info("账单编号[" + billNo + "]客户流水号[" + clientID + "]提交成功");
                parkBillTmp.setPaystate("正在付款");
                parkBillTmp.setBatNo(batNo);
                parkBillTmp.setClientId(clientID);
                results[0].add(parkBillTmp);
            } else {
                // b:单笔提交失败
                logger.info("账单编号[" + billNo + "]客户流水号[" + clientID + "]提交失败,状态码[" + status + "],原因[" + statusTextOne
                        + "]");
                parkBillTmp.setBatNo("");
                parkBillTmp.setClientId(clientID);
                results[1].add(parkBillTmp);
            }
        }
        return results;
    }

    // 对提交过程成功返回报文进行处理,显示每条账单处理状态并作出相应提示,保存相关数据,
    // 返回包含成功的账单数组results[0]与包含失败的账单数组results[1]的List数组
    @SuppressWarnings("unchecked")
    public List<AccountingBill>[] handle(Map<String, Object> map, AccountingBill[] accountingBills) throws Exception {
        // List<String> results = new ArrayList<String>();
        List<AccountingBill>[] results = new List[2];
        // 保存成功的月卡账单
        results[0] = new ArrayList();
        // 保存失败的月卡账单
        results[1] = new ArrayList();
        // 解析批次号
        String batNo = (String) map.get("batNo");
        // 解析数量
        Integer sucTotalNum = Integer.parseInt((String) map.get("sucTotalNum"));
        Integer errTotalNum = Integer.parseInt((String) map.get("errTotalNum"));
        Integer totalNum = sucTotalNum + errTotalNum;
        logger.info("----------解析出总笔数:[" + totalNum + "]");
        // 解析所有账单于Map<String,Object> lists中
        List<Map<String, Object>> lists = new ArrayList<Map<String, Object>>();
        lists = (ArrayList<Map<String, Object>>) map.get("list");
        for (Map<String, Object> entity : lists) {
            // 单笔交易状态
            String status = (String) entity.get("status");
            // 单笔交易状态提示
            String statusTextOne = (String) entity.get("statusText");
            String clientID = (String) entity.get("clientID");

            // 根据clientID从parkBills数组中找到制定parkBillTmp(clientId=clientId)
            // ParkBill parkBillTmp =
            // restTemplate.postForObject(citic.getFindurlone(),clientID,ParkBill.class);
            AccountingBill accountingBillTmp = null;
            for (int i = 0; i < accountingBills.length; i++) {
                if (clientID.equals(accountingBills[i].getClientId()))
                    accountingBillTmp = accountingBills[i];
            }
            String billNo = accountingBillTmp.getBillNo();
            if ("AAAAAAA".equals(status) || "AAAAAAE".equals(status)) {
                // a:单笔提交成功
                logger.info("账单编号[" + billNo + "]客户流水号[" + clientID + "]提交成功");
                accountingBillTmp.setPaystate("正在付款");
                accountingBillTmp.setBatNo(batNo);
                accountingBillTmp.setClientId(clientID);
                results[0].add(accountingBillTmp);
            } else {
                // b:单笔提交失败
                logger.info("账单编号[" + billNo + "]客户流水号[" + clientID + "]提交失败,状态码[" + status + "],原因[" + statusTextOne
                        + "]");
                accountingBillTmp.setBatNo("");
                accountingBillTmp.setClientId(clientID);
                results[1].add(accountingBillTmp);
            }
        }
        return results;
    }

    // 对查询过程成功返回报文进行处理,显示每条账单处理状态并作出相应提示,保存相关数据,
    // 返回包含成功的账单数组results[0]与包含失败的账单数组results[1]的List数组
    @SuppressWarnings("unchecked")
    public List<ParkBill>[] queryHandlePark(Map<String, Object> map, List<String> billNos) throws Exception {
        List<Map<String, Object>> lists = new ArrayList<Map<String, Object>>();
        List<ParkBill>[] results = new List[3];
        // 保存成功的账单
        results[0] = new ArrayList<ParkBill>();
        // 保存失败的账单
        results[1] = new ArrayList<ParkBill>();
        // 保存正在处理中的账单
        results[2] = new ArrayList<ParkBill>();
        lists = (ArrayList<Map<String, Object>>) map.get("list");
        for (Map<String, Object> entity : lists) {
            String status = (String) entity.get("tranStt");
            logger.info("单条交易状态:tranStt[" + status + "]");
            String clientID = (String) entity.get("clientID");
            // ParkBill parkBillTmp = parkBillDAO.findByClientId(clientId);
            Map<String, Object> postMapClientId = getPostMapByClientId(clientID);
            ParkBill parkBillTmp = restTemplate.postForObject(citic.getSerurl() + "/bill/find/client", postMapClientId,
                    ParkBill.class);
            String billNo = parkBillTmp.getBillNo();
            // 判断所处理的账单号包含在前端提交的账单编号内
            if (billNos.contains(billNo)) {
                // 单笔交易成功-更新状态(isSettle:true,status:1,paystate:"付款完成")
                if ("7".equals(status.trim())) {
                    logger.info("账单编号[" + billNo + "]客户流水号[" + clientID + "]交易成功");
                    // results[0].add(billNo);
                    parkBillTmp.setIsSettle(true);
                    parkBillTmp.setStatus(1);
                    parkBillTmp.setSettleDate(new Date());
                    parkBillTmp.setPaystate("付款完成");
                    // 将正确的解析结果放到receipt中,并生成receipt
                    parkBillTmp.setReceipt(getReceipt(entity));
                    results[0].add(parkBillTmp);
                } // 单笔交易正在处理中(4,6,10,11,12)-不更新状态
                else if ("4".equals(status.trim()) || "6".equals(status.trim()) || "10".equals(status.trim())
                        || "11".equals(status.trim()) || "12".equals(status.trim())) {
                    logger.info("账单编号[" + billNo + "]客户流水号[" + clientID + "]正在处理中,状态码为[" + status.trim() + "]");
                    results[2].add(parkBillTmp);
                } // 单笔交易失败-更新状态(paystate:"",batNo:null)
                else {
                    logger.info("账单编号[" + billNo + "]客户流水号[" + clientID + "]交易失败,状态码为[" + status.trim() + "]");
                    parkBillTmp.setPaystate("");
                    parkBillTmp.setBatNo("");
                    results[1].add(parkBillTmp);
                }

            }

        }
        return results;
    }

    // 对查询过程成功返回报文进行处理,显示每条账单处理状态并作出相应提示,保存相关数据,
    // 返回包含成功的账单数组results[0]与包含失败的账单数组results[1]的List数组
    @SuppressWarnings("unchecked")
    public List<AccountingBill>[] queryHandleAccounting(Map<String, Object> map, List<String> billNos)
            throws Exception {
        List<Map<String, Object>> lists = new ArrayList<Map<String, Object>>();
        List<AccountingBill>[] results = new List[3];
        // 保存成功的账单
        results[0] = new ArrayList<AccountingBill>();
        // 保存失败的账单
        results[1] = new ArrayList<AccountingBill>();
        // 保存正在处理中的账单
        results[2] = new ArrayList<AccountingBill>();
        lists = (ArrayList<Map<String, Object>>) map.get("list");
        for (Map<String, Object> entity : lists) {
            String status = (String) entity.get("tranStt");
            logger.info("单条交易状态:tranStt[" + status + "]");
            String clientID = (String) entity.get("clientID");
            Map<String, Object> postMapClientId = getPostMapByClientId(clientID);
            AccountingBill accountingBillTmp = restTemplate.postForObject(
                    citic.getSerurl() + "/bill/find/client/accounting", postMapClientId, AccountingBill.class);
            String billNo = accountingBillTmp.getBillNo();
            // 判断所处理的账单号包含在前端提交的账单编号内
            if (billNos.contains(billNo)) {
                // 单笔交易成功-更新状态(isSettle:true,status:1,paystate:"付款完成")          
                if ("7".equals(status.trim())) {
                    logger.info("账单编号[" + billNo + "]客户流水号[" + clientID + "]交易成功");
                    // accountingBillTmp.setIsSettle(true);
                    accountingBillTmp.setStatus(1);
                    accountingBillTmp.setPaystate("付款完成");
                    // 将正确的解析结果放到receipt中,并生成receipt
                    accountingBillTmp.setReceipt(getReceipt(entity));
                    results[0].add(accountingBillTmp);
                } // 单笔交易正在处理中(4,6,10,11,12)-不更新状态
                else if ("4".equals(status.trim()) || "6".equals(status.trim()) || "10".equals(status.trim())
                        || "11".equals(status.trim()) || "12".equals(status.trim())) {
                    logger.info("账单编号[" + billNo + "]客户流水号[" + clientID + "]正在处理中,状态码为[" + status.trim() + "]");
                    results[2].add(accountingBillTmp);
                } // 单笔交易失败-更新状态(paystate:"",batNo:null)
                else {
                    logger.info("账单编号[" + billNo + "]客户流水号[" + clientID + "]交易失败,状态码为[" + status.trim() + "]");
                    accountingBillTmp.setPaystate("");
                    accountingBillTmp.setBatNo("");
                    results[1].add(accountingBillTmp);
                }
            }
        }
        return results;
    }

    // 生成交易成功后保存银行返回的信息receipt字段
    public String getReceipt(Map<String, Object> entity) {
        String receipt = "流水号" + (String) entity.get("clientID") + "{付款名称:" + (String) entity.get("payAccountName")
                + ",付款帐号:" + (String) entity.get("payAccountNo") + ",收款名称:" + (String) entity.get("recAccountName")
                + ",收款帐号:" + (String) entity.get("recAccountNo") + ",转账金额:" + entity.get("tranAmount") + ",转账日期:"
                + (String) entity.get("operateDate") + "}";
        return receipt;
    }

    // 拼接停车账单批量提交字符串
    private String genParkBillStr(ParkBill[] parkBills) {
        StringBuffer sb = new StringBuffer();
        sb.append("<?xml version=\"1.0\" encoding=\"GBK\"?>");
        sb.append("<stream>");
        sb.append("<action>DLOUTTNB</action>");
        sb.append("<userName>" + citic.getName() + "</userName>");
        sb.append("<list name=\"userDataList\">");

        for (int i = 0; i < parkBills.length; i++) {
            sb.append("<row>");
            logger.info("----------账单详情:" + parkBills[i].toString());
            String clientID = getClientID(i, parkBills[i]);
            if (clientID == null) {
                logger.info("第" + (i + 1) + "笔交易客户流水号为空,");
            }
            sb.append("<clientID>" + clientID + "</clientID>");
            sb.append("<preFlg>0</preFlg>");
            sb.append("<preDate></preDate>");
            sb.append("<preTime></preTime>");
            String payType = getPayType(parkBills[i]);
            if (payType == null) {
                logger.info("第" + (i + 1) + "笔交易付款方式为空,");
            }
            sb.append("<payType>" + payType + "</payType>");
            sb.append("<recBankNo></recBankNo>");
            sb.append("<payAccountNo>" + citic.getPayaccount() + "</payAccountNo>");
            String recAccountNo = parkBills[i].getBankAccount();
            if (recAccountNo == null) {
                logger.info("第" + (i + 1) + "笔交易收款帐号为空,");
            }
            sb.append("<recAccountNo>" + recAccountNo + "</recAccountNo>");
            String recAccountName = parkBills[i].getRealName();
            if (recAccountName == null) {
                logger.info("第" + (i + 1) + "笔交易收款帐号为空,");
            }
            sb.append("<recAccountName>" + recAccountName + "</recAccountName>");
            String recOpenBankName = parkBills[i].getBankName();
            if (recOpenBankName == null) {
                logger.info("第" + (i + 1) + "笔交易收款银行名称为空,");
            }
            sb.append("<recOpenBankName>" + recOpenBankName + "</recOpenBankName>");
            sb.append("<recOpenBankCode></recOpenBankCode>");
            Double tranAmount = parkBills[i].getBalance();
            if (tranAmount == null) {
                logger.info("第" + (i + 1) + "笔交易转账金额为空,");
            }
            sb.append("<tranAmount>" + tranAmount + "</tranAmount>");
            String citicBankFlag = getCiticbankFlag(parkBills[i]);
            if (citicBankFlag == null) {
                logger.info("第" + (i + 1) + "笔交易中信银行标记为空,");
            }
            sb.append("<citicbankFlag>" + citicBankFlag + "</citicbankFlag>");
            String cityFlag = getCityFlag(parkBills[i]);
            if (cityFlag == null) {
                logger.info("第" + (i + 1) + "笔交易同城标记标记为空,");
            }
            sb.append("<cityFlag>" + cityFlag + "</cityFlag>");
            sb.append("<abstract></abstract>");
            sb.append("<memo></memo>");
            sb.append("<takerName></takerName>");
            sb.append("<takerID></takerID>");
            sb.append("<takerIDType></takerIDType>");
            sb.append("</row>");
        }
        sb.append("</list>");
        sb.append("</stream>");

        return sb.toString();
    } // end genParkBillStr

    // 拼接月卡账单批量提交字符串
    @SuppressWarnings("unused")
    private String genAccountingBillStr(AccountingBill[] accountingBills) {
        StringBuffer sb = new StringBuffer();
        sb.append("<?xml version=\"1.0\" encoding=\"GBK\"?>");
        sb.append("<stream>");
        sb.append("<action>DLOUTTNB</action>");
        sb.append("<userName>" + citic.getName() + "</userName>");
        sb.append("<list name=\"userDataList\">");
        for (int i = 0; i < accountingBills.length; i++) {
            sb.append("<row>");
            logger.info("----------账单详情:" + accountingBills[i].toString());
            String clientID = getClientID(i, accountingBills[i]);
            if (clientID == null) {
                logger.info("第" + (i + 1) + "笔交易客户流水号为空,");
            }
            sb.append("<clientID>" + clientID + "</clientID>");

            sb.append("<preFlg>0</preFlg>");
            sb.append("<preDate></preDate>");
            sb.append("<preTime></preTime>");
            String payType = getPayType(accountingBills[i]);
            if (payType == null) {
                logger.info("第" + (i + 1) + "笔交易付款方式为空,");
            }
            sb.append("<payType>" + payType + "</payType>");
            sb.append("<recBankNo></recBankNo>");
            sb.append("<payAccountNo>" + citic.getPayaccount() + "</payAccountNo>");
            String recAccountNo = accountingBills[i].getBankAccount();
            if (recAccountNo == null) {
                logger.info("第" + (i + 1) + "笔交易收款帐号为空,");
            }
            sb.append("<recAccountNo>" + recAccountNo + "</recAccountNo>");
            String recAccountName = accountingBills[i].getRealName();
            if (recAccountName == null) {
                logger.info("第" + (i + 1) + "笔交易收款帐号为空,");
            }
            sb.append("<recAccountName>" + recAccountName + "</recAccountName>");
            String recOpenBankName = accountingBills[i].getBankName();
            if (recOpenBankName == null) {
                logger.info("第" + (i + 1) + "笔交易收款银行名称为空,");
            }
            sb.append("<recOpenBankName>" + recOpenBankName + "</recOpenBankName>");
            sb.append("<recOpenBankCode></recOpenBankCode>");
            Double tranAmount = accountingBills[i].getBalance();
            if (tranAmount == null) {
                logger.info("第" + (i + 1) + "笔交易转账金额为空,");
            }
            sb.append("<tranAmount>" + tranAmount + "</tranAmount>");
            String citicBankFlag = getCiticbankFlag(accountingBills[i]);
            if (citicBankFlag == null) {
                logger.info("第" + (i + 1) + "笔交易中信银行标记为空,");
            }
            sb.append("<citicbankFlag>" + citicBankFlag + "</citicbankFlag>");
            String cityFlag = getCityFlag(accountingBills[i]);
            if (cityFlag == null) {
                logger.info("第" + (i + 1) + "笔交易同城标记标记为空,");
            }
            sb.append("<cityFlag>" + cityFlag + "</cityFlag>");
            sb.append("<abstract></abstract>");
            sb.append("<memo></memo>");
            sb.append("<takerName></takerName>");
            sb.append("<takerID></takerID>");
            sb.append("<takerIDType></takerIDType>");
            sb.append("</row>");
        }
        sb.append("</list>");
        sb.append("</stream>");

        return sb.toString();
    } // end genParkBillStr

    // 拼接停车账单批量查询字符串
    @SuppressWarnings("unused")
    private String genParkBillQuery(String batNo) {
        StringBuffer sb = new StringBuffer();
        sb.append("<?xml version=\"1.0\" encoding=\"GBK\"?>");
        sb.append("<stream>");
        sb.append("<action>DLOUTQRY</action>");
        sb.append("<userName>" + citic.getName() + "</userName>");
        if (batNo == null) {
            logger.info("----------批次号为空----------");
        }
        sb.append("<batNo>" + batNo + "</batNo>");
        sb.append("<payAccountNo>" + citic.getPayaccount() + "</payAccountNo>");
        sb.append("<recAccountNo></recAccountNo>");
        sb.append("<startDate></startDate>");
        sb.append("<endDate></endDate>");
        sb.append("<startRecord>" + 1 + "</startRecord>");
        sb.append("<pageNumber>" + 20 + "</pageNumber>");
        sb.append("</stream>");
        return sb.toString();
    }

    // 拼接月卡账单批量查询字符串
    @SuppressWarnings("unused")
    private String genAccountingBillQuery(String batNo) {
        StringBuffer sb = new StringBuffer();
        sb.append("<?xml version=\"1.0\" encoding=\"GBK\"?>");
        sb.append("<stream>");
        sb.append("<action>DLOUTQRY</action>");
        sb.append("<userName>" + citic.getName() + "</userName>");
        if (batNo == null) {
            logger.info("----------批次号为空----------");
        }
        sb.append("<batNo>" + batNo + "</batNo>");
        sb.append("<payAccountNo>" + citic.getPayaccount() + "</payAccountNo>");
        sb.append("<recAccountNo></recAccountNo>");
        sb.append("<startDate></startDate>");
        sb.append("<endDate></endDate>");
        sb.append("<startRecord>" + 1 + "</startRecord>");
        sb.append("<pageNumber>" + 20 + "</pageNumber>");
        sb.append("</stream>");
        return sb.toString();
    }

    // 生成停车账单客户流水号clientID,并保存到实体中
    public String getClientID(int i, ParkBill parkBill) {
        if (parkBill.getClientId() != null && parkBill.getClientId() != "") {
            return parkBill.getClientId();
        }
        // 流水号生成规则:时间(yyyyMMddHHmmss)+账单标记(PB:停车账单/OB:会员账单)+本次提交编号(4位:i格式转换成的4位数)
        String clientId = sdf.format(new Date()) + "PB" + df.format(i);
        parkBill.setClientId(clientId);
        return clientId;
    }

    // 生成月卡账单客户流水号clientID,并保存到AccountingBill,OperateBill实体中
    public String getClientID(int i, AccountingBill accountingBill) {
        if (accountingBill.getClientId() != null && accountingBill.getClientId() != "") {
            return accountingBill.getClientId();
        }
        // 流水号生成规则:时间(yyyyMMddHHmmss)+账单标记(PB:停车账单/OB:会员账单)+本次提交编号(4位:i格式转换成的4位数)
        String clientId = sdf.format(new Date()) + "OB" + df.format(i);
        accountingBill.setClientId(clientId);
        return clientId;
    }

    // 得到停车账单付费方式payType
    public String getPayType(ParkBill parkBill) {
        if (parkBill.getBankName().indexOf("中信银行") != -1)
            return Constant.CITIC_PAYTYPE_INSIDE;// 中信内部转账
        if (parkBill.getBalance() > 50000)
            return Constant.CITIC_PAYTYPE_LARGE;// 大额支付
        return Constant.CITIC_PAYTYPE_SMALL;// 小额支付
    }

    // 得到月卡账单付费方式payType
    public String getPayType(AccountingBill accountingBill) {
        if (accountingBill.getBankName().indexOf("中信银行") != -1)
            return Constant.CITIC_PAYTYPE_INSIDE;// 中信内部转账
        if (accountingBill.getBalance() > 50000)
            return Constant.CITIC_PAYTYPE_LARGE;// 大额支付
        return Constant.CITIC_PAYTYPE_SMALL;// 小额支付
    }

    // 得到停车账单中信标志(是否为中信转中信)0:中信 1:他行 前提我们转账用的是中信银行信用卡
    public String getCiticbankFlag(ParkBill parkBill) {
        if (parkBill.getBankName().indexOf("中信银行") != -1)
            return Constant.CITIC_CITICBANK;
        return Constant.CITIC_OTHERBANK;
    }

    // 得到月卡账单中信标志(是否为中信转中信)0:中信 1:他行 前提我们转账用的是中信银行信用卡
    public String getCiticbankFlag(AccountingBill accountingBill) {
        if (accountingBill.getBankName().indexOf("中信银行") != -1)
            return Constant.CITIC_CITICBANK;
        return Constant.CITIC_OTHERBANK;
    }

    // 得到停车账单同城标记 0:同城 1:异地
    public String getCityFlag(ParkBill parkBill) {
        // MongoParking mongoParking =
        // parkingDAO.findBySmallId(parkBill.getSmallId());
        Map<String, Object> postMapSmallId = getPostMapMongoParkingBySmallId(parkBill.getSmallId());
        MongoParking mongoParking = restTemplate.postForObject(citic.getSerurl() + "/bill/find/mongoparking",
                postMapSmallId, MongoParking.class);
        Boolean notLocalBank = mongoParking.getParking().getNotLocalBank();
        if (notLocalBank != null && notLocalBank) {
            return Constant.CITIC_CITYFLAG_DIFFERENT;
        }
        return Constant.CITIC_CITYFLAG_SAME;
    }

    // 得到月卡账单同城标记 0:同城 1:异地
    public String getCityFlag(AccountingBill accountingBill) {
        // MongoParking mongoParking =
        // parkingDAO.findBySmallId(parkBill.getSmallId());
        Map<String, Object> postMapSmallId = getPostMapMongoParkingBySmallId(accountingBill.getSmallId());
        MongoParking mongoParking = restTemplate.postForObject(citic.getSerurl() + "/bill/find/mongoparking",
                postMapSmallId, MongoParking.class);
        Boolean notLocalBank = mongoParking.getParking().getNotLocalBank();
        if (notLocalBank != null && notLocalBank) {
            return Constant.CITIC_CITYFLAG_DIFFERENT;
        }
        return Constant.CITIC_CITYFLAG_SAME;
    }

    // 将收到的XML字符串转化为MAP
    public static Map<String, Object> getMapByXml(String xml) {
        Map<String, Object> returnMap = new HashMap<String, Object>();
        Document document = null;
        try {
            document = DocumentHelper.parseText(xml);
        } catch (DocumentException e) {
            // throw new CiticDirectException(e);
        }
        Element infoElement = (Element) document.getRootElement();
        Iterator rootIter = infoElement.elementIterator();
        while (rootIter.hasNext()) {
            Element element = (Element) rootIter.next();
            // System.out.println(element.getName());
            if (element.getName().equals("list")) {
                List list = new ArrayList();
                Iterator rowIter = element.elementIterator();
                while (rowIter.hasNext()) {
                    Map<String, Object> map = new HashMap<String, Object>();
                    Element rowEle = (Element) rowIter.next();
                    Iterator resIter = rowEle.elementIterator();
                    while (resIter.hasNext()) {
                        Element resEle = (Element) resIter.next();
                        map.put(resEle.getName(), resEle.getText());
                    }
                    list.add(map);
                }
                returnMap.put("list", list);
            } else {
                returnMap.put(element.getName(), element.getText());
            }
        }
        return returnMap;
    }

    // 将所有停车账单账单按照每len长度进行分批次进行处理
    public ParkBill[][] getBatch(ParkBill[] parkBills, int len) {
        int size = parkBills.length;
        ParkBill[][] parks = new ParkBill[(size / len) + 1][len];
        for (int i = 0; i < (size / len); i++) {
            for (int j = 0; j < len; j++) {
                parks[i][j] = parkBills[len * i + j];
            }
        }
        for (int z = 0; z < (size % len); z++) {
            parks[size / len][z] = parkBills[(size / len) * len + z];
        }
        return parks;
    }

    // 将所有月卡账单账单按照每len长度进行分批次进行处理
    public AccountingBill[][] getBatch(AccountingBill[] accountingBills, int len) {
        int size = accountingBills.length;
        AccountingBill[][] parks = new AccountingBill[(size / len) + 1][len];
        for (int i = 0; i < (size / len); i++) {
            for (int j = 0; j < len; j++) {
                parks[i][j] = accountingBills[len * i + j];
            }
        }
        for (int z = 0; z < (size % len); z++) {
            parks[size / len][z] = accountingBills[(size / len) * len + z];
        }
        return parks;
    }

    /*
     * 以下代码:处理生成发送给云端的postMap
     */
    // 通过List<String> billNos得到发送给云端的postMap
    public Map<String, Object> getPostMapByBillNos(List<String> billNos) {
        Map<String, Object> postParam = new HashMap<String, Object>();
        postParam.put("billNos", billNos);
        String sign = Encry_MD5.getSign(postParam);
        Map<String, Object> postMap = new HashMap<String, Object>();
        postMap.put("billNos", billNos);
        postMap.put("sign", sign);
        return postMap;
    }

    // 通过billNo得到发送给云端的postMap
    public Map<String, Object> getPostMapByBillNo(String billNo) {
        Map<String, Object> postParam = new HashMap<String, Object>();
        postParam.put("billNo", billNo);
        String sign = Encry_MD5.getSign(postParam);
        Map<String, Object> postMap = new HashMap<String, Object>();
        postMap.put("billNo", billNo);
        postMap.put("sign", sign);
        return postMap;
    }

    // 通过clientId得到发送给云端的postMap
    public Map<String, Object> getPostMapByClientId(String clientId) {
        Map<String, Object> postParam = new HashMap<String, Object>();
        postParam.put("clientId", clientId);
        String sign = Encry_MD5.getSign(postParam);
        Map<String, Object> postMap = new HashMap<String, Object>();
        postMap.put("clientId", clientId);
        postMap.put("sign", sign);
        return postMap;
    }

    // 通过billParam得到发送给云端的postMap
    public Map<String, Object> getPostMapByBillParam(BillParam billParam) {
        Map<String, Object> postParam = new HashMap<String, Object>();
        postParam.put("billNos", billParam.getBillNos());
        postParam.put("operationPerson", billParam.getOperationPerson());
        String sign = Encry_MD5.getSign(postParam);
        Map<String, Object> postMap = new HashMap<String, Object>();
        postMap.put("billNos", billParam.getBillNos());
        postMap.put("operationPerson", billParam.getOperationPerson());
        postMap.put("sign", sign);
        return postMap;
    }

    // 通过List<AccountingBill>得到发送给云端的postMap
    public Map<String, Object> getPostMapByAcc(List<AccountingBill> lists) {
        Map<String, Object> postParam = new HashMap<String, Object>();
        // 生成发给云端的List<AccountingBill>的String
        String accountingBills = genAccountingBill(lists);
        postParam.put("accountingBills", accountingBills);
        String sign = Encry_MD5.getSign(postParam);
        Map<String, Object> postMap = new HashMap<String, Object>();
        postMap.put("accountingBills", accountingBills);
        postMap.put("sign", sign);
        return postMap;
    }

    // 通过List<OperateBill>得到发送给云端的postMap
    public Map<String, Object> getPostMapByOpe(List<OperateBill> lists) {
        Map<String, Object> postParam = new HashMap<String, Object>();
        // 生成发给云端的List<OperateBill>的String
        String operateBills = genOperateBill(lists);
        postParam.put("operateBills", operateBills);
        String sign = Encry_MD5.getSign(postParam);
        Map<String, Object> postMap = new HashMap<String, Object>();
        postMap.put("operateBills", operateBills);
        postMap.put("sign", sign);
        return postMap;
    }

    // 通过List<ParkBill>得到发送给云端的postMap
    public Map<String, Object> getPostMapByPrk(List<ParkBill> lists) {
        Map<String, Object> postParam = new HashMap<String, Object>();
        // 生成发给云端的List<ParkBill>的String
        String parkBills = genParkBill(lists);
        postParam.put("parkBills", parkBills);
        String sign = Encry_MD5.getSign(postParam);
        Map<String, Object> postMap = new HashMap<String, Object>();
        postMap.put("parkBills", parkBills);
        postMap.put("sign", sign);
        return postMap;
    }

    // 通过smallId得到发送给云端的postMap
    public Map<String, Object> getPostMapMongoParkingBySmallId(String smallId) {
        Map<String, Object> postParam = new HashMap<String, Object>();
        postParam.put("smallId", smallId);
        String sign = Encry_MD5.getSign(postParam);
        Map<String, Object> postMap = new HashMap<String, Object>();
        postMap.put("smallId", smallId);
        postMap.put("sign", sign);
        return postMap;
    }

    /*
     * 以下代码:生成发送给云端包含实体部分字段的String
     */
    // 生成传送给云端accountingBills实体字段String
    public String genAccountingBill(List<AccountingBill> accountingBills) {
        StringBuilder sb = new StringBuilder();
        sb.append("<?xml version=\"1.0\" encoding=\"GBK\"?>");
        sb.append("<stream>");
        sb.append("<list name=\"userDataList\">");
        for (AccountingBill accountingBill : accountingBills) {
            sb.append("<row>");
            sb.append("<billNo>" + accountingBill.getBillNo() + "</billNo>");
            sb.append("<paystate>" + accountingBill.getPaystate() + "</paystate>");
            sb.append("<batNo>" + accountingBill.getBatNo() + "</batNo>");
            sb.append("<status>" + accountingBill.getStatus() + "</status>");
            sb.append("<receipt>" + accountingBill.getReceipt() + "</receipt>");
            sb.append("<clientId>" + accountingBill.getClientId() + "</clientId>");
            sb.append("</row>");
        }
        sb.append("</list>");
        sb.append("</stream>");
        return sb.toString();
    }

    // 生成传送给云端operateBills实体字段String
    public String genOperateBill(List<OperateBill> operateBills) {
        StringBuilder sb = new StringBuilder();
        sb.append("<?xml version=\"1.0\" encoding=\"GBK\"?>");
        sb.append("<stream>");
        sb.append("<list>");
        for (OperateBill operateBill : operateBills) {
            sb.append("<row>");
            sb.append("<billNo>" + operateBill.getBillNo() + "</billNo>");
            sb.append("<paystate>" + operateBill.getPaystate() + "</paystate>");
            sb.append("<batNo>" + operateBill.getBatNo() + "</batNo>");
            sb.append("<isSettle>" + operateBill.getIsSettle() + "</isSettle>");
            sb.append("<status>" + operateBill.getStatus() + "</status>");
            sb.append("<receipt>" + operateBill.getReceipt() + "</receipt>");
            sb.append("<clientId>" + operateBill.getClientId() + "</clientId>");
            if (operateBill.getSettleDate() != null) {
                sb.append("<settleDate>" + sdf.format(operateBill.getSettleDate()) + "</settleDate>");
            }

            sb.append("</row>");
        }
        sb.append("</list>");
        sb.append("</stream>");
        return sb.toString();
    }

    // 生成传送给云端parkBill实体字段String
    public String genParkBill(List<ParkBill> parkBills) {
        StringBuilder sb = new StringBuilder();
        sb.append("<?xml version=\"1.0\" encoding=\"GBK\"?>");
        sb.append("<stream>");
        sb.append("<list>");
        for (ParkBill parkBill : parkBills) {
            sb.append("<row>");
            sb.append("<billNo>" + parkBill.getBillNo() + "</billNo>");
            sb.append("<paystate>" + parkBill.getPaystate() + "</paystate>");
            sb.append("<batNo>" + parkBill.getBatNo() + "</batNo>");
            sb.append("<isSettle>" + parkBill.getIsSettle() + "</isSettle>");
            sb.append("<status>" + parkBill.getStatus() + "</status>");
            sb.append("<receipt>" + parkBill.getReceipt() + "</receipt>");
            sb.append("<clientId>" + parkBill.getClientId() + "</clientId>");
            if (parkBill.getSettleDate() != null) {
                sb.append("<settleDate>" + sdf.format(parkBill.getSettleDate()) + "</settleDate>");
            }

            sb.append("</row>");
        }
        sb.append("</list>");
        sb.append("</stream>");
        return sb.toString();
    }
}// end class

4.对接步骤

  • 找中信财务经理和技术人员获取对接文档及相关测试环境。
  • 安装测试银企直连软件,安装相关文字证书。
  • 云端与本地开发,进行联调。
  • 申请正式环境,切换正式环境上线。

5.上线准备

  • 财务端电脑安装前置机
  • 财务端安装飞天驱动(相当于证书)
  • 财务端安装jdk1.8(本地服务需要)
  • 本地服务部署在财务端并启动
  • 云端部署云端服务并上线
  • web代码部署并上线

6.其他注意事项

等正式上线再补充

本人邮箱:aaa@qq.com 如果有问题可以联系我

上一篇:

下一篇: