|  | @ -0,0 +1,294 @@
 | 
	
		
			
				|  |  | package com.yihu.wlyy.service.express;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  | import com.yihu.wlyy.entity.dict.DmExpressagePriceEntity;
 | 
	
		
			
				|  |  | import com.yihu.wlyy.entity.organization.Hospital;
 | 
	
		
			
				|  |  | import com.yihu.wlyy.entity.patient.prescription.Prescription;
 | 
	
		
			
				|  |  | import com.yihu.wlyy.entity.patient.prescription.PrescriptionExpressage;
 | 
	
		
			
				|  |  | import com.yihu.wlyy.entity.patient.prescription.PrescriptionExpressageLog;
 | 
	
		
			
				|  |  | import com.yihu.wlyy.entity.patient.prescription.PrescriptionLog;
 | 
	
		
			
				|  |  | import com.yihu.wlyy.repository.organization.HospitalDao;
 | 
	
		
			
				|  |  | import com.yihu.wlyy.repository.prescription.PrescriptionDao;
 | 
	
		
			
				|  |  | import com.yihu.wlyy.repository.prescription.PrescriptionExpressageDao;
 | 
	
		
			
				|  |  | import com.yihu.wlyy.repository.prescription.PrescriptionLogDao;
 | 
	
		
			
				|  |  | import com.yihu.wlyy.service.BaseService;
 | 
	
		
			
				|  |  | import com.yihu.wlyy.service.app.prescription.PrescriptionExpressageService;
 | 
	
		
			
				|  |  | import com.yihu.wlyy.util.DateUtil;
 | 
	
		
			
				|  |  | import com.yihu.wlyy.util.HttpClientUtil;
 | 
	
		
			
				|  |  | import com.yihu.wlyy.util.SFUtils;
 | 
	
		
			
				|  |  | import org.apache.commons.lang3.StringUtils;
 | 
	
		
			
				|  |  | import org.apache.http.NameValuePair;
 | 
	
		
			
				|  |  | import org.apache.http.message.BasicNameValuePair;
 | 
	
		
			
				|  |  | import org.dom4j.Document;
 | 
	
		
			
				|  |  | 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.beans.factory.annotation.Value;
 | 
	
		
			
				|  |  | import org.springframework.orm.jpa.JpaTransactionManager;
 | 
	
		
			
				|  |  | import org.springframework.stereotype.Service;
 | 
	
		
			
				|  |  | import org.springframework.transaction.TransactionDefinition;
 | 
	
		
			
				|  |  | import org.springframework.transaction.TransactionStatus;
 | 
	
		
			
				|  |  | import org.springframework.transaction.support.DefaultTransactionDefinition;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  | import java.util.*;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  | /**
 | 
	
		
			
				|  |  |  * 顺丰快递业务层方法
 | 
	
		
			
				|  |  |  * Created by huangwenjie  on 2017/8/2.
 | 
	
		
			
				|  |  |  */
 | 
	
		
			
				|  |  | @Service
 | 
	
		
			
				|  |  | public class SFExpressService extends BaseService {
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     private static Logger logger = LoggerFactory.getLogger(SFExpressService.class);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     //顺丰快递接口请求地址
 | 
	
		
			
				|  |  |     @Value("${express.sf_url}")
 | 
	
		
			
				|  |  |     private String sf_url;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     //顺丰快递接口接入编码
 | 
	
		
			
				|  |  |     @Value("${express.sf_code}")
 | 
	
		
			
				|  |  |     private String sf_code;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     //顺丰快递接口checkword
 | 
	
		
			
				|  |  |     @Value("${express.sf_check_word}")
 | 
	
		
			
				|  |  |     private String sf_check_word;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     @Autowired
 | 
	
		
			
				|  |  |     private HttpClientUtil HttpClientUtil;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     @Autowired
 | 
	
		
			
				|  |  |     private SFUtils SFUtils;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     @Autowired
 | 
	
		
			
				|  |  |     private PrescriptionLogDao prescriptionLogDao;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     @Autowired
 | 
	
		
			
				|  |  |     private PrescriptionDao prescriptionDao;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     @Autowired
 | 
	
		
			
				|  |  |     private PrescriptionExpressageDao prescriptionExpressageDao;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     @Autowired
 | 
	
		
			
				|  |  |     private PrescriptionExpressageService prescriptionExpressageService;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     @Autowired
 | 
	
		
			
				|  |  |     private HospitalDao hospitalDao;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     /**
 | 
	
		
			
				|  |  |      * 组装请求参数,发送请求
 | 
	
		
			
				|  |  |      * @param xml
 | 
	
		
			
				|  |  |      * @return
 | 
	
		
			
				|  |  |      * @throws Exception
 | 
	
		
			
				|  |  |      */
 | 
	
		
			
				|  |  |     private String SFExpressPost(String xml)throws Exception{
 | 
	
		
			
				|  |  |         String verifyCode = SFUtils.verifyCodeSFXmlStr(xml,sf_check_word);
 | 
	
		
			
				|  |  |         List<NameValuePair> params = new ArrayList<>();
 | 
	
		
			
				|  |  |         params.add(new BasicNameValuePair("xml", xml));
 | 
	
		
			
				|  |  |         params.add(new BasicNameValuePair("verifyCode", verifyCode));
 | 
	
		
			
				|  |  |         String re = HttpClientUtil.post(sf_url, params, "UTF-8");
 | 
	
		
			
				|  |  |         return re;
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     /**
 | 
	
		
			
				|  |  |      * 校验返回的xml报文
 | 
	
		
			
				|  |  |      * @param responseXml
 | 
	
		
			
				|  |  |      * @param title
 | 
	
		
			
				|  |  |      */
 | 
	
		
			
				|  |  |     private void verificationResponXml(String responseXml,String title) throws Exception {
 | 
	
		
			
				|  |  |         String error = "";
 | 
	
		
			
				|  |  |         if (StringUtils.isBlank(responseXml)) {
 | 
	
		
			
				|  |  |             // 如果返回的XML报文为空,请求也算失败
 | 
	
		
			
				|  |  |             //保存http日志
 | 
	
		
			
				|  |  |             error = title + ",返回的XML为空!";
 | 
	
		
			
				|  |  |             logger.info(error);
 | 
	
		
			
				|  |  |             throw new Exception(error);
 | 
	
		
			
				|  |  |         }else{
 | 
	
		
			
				|  |  | //          报错的报文示例<Response service="ScopeService"><Head>ERR</Head><ERROR code="8014">校验码错误 </ERROR></Response>
 | 
	
		
			
				|  |  |             Document doc = DocumentHelper.parseText(responseXml);
 | 
	
		
			
				|  |  |             String headvalue = doc.selectSingleNode("/Response/Head").getText();
 | 
	
		
			
				|  |  |             if(StringUtils.isNotBlank(headvalue) && "ERR".equals(headvalue)){
 | 
	
		
			
				|  |  |                 //错误代码
 | 
	
		
			
				|  |  |                 String errorCode = "";
 | 
	
		
			
				|  |  |                 //错误代对应的文字
 | 
	
		
			
				|  |  |                 String errorMessage = doc.selectSingleNode("/Response/ERROR").getText();
 | 
	
		
			
				|  |  |                 Document error_doc = doc.selectSingleNode("/Response/ERROR").getDocument();
 | 
	
		
			
				|  |  |                 Element root = error_doc.getRootElement();
 | 
	
		
			
				|  |  |                 List<?> child = root.elements();
 | 
	
		
			
				|  |  |                 for (Object o : child){
 | 
	
		
			
				|  |  |                     Element e = (Element) o;
 | 
	
		
			
				|  |  |                     errorCode = e.attributeValue("code");
 | 
	
		
			
				|  |  |                 }
 | 
	
		
			
				|  |  |                 error = title+","+errorCode+","+errorMessage;
 | 
	
		
			
				|  |  |                 logger.info(error);
 | 
	
		
			
				|  |  |                 throw new Exception(error);
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     /**
 | 
	
		
			
				|  |  |      * 遍历下单失败的快递记录,重新下单
 | 
	
		
			
				|  |  |      * @param expresslist
 | 
	
		
			
				|  |  |      */
 | 
	
		
			
				|  |  |     public void reOrderExpress(List<PrescriptionExpressage> expresslist) throws Exception{
 | 
	
		
			
				|  |  |         for (PrescriptionExpressage prescriptionExpressage : expresslist) {
 | 
	
		
			
				|  |  |             try {
 | 
	
		
			
				|  |  |                 //根据业务订单号判断是否已经下单成功
 | 
	
		
			
				|  |  |                 boolean go_on = this.sfOrderSearchService(prescriptionExpressage);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |                 //如果该业务订单号未下单成功过,则重新下单
 | 
	
		
			
				|  |  |                 if(go_on){
 | 
	
		
			
				|  |  |                     //请求顺丰接口下单,成功下单后,返回快递单号
 | 
	
		
			
				|  |  |                     prescriptionExpressage = this.postSFOrderService(prescriptionExpressage);
 | 
	
		
			
				|  |  |                     //保存快递单号和增加处方物流记录为配送
 | 
	
		
			
				|  |  |                     prescriptionExpressageService.updatePrescriptionExpressage(prescriptionExpressage);
 | 
	
		
			
				|  |  |                 }
 | 
	
		
			
				|  |  |                 logger.info("顺丰快递JOB:重新下单成功,处方编码:"+prescriptionExpressage.getPrescriptionCode());
 | 
	
		
			
				|  |  |             }catch (Exception e){
 | 
	
		
			
				|  |  |                 logger.info("顺丰快递JOB:重新下单失败,处方编码:"+prescriptionExpressage.getPrescriptionCode());
 | 
	
		
			
				|  |  |                 continue;
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     /**
 | 
	
		
			
				|  |  |      * 向顺丰快递下订单
 | 
	
		
			
				|  |  |      * @param sfexpress_obj
 | 
	
		
			
				|  |  |      * @return
 | 
	
		
			
				|  |  |      * @throws Exception
 | 
	
		
			
				|  |  |      */
 | 
	
		
			
				|  |  |     public PrescriptionExpressage postSFOrderService(PrescriptionExpressage sfexpress_obj) throws Exception {
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         //获取医生所处的医院详细地址,作为寄件人地址
 | 
	
		
			
				|  |  |         Prescription prescription = prescriptionDao.findByCode(sfexpress_obj.getPrescriptionCode());
 | 
	
		
			
				|  |  |         Hospital hospital = hospitalDao.findByCode(prescription.getHospital());
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         String xml = SFUtils.postSFOrderService(sfexpress_obj,hospital,sf_code);
 | 
	
		
			
				|  |  |         String re = this.SFExpressPost(xml);
 | 
	
		
			
				|  |  | //        String re = "<Response service=\"OrderService\"><Head>OK</Head><Body><OrderResponse filter_result=\"2\" destcode=\"592\" mailno=\"444844978335\" origincode=\"592\" orderid=\"6daa6baec5fd4b65a1b023a8b60e2e91\"/></Body></Response>";
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         //xml验证
 | 
	
		
			
				|  |  |         verificationResponXml(re,"向顺丰快递下订单失败!");
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         Document doc = DocumentHelper.parseText(re);
 | 
	
		
			
				|  |  |         String headvalue = doc.selectSingleNode("/Response/Head").getText();
 | 
	
		
			
				|  |  |         if(StringUtils.isNotBlank(headvalue) && "OK".equals(headvalue)) {
 | 
	
		
			
				|  |  |             Element root = doc.getRootElement();
 | 
	
		
			
				|  |  |             if (root.element("Body") != null)     //包含OrderResponse节点
 | 
	
		
			
				|  |  |             {
 | 
	
		
			
				|  |  |                 root = root.element("Body");
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             //是否能派送:1:人工确认;2:可收派;3:不可以收派
 | 
	
		
			
				|  |  |             String filter_result = "";
 | 
	
		
			
				|  |  |             String orderid = "";//业务订单号
 | 
	
		
			
				|  |  |             String mailno = "";//顺丰运单号
 | 
	
		
			
				|  |  |             String destCode = "";//目的地区域代码
 | 
	
		
			
				|  |  |             List<?> child = root.elements();
 | 
	
		
			
				|  |  |             for (Object o : child) {
 | 
	
		
			
				|  |  |                 Element e = (Element) o;
 | 
	
		
			
				|  |  |                 filter_result = e.attributeValue("filter_result");
 | 
	
		
			
				|  |  |                 orderid = e.attributeValue("orderid");
 | 
	
		
			
				|  |  |                 mailno = e.attributeValue("mailno");
 | 
	
		
			
				|  |  |                 destCode = e.attributeValue("destCode");
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  |             if(StringUtils.isNotBlank(filter_result) && "3".equals(filter_result)){
 | 
	
		
			
				|  |  |                 logger.info("顺丰快递下订单失败:派送地址不可派送,处方编号:"+sfexpress_obj.getPrescriptionCode());
 | 
	
		
			
				|  |  |                 throw new Exception("顺丰快递下订单失败:派送地址不可派送");
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             if(StringUtils.isBlank(mailno)){
 | 
	
		
			
				|  |  |                 logger.info("顺丰快递下订单失败:未获取到快递单号!"+sfexpress_obj.getPrescriptionCode());
 | 
	
		
			
				|  |  |                 throw new Exception("顺丰快递下订单失败:未获取到快递单号!");
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  |             sfexpress_obj.setMailno(mailno);
 | 
	
		
			
				|  |  |             sfexpress_obj.setCityCode(destCode);
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  |         return sfexpress_obj;
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     /**
 | 
	
		
			
				|  |  |      * 根据处方快递订单号判断是否下单成功
 | 
	
		
			
				|  |  |      * 如果下单成功,保存处方物流记录,保存配送日志
 | 
	
		
			
				|  |  |      * @param sfexpress_obj
 | 
	
		
			
				|  |  |      * @return
 | 
	
		
			
				|  |  |      * @throws Exception
 | 
	
		
			
				|  |  |      */
 | 
	
		
			
				|  |  |     public boolean sfOrderSearchService(PrescriptionExpressage sfexpress_obj)  throws Exception{
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         boolean go_on = false;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         String xml = SFUtils.sfOrderSearchService(sfexpress_obj.getCode(),sf_code);
 | 
	
		
			
				|  |  |         String re = this.SFExpressPost(xml);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         try {
 | 
	
		
			
				|  |  |             //xml验证
 | 
	
		
			
				|  |  |             verificationResponXml(re,"订单处理失败!");
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             Document doc = DocumentHelper.parseText(re);
 | 
	
		
			
				|  |  |             String headvalue = doc.selectSingleNode("/Response/Head").getText();
 | 
	
		
			
				|  |  |             if(StringUtils.isNotBlank(headvalue) && "OK".equals(headvalue)) {
 | 
	
		
			
				|  |  |                 //是否能派送:1:人工确认;2:可收派;3:不可以收派
 | 
	
		
			
				|  |  |                 String filter_result = "";
 | 
	
		
			
				|  |  |                 String orderid = "";//业务订单号
 | 
	
		
			
				|  |  |                 String mailno = "";//顺丰运单号
 | 
	
		
			
				|  |  |                 String destCode = "";//目的地区域代码
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |                 //错误代对应的文字
 | 
	
		
			
				|  |  |                 Document redoc = doc.selectSingleNode("/Response/Body/Orderresponse").getDocument();
 | 
	
		
			
				|  |  |                 Element root = redoc.getRootElement();
 | 
	
		
			
				|  |  |                 List<?> child = root.elements();
 | 
	
		
			
				|  |  |                 for (Object o : child) {
 | 
	
		
			
				|  |  |                     Element e = (Element) o;
 | 
	
		
			
				|  |  |                     filter_result = e.attributeValue("filter_result");
 | 
	
		
			
				|  |  |                     orderid = e.attributeValue("orderid");
 | 
	
		
			
				|  |  |                     mailno = e.attributeValue("mailno");
 | 
	
		
			
				|  |  |                     destCode = e.attributeValue("destCode");
 | 
	
		
			
				|  |  |                 }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |                 if(StringUtils.isBlank(mailno)){
 | 
	
		
			
				|  |  |                     logger.info("顺丰快递下订单失败:未获取到快递单号!"+sfexpress_obj.getPrescriptionCode());
 | 
	
		
			
				|  |  |                     return true;
 | 
	
		
			
				|  |  |                 }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |                 if(StringUtils.isNotBlank(filter_result) && "3".equals(filter_result)){
 | 
	
		
			
				|  |  |                     logger.info("顺丰快递下订单失败:派送地址不可派送,处方编号:"+sfexpress_obj.getPrescriptionCode());
 | 
	
		
			
				|  |  |                     return true;
 | 
	
		
			
				|  |  |                 }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |                 sfexpress_obj.setMailno(mailno);
 | 
	
		
			
				|  |  |                 sfexpress_obj.setCityCode(destCode);
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             //如果成功获取到快递单号,则保存处方物流记录,保存配送日志
 | 
	
		
			
				|  |  |             //修改处方状态为配送中
 | 
	
		
			
				|  |  |             prescriptionDao.updateStatus(sfexpress_obj.getPrescriptionCode(),65);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             //保存处方物流记录
 | 
	
		
			
				|  |  |             prescriptionExpressageDao.save(sfexpress_obj);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             //保存配送日志
 | 
	
		
			
				|  |  |             PrescriptionLog prescriptionLog = new PrescriptionLog();
 | 
	
		
			
				|  |  |             prescriptionLog.setPrescriptionCode(sfexpress_obj.getPrescriptionCode());
 | 
	
		
			
				|  |  |             prescriptionLog.setCode(UUID.randomUUID().toString());
 | 
	
		
			
				|  |  |             prescriptionLog.setType(PrescriptionLog.PrescriptionLogType.sf.getValue());
 | 
	
		
			
				|  |  |             prescriptionLog.setCreateTime(new Date());
 | 
	
		
			
				|  |  |             prescriptionLog.setFlag(1);
 | 
	
		
			
				|  |  |             prescriptionLog.setStatus(PrescriptionLog.PrescriptionLogStatus.expressageing.getValue());
 | 
	
		
			
				|  |  |             prescriptionLogDao.save(prescriptionLog);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         }catch (Exception ex){
 | 
	
		
			
				|  |  |             logger.info("顺丰快递下订单失败:派送地址不可派送,处方编号:"+sfexpress_obj.getPrescriptionCode());
 | 
	
		
			
				|  |  |             //如果订单处理失败,则可以继续下单
 | 
	
		
			
				|  |  |             go_on = true;
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         return go_on;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | }
 |