/***文档注释***********************************************
 * 作者               :                   宋燕辉
 * 创建日期      :                   2018.08.13
 * 描述               :                  罩退  pdipdo
 * 注意事项      :                   无
 * 遗留BUG :                   无
 * 修改日期      :                   
 * 修改人员      :                   
 * 修改内容      :                   
 ***********************************************************/
package market.Api.Mes.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import market.Api.Lms.impl.LmsApiServiceImpl;
import market.Api.Mes.service.MesApiAnnealPdiPdoService;
import market.Api.Qms.impl.QmsApiServiceImpl;
import market.Com.mapper.ComBaseMachineMapper;
import market.Com.mapper.ComBasePlineMapper;
import market.Com.mapper.ComBaseSteelMapper;
import market.Com.pb.DoubleUtil;
import market.Com.pb.PropertiesUtils;
import market.Com.vo.ComBaseMachine;
import market.Com.vo.ComBasePline;
import market.Com.vo.ComBaseSteel;
import market.Com.vo.CommonPage;
import market.Com.vo.ResultModel;
import market.Lms.Warehouse.mapper.YdmProductDetailMapper;
import market.Lms.Warehouse.mapper.YdmProductOutlistMapper;
import market.Lms.Warehouse.vo.YdmProductDetail;
import market.Lms.Warehouse.vo.YdmProductOutlist;
import market.Mes.Lengthwise.Plan.mapper.PlnMaterielDetailMapper;
import market.Mes.Lengthwise.Plan.mapper.PlnProcessPlanMapper;
import market.Mes.Lengthwise.Plan.vo.PlnMaterielDetail;
import market.Mes.Lengthwise.Plan.vo.PlnProcessPlan;
import market.Mes.OrderManager.Plan.mapper.PlnProdorderMapper;
import market.Mes.OrderManager.Plan.vo.PlnProdorder;
import market.Mes.Shift.mapper.MesShiftMMapper;
import market.Mes.Shift.vo.MesShiftM;
import market.Mes.anneal.mapper.IfBaf01L2AswL3PlanMapper;
import market.Mes.anneal.mapper.IfBaf01L3AswL2PlanMapper;
import market.Mes.anneal.mapper.IfBaf01LogMapper;
import market.Mes.anneal.mapper.IfBaf01PdiMapper;
import market.Mes.anneal.mapper.IfBaf01PdoEnergyMapper;
import market.Mes.anneal.mapper.IfBaf01PdoMMapper;
import market.Mes.anneal.mapper.IfBaf01PdoProcMapper;
import market.Mes.anneal.mapper.IfBaf01RevokeL2Mapper;
import market.Mes.anneal.mapper.IfBaf01RevokeL3Mapper;
import market.Mes.anneal.mapper.MesCrAnnealEnergyMapper;
import market.Mes.anneal.mapper.MesCrAnnealMMapper;
import market.Mes.anneal.mapper.PlnAnnealPlanDetailMapper;
import market.Mes.anneal.mapper.PlnAnnealPlanMapper;
import market.Mes.anneal.vo.IfBaf01L2AswL3Plan;
import market.Mes.anneal.vo.IfBaf01L3AswL2Plan;
import market.Mes.anneal.vo.IfBaf01Pdi;
import market.Mes.anneal.vo.IfBaf01PdoEnergy;
import market.Mes.anneal.vo.IfBaf01PdoM;
import market.Mes.anneal.vo.IfBaf01PdoProc;
import market.Mes.anneal.vo.IfBaf01RevokeL2;
import market.Mes.anneal.vo.IfBaf01RevokeL3;
import market.Mes.anneal.vo.MesCrAnnealEnergy;
import market.Mes.anneal.vo.MesCrAnnealM;
import market.Mes.anneal.vo.MesJihuaZhi;
import market.Mes.anneal.vo.PlnAnnealPlanDetail;
import market.Mes.util.DateUtil;
import market.Qms.qcm.service.impl.QcmJhySampleConsignDItemServiceImpl;
import market.Qms.qcm.vo.QcmJhySampleFromPlan;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;

import org.apache.log4j.Logger;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.hnshituo.basic.service.impl.BaseServiceImpl;
import com.hnshituo.basic.spring.remoting.annotation.RemoteService;
import com.hnshituo.core.auth.service.HomeService;

@RemoteService(path = "MesApiAnnealPdiPdoService")
public class MesApiAnnealPdiPdoImpl extends BaseServiceImpl implements MesApiAnnealPdiPdoService{
 
	public static String ANNEALPDI1 = PropertiesUtils.getPdioProperties().getProperty("ANNEALPDI1");
	public static String ANNEALPDI2 = PropertiesUtils.getPdioProperties().getProperty("ANNEALPDI2");
	public static String ANNEALPDI3 = PropertiesUtils.getPdioProperties().getProperty("ANNEALPDI3");
	public static String ANNEALPDI1_NAN = PropertiesUtils.getPdioProperties().getProperty("ANNEALPDI1_NAN");
	public static String ANNEALPDI2_NAN = PropertiesUtils.getPdioProperties().getProperty("ANNEALPDI2_NAN");
	public static String ANNEALPDI3_NAN = PropertiesUtils.getPdioProperties().getProperty("ANNEALPDI3_NAN");
	public static String ANNEALPDI1_AI = PropertiesUtils.getPdioProperties().getProperty("ANNEALPDI1_AI");
	public static String ANNEALPDI2_AI = PropertiesUtils.getPdioProperties().getProperty("ANNEALPDI2_AI");
	public static String ANNEALPDI3_AI = PropertiesUtils.getPdioProperties().getProperty("ANNEALPDI3_AI");
	
	//获取日志记录器Logger，名字为本类类名
    private static Logger log = Logger.getLogger(MesApiAnnealPdiPdoImpl.class);
    
    
    /**
	 * 宝信退火炉作业指示、艾伯纳退火炉作业指示
	 * @param oci
	 * object:
	 * material_no:投料卷号
	 * materailcoilno：原始卷号
	 * steel_name:牌号
	 * order_no:订单号
	 * reciver_unit_name:客户名称
	 * furnace_no：炉座号
	 * memo1:传机台代码
	 * startTime:开始时间
	 * endTime:结束时间
	 * @return
	 */
	public ResultModel doQueryAnnealWeb(CommonPage<MesJihuaZhi> oci){
		ResultModel rm=new ResultModel();
		if(oci.getMemo1()==null || "".equals(oci.getMemo1())){
			rm.setState("500");
			rm.setMsgInfo("请输入机台代码");
			return rm;
		}
		try{
			List<HashMap> lpav=this.getMapper(IfBaf01PdiMapper.class).doQueryWeb(oci.getObject(),oci.getMemo1(),oci.getMemo2(),oci.getStartTime(),oci.getEndTime(),oci.getMemo3());
			rm.setData(lpav);
			rm.setState("200");
		}catch(Exception ex){
			ex.printStackTrace();
			rm.setState("500");
			rm.setMsgInfo("查询失败!"+ex.getMessage());
		}
		return rm;
	}
    
	  /**
		 * 南方退火炉作业指示
		 * @param oci
		 * object:
		  * material_no:投料卷号
		 * materailcoilno：原始卷号
		 * steel_name:牌号
		 * order_no:订单号
		 * reciver_unit_name:客户名称
		 * furnace_no：炉座号
		 * memo1:传机台代码    传M0005
		 * startTime:开始时间
		 * endTime:结束时间
		 * @return
		 */
		public ResultModel doQueryAnnealDG_Web(CommonPage<MesJihuaZhi> oci){
			ResultModel rm=new ResultModel();
			if(oci.getMemo1()==null || "".equals(oci.getMemo1())){
				rm.setState("500");
				rm.setMsgInfo("请输入机台代码");
				return rm;
			}
			try{
				List<HashMap> lpav=this.getMapper(IfBaf01PdiMapper.class).doQueryWeb_DG(oci.getObject(),oci.getMemo1(),oci.getMemo2(),oci.getStartTime(),oci.getEndTime(),oci.getMemo3());
				rm.setData(lpav);
				rm.setState("200");
			}catch(Exception ex){
				ex.printStackTrace();
				rm.setState("500");
				rm.setMsgInfo("查询失败!"+ex.getMessage());
			}
			return rm;
		}
	
	
    
	//下发PDI
	@Transactional(value="tm", rollbackFor=Exception.class)
	public String SendBaf01Pdi(String v_mch_code, String v_plan_no,
			String v_object_no_vt, String v_material_no, String v_opr_name,
			String v_message) throws Exception{
		
		Integer v_cnt ;
		//  --(1)、验证前端传入参数的基本有效性
		if(v_mch_code==null){
			v_message="参数错误：机台代码不能为空！";
			return v_message;
		}
		//  --(1.1)、验证机台基础信息存在
		v_cnt = this.getMapper(ComBaseMachineMapper.class).countWithCondition(null,"machine_code='"+v_mch_code+"'");
		if(v_cnt<=0){
			v_message="机台代码{"+v_mch_code+"} 机台基础信息不存在！";
			return v_message;
		}
		//  --（1.2）、获取机台基础信息表中，配置的机台设备代号（设备编号，如1,2,3）
		List<ComBaseMachine> lcbm = this.getMapper(ComBaseMachineMapper.class).findWithCondition(null,
				"machine_code='"+v_mch_code+"'", null, 0, 0);
		String v_mch_mark=lcbm.get(0).getMachine_mark();
		if(v_mch_mark==null){
			v_message="机台代码{"+v_mch_code+"} 设备编号未配置，无法处理！";
			return v_message;
		}
		//  --(2)、验证当前还未收到L2生产实绩
		List<PlnAnnealPlanDetail> v_rec_pln_d=this.getMapper(PlnAnnealPlanDetailMapper.class).doQuery(v_mch_code,v_plan_no,v_object_no_vt,v_material_no);
		if(v_rec_pln_d==null || v_rec_pln_d.size()<=0){
			v_message="罩退作业计划不存在！";
			return v_message;
		}
		//--此处暂且限制，可能实际应用过程中，需要去掉此限制，先保留，后续根据实际需要再屏蔽
		if("2".equals(v_rec_pln_d.get(0).getSend_flag())){
			//v_message="原料卷号{"+v_material_no+"} 已收到L2生产实绩，不能重复下发！";
			v_message="已收到L2生产实绩，不能重复下发！";
			return v_message;
		}
		//  --(3)、验证当前还未生产交工
		List<MesCrAnnealM> v_rec_anl_m = this.getMapper(MesCrAnnealMMapper.class).findWithCondition(null, "schedule_no='"+v_plan_no+"' and material_no='"+v_material_no+"'", null, 0, 0);
		if(v_rec_anl_m!=null && v_rec_anl_m.size()>0){
			if("1".equals(v_rec_anl_m.get(0).getHand_over_status())){
				v_message="已生产交工，不能重复下发！";
				return v_message;
			}
		}
		//  --(4)、验证虚拟物料表中，原料卷计划信息存在
		List<PlnMaterielDetail> v_rec_mtr_in = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,"object_no_vt='"+v_object_no_vt+"'", null, 0, 0);
		if(v_rec_mtr_in==null || v_rec_mtr_in.size()<=0){
			v_message="原料卷虚拟物料信息不存在！";
			return v_message;
		}
		//  --(5)、验证虚拟物料表中，出口卷虚拟物料信息存在
		PlnMaterielDetail pmd2=new PlnMaterielDetail();
		pmd2.setMat_object_no_vt(v_object_no_vt);
		v_cnt = this.getMapper(PlnMaterielDetailMapper.class).count(pmd2);
		if (v_cnt<=0) {
			v_message="出口卷虚拟物料信息不存在！";
			return v_message;
		}
		List<PlnMaterielDetail> v_rec_mtr_out=this.getMapper(PlnMaterielDetailMapper.class).doQueryWeb2(v_object_no_vt,"");
		//  --(6)、验证原料卷库存明细存在
		List<YdmProductDetail> v_rec_ydm_d = this.getMapper(YdmProductDetailMapper.class).findWithCondition(null, "coilno='"+v_material_no+"'", null, 0, 0);
		if(v_rec_ydm_d==null || v_rec_ydm_d.size()<=0){
			v_message="库存明细记录不存在！";
			return v_message;
		}
		//  --(7)、获取生产订单信息
		List<PlnProdorder> v_rec_prod = this.getMapper(PlnProdorderMapper.class).findWithCondition(null, "prod_order_no='"+v_rec_mtr_in.get(0).getProd_order_no()+"'", null, 0, 0);
		if(v_rec_prod==null || v_rec_prod.size()<=0){
			v_message="生产订单号{"+v_rec_mtr_in.get(0).getProd_order_no()+"} 生产订单信息不存在！";
			return v_message;
		}
		//  --(8)、获取牌号(名称)
		String v_steel=null;
		List<ComBaseSteel> lcbs = this.getMapper(ComBaseSteelMapper.class).findWithCondition(null, "steel_code='"+v_rec_mtr_in.get(0).getSteel_code()+"'", null, 0, 0);
		if(lcbs==null || lcbs.size()<=0){
			v_steel="";
		}else{
			if(lcbs.get(0).getSteel_name()==null){
				v_steel=lcbs.get(0).getSteel_code();
			}else{
				v_steel=lcbs.get(0).getSteel_name();
			}
		}
		//  --(9)、获取库区
		String v_stock_code=this.getMapper(MesCrAnnealMMapper.class).doQueryStock(v_material_no);
		if(v_stock_code==null){
			v_stock_code="";
		}
		//  --(10)、获取库位
		String v_location_no=this.getMapper(MesCrAnnealMMapper.class).doQueryLocation(v_material_no);
		if(v_location_no==null){
			v_location_no="";
		}
		//  --(11)、获取备注
		String  v_memo=this.getMapper(MesCrAnnealMMapper.class).doQueryMemo(v_material_no);
		if(v_memo==null){
			 v_memo="";
		}
		//  --(12)、出口卷编码前缀：原料卷号（最初始原料卷号） + 1位工序代号（退火T）+ 2位设备代号（01-99）
		String v_coil_no=null;
		if(v_rec_anl_m!=null && v_rec_anl_m.size()>0){
			if(v_rec_anl_m.get(0).getFurnace_no()!=null){
				v_coil_no = v_material_no.substring(0, 8) + "T"+ lpad(v_rec_anl_m.get(0).getFurnace_no(), 2, "0");
			}else{
				v_coil_no = v_material_no.substring(0, 8) + "T"+ lpad(v_mch_mark, 2, "0");
			}
		}else{
			v_coil_no = v_material_no.substring(0, 8) + "T"+ lpad(v_mch_mark, 2, "0");
		}
		
		//    --(12.1)、获取当前起始流水号
		v_cnt=this.getMapper(MesCrAnnealMMapper.class).doQueryWeb5(v_coil_no,v_plan_no,v_material_no);
		if(v_cnt==null){
			v_cnt=1;
		}else if(v_cnt>99){
			v_message="出口钢卷号超出规则范围，流水号超出最大值99！";
			return v_message;
		}
		//  --(12.2)、出口卷编码规则：出口卷编码前缀【原料卷号（最初始原料卷号） + 1位工序代号（退火T）+ 2位设备代号（01-99）】+ 2位流水（01 - 99）																																							
		v_coil_no=v_coil_no+lpad(v_cnt+"",2,"0");
		//  --(13)、组装PDI数据项
		IfBaf01Pdi v_rec_pdi=new IfBaf01Pdi();
		v_rec_pdi.setPlan_no ( v_plan_no);//计划号																																							
		v_rec_pdi.setSeq_no( v_rec_pln_d.get(0).getAn_seq());//序号					
		//2018-11-06  机组代码  二级长度为4
		if(v_mch_code.contains("M")){
			v_rec_pdi.setUnit_code(v_mch_code.substring(1));//机组代码（区分厂家：艾伯纳、中冶南方、宝信）	
		}
		v_rec_pdi.setPlan_type ("0");//计划类型（0：正常计划、1：返修计划）																																							
		v_rec_pdi.setRepair_type ( null);//返修类型																																							
		v_rec_pdi.setDivide_num( 0l);//等分卷数																																							
		v_rec_pdi.setIn_mat_type ("1");//入口钢卷类型（0：虚拟钢卷、1：实物钢卷）
		if(!v_mch_code.equals("M0006")){
			v_rec_pdi.setStock_code( v_stock_code);//库区代码				
			v_rec_pdi.setLocation_no ( v_location_no);//库位号		
		}
																																							
		v_rec_pdi.setIn_mat_no ( v_material_no);//入口钢卷号																																							
		v_rec_pdi.setIn_mat_thick( v_rec_ydm_d.get(0).getThick());//入口钢卷厚度（mm）																																							
		v_rec_pdi.setIn_mat_width( v_rec_ydm_d.get(0).getWidth());//入口钢卷宽度（mm）
		if(v_rec_ydm_d.get(0).getLength()!=null){
			v_rec_pdi.setIn_mat_len(v_rec_ydm_d.get(0).getLength()/1000);//入口钢卷长度（m）  9,3				
		}
		
		v_rec_pdi.setIn_mat_in_dia ( v_rec_ydm_d.get(0).getDiameter_inn());//入口钢卷内径（mm）																																							
		v_rec_pdi.setIn_mat_dia( v_rec_ydm_d.get(0).getDiameter_out());//入口钢卷外径（mm）	
		if(v_mch_code.equals("M0006")){
			if(v_rec_pdi.getIn_mat_in_dia()==null || v_rec_pdi.getIn_mat_in_dia().intValue()==0){
				v_rec_pdi.setIn_mat_in_dia(610d);
			}
			if(v_rec_pdi.getIn_mat_dia()==null || v_rec_pdi.getIn_mat_dia().intValue()==0){
				v_rec_pdi.setIn_mat_dia(1710d);
			}
		}
		
		if(v_rec_ydm_d.get(0).getFactweight()!=null){
			v_rec_pdi.setIn_mat_wt ( v_rec_ydm_d.get(0).getFactweight()/1000);//入口钢卷重量（t）	
			v_rec_pdi.setOut_mat_wt( v_rec_ydm_d.get(0).getFactweight()/1000);//出口材料重量（t）																																							
			v_rec_pdi.setOut_mat_min_wt( v_rec_ydm_d.get(0).getFactweight()/1000);//出口材料重量最小值（t）																																							
			v_rec_pdi.setOut_mat_max_wt( v_rec_ydm_d.get(0).getFactweight()/1000);//出口材料重量最大值（t）	
		}
		v_rec_pdi.setOut_mat_no( v_coil_no);//出口材料号																																							
		v_rec_pdi.setOut_mat_thick ( v_rec_mtr_out.get(0).getThick());//出口钢卷厚度（mm）																																							
		v_rec_pdi.setOut_mat_min_thick ( v_rec_mtr_out.get(0).getThick());//出口材料厚度最小值（mm）																																							
		v_rec_pdi.setOut_mat_max_thick ( v_rec_mtr_out.get(0).getThick());//出口材料厚度最大值（mm）																																							
		v_rec_pdi.setOut_mat_width ( v_rec_mtr_out.get(0).getWidth());//出口材料宽度（mm）																																							
		v_rec_pdi.setOut_mat_min_width ( v_rec_mtr_out.get(0).getWidth());//出口材料宽度最小值（mm）																																							
		v_rec_pdi.setOut_mat_max_width ( v_rec_mtr_out.get(0).getWidth());//出口材料宽度最大值（mm）	
		if(v_rec_mtr_out.get(0).getLength()!=null){
			v_rec_pdi.setOut_mat_len ( v_rec_mtr_out.get(0).getLength()/1000);//出口材料长度（m）																																							
			v_rec_pdi.setOut_mat_min_len ( v_rec_mtr_out.get(0).getLength()/1000);//出口材料长度最小值（m）																																							
			v_rec_pdi.setOut_mat_max_len ( v_rec_mtr_out.get(0).getLength()/1000);//出口材料长度最大值（m）	
		}
		v_rec_pdi.setOut_mat_inner_dia ( v_rec_ydm_d.get(0).getDiameter_inn());//出口材料内径（mm）																																							
		v_rec_pdi.setOut_mat_outer_dia ( v_rec_ydm_d.get(0).getDiameter_out());//出口材料外径（mm）	
																																								
		v_rec_pdi.setWt_mode ("1");//出口计重方式																																							
		v_rec_pdi.setNext_whole_backlog_code ( null);//后工序代码																																							
		v_rec_pdi.setPrev_whole_backlog_code ( null);//前工序代码																																							
		v_rec_pdi.setOrder_no( v_rec_mtr_out.get(0).getOrder_no());//合同号																																							
		v_rec_pdi.setOrder_thick ( v_rec_prod.get(0).getThick());//订货厚度（mm）	
		//订货宽度  ORDER_WIDTH	订货宽度	N	5,1						NUMBER(7,3)
		if(v_rec_prod.get(0).getWidth()!=null){
			v_rec_pdi.setOrder_width (DoubleUtil.round(v_rec_prod.get(0).getWidth(), 1));//订货宽度（mm）
		}
//		if(v_rec_prod.get(0).getSingle_weight()!=null){//PLN_PRODORDER的Single_weight没有值
//		}
		//v_rec_pdi.setOrder_unit_max_wt ( v_rec_prod.get(0).getSingle_weight()/1000);//订货单件最大重量（t）	null	
		if(v_rec_prod.get(0).getSingle_weight_max()!=null){
			v_rec_pdi.setOrder_unit_max_wt ( v_rec_prod.get(0).getSingle_weight_max()/1000);//订货单件最大重量（t）	22000.000/1000
			v_rec_pdi.setOrder_unit_aim_wt ( v_rec_prod.get(0).getSingle_weight_max()/1000);//订货单件目标重量（t）	22000.000/1000
		}
		if(v_rec_prod.get(0).getSingle_weight_min()!=null){
			v_rec_pdi.setOrder_unit_min_wt (v_rec_prod.get(0).getSingle_weight_min()/1000);//订货单件最小重量（t）		18000.000/1000
		}
		
		v_rec_pdi.setPono_no ( null);//炉号																																							
		v_rec_pdi.setPono( null);//制造命令号			
		//2018-11-06 产品最终用途码      二级长度是4
		if(v_rec_prod.get(0).getUse_code()!=null){
			if(v_rec_prod.get(0).getUse_code().length()>4){
				v_rec_pdi.setApn ( v_rec_prod.get(0).getUse_code().substring(v_rec_prod.get(0).getUse_code().length()-4, 
						v_rec_prod.get(0).getUse_code().length()));//产品最终用途码	
			}else{
				v_rec_pdi.setApn ( v_rec_prod.get(0).getUse_code());//产品最终用途码	
			}
		}
		
		String formatDate = DateUtil.formatDate(v_rec_prod.get(0).getDeliver_date(), "yyyyMMddHHmmss");
		v_rec_pdi.setDelivy_date (formatDate);//交货日期（14位字符串）																																							
		v_rec_pdi.setPackage_code( null);//包装代码																																							
		v_rec_pdi.setSg_sign ( v_steel);//钢种																																							
		v_rec_pdi.setDensity ( 7.85);//密度																																							
		v_rec_pdi.setOrder_special ( null);//合同特殊要求																																							
		v_rec_pdi.setSurface_struct_code ( null);//目标表面结构（毛面、光面）																																							
		v_rec_pdi.setAnneal_diagram_code ( null);//退火曲线代码																																							
		v_rec_pdi.setAnneal_temp_min ( null);//退火温度最小值																																							
		v_rec_pdi.setAnneal_temp_aim ( null);//退火温度目标值																																							
		v_rec_pdi.setAnneal_temp_max ( null);//退火温度最大值																																							
		v_rec_pdi.setRemark("【"+v_rec_ydm_d.get(0).getMaterailcoilno()+"】"+ (v_memo==null?"":v_memo));//备注		
//		//测试2019-04-26 
//		v_rec_pdi.setRemark( "备注信息测试");//备注		
		
		
		v_rec_pdi.setSend_time ( new Date());																																							
		v_rec_pdi.setSend_opr( v_opr_name);		
		
		//  --(14)、无接口调试时，设置1，直接跳过，否则设置为0
		int v_flag=0;//
		//  --(14.1)、调用公司接口，将“PDI电文” v_rec_pdi 发送给L2（获取接口执行成功状态：v_flag，错误信息：v_message）
		JsonConfig jsonConfig=new JsonConfig();
		jsonConfig.registerJsonValueProcessor(java.util.Date.class, new DateJsonValueProcessor("yyyy-MM-dd HH:mm:ss"));
		jsonConfig.registerJsonValueProcessor(java.lang.Double.class, new DoubleJsonValueProcessor());
		jsonConfig.registerJsonValueProcessor(java.lang.Long.class, new LongJsonValueProcessor());
		jsonConfig.registerJsonValueProcessor(java.lang.Integer.class, new IntegerJsonValueProcessor());
		JSONObject jsonObject=JSONObject.fromObject(v_rec_pdi,jsonConfig);
		System.out.println(jsonObject.toString());
		try{
			String url="";
			if(v_mch_code.equals("M0004")){
				url = ANNEALPDI1;
			}else if(v_mch_code.equals("M0006")){
				url = ANNEALPDI1_AI;
			}else if(v_mch_code.equals("M0005") || v_mch_code.equals("M0009")){
				url = ANNEALPDI1_NAN;
			}
			log.debug("url:"+url);
			
			String body = jsonObject.toString();
	        RestfulHttpClient.HttpResponse response = RestfulHttpClient.getClient(url)
	                .post()              //设置post请求
	                .addPostParam("body", "json")
	                .body(body)
	                .addHeader("Content-type", "application/json")   //添加header
	                //.addPathParam("id", "2")        //设置url路径参数
	                //.addQueryParam("test", "value") //设置url请求参数
	                .request();         //发起请求
	        System.out.println(response.getCode());     //响应状态码
	        System.out.println(response.getRequestUrl());//最终发起请求的地址
	        if(response.getCode() == 200){
	            //请求成功
	            //System.out.println(response.getContent());  //响应内容
	            log.debug("responseCONTENT:"+response.getContent());
	            if(response.getContent()!=null && (response.getContent().contains("vsuccess")|| response.getContent().contains("成功"))){//成功往L2的pdi表中插入数据
	            	v_flag=1;
	            	v_message="PDI下发成功！";
	            }else{
	            	if(response.getContent()!=null && response.getContent().length()>200){
	    				v_message="已下发PDI给L2，插入失败！【"+response.getContent().substring(0,200)+"】";
	    			}else{
	    				v_message="已下发PDI给L2，插入失败！【"+response.getContent()+"】";
	    			}
	            }
	            //v_message="原料卷号{"+v_rec_mat_d.get(0).getObject_no()+"}已下发PDI给L2！";
	        }else{
	        	v_message="下发PDI给L2失败！发送请求失败！";
	        }
		}catch(Exception e){
			e.printStackTrace();
			v_message="【通讯过程出错："+e.getMessage()+"】";
		}
		//  --(14.1.1)、电文发送失败（失败状态，根据接口提供定义确定）
		if(v_flag==0){
			v_message="SendBaf01Pdi PDI电文发送失败！"+v_message;
			return v_message;
		}
		//  --(14)、插入PDI记录表
		this.getMapper(IfBaf01PdiMapper.class).insert(v_rec_pdi);
		//  --(15)、修改作业计划表下发L2状态
		//this.getMapper(PlnAnnealPlanDetailMapper.class).doUpdate(v_plan_no,v_object_no_vt,v_opr_name);
		v_message="操作人{"+v_opr_name+"} PDI下发成功！";
		//  --(16)、提交事务
		//  --(17)、调用公司电文处理，真正下发PDI给L2（v_rec_pdi 对象） ？？
		return v_message;
	}

	//撤销PDI
	@Transactional(value="tm", rollbackFor=Exception.class)
	public String L3RevokeBaf01Pdi(String v_mch_code, String v_plan_no,
			String v_object_no_vt, String v_material_no, String v_opr_name,String v_message) throws Exception{
		
		Integer v_cnt;
		// --(1)、验证作业计划存在
		List<PlnAnnealPlanDetail> v_rec_pln_d=this.getMapper(PlnAnnealPlanDetailMapper.class).doQuery(v_mch_code,v_plan_no,v_object_no_vt,v_material_no);
		if(v_rec_pln_d==null || v_rec_pln_d.size()<=0){
			v_message="罩退作业计划不存在！";
			return v_message;
		}
		//  --(2)、验证已下发过PDI
		if(v_rec_pln_d.get(0).getSend_flag()==null || "0".equals(v_rec_pln_d.get(0).getSend_flag())){
			v_message="还未下发PDI！";
			return v_message;
		}
		
		//--(3)、验证还未收到PDO，否则不允许撤销PDI
		if("2".equals(v_rec_pln_d.get(0).getSend_flag())){
			v_message="已收到L2生产实绩，不能撤销PDI！";
			return v_message;
		}
		//  --(4)、验证当前还未生产交工
		List<MesCrAnnealM> v_rec_anl_m = this.getMapper(MesCrAnnealMMapper.class).findWithCondition(null, "schedule_no='"+v_plan_no+"' and material_no='"+v_material_no+"'", null, 0, 0);
		if(v_rec_anl_m!=null && v_rec_anl_m.size()>0){
			if("1".equals(v_rec_anl_m.get(0).getHand_over_status())){
				v_message="已生产交工，不能撤销PDI！";
				return v_message;
			}
		}
		//  --(5)、组装撤销PDI对象数据项
		IfBaf01RevokeL3 v_rec_revoke=new IfBaf01RevokeL3();
		v_rec_revoke.setPlan_no ( v_plan_no); //计划号																																							
		v_rec_revoke.setSeq_no( v_rec_pln_d.get(0).getAn_seq()); //序号																																							
		//2018-11-06  机组代码  二级长度为4
		if(v_mch_code.contains("M")){
			v_rec_revoke.setUnit_code(v_mch_code.substring(1));//机组代码（区分厂家：艾伯纳、中冶南方、宝信）	
		}
		v_rec_revoke.setIn_mat_no ( v_material_no); //入口钢卷号																																							
		v_rec_revoke.setRevoke_time ( new Date());																																							
		v_rec_revoke.setRevoke_opr( v_opr_name);
		
	    //  --(14)、无接口调试时，设置1，直接跳过，否则设置为0
		int v_flag=0;
		//  --(14.1)、调用公司接口，将“PDI电文” v_rec_pdi 发送给L2（获取接口执行成功状态：v_flag，错误信息：v_message）
		JsonConfig jsonConfig=new JsonConfig();
		jsonConfig.registerJsonValueProcessor(java.util.Date.class, new DateJsonValueProcessor("yyyy-MM-dd HH:mm:ss"));
		jsonConfig.registerJsonValueProcessor(java.lang.Double.class, new DoubleJsonValueProcessor());
		jsonConfig.registerJsonValueProcessor(java.lang.Long.class, new LongJsonValueProcessor());
		jsonConfig.registerJsonValueProcessor(java.lang.Integer.class, new IntegerJsonValueProcessor());
		JSONObject jsonObject=JSONObject.fromObject(v_rec_revoke,jsonConfig);
		System.out.println(jsonObject.toString());
		try{
			String url="";
			if(v_mch_code.equals("M0004")){
				url = ANNEALPDI2;
			}else if(v_mch_code.equals("M0006")){
				url = ANNEALPDI2_AI;
			}else if(v_mch_code.equals("M0005") || v_mch_code.equals("M0009")){
				url = ANNEALPDI2_NAN;
			}
			log.debug("url:"+url);
			
			
			String body = jsonObject.toString();
	        RestfulHttpClient.HttpResponse response = RestfulHttpClient.getClient(url)
	                .post()              //设置post请求
	                .addPostParam("body", "json")
	                .body(body)
	                .addHeader("Content-type", "application/json")   //添加header
	                //.addPathParam("id", "2")        //设置url路径参数
	                //.addQueryParam("test", "value") //设置url请求参数
	                .request();         //发起请求
	        System.out.println(response.getCode());     //响应状态码
	        System.out.println(response.getRequestUrl());//最终发起请求的地址
	        if(response.getCode() == 200){
	            //请求成功
	            //System.out.println(response.getContent());  //响应内容
	            log.debug("responseCONTENT:"+response.getContent());
	            if(response.getContent()!=null && (response.getContent().contains("vsuccess")|| response.getContent().contains("成功"))){//成功往L2的pdi表中插入数据
	            	v_flag=1;
	            	v_message="撤销PDI成功！";
	            }else{
	            	if(response.getContent()!=null && response.getContent().length()>200){
	    				v_message="撤销PDI电文下发给L2，插入失败！【"+response.getContent().substring(0,200)+"】";
	    			}else{
	    				v_message="撤销PDI电文下发给L2，插入失败！【"+response.getContent()+"】";
	    			}
	            }
	            //v_message="原料卷号{"+v_rec_mat_d.get(0).getObject_no()+"}已下发PDI给L2！";
	        }else{
	        	v_message="撤销PDI电文下发失败！发送请求失败！";
	        }
		}catch(Exception e){
			e.printStackTrace();
			v_message="【通讯过程出错："+e.getMessage()+"】";
		}
		//  --(14.1.1)、电文发送失败（失败状态，根据接口提供定义确定）
		if(v_flag==0){
			v_message="L3RevokeBaf01Pdi 撤销PDI电文下发失败！"+v_message;
			return v_message;
		}
		//  --(6)、插入PDI撤销下发记录表
		this.getMapper(IfBaf01RevokeL3Mapper.class).insert(v_rec_revoke);
		//  --(7)、修改作业计划表下发L2状态
		//this.getMapper(PlnAnnealPlanDetailMapper.class).doUpdate2(v_plan_no, v_object_no_vt);
		v_message="操作人{"+v_opr_name+"} 撤销PDI电文下发成功！";
		return v_message;
	}
	
	
	/**
		1)、	此接口为纯后台逻辑，不与前端页面交互，收到罩退L2应答L3计划信息电文时调用；																																							
		2)、	此接口参数为JSON对象（对象结构见数据库表 IF_BAF01_L2_ASW_L3_PLAN）；																																							
	 * @param IfBaf01L2AswL3Plan  L2应答L3计划信息电文对象
	 * @param v_message
	 * @return
	 * @throws Exception
	 */
	public String Baf01L2AswL3Revoke(IfBaf01L2AswL3Plan json){
		String v_message="";
		//  --(1)、函数参数为JSON对象，先转换为Java实体类，此处以 v_rec_asw 代替描述
		IfBaf01L2AswL3Plan v_rec_asw=json;
		if(json==null ){
			v_message="参数错误：二级接口-宝信罩退炉-L2应答L3计划信息电文为空";
			//v_message="500";
			return v_message;
		}
		//  --(2)、如果电文中（接口参数）未包含消息时间（MSG_TIME），或为空值，则赋值为当前时刻
		if(v_rec_asw.getMsg_time()==null){//作业时间为null，则取当前时间
			v_rec_asw.setMsg_time(new Date());
		}
		//  --(3)、将对象，插入L2应答L3计划信息表（单独的事务）
		try{
			this.getMapper(IfBaf01L2AswL3PlanMapper.class).insert(v_rec_asw);
		}catch(Exception e){
			e.printStackTrace();
		}
		//  --(4)、调用处理L2应答L3计划信息函数（事务在函数内）
		try{
			v_message=this.getBean(MesApiAnnealPdiPdoImpl.class).Baf01L2AswL3Revoke_D(v_rec_asw,v_message);
			//this.getSqlSession("sqlSessionFactory").getConnection().
		}catch(Exception e){
			e.printStackTrace();
			v_message=e.getMessage();
			//throw new Exception(e.getMessage());
		}finally{
			//  --(5)、拼接参数
			String v_param="作业计划号{"+v_rec_asw.getPlan_no()+"}入口钢卷号{"+v_rec_asw.getIn_mat_no()+"}机台代码{"+v_rec_asw.getUnit_code()+"}";
			//  --(6)、写接口日志：与业务处理分开，单独的事务
			try{
				 this.getMapper(IfBaf01LogMapper.class).doInsert(null,"Baf01L2AswL3Revoke",v_param,v_message);
			}catch(Exception e){
				e.printStackTrace();
			}
		}
		return v_message;
	}
	
	/**
	 * 	1)、	此函数为JAVA后台内调函数，可考虑将方法设为私有，由接口 Baf01L2AswL3Revoke 调用；																																							
		2)、	接口参数 IN：V_REC_ASW（L2应答L3计划信息电文对象）																																							
		3)、	接口参数 OUT：V_MESSAGE（操作结果信息）																																							
	 * @param v_rec_asw
	 * @param v_message
	 * @return
	 * @throws Exception
	 */
	@Transactional(value="tm", rollbackFor=Exception.class)
	public String Baf01L2AswL3Revoke_D(IfBaf01L2AswL3Plan v_rec_asw,
			String v_message) throws Exception {
		try{
			// --(1)、验证罩退作业计划存在
			List<PlnAnnealPlanDetail> v_rec_pln_d=this.getMapper(PlnAnnealPlanDetailMapper.class).doQuery2(v_rec_asw.getPlan_no(),v_rec_asw.getIn_mat_no());
			if(v_rec_pln_d==null || v_rec_pln_d.size()<=0){
				v_message="罩退作业计划不存在！";
				return v_message;
			}
			//flg为null,flag为null？？？
			if(v_rec_asw.getFlg()==null || v_rec_asw.getFlag()==null 
					|| "".equals(v_rec_asw.getFlg()) || "".equals(v_rec_asw.getFlag()) ){
				v_message="L2应答L3计划信息电文中操作标识flg【"+v_rec_asw.getFlg()+"】，处理标志flag【"+v_rec_asw.getFlag()+"】无效！";
				return v_message;
			}
			//L2-L3在后台自动处理，所以获取SESSION中的登录人员为空     
			String vOprName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
			List<IfBaf01Pdi> lib01p = this.getMapper(IfBaf01PdiMapper.class).findWithCondition(null, "plan_no ='"+v_rec_asw.getPlan_no()+"' and in_mat_no='"+v_rec_asw.getIn_mat_no()+"'", null, 0, 0);
			if(lib01p!=null && lib01p.size()>0){
				vOprName=lib01p.get(0).getSend_opr();
			}
			if(vOprName==null){
				vOprName="L2Asw";
			}
			//  --(2)、开始事务：修改作业计划表下发L2状态
			if("1".equals(v_rec_asw.getFlg()) && "0".equals(v_rec_asw.getFlag())){
				//    --(2.1)、flg = '1' && v_rec_asw.flag = '0' 代表L2新增操作成功
				this.getMapper(PlnAnnealPlanDetailMapper.class).doUpdate4(v_rec_asw.getPlan_no(),v_rec_asw.getIn_mat_no(),vOprName);
			}else if("2".equals(v_rec_asw.getFlg()) && "0".equals(v_rec_asw.getFlag())){
				//    --(2.2)、flg = '2' && v_rec_asw.flag = '0' 代表L2撤销操作成功
				this.getMapper(PlnAnnealPlanDetailMapper.class).doUpdate3(v_rec_asw.getPlan_no(),v_rec_asw.getIn_mat_no());
			}
			//  --(3)、提交事务
			v_message="L2应答L3计划信息电文处理成功！";
		}catch(Exception e){
			e.printStackTrace();
			if(e.getMessage()!=null && e.getMessage().length()>200){
				v_message="L2应答L3计划信息电文处理失败："+e.getMessage().substring(0,200);
			}else{
				v_message="L2应答L3计划信息电文处理失败："+e.getMessage();
			}
			throw new Exception(v_message);
		}
		return v_message;
	}
	
	
	/**
		1)、	此接口为纯后台逻辑，不与前端页面交互，收到罩退L2删除计划钢卷电文时调用；																																							
		2)、	此接口参数为JSON对象（对象结构见数据库表 IF_BAF01_REVOKE_L2）；																																							
	 * @param json
	 * @return
	 */
	public String L2RevokeBaf01Pdi(IfBaf01RevokeL2 json) throws Exception{
		String v_message="";
		if(json==null || "".equals(json.toString())){
			v_message="二级接口-宝信罩退炉PDI-L2删除为空";
			return v_message;
		}
		IfBaf01RevokeL2 v_rec_revoke=json;
		//   --(2)、如果电文中（接口参数）未包含消息时间（MSG_TIME），或为空值，则赋值为当前时刻
		if(v_rec_revoke.getMsg_time()==null){
			v_rec_revoke.setMsg_time(new Date());
		}
		//  --(3)、将对象，插入L2计划钢卷删除表（单独的事务）  
		try{
			this.getMapper(IfBaf01RevokeL2Mapper.class).insert(v_rec_revoke);
		}catch(Exception e){
			e.printStackTrace();
		}
		//  --(4)、调用处理L2计划钢卷删除函数（事务在函数内）
		try{
			v_message=this.getBean(MesApiAnnealPdiPdoImpl.class).L2RevokeBaf01Pdi_D(v_rec_revoke, v_message);
			//this.getSqlSession("sqlSessionFactory").getConnection().
		}catch(Exception e){
			e.printStackTrace();
			v_message=e.getMessage();
			//throw new Exception(e.getMessage());
		}
		// --(5)、拼接返回字符串
		 v_message = "作业计划号{"+v_rec_revoke.getPlan_no()+"}入口钢卷号{"+v_rec_revoke.getIn_mat_no()+"}机台代码{"+v_rec_revoke.getUnit_code()+"}"+v_message;
		//  --(6)、写接口日志：与业务处理分开，单独的事务
		try{
			 this.getMapper(IfBaf01LogMapper.class).doInsert(null,"L2RevokeBaf01Pdi","",v_message);
		}catch(Exception e){
			e.printStackTrace();
		}
		return v_message;
	}
	
	/**
	 * 	1)、	此函数为JAVA后台内调函数，可考虑将方法设为私有，由接口 L2RevokeBaf01Pdi 调用；																																							
		2)、	接口参数 IN：V_REC_REVOKE（L2计划钢卷删除实体对象实例）																																							
		3)、	接口参数 OUT：V_MESSAGE（操作结果信息）																																							
	 * @param v_rec_revoke
	 * @param v_message
	 * @return
	 * @throws Exception
	 */
	@Transactional(value="tm", rollbackFor=Exception.class)
	public String L2RevokeBaf01Pdi_D(IfBaf01RevokeL2 v_rec_revoke,
			String v_message) throws Exception {
		Integer v_success=null;//--操作成功标志（1：成功、0：失败）
		IfBaf01L3AswL2Plan v_rec_asw=new IfBaf01L3AswL2Plan();//--L3应答L2计划信息电文对象
		try{
			//  --(1)、调用处理L2计划钢卷删除函数（事务在函数内）																																							
			//  --(1.1)、输出参数 v_success = 1，表示L3处理L2计划钢卷删除操作成功，否则失败																																							
			try{
				v_message=this.getBean(MesApiAnnealPdiPdoImpl.class).L2RevokeBaf01Pdi_D_D(v_rec_revoke, v_success, v_message);
				//this.getSqlSession("sqlSessionFactory").getConnection().
			}catch(Exception e){
				e.printStackTrace();
				v_message=e.getMessage();
				//throw new Exception(e.getMessage());
			}
			if(v_message==null){
				v_message="";
			}
			String v_success_str="";
			//对v_message和v_success进行处理
			//if("_success:".equals(v_message)){
			if(v_message.contains("_success:")){
				v_success_str=v_message.substring(v_message.length()-1);
				//v_success= Integer.parseInt(v_success_str);
				v_message=v_message.substring(0, v_message.lastIndexOf("_success"));
			}
			//  --(2)、构建应答电文对象（电文格式见接口文档对应电文格式部分）
			v_rec_asw.setSend_time(new Date());//--发送时间
			v_rec_asw.setSend_opr("L3Asw");//--发送人
			v_rec_asw.setPlan_no(v_rec_revoke.getPlan_no());//--计划号
			v_rec_asw.setSeq_no(v_rec_revoke.getSeq_no());// --序号
			v_rec_asw.setUnit_code(v_rec_revoke.getUnit_code());//--机组代码（区分厂家：艾伯纳、中冶南方、宝信）
			v_rec_asw.setIn_mat_no(v_rec_revoke.getIn_mat_no());//--入口钢卷号
			if("1".equals(v_success_str)){
				v_rec_asw.setFlag("0");//--处理标志（0：成功、1：不成功）
			}else{
				v_rec_asw.setFlag("1");//--处理标志（0：成功、1：不成功）
			}
			v_rec_asw.setDeal_result("");// --处理结果（异常处理原因描述）
			//  --(3)、调用L3应答L2计划信息处理函数
			String v_message2="";
			try{
				v_message2=this.getBean(MesApiAnnealPdiPdoImpl.class).Baf01L3AswL2Revoke(v_rec_asw, v_message2);
			}catch(Exception e){
				e.printStackTrace();
				v_message2=e.getMessage();
			}
			//  --(4)、拼接返回字符串
			String v_param="作业计划号{"+v_rec_asw.getPlan_no()+"}入口钢卷号{"+v_rec_asw.getIn_mat_no()+"}机台代码{"+v_rec_asw.getUnit_code()+"}";
			//  --(5)、写接口日志：与业务处理分开，单独的事务
			try{
				 this.getMapper(IfBaf01LogMapper.class).doInsert(null,"Baf01L3AswL2Revoke",v_param,v_message2);
			}catch(Exception e){
				e.printStackTrace();
			}
		}catch(Exception e){
			e.printStackTrace();
			if(e.getMessage()!=null && e.getMessage().length()>200){
				v_message="L2RevokeBaf01Pdi_D处理出错："+e.getMessage().substring(0,200);
			}else{
				v_message="L2RevokeBaf01Pdi_D处理出错："+e.getMessage();
			}
			throw new Exception(v_message);
		}
		return v_message;
	}
	
	/**
	 * 	1)、	此函数为JAVA后台内调函数，可考虑将方法设为私有，由接口 L2RevokeBaf01Pdi 调用；																																							
		2)、	接口参数 IN：V_REC_REVOKE（L2计划钢卷删除实体对象实例）																																							
		3)、	接口参数 OUT：V_MESSAGE（操作结果信息）																																							
	 * @param v_rec_revoke
	 * @param v_message
	 * @return
	 * @throws Exception
	 */
	@Transactional(propagation = Propagation.REQUIRES_NEW,value="tm", rollbackFor=Exception.class)
	public String L2RevokeBaf01Pdi_D_D(IfBaf01RevokeL2 v_rec_revoke,Integer v_success,
			String v_message) throws Exception {
		//  --(0)、置输出参数：操作成功标志为0：失败
		v_success=0;
		try{
			String plan_no=v_rec_revoke.getPlan_no()==null?"":v_rec_revoke.getPlan_no();
			String in_mat_no=v_rec_revoke.getIn_mat_no()==null?"":v_rec_revoke.getIn_mat_no();//入口钢卷号
			// --(1)、验证作业计划存在
			List<PlnAnnealPlanDetail> v_rec_pln_d=this.getMapper(PlnAnnealPlanDetailMapper.class).doQuery2(plan_no,in_mat_no);
			if(v_rec_pln_d==null || v_rec_pln_d.size()<=0){
				v_message="罩退作业计划不存在！";
				return v_message+"_success:"+v_success;
			}
			//  --(2)、验证已下发过PDI
			if(v_rec_pln_d.get(0).getSend_flag()==null || "0".equals(v_rec_pln_d.get(0).getSend_flag())){
				v_message="还未下发PDI！";
				return v_message+"_success:"+v_success;
			}
			//  --(4)、验证当前还未生产交工
			List<MesCrAnnealM> v_rec_anl_m = this.getMapper(MesCrAnnealMMapper.class).findWithCondition(null, "schedule_no='"+plan_no+"' and material_no='"+in_mat_no+"'", null, 0, 0);
			if(v_rec_anl_m!=null && v_rec_anl_m.size()>0){
				if("1".equals(v_rec_anl_m.get(0).getHand_over_status())){
					v_message="已生产交工，不能删除钢卷！";
					return v_message+"_success:"+v_success;
				}
			}
			
			//  --(3)、修改作业计划表下发L2状态
			this.getMapper(PlnAnnealPlanDetailMapper.class).doUpdate3(v_rec_revoke.getPlan_no(),v_rec_revoke.getIn_mat_no());
			//  --(4)、提交事务
			//唯一标示操作成功的地方
			v_success=1;
			v_message="L2计划钢卷删除处理完成！"+"_success:"+v_success;
		}catch(Exception e){
			e.printStackTrace();
			if(e.getMessage()!=null && e.getMessage().length()>200){
				v_message="L2计划钢卷删除处理出错："+e.getMessage().substring(0,200)+"_success:"+v_success;
			}else{
				v_message="L2计划钢卷删除处理出错："+e.getMessage()+"_success:"+v_success;
			}
			throw new Exception(v_message);
		}
		return v_message;
	}
	
	/**
	 * 	1)、	此函数为JAVA后台内调函数，可考虑将方法设为私有，由接口 L2RevokeBaf01Pdi_D 调用；																																							
	    2)、	接口参数 IN：V_REC_ASW（L3应答L2计划信息电文对象）																																							
	    3)、	接口参数 OUT：V_MESSAGE（操作结果信息）																																							
	 * @param v_rec_asw
	 * @param v_message
	 * @throws Exception
	 */
	@Transactional(propagation = Propagation.REQUIRES_NEW,value="tm", rollbackFor=Exception.class)
	public String Baf01L3AswL2Revoke(IfBaf01L3AswL2Plan v_rec_asw,
			String v_message) throws Exception{
		Integer v_flag=null;// --电文发送成功标志
		try{
			//  --(1)、无接口调试时，设置1，直接跳过，否则设置为0
			v_flag=0;//
			//  --(2)、调用公司接口，将“L3应答L2计划信息电文” v_rec_asw 发送给L2（获取接口执行成功状态：v_flag，错误信息：v_message）
			JsonConfig jsonConfig=new JsonConfig();
			jsonConfig.registerJsonValueProcessor(java.util.Date.class, new DateJsonValueProcessor("yyyy-MM-dd HH:mm:ss"));
			jsonConfig.registerJsonValueProcessor(java.lang.Double.class, new DoubleJsonValueProcessor());
			jsonConfig.registerJsonValueProcessor(java.lang.Long.class, new LongJsonValueProcessor());
			jsonConfig.registerJsonValueProcessor(java.lang.Integer.class, new IntegerJsonValueProcessor());
			JSONObject jsonObject=JSONObject.fromObject(v_rec_asw,jsonConfig);
			System.out.println(jsonObject.toString());
			try{
				String url="";
				if("M0004".equals(v_rec_asw.getUnit_code())){
					url = ANNEALPDI3;
				}else if("M0006".equals(v_rec_asw.getUnit_code())){
					url = ANNEALPDI3_AI;
				}else if("M0005".equals(v_rec_asw.getUnit_code()) || "M0009".equals(v_rec_asw.getUnit_code())){
					url = ANNEALPDI3_NAN;
				}
				log.debug("url:"+url);
				
				String body = jsonObject.toString();
		        RestfulHttpClient.HttpResponse response = RestfulHttpClient.getClient(url)
		                .post()              //设置post请求
		                .addPostParam("body", "json")
		                .body(body)
		                .addHeader("Content-type", "application/json")   //添加header
		                //.addPathParam("id", "2")        //设置url路径参数
		                //.addQueryParam("test", "value") //设置url请求参数
		                .request();         //发起请求
		        System.out.println(response.getCode());     //响应状态码
		        System.out.println(response.getRequestUrl());//最终发起请求的地址
		        if(response.getCode() == 200){
		            //请求成功
		            //System.out.println(response.getContent());  //响应内容
		            log.debug("responseCONTENT:"+response.getContent());
		            if(response.getContent()!=null && (response.getContent().contains("vsuccess")|| response.getContent().contains("成功"))){//成功往L2的pdi表中插入数据
		            	v_flag=1;
		            	v_message="L3应答L2计划信息电文成功！";
		            }else{
		            	if(response.getContent()!=null && response.getContent().length()>200){
		    				v_message="L3应答L2计划信息电文，插入失败！【"+response.getContent().substring(0,200)+"】";
		    			}else{
		    				v_message="L3应答L2计划信息电文，插入失败！【"+response.getContent()+"】";
		    			}
		            }
		            //v_message="原料卷号{"+v_rec_mat_d.get(0).getObject_no()+"}已下发PDI给L2！";
		        }else{
		        	v_message="L3应答L2计划信息电文失败！发送请求失败！";
		        }
			}catch(Exception e){
				e.printStackTrace();
				v_message="【通讯过程出错："+e.getMessage()+"】";
			}
			//  --(2.1)、电文发送失败（失败状态，根据接口提供定义确定）
			if(v_flag==0){
				v_message="Baf01L3AswL2Revoke L3应答L2计划信息电文发送失败！"+v_message;
				return v_message;
			}
			//  --(3)、开始事物：插入接口记录表相关信息																																							
			//  --(3.1)、插入 IF_BAF01_L3_ASW_L2_PLAN L3应答L2计划信息电文发送记录																																							
			this.getMapper(IfBaf01L3AswL2PlanMapper.class).insert(v_rec_asw);
			//  --(4)、提交事务
			v_message="Baf01L3AswL2Revoke L3应答L2计划信息电文发送成功！";
		}catch(Exception e){
			e.printStackTrace();
		    //--(5)、捕获未定义的异常，提示信息最多200字符																																							
		    //--(5.1)、电文发送成功（成功状态，根据接口提供定义确定）																																							
			if(v_flag==1){
				// --部分成功（电文已下发成功，但记录未写成功）
				if(e.getMessage()!=null && e.getMessage().length()>200){
					v_message="Baf01L3AswL2Revoke L3应答L2计划信息电文发送成功："+e.getMessage().substring(0,200);
				}else{
					v_message="Baf01L3AswL2Revoke L3应答L2计划信息电文发送成功："+e.getMessage();
				}
			}else{
				if(e.getMessage()!=null && e.getMessage().length()>200){
					v_message="Baf01L3AswL2Revoke L3应答L2计划信息电文发送失败："+e.getMessage().substring(0,200);
				}else{
					v_message="Baf01L3AswL2Revoke L3应答L2计划信息电文发送失败："+e.getMessage();
				}
			}
			throw new Exception(v_message);
		}
		return v_message;
	}
	
	/**
		1)、	此接口为纯后台逻辑，不与前端页面交互，收到罩退L2产出实绩电文时调用；																																							
		2)、	此接口参数为JSON对象（对象结构见数据库表 IF_BAF01_PDO_M）；																																							
	 * @param json
	 * @return
	 */
	public String ReceiveBaf01Pdo_M(IfBaf01PdoM json) throws Exception{
		String v_message="";
		if(json==null || "".equals(json.toString())){
			v_message="二级接口-宝信罩退炉PDO-产出实绩为空";
			return v_message;
		}
		//  --(1)、函数参数为JSON对象，先转换为Java实体类，此处以 v_rec_pdo 代替描述
		//暂定
		IfBaf01PdoM v_rec_pdo=json;
		//  --(2)、如果电文中（接口参数）未包含消息时间（MSG_TIME），或为空值，则赋值为当前时刻
		if(v_rec_pdo.getMsg_time()==null){
			v_rec_pdo.setMsg_time(new Date());
		}
		//  --(3)、将对象，插入L2产出实绩表（单独的事务）  
		try{
			this.getMapper(IfBaf01PdoMMapper.class).insert(v_rec_pdo);
		}catch(Exception e){
			e.printStackTrace();
		}
		//  --(4)、调用处理L2产出实绩函数（事务在函数内）
		try{
			v_message=this.getBean(MesApiAnnealPdiPdoImpl.class).ReceiveBaf01Pdo_M_D(v_rec_pdo, v_message);
		}catch(Exception e){
			e.printStackTrace();
			v_message=e.getMessage();
		}
		//  --(5)、拼接接口参数字符串
		String  v_params = "作业计划号1{"+v_rec_pdo.getPlan_no_1()+"} "+"入口钢卷号1{" +																																							
	              v_rec_pdo.getIn_mat_no_1()+"} "+"炉内序号1{" +																																							
	              v_rec_pdo.getIn_fur_seq_1()+"} "+"作业计划号2{" +																																							
	              v_rec_pdo.getPlan_no_2()+"} "+"入口钢卷号2{" +																																							
	              v_rec_pdo.getIn_mat_no_2()+"} "+"炉内序号2{" +																																							
	              v_rec_pdo.getIn_fur_seq_2()+"} "+"作业计划号3{" +																																							
	              v_rec_pdo.getPlan_no_3()+"} "+"入口钢卷号3{" +																																							
	              v_rec_pdo.getIn_mat_no_3()+"} "+"炉内序号3{" +																																							
	              v_rec_pdo.getIn_fur_seq_3()+"} "+"作业计划号4{" +																																							
	              v_rec_pdo.getPlan_no_4()+"} "+"入口钢卷号4{" +																																							
	              v_rec_pdo.getIn_mat_no_4()+"} "+"炉内序号4{" +																																							
	              v_rec_pdo.getIn_fur_seq_4()+"} "+"作业计划号5{" +																																							
	              v_rec_pdo.getPlan_no_5()+"} "+"入口钢卷号5{" +																																							
	              v_rec_pdo.getIn_mat_no_5()+"} "+"炉内序号5{" +																																							
	              v_rec_pdo.getIn_fur_seq_5()+"} "+"作业计划号6{" +																																							
	              v_rec_pdo.getPlan_no_6()+"} "+"入口钢卷号6{" +																																							
	              v_rec_pdo.getIn_mat_no_6()+"} "+"炉内序号6{" +																																							
	              v_rec_pdo.getIn_fur_seq_6()+"} "+"作业计划号7{" +																																							
	              v_rec_pdo.getPlan_no_7()+"} "+"入口钢卷号7{" +																																							
	              v_rec_pdo.getIn_mat_no_7()+"} "+"炉内序号7{" +																																							
	              v_rec_pdo.getIn_fur_seq_7()+"} "+"作业计划号8{" +																																							
	              v_rec_pdo.getPlan_no_8()+"} "+"入口钢卷号8{" +																																							
	              v_rec_pdo.getIn_mat_no_8()+"} "+"炉内序号8{" +																																							
	              v_rec_pdo.getIn_fur_seq_8()+"} "+"炉次号{" +																																							
	              v_rec_pdo.getFurnace_batch_no()+"}"; 																																			
		//  --(6)、写接口日志：与业务处理分开，单独的事务
		try{
			List<MesCrAnnealM> list = this.getMapper(MesCrAnnealMMapper.class).findWithCondition(null, "material_no='"+v_rec_pdo.getIn_mat_no_1()+"'", "", 0, 0);
			if(list!=null && list.size()>0){
				v_params="机台代码【"+list.get(0).getMachine_code()+"】"+v_params;
			}
			this.getMapper(IfBaf01LogMapper.class).doInsert(null,"ReceiveBaf01Pdo_M",v_params,v_message);
		}catch(Exception e){
			e.printStackTrace();
		}
		return v_message;
	}
		
	
	/**
	 * 	1)、	此函数为JAVA后台内调函数，可考虑将方法设为私有，由接口 ReceiveBaf01Pdo_M 调用；																																							
		2)、	接口参数 IN：V_REC_PDO（L2产出实绩对象实例）																																							
		3)、	接口参数 OUT：V_MESSAGE（操作结果信息）																																							
	 * @param v_rec_pdo
	 * @param v_message
	 * @return
	 * @throws Exception 
	 */
	@Transactional(value="tm", rollbackFor=Exception.class)
	public String ReceiveBaf01Pdo_M_D(IfBaf01PdoM v_rec_pdo, String v_message) throws Exception {
		Integer v_cnt;
		//  --(1)、根据电文中，构建作业计划号、钢卷号、炉内序号集合
		List<String> v_plan_no=new ArrayList<>();
		List<String> v_material_no=new ArrayList<>();
		List<Long> v_fur_seq=new ArrayList<>();
		try{
			
		//  --炉内第1卷（炉内位置由下往上递增）
		if(v_rec_pdo.getPlan_no_1()!=null && v_rec_pdo.getIn_mat_no_1()!=null
				&& !"".equals(v_rec_pdo.getPlan_no_1()) && !"".equals(v_rec_pdo.getIn_mat_no_1())){
			v_plan_no.add(v_rec_pdo.getPlan_no_1());
			v_material_no.add(v_rec_pdo.getIn_mat_no_1());
			v_fur_seq.add(v_rec_pdo.getIn_fur_seq_1());
		}
		//  --炉内第2卷（炉内位置由下往上递增）
		if(v_rec_pdo.getPlan_no_2()!=null && v_rec_pdo.getIn_mat_no_2()!=null
				&& !"".equals(v_rec_pdo.getPlan_no_2()) && !"".equals(v_rec_pdo.getIn_mat_no_2())){
			v_plan_no.add(v_rec_pdo.getPlan_no_2());
			v_material_no.add(v_rec_pdo.getIn_mat_no_2());
			v_fur_seq.add(v_rec_pdo.getIn_fur_seq_2());
		}
		//  --炉内第3卷（炉内位置由下往上递增）
		if(v_rec_pdo.getPlan_no_3()!=null && v_rec_pdo.getIn_mat_no_3()!=null
				&& !"".equals(v_rec_pdo.getPlan_no_3()) && !"".equals(v_rec_pdo.getIn_mat_no_3())){
			v_plan_no.add(v_rec_pdo.getPlan_no_3());
			v_material_no.add(v_rec_pdo.getIn_mat_no_3());
			v_fur_seq.add(v_rec_pdo.getIn_fur_seq_3());
		}
		//  --炉内第4卷（炉内位置由下往上递增）
		if(v_rec_pdo.getPlan_no_4()!=null && v_rec_pdo.getIn_mat_no_4()!=null
				&& !"".equals(v_rec_pdo.getPlan_no_4()) && !"".equals(v_rec_pdo.getIn_mat_no_4())){
			v_plan_no.add(v_rec_pdo.getPlan_no_4());
			v_material_no.add(v_rec_pdo.getIn_mat_no_4());
			v_fur_seq.add(v_rec_pdo.getIn_fur_seq_4());
		}
		//  --炉内第5卷（炉内位置由下往上递增）
		if(v_rec_pdo.getPlan_no_5()!=null && v_rec_pdo.getIn_mat_no_5()!=null
				&& !"".equals(v_rec_pdo.getPlan_no_5()) && !"".equals(v_rec_pdo.getIn_mat_no_5())){
			v_plan_no.add(v_rec_pdo.getPlan_no_5());
			v_material_no.add(v_rec_pdo.getIn_mat_no_5());
			v_fur_seq.add(v_rec_pdo.getIn_fur_seq_5());
		}		
		//  --炉内第6卷（炉内位置由下往上递增）
		if(v_rec_pdo.getPlan_no_6()!=null && v_rec_pdo.getIn_mat_no_6()!=null
				&& !"".equals(v_rec_pdo.getPlan_no_6()) && !"".equals(v_rec_pdo.getIn_mat_no_6())){
			v_plan_no.add(v_rec_pdo.getPlan_no_6());
			v_material_no.add(v_rec_pdo.getIn_mat_no_6());
			v_fur_seq.add(v_rec_pdo.getIn_fur_seq_6());
		}
		//  --炉内第7卷（炉内位置由下往上递增）
		if(v_rec_pdo.getPlan_no_7()!=null && v_rec_pdo.getIn_mat_no_7()!=null
				&& !"".equals(v_rec_pdo.getPlan_no_7()) && !"".equals(v_rec_pdo.getIn_mat_no_7())){
			v_plan_no.add(v_rec_pdo.getPlan_no_7());
			v_material_no.add(v_rec_pdo.getIn_mat_no_7());
			v_fur_seq.add(v_rec_pdo.getIn_fur_seq_7());
		}	
		//  --炉内第8卷（炉内位置由下往上递增）
		if(v_rec_pdo.getPlan_no_8()!=null && v_rec_pdo.getIn_mat_no_8()!=null
				&& !"".equals(v_rec_pdo.getPlan_no_8()) && !"".equals(v_rec_pdo.getIn_mat_no_8())){
			v_plan_no.add(v_rec_pdo.getPlan_no_8());
			v_material_no.add(v_rec_pdo.getIn_mat_no_8());
			v_fur_seq.add(v_rec_pdo.getIn_fur_seq_8());
		}		
		if(v_plan_no.size()<=0){
			v_message="电文中未包含钢卷信息，无法处理！";
			return v_message;
		}
		//  --(1.1)、根据生产开始时刻，计算投料日期、班次
		Date v_charge_time=null;
		if(v_rec_pdo.getStart_prod_time()==null || "".equals(v_rec_pdo.getStart_prod_time())){
			v_message="电文中生产开始时间为空，无法计算投料日期班次！";
			return v_message;
		}else{
			//    --将生产开始时间的字符串，转换日期时间格式（可以在JAVA中转化，此处以PLSQL处理代替描述）
			try {
				//v_charge_time = DateUtil.formatString(v_rec_pdo.getStart_prod_time(), "yyyyMMddHHmmss");
				List<MesCrAnnealM> li =this.getMapper(MesCrAnnealMMapper.class).doQueryDate(v_rec_pdo.getStart_prod_time());
				v_charge_time=li.get(0).getCreate_time();
			} catch (Exception e) {
				e.printStackTrace();
				v_message="电文中生产开始时间{"+v_rec_pdo.getStart_prod_time()+"} 格式转化失败，无法计算投料日期班次！约定的标准格式【yyyyMMddHHmmss】";
				return v_message;
			}
		}
		String rmDb=DateUtil.formatDate(v_charge_time, "yyyy-MM-dd HH:mm:ss");
		String v_charge_date=null,v_charge_ord=null;
		String dbTime=rmDb.substring(11);
		v_charge_date=rmDb.substring(0,10);
		// --(1.1.1)、如果 v_charge_time 的时间>=00:00:00并且<08:00:00，则 作业日期 = v_charge_time 的日期（格式化为yyyy-MM-dd），班次 = "1"，即表示当天晚班；
		if(dbTime.compareTo(DateUtil.NBeginTime)>-1&&dbTime.compareTo(DateUtil.BeginTime)<0){
			v_charge_ord="1";
		}else if(dbTime.compareTo(DateUtil.BeginTime)>-1&&dbTime.compareTo(DateUtil.EndTime)<0){
			v_charge_ord="2";
		}else if(dbTime.compareTo(DateUtil.EndTime)>-1&&dbTime.compareTo(DateUtil.NEndTime)<0){
			v_charge_ord="1";
			SimpleDateFormat formatYmd = new SimpleDateFormat("yyyy-MM-dd");
			Date date;
			try {
				date = formatYmd.parse(v_charge_date);
			} catch (Exception e) {
				return "获取数据库时间失败，请稍后重试";
			}
			Calendar c = Calendar.getInstance();  
	        c.setTime(date);  
	        c.add(Calendar.DAY_OF_MONTH, 1);//日期+1 
	        v_charge_date=formatYmd.format(c.getTime());
		}
		//  --(1.2)、根据生产结束时刻，计算产出日期、班次
		Date v_discharge_time=null;
		if(v_rec_pdo.getEnd_prod_time()==null || "".equals(v_rec_pdo.getEnd_prod_time())){
			v_message="电文中生产结束时间为空，无法计算产出日期班次！";
			return v_message;
		}else{
			//    --将生产结束时间的字符串，转换日期时间格式（可以在JAVA中转化，此处以PLSQL处理代替描述）
			try {
				//v_discharge_time = DateUtil.formatString(v_rec_pdo.getEnd_prod_time(), "yyyyMMddHHmmss");
				List<MesCrAnnealM> li =this.getMapper(MesCrAnnealMMapper.class).doQueryDate(v_rec_pdo.getEnd_prod_time());
				v_discharge_time=li.get(0).getCreate_time();
				//L2发送的生产结束时间不准，生产结束时间   ！！！！！
				
			} catch (Exception e) {
				e.printStackTrace();
				v_message="电文中生产结束时间{"+v_rec_pdo.getEnd_prod_time()+"} 格式转化失败，无法计算产出日期班次！约定的标准格式【yyyyMMddHHmmss】";
				return v_message;
			}
		}
		String rmDb2=DateUtil.formatDate(v_discharge_time, "yyyy-MM-dd HH:mm:ss");
		String v_discharge_date=null,v_discharge_ord=null;
		String dbTime2=rmDb2.substring(11);
		v_discharge_date=rmDb2.substring(0,10);
		// --(1.2.1)、如果 v_discharge_time 的时间>=00:00:00并且<08:00:00，则 作业日期 = v_discharge_time 的日期（格式化为yyyy-MM-dd），班次 = "1"，即表示当天晚班；
		if(dbTime2.compareTo(DateUtil.NBeginTime)>-1&&dbTime2.compareTo(DateUtil.BeginTime)<0){
			v_discharge_ord="1";
		}else if(dbTime2.compareTo(DateUtil.BeginTime)>-1&&dbTime2.compareTo(DateUtil.EndTime)<0){
			v_discharge_ord="2";
		}else if(dbTime2.compareTo(DateUtil.EndTime)>-1&&dbTime2.compareTo(DateUtil.NEndTime)<0){
			v_discharge_ord="1";
			SimpleDateFormat formatYmd = new SimpleDateFormat("yyyy-MM-dd");
			Date date;
			try {
				date = formatYmd.parse(v_discharge_date);
			} catch (Exception e) {
				return "获取数据库时间失败，请稍后重试";
			}
			Calendar c = Calendar.getInstance();  
	        c.setTime(date);  
	        c.add(Calendar.DAY_OF_MONTH, 1);//日期+1 
	        v_discharge_date=formatYmd.format(c.getTime());
		}
		
		//2019-02-21
		/*
		检验批分批规则：
			同炉次号向下相同牌号、相同尺寸（厚度、宽度）的物料集合生成一个检验批号
			检验批号编码规则：炉次号+两位流水号，示例：2619000401） 
		 */
		List<MesCrAnnealM> v_rec_baf_mList = this.getMapper(MesCrAnnealMMapper.class).findWithCondition(null,"batch_no='"+v_rec_pdo.getFurnace_batch_no()+"'", null, 0, 0);
		Map<String, List<MesCrAnnealM>> mc_list =new HashMap<String, List<MesCrAnnealM>>();
		if(v_rec_baf_mList!=null && v_rec_baf_mList.size()>0){
				try{
					mc_list = groupBillingDataByExcpBatchCode(v_rec_baf_mList);
				}catch(Exception e){
					
				}
		}
				
		
		
		//质量检验委托
		List<QcmJhySampleFromPlan> lqsfp=new ArrayList<>();
		//  --处理逻辑思路：类似页面“上料”按钮操作的相关处理逻辑
		//  --(2)、循环 { 作业计划号、原料卷号 } 集合中各元素
		//for(String plan_no:v_plan_no){
		for(int i=0;i<v_plan_no.size();i++){
			//    --(2.1)、验证罩退作业计划主记录存在
			v_cnt = this.getMapper(PlnAnnealPlanMapper.class).countWithCondition(null, "an_plan_no='"+v_plan_no.get(i)+"'");
			if(v_cnt<=0){
				v_message="作业计划号{"+v_plan_no.get(i)+"} 作业计划主记录不存在！";
				throw new Exception(v_message);
			}
			//    --(2.2)、验证罩退作业计划明细记录存在
			v_cnt=this.getMapper(PlnAnnealPlanDetailMapper.class).countWithCondition(null, "an_plan_no='"+v_plan_no.get(i)+"' and object_no='"+v_material_no.get(i)+"'");
			if(v_cnt<=0){
				v_message="作业计划号{"+v_plan_no.get(i)+"} 原料卷号{"+v_material_no.get(i)+"} 作业计划明细记录不存在！";
				throw new Exception(v_message);
			}else if(v_cnt>1){
				//      --计划表 pln_anneal_plan_detail 未设置唯一约束，考虑极端情况下程序BUG导致的数据错误
				v_message="作业计划号{"+v_plan_no.get(i)+"} 原料卷号{"+v_material_no.get(i)+"} 存在一条以上作业计划明细记录，无法处理！";
				throw new Exception(v_message);
			}
			List<PlnAnnealPlanDetail> v_rec_pln_d_list = this.getMapper(PlnAnnealPlanDetailMapper.class).findWithCondition(null, "an_plan_no='"+v_plan_no.get(i)+"' and object_no='"+v_material_no.get(i)+"'", null, 0, 0);
			PlnAnnealPlanDetail v_rec_pln_d=v_rec_pln_d_list.get(0);
			//    --(2.3)、如果已有生产实绩（人工操作或L2重复发送PDO情况下），且已交工，则返回（忽略此PDO生产主实绩）
			List<MesCrAnnealM> v_rec_baf_m_list = this.getMapper(MesCrAnnealMMapper.class).findWithCondition(null,"schedule_no='"+v_plan_no.get(i)+"' and material_no='"+v_material_no.get(i)+"'", null, 0, 0);
			MesCrAnnealM v_rec_baf_m=new MesCrAnnealM();
			MesCrAnnealM v_rec_baf_m_last=new MesCrAnnealM();
			if(v_rec_baf_m_list!=null && v_rec_baf_m_list.size()>0){
				if("1".equals(v_rec_baf_m_list.get(0).getHand_over_status())){
					v_message="作业计划号{"+v_plan_no.get(i)+"} 原料卷号{"+v_material_no.get(i)+"} 已生产交工，忽略此PDO生产主实绩！";
					throw new Exception(v_message);
				}
				v_rec_baf_m=v_rec_baf_m_list.get(0);
				v_rec_baf_m_last=v_rec_baf_m_list.get(0);
			}
			
			
			//    --(2.4)、验证机台基础信息存在
			v_cnt = this.getMapper(ComBaseMachineMapper.class).countWithCondition(null,"machine_code='"+v_rec_pln_d.getMachine_code()+"'");
			if(v_cnt<=0){
				v_message="作业计划号{"+v_plan_no.get(i)+"} 原料卷号{"+v_material_no.get(i)+"} 机台代码{"+v_rec_pln_d.getMachine_code()+"} 机台基础信息不存在！";
				throw new Exception(v_message);
			}
			//    --（2.5)、获取机台基础信息表中，配置的机台设备代号（设备编号，如1,2,3）
			List<ComBaseMachine> lcbm = this.getMapper(ComBaseMachineMapper.class).findWithCondition(null,
					"machine_code='"+v_rec_pln_d.getMachine_code()+"'", null, 0, 0);
			String v_mch_mark=lcbm.get(0).getMachine_mark();
			if(v_mch_mark==null){
				v_message="作业计划号{"+v_plan_no.get(i)+"} 原料卷号{"+v_material_no.get(i)+"} 机台代码{"+v_rec_pln_d.getMachine_code()+"} 设备编号未配置，无法处理！";
				throw new Exception(v_message);
			}
			//    --(2.6)、验证虚拟物料表中，原料卷计划信息存在
			List<PlnMaterielDetail> v_rec_mtr_in = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,"object_no_vt='"+v_rec_pln_d.getObject_no_vt()+"'", null, 0, 0);
			if(v_rec_mtr_in==null || v_rec_mtr_in.size()<=0){
				v_message="作业计划号{"+v_plan_no.get(i)+"} 原料卷号{"+v_material_no.get(i)+"} 虚拟卷号{"+v_rec_pln_d.getObject_no_vt()+"} 原料卷虚拟物料信息不存在！";
				throw new Exception(v_message);
			}
			//    --(2.7)、验证原料卷号库存明细记录存在
			List<YdmProductDetail> v_rec_ydm_d = this.getMapper(YdmProductDetailMapper.class).findWithCondition(null, "coilno='"+v_material_no.get(i)+"'", null, 0, 0);
			if(v_rec_ydm_d==null || v_rec_ydm_d.size()<=0){
				v_message="作业计划号{"+v_plan_no.get(i)+"} 原料卷号{"+v_material_no.get(i)+"} 原料卷库存明细记录不存在！";
				throw new Exception(v_message);
			}
			//验证原料卷号库存明细记录为“在库”状态 ??
			
			//    --(2.8)、验证虚拟物料表中，出口卷虚拟物料信息存在
			PlnMaterielDetail pmd2=new PlnMaterielDetail();
			pmd2.setMat_object_no_vt(v_rec_pln_d.getObject_no_vt());
			v_cnt = this.getMapper(PlnMaterielDetailMapper.class).count(pmd2);
			if (v_cnt<=0) {
				v_message="作业计划号{"+v_plan_no.get(i)+"} 原料卷号{"+v_material_no.get(i)+"} 虚拟卷号{"+v_rec_pln_d.getObject_no_vt()+"} 出口卷虚拟物料信息不存在！";
				throw new Exception(v_message);
			}
			
			//2018-11-29 只有是已下发状态的钢卷才能下发
			if(v_rec_pln_d!=null){
				if(!("5BAN02".equals(v_rec_pln_d.getStatus()) || "5BAN03".equals(v_rec_pln_d.getStatus()))){
					v_message="当前状态{"+v_rec_pln_d.getStatus()+"}错误";
					return v_message;
				}
			}
			
			List<PlnMaterielDetail> v_rec_mtr_out=this.getMapper(PlnMaterielDetailMapper.class).doQueryWeb2(v_rec_pln_d.getObject_no_vt(),"");
			//    --(2.9)、根据计算的投料日期班次，获取交接班记录的班组 
			MesShiftM msm=new MesShiftM();
			if(v_rec_pln_d.getMachine_code().equals("M0009")){
				msm.setMachine_code("M0005");
			}else{
				msm.setMachine_code(v_rec_pln_d.getMachine_code());
			}
			msm.setWrk_date(v_charge_date);
			msm.setWrk_ord(v_charge_ord);
			v_cnt=this.getMapper(MesShiftMMapper.class).count(msm);
			String v_charge_grp=null;
			if(v_cnt<=0){
				 v_charge_grp="";// --无交接班记录，则赋空值（交工时，会提示用户完善信息）
			}else{
				//    --否则获取交接班记录中的班组
				List<MesShiftM> lmsm = this.getMapper(MesShiftMMapper.class).find(msm, 0, 0);
				v_charge_grp=lmsm.get(0).getWrk_grp();
			}
			//    --(2.10)、根据计算的产出日期班次，获取交接班记录的班组
			MesShiftM msm2=new MesShiftM();
			if(v_rec_pln_d.getMachine_code().equals("M0009")){
				msm2.setMachine_code("M0005");
			}else{
				msm2.setMachine_code(v_rec_pln_d.getMachine_code());
			}
			msm2.setWrk_date(v_discharge_date);
			msm2.setWrk_ord(v_discharge_ord);
			v_cnt=this.getMapper(MesShiftMMapper.class).count(msm2);
			String v_discharge_grp=null;
			if(v_cnt<=0){
				  String l2_grp=v_rec_pdo.getProd_shift_group(); //--无交接班记录，是使用电文中的生产班别
				  if("A".equals(l2_grp)){
					  v_discharge_grp = "1"; //--无交接班记录，是使用电文中的生产班别
				  }else if("B".equals(l2_grp)){
					  v_discharge_grp = "2"; //--无交接班记录，是使用电文中的生产班别
				  }else if("C".equals(l2_grp)){
					  v_discharge_grp = "3"; //--无交接班记录，是使用电文中的生产班别
				  }else if("D".equals(l2_grp)){
					  v_discharge_grp = "4"; //--无交接班记录，是使用电文中的生产班别
				  }
			}else{
				//    --否则获取交接班记录中的班组
				List<MesShiftM> lmsm = this.getMapper(MesShiftMMapper.class).find(msm2, 0, 0);
				v_discharge_grp=lmsm.get(0).getWrk_grp();
			}
			//    --(2.11)、出口卷编码前缀：原料卷号（最初始原料卷号） + 1位工序代号（退火T）+ 2位设备代号（01-99）
			//String v_coil_no = v_material_no.get(i).substring(0, 8) + "T"+ lpad(v_mch_mark, 2, "0");
//			String v_coil_no=null;
//			if(v_rec_pdo.getFurnace_no()!=null && !"".equals(v_rec_pdo.getFurnace_no())){
//				v_coil_no = v_material_no.get(i).substring(0, 8) + "T"+ lpad(v_rec_pdo.getFurnace_no(), 2, "0");
//			}else{
//				v_coil_no = v_material_no.get(i).substring(0, 8) + "T"+ lpad(v_mch_mark, 2, "0");
//			}
			String v_coil_no=null;
			String v_leo="";
			if(v_rec_pdo.getFurnace_no()!=null && !"".equals(v_rec_pdo.getFurnace_no())){
				int leo1x = Integer.parseInt(v_rec_pdo.getFurnace_no());
				v_rec_pdo.setFurnace_no(leo1x+"");
				String v_syh=lpad(v_rec_pdo.getFurnace_no(), 2, "0");
				if(v_rec_baf_m.getCoil_no()!=null){
					v_leo=v_rec_baf_m.getCoil_no().substring(v_rec_baf_m.getCoil_no().length()-4, v_rec_baf_m.getCoil_no().length()-2);
					if(!v_syh.equals(v_leo)){
						v_coil_no = v_material_no.get(i).substring(0, 8) + "T"+ lpad(v_rec_pdo.getFurnace_no(), 2, "0");
					}else{
						v_coil_no = v_material_no.get(i).substring(0, 8) + "T"+ lpad(v_rec_pdo.getFurnace_no(), 2, "0");
					}
				}else{
					v_coil_no = v_material_no.get(i).substring(0, 8) + "T"+ lpad(v_rec_pdo.getFurnace_no(), 2, "0");
				}
				
			}else{
				v_coil_no = v_material_no.get(i).substring(0, 8) + "T"+ lpad(v_mch_mark, 2, "0");
			}
			
			
			//    --(2.11.1)、获取当前起始流水号
			v_cnt=this.getMapper(MesCrAnnealMMapper.class).doQueryWeb6(v_coil_no,v_plan_no.get(i),v_material_no.get(i));
			if(v_cnt==null){
				v_cnt=1;
			}else if(v_cnt>99){
				v_message="作业计划号{"+v_plan_no.get(i)+"} 原料卷号{"+v_material_no.get(i)+"} 出口钢卷号超出规则范围，流水号超出最大值99！";
				throw new Exception(v_message);
			}
			//--(2.11.2)、出口卷编码规则：出口卷编码前缀【原料卷号（最初始原料卷号） + 1位工序代号（退火T）+ 2位设备代号（01-99）】+ 2位流水（01 - 99）																																						
			v_coil_no=v_coil_no+lpad(v_cnt+"",2,"0");
			//如果之前有，就用之前的
			if(v_rec_pdo.getFurnace_no()!=null && !"".equals(v_rec_pdo.getFurnace_no())){
				String v_syh=lpad(v_rec_pdo.getFurnace_no(), 2, "0");
				if(v_rec_baf_m.getCoil_no()!=null){
					v_leo=v_rec_baf_m.getCoil_no().substring(v_rec_baf_m.getCoil_no().length()-4, v_rec_baf_m.getCoil_no().length()-2);
					if(v_syh.equals(v_leo)){
						v_coil_no=v_rec_baf_m.getCoil_no();
					}else{
						
					}
					
				}else{
					//v_rec_cam.setCoil_no(v_coil_no);
				}
				
			}
			
			
			
			//    --(2.12)、删除可能存在罩退作业实绩
			this.getMapper(MesCrAnnealMMapper.class).doDelete2(v_plan_no.get(i),v_material_no.get(i));
			
		    //--(2.13)、在 v_rec_baf_m 对象基础上，构建罩退主实绩，并插入记录																																							
		    //--(2.13.1)：v_rec_baf_m 对象可能不为空（之前实绩已存在），则更新部分信息，保留部分信息（未赋值的属性即是保留原有对象的属性值，如：相关事件时刻）																																							
		    //--(2.13.2)：v_rec_baf_m 对象如果为空，请先实例化此对象（plsql示例逻辑无此问题）																																							
			//MesCrAnnealM v_rec_baf_m=new MesCrAnnealM();
			v_rec_baf_m.setSchedule_no ( v_plan_no.get(i)); //作业计划号																																							
			v_rec_baf_m.setMaterial_no ( v_material_no.get(i)); //原料卷号																																							
			v_rec_baf_m.setMaterial_no_vt( v_rec_pln_d.getObject_no_vt()); //虚拟原料卷号																																							
			v_rec_baf_m.setPln_steel_code( v_rec_mtr_in.get(0).getSteel_code()); //计划原料卷牌号																																							
			v_rec_baf_m.setPln_mtr_thk ( v_rec_mtr_in.get(0).getThick()); //计划原料卷厚度																																							
			v_rec_baf_m.setPln_mtr_wdt ( v_rec_mtr_in.get(0).getWidth()); //计划原料卷宽度																																							
			v_rec_baf_m.setPln_mtr_len ( v_rec_mtr_in.get(0).getLength()); //计划原料卷长度																																							
			v_rec_baf_m.setPln_mtr_inn_dia ( v_rec_mtr_in.get(0).getDiameter_inn()); //计划原料卷内径																																							
			v_rec_baf_m.setPln_mtr_out_dia (v_rec_mtr_in.get(0).getDiameter_out()); //计划原料卷外径																																							
			v_rec_baf_m.setPln_mtr_thr_wgt ( v_rec_mtr_in.get(0).getSingle_weight()); //计划原料卷理重																																							
			v_rec_baf_m.setMaterial_no_src ( v_rec_ydm_d.get(0).getMaterailcoilno()); //原始卷号																																							
			v_rec_baf_m.setMtr_thk ( v_rec_ydm_d.get(0).getThick()); //原料卷厚度																																							
			v_rec_baf_m.setMtr_wdt ( v_rec_ydm_d.get(0).getWidth()); //原料卷宽度																																							
			v_rec_baf_m.setMtr_len ( v_rec_ydm_d.get(0).getLength()); //原料卷长度																																							
			v_rec_baf_m.setMtr_inn_dia ( v_rec_ydm_d.get(0).getDiameter_inn()); //原料卷内径																																							
			v_rec_baf_m.setMtr_out_dia ( v_rec_ydm_d.get(0).getDiameter_out()); //原料卷外径																																							
			v_rec_baf_m.setMtr_thr_wgt ( v_rec_ydm_d.get(0).getTheoryweight()); //原料卷理重																																							
			v_rec_baf_m.setMtr_act_wgt ( v_rec_ydm_d.get(0).getFactweight()); //原料卷实重																																							
			v_rec_baf_m.setSteel_code( v_rec_ydm_d.get(0).getSteelcode()); //原料卷牌号																																							
			v_rec_baf_m.setMachine_code( v_rec_pln_d.getMachine_code()); //机台号（区分厂家：艾伯纳、中冶南方、宝信）																																							
			v_rec_baf_m.setBatch_no( v_rec_pdo.getFurnace_batch_no()); //炉批号（2位炉座号+ 2位年份 + 4位流水号）																																							
			v_rec_baf_m.setFurnace_no( v_rec_pdo.getFurnace_no()); //炉座号（1-5 艾伯纳，6-16中冶南方、17-26宝信）																																							
			v_rec_baf_m.setIn_fur_seq( v_fur_seq.get(i)); //炉内位置																																							
			v_rec_baf_m.setStatus( "12"); //状态（00：组垛完成、01：上炉台、02：扣加热罩、03：加热开始、04：加热结束、05：带罩冷却开始、06：带罩冷却结束、07：风冷开始、08：风冷结束、09：水冷开始、10：水冷结束、11：出炉/上终冷台、12：下终冷台）																																							
			v_rec_baf_m.setCharge_date ( v_charge_date); //投料日期（YYYY-MM-DD）																																							
			v_rec_baf_m.setCharge_ord( v_charge_ord); //投料班次（1晚班、2白班、3中班）																																							
			v_rec_baf_m.setCharge_grp( v_charge_grp); //投料班组（1甲班、2乙班、3丙班、4丁班）																																							
			v_rec_baf_m.setCharge_time ( v_charge_time); //投料时间/生产开始时间																																							
			//v_rec_baf_m.setHeat_hood ( v_rec_pdo.getHeat_hood()); //加热罩号	
			if(v_rec_baf_m.getHeat_hood()!=null && !v_rec_baf_m.getHeat_hood().contains("-")){
				
			}else{
				v_rec_baf_m.setHeat_hood ( v_rec_pdo.getHeat_hood()); //加热罩号		
			}
			
			//加热开始时刻（字符串转化为时间，可能为空，做好异常处理）	
			Date event_time_heat_str =null;
			try{
				if(v_rec_pdo.getHeat_start_time()!=null && v_rec_pdo.getHeat_start_time().length()>0){
					List<MesCrAnnealM> li =this.getMapper(MesCrAnnealMMapper.class).doQueryDate(v_rec_pdo.getHeat_start_time());
					if(li!=null && li.size()>0){
						event_time_heat_str=li.get(0).getCreate_time();
					}
				}
			}catch(Exception e){
				e.printStackTrace();
			}
			//v_rec_baf_m.setEvent_time_heat_str ( DateUtil.formatString(v_rec_pdo.getHeat_start_time(), "yyyyMMddHHmmss")); //加热开始时刻（字符串转化为时间，可能为空，做好异常处理）																																							
			v_rec_baf_m.setEvent_time_heat_str (event_time_heat_str); //加热开始时刻（字符串转化为时间，可能为空，做好异常处理）																																							
			
			v_rec_baf_m.setHeating_time( v_rec_pdo.getHeating_time()); //实际升温时间																																							
			v_rec_baf_m.setKeeping_time( v_rec_pdo.getKeeping_time()); //实际保温时间																																							
			v_rec_baf_m.setHoodoff_temp( v_rec_pdo.getHoodoff_temp()); //去加热罩温度																																							
			v_rec_baf_m.setAnneal_diagram_code ( v_rec_pdo.getAnneal_diagram_code()); //退火曲线代码																																							
			v_rec_baf_m.setAnneal_temp_min ( v_rec_pdo.getAnneal_temp_min()); //退火温度最小值																																							
			v_rec_baf_m.setAnneal_temp_avg ( v_rec_pdo.getAnneal_temp_avg()); //退火温度平均值																																							
			v_rec_baf_m.setAnneal_temp_max ( v_rec_pdo.getAnneal_temp_max()); //退火温度最大值	
			//注意！！！！！
			v_rec_baf_m.setCooling_time_hood ( v_rec_pdo.getCooling_time_hood()); //带罩冷却时长（min）																																							
			//v_rec_baf_m.setCool_hood ( v_rec_pdo.getCool_hood()); //冷却罩号
			if(v_rec_baf_m.getCool_hood()!=null && !v_rec_baf_m.getCool_hood().contains("-")){
				
			}else{
				v_rec_baf_m.setCool_hood ( v_rec_pdo.getCool_hood()); //冷却罩号
			}
			//冷却开始时刻（字符串转化为时间，可能为空，做好异常处理）	
			Date cool_start_time =null;
			try{
				if(v_rec_pdo.getCool_start_time()!=null && v_rec_pdo.getCool_start_time().length()>0){
					List<MesCrAnnealM> li =this.getMapper(MesCrAnnealMMapper.class).doQueryDate(v_rec_pdo.getCool_start_time());
					if(li!=null && li.size()>0){
						cool_start_time=li.get(0).getCreate_time();
					}
				}
			}catch(Exception e){
				e.printStackTrace();
			}
			//v_rec_baf_m.setCool_start_time (DateUtil.formatString(v_rec_pdo.getCool_start_time(), "yyyyMMddHHmmss")); //冷却开始时刻（字符串转化为时间，可能为空，做好异常处理）																																							
			v_rec_baf_m.setCool_start_time (cool_start_time);
			
			v_rec_baf_m.setCooling_time( v_rec_pdo.getCooling_time()); //实际冷却时间																																							
			v_rec_baf_m.setCooling_mode( v_rec_pdo.getCooling_mode()); //冷却方式（01：带罩、02：不带罩）																																							
			//v_rec_baf_m.setFc_no ( v_rec_pdo.getFc_no()); //终冷台号	
			if(v_rec_baf_m.getFc_no()!=null && !v_rec_baf_m.getFc_no().contains("-")){
				
			}else{
				v_rec_baf_m.setFc_no ( v_rec_pdo.getFc_no()); //终冷台号		
			}
			
			v_rec_baf_m.setOut_temp_set( v_rec_pdo.getOut_temp_set()); //出炉设定温度		
			//L2发送的生产结束时间不准，生产结束时间   ！！！！！
			v_rec_baf_m.setDischarge_date( v_discharge_date); //产出日期（YYYY-MM-DD）																																							
			v_rec_baf_m.setDischarge_ord ( v_discharge_ord); //产出班次（1晚班、2白班、3中班）																																							
			v_rec_baf_m.setDischarge_grp ( v_discharge_grp); //产出班组（1甲班、2乙班、3丙班、4丁班）																																							
			v_rec_baf_m.setDischarge_time( v_discharge_time); //产出时间/生产结束时间																																							
			v_rec_baf_m.setPersist_prod_time ( v_rec_pdo.getPersist_prod_time()); //生产持续时长																																							
			v_rec_baf_m.setCoil_no ( v_coil_no); //产出卷号																																							
			v_rec_baf_m.setAim_thk ( v_rec_mtr_out.get(0).getThick()); //产出卷目标厚度																																							
			v_rec_baf_m.setAim_wdt ( v_rec_mtr_out.get(0).getWidth()); //产出卷目标宽度																																							
			v_rec_baf_m.setAim_len ( v_rec_mtr_out.get(0).getLength()); //产出卷目标长度																																							
			v_rec_baf_m.setAim_inn_dia ( v_rec_mtr_out.get(0).getDiameter_inn()); //产出卷目标内径																																							
			v_rec_baf_m.setAim_out_dia ( v_rec_mtr_out.get(0).getDiameter_out()); //产出卷目标外径																																							
			v_rec_baf_m.setAct_thk ( v_rec_ydm_d.get(0).getThick()); //产出卷厚度																																							
			v_rec_baf_m.setAct_wdt ( v_rec_ydm_d.get(0).getWidth()); //产出卷宽度																																							
			v_rec_baf_m.setAct_len ( v_rec_ydm_d.get(0).getLength()); //产出卷长度																																							
			v_rec_baf_m.setAct_inn_dia ( v_rec_ydm_d.get(0).getDiameter_inn()); //产出卷内径																																							
			v_rec_baf_m.setAct_out_dia ( v_rec_ydm_d.get(0).getDiameter_out()); //产出卷外径																																							
			v_rec_baf_m.setCoil_thr_wgt( v_rec_ydm_d.get(0).getTheoryweight()); //产出卷理重																																							
			v_rec_baf_m.setCoil_act_wgt( v_rec_ydm_d.get(0).getFactweight()); //产出卷实量																																							
			v_rec_baf_m.setProd_order_no ( v_rec_mtr_out.get(0).getProd_order_no()); //生产订单号																																							
			v_rec_baf_m.setOrder_no( v_rec_mtr_out.get(0).getOrder_no()); //订单号																																							
			v_rec_baf_m.setMemo( null); //备注																																							
			v_rec_baf_m.setHand_over_status( "0"); //交工状态																																							
			v_rec_baf_m.setHand_over_time( null); //交工时间																																							
			v_rec_baf_m.setHand_over_opr ( null); //交工人
			//    --如果 v_rec_baf_m 对象为空（即之前无生产实绩），则：
			if(v_rec_baf_m.getCreate_opr()==null){
				v_rec_baf_m.setCreate_opr("L2_PDO");
				v_rec_baf_m.setCreate_time(new Date());
			}else{//    --如果 v_rec_baf_m 对象不为空（即之前存在生产实绩），则（创建人、创建时间保留原值）：
				v_rec_baf_m.setUpdate_opr("L2_PDO");
				v_rec_baf_m.setUpdate_time(new Date());
			}
			//    --(2.13.3)、插入罩退实绩记录
			this.getMapper(MesCrAnnealMMapper.class).insert(v_rec_baf_m);
		    //	  --(2.14)、调用生产管理接口，执行业计划状态、物料进程状态相关操作（接口由生产管理模块提供）；；																																							
			//  --(2.14.1)、注意：可能在收到此PDO前，已执行过上料操作，并进行了此接口的操作，要求能正常处理，不能影响上述操作																																							
			  																																							
			//  --(2.15)、调用物流模块接口，执行原料卷生产投料出库相关操作（接口由物流模块提供）；																																							
			//  --(2.15.1)、注意：可能在收到此PDO前，已执行过上料操作，原料卷可能已投料出库，此时不能影响上述操作																																							
			//  --(4.10)、调用生产管理接口，执行业计划状态、物料进程状态相关操作（接口由生产管理模块提供）； ？？
			MesCrAnnealM  mcsm=new MesCrAnnealM();
			mcsm.setMachine_code(v_rec_baf_m.getMachine_code());//机台号
			mcsm.setSchedule_no(v_rec_baf_m.getSchedule_no());//作业计划号
			mcsm.setMaterial_no(v_rec_baf_m.getMaterial_no());//投料卷号
			mcsm.setMaterial_no_vt(v_rec_baf_m.getMaterial_no_vt());//虚拟卷号 
			List<MesCrAnnealM> lmcsm=new ArrayList<MesCrAnnealM>();
			//时间
			SimpleDateFormat dfs = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");//设置日期格式
		    String date = dfs.format(new Date());// new Date()为获取当前系统时间，也可使用当前时间戳
		    mcsm.setMemo(date);
		    lmcsm.add(mcsm);
			//调用生产管理接口验证作业计划状态能执行此操作
			boolean flag=true;
			try{
				this.getBean(MesApiAnnealPlanImpl.class).MesCrAnnealMAddValid(lmcsm);
			}catch(Exception e){
				flag=false;
				e.printStackTrace();
			}
			if(flag){
				//调用生产管理接口，更改业计划状态（主表、从表）、原料虚拟物料进程状态
				this.getBean(MesApiAnnealPlanImpl.class).MesCrAnnealMAdd(lmcsm); 
			}
		    //--(18)、调用物流模块接口，执行原料卷生产投料出库相关操作（接口由物流模块提供）；																																							
			//--(18.1)、注意：可能在收到此PDO前，已执行过上料操作，原料卷可能已投料出库，此时不能影响上述操作	
			//判断原料卷是否已生产投料出库
			YdmProductOutlist ypo=new YdmProductOutlist();
			//ypo.setCoilno(v_rec_ydm_d.get(0).getCoilno());
			ypo.setCoilno(v_rec_baf_m.getMaterial_no());
			ypo.setOuttype("500501");
			v_cnt = this.getMapper(YdmProductOutlistMapper.class).count(ypo);
			if(v_cnt<=0){
				CommonPage<YdmProductDetail> cp2=new CommonPage<YdmProductDetail>();
				YdmProductDetail ypdu=new YdmProductDetail();
				//ypdu.setCoilno(v_rec_ydm_d.get(0).getCoilno());//注意
				ypdu.setCoilno(v_rec_baf_m.getMaterial_no());//注意
				// 传入操作时间字符串带毫秒
				ypdu.setMemo(date);
				cp2.setObject(ypdu);
				this.getBean(LmsApiServiceImpl.class).doOutStorage(cp2);
			}
			//=======================质量检验委托参数开始=============================
			try{
				QcmJhySampleFromPlan ajsfp=new QcmJhySampleFromPlan();
				String prod_order_no=v_rec_mtr_out.get(0).getProd_order_no();
				List<PlnProdorder> lpp = this.getMapper(PlnProdorderMapper.class).findWithCondition(null, "prod_order_no='"+prod_order_no+"'", null, 0, 0);
				if(lpp!=null && lpp.size()>0){
					
					if(mc_list!=null && mc_list.size()>0){
						for(Map.Entry<String, List<MesCrAnnealM>> grouplist :mc_list.entrySet()){
							String key = grouplist.getKey();
							List<MesCrAnnealM> listCes = grouplist.getValue();
							for(MesCrAnnealM mcam:listCes){
								String anm_key=v_rec_baf_m.getSteel_code()+"T"+v_rec_baf_m.getMtr_thk()+"T"+v_rec_baf_m.getMtr_wdt();
								if(anm_key.equals(key) && v_rec_baf_m.getMaterial_no().equals(mcam.getMaterial_no())){
									ajsfp.setInspection_lot(mcam.getInspection_lot());
									
									MesCrAnnealM mCrossleo = new MesCrAnnealM();
									//mCrossleo.setMachine_code(sum.getMemo1());
									mCrossleo.setSchedule_no(mcam.getSchedule_no());
									//mCrossleo.setMaterial_no_vt(mcm.getMaterial_no_vt());
									mCrossleo.setMaterial_no(mcam.getMaterial_no());
									mCrossleo.setInspection_lot(mcam.getInspection_lot());
									this.getMapper(MesCrAnnealMMapper.class).update(mCrossleo);
									
								}
							}
						}
					}
					if(v_rec_baf_m_last!=null && v_rec_baf_m_last.getBatch_no()!=null){
						if(!v_rec_baf_m_last.getBatch_no().equals(v_rec_pdo.getFurnace_batch_no())){
							QcmJhySampleFromPlan qjsprem=new QcmJhySampleFromPlan();
							qjsprem.setDesign_key(lpp.get(0).getDesign_key());
							qjsprem.setInspection_lot(v_rec_baf_m_last.getInspection_lot());
							CommonPage<QcmJhySampleFromPlan> sum=new CommonPage<QcmJhySampleFromPlan>();
							sum.setObject(qjsprem);
							this.getBean(QmsApiServiceImpl.class).removeInspection(sum);
						}
					}
					
					
					ajsfp.setBatch_no(v_rec_baf_m.getBatch_no());//轧批号    炉次号
					List<PlnProcessPlan> list_plnP = this.getMapper(PlnProcessPlanMapper.class).findWithCondition(null, "produce_no='"+lpp.get(0).getProduce_no()+"' and cut_order_no = 1", "", 0, 0);
					if(list_plnP!=null && list_plnP.size()>0){
						ajsfp.setContract_line_no(list_plnP.get(0).getPlan_no());//合同行信息  销售的订单的加工计划号
					}
					
					ajsfp.setDesign_key(lpp.get(0).getDesign_key());//design_key的集合
					//ajsfp.setGrade_code(lpp.get(0).getGrade_code());//炼钢牌号代码
					//ajsfp.setGrade_name(grade_name);//炼钢牌号名称
					ajsfp.setHeat_no(v_rec_baf_m.getBatch_no());//炉号       炉次号，？？
					//ajsfp.setInspection_lot(v_rec_baf_m.getBatch_no());//检验号    炉次号
					ajsfp.setJudge("0");//用于判断是改判还是原判 0：原判；1：改判  no
					ajsfp.setMaterial_no(v_rec_baf_m.getMaterial_no());//取样材料号   
					ajsfp.setMsc_pline(lpp.get(0).getMsc_pline());//全程产线号  制成号
					ajsfp.setOrder_no(lpp.get(0).getOrder_no());//销售订单号(合同号+订单行号，示例:YT-66G66001)
					ajsfp.setBoard_no(v_rec_baf_m.getMaterial_no());
					
					ComBaseMachine cbm = this.getMapper(ComBaseMachineMapper.class).findById(v_rec_baf_m.getMachine_code());
					ComBasePline cbp = this.getMapper(ComBasePlineMapper.class).findById(cbm.getPline_code());
					ajsfp.setPline_code(cbm.getPline_code());//产线代码
					ajsfp.setPline_name(cbp.getPline_name());// 产线名称
					//后期需要修改
					ajsfp.setProcess_code("B");//工序代码    com_base_process表
					ajsfp.setPsc(lpp.get(0).getPsc());//物料编码，
					//ajsfp.setPline_seq(3l);//产线顺序  计划上道工序?还是计划下道工序？  当前工序点代码 1 分条/2 开平/3 罩退/4 平整
					CommonPage<QcmJhySampleFromPlan>  cpqjsfp=new CommonPage<QcmJhySampleFromPlan>();
					
					int judge_Contain_Qcm = this.getBean(MesApiDesignInfoImpl.class).Judge_Contain_Qcm(v_rec_baf_m.getMaterial_no_vt(), "B");
					// 获取工艺路径包含成分或者材质类
					if(judge_Contain_Qcm!=-1){
						ajsfp.setPline_seq((long)judge_Contain_Qcm);
						if(v_rec_baf_m_last!=null && v_rec_baf_m_last.getBatch_no()!=null){
							if(!v_rec_baf_m_last.getBatch_no().equals(v_rec_pdo.getFurnace_batch_no())){
								QcmJhySampleFromPlan qjsprem=new QcmJhySampleFromPlan();
								qjsprem.setDesign_key(lpp.get(0).getDesign_key());
								qjsprem.setInspection_lot(v_rec_baf_m_last.getInspection_lot());
								CommonPage<QcmJhySampleFromPlan> sum=new CommonPage<QcmJhySampleFromPlan>();
								sum.setObject(qjsprem);
								this.getBean(QmsApiServiceImpl.class).removeInspection(sum);
							}
						}
						lqsfp.add(ajsfp);
					}
					
				}
			}catch(Exception e){
				e.printStackTrace();
			}
			//==========================质量检验委托参数结束==================================
			
		}
		//=========调用质量检验委托接口==============================
		try{
			if(lqsfp!=null && lqsfp.size()>0){
				CommonPage<QcmJhySampleFromPlan>  cpqjsfp=new CommonPage<QcmJhySampleFromPlan>();
				cpqjsfp.setObjectList(lqsfp);
				ResultModel reModel = this.getBean(QcmJhySampleConsignDItemServiceImpl.class).AutoGenerationSampleInfo(cpqjsfp);
				if(reModel!=null){
					System.out.println(reModel.getState());
					System.out.println(reModel.getMsgInfo());
				}
			}
		}catch(Exception e){
			e.printStackTrace();
		}
		//  --(3)、提交事务
		v_message="L2产出实绩处理完成！";
		}catch(Exception e){
			e.printStackTrace();
			if(v_message==null || "".equals(v_message)){
				if(e.getMessage()!=null && e.getMessage().length()>200){
					v_message="L2产出实绩处理出错："+e.getMessage().substring(0,200);
				}else{
					v_message="L2产出实绩处理出错："+e.getMessage();
				}
			}
			throw new Exception(v_message);
		}
		return v_message;
	}
	
	/**
		1)、	此接口为纯后台逻辑，不与前端页面交互，收到罩退L2生产过程事件电文时调用；																																							
		2)、	此接口参数为JSON对象（对象结构见数据库表 IF_BAF01_PDO_PROC）；																																							
	 * @param json
	 * @return
	 */
	public String ReceiveBaf01Pdo_Proc(IfBaf01PdoProc json) throws Exception{
		String v_message="";
		if(json==null || "".equals(json.toString())){
			v_message="二级接口-宝信罩退炉PDO-过程事件为空";
			return v_message;
		}
		//  --(1)、函数参数为JSON对象，先转换为Java实体类，此处以 v_rec_pdo_proc 代替描述
		//暂定
		IfBaf01PdoProc v_rec_pdo_proc=json;
		//  --(2)、如果电文中（接口参数）未包含消息时间（MSG_TIME），或为空值，则赋值为当前时刻
		if(v_rec_pdo_proc.getMsg_time()==null){
			v_rec_pdo_proc.setMsg_time(new Date());
		}
		//  --(3)、将对象，插入L2生产过程事件表（单独的事务）
		try{
			this.getMapper(IfBaf01PdoProcMapper.class).insert(v_rec_pdo_proc);
		}catch(Exception e){
			e.printStackTrace();
		}
		//  --(4)、调用处理L2生产过程事件函数（事务在函数内）
		try{
			v_message=this.getBean(MesApiAnnealPdiPdoImpl.class).ReceiveBaf01Pdo_Proc_D(v_rec_pdo_proc, v_message);
		}catch(Exception e){
			e.printStackTrace();
			v_message=e.getMessage();
		}
		//  --(5)、拼接接口参数字符串
		String v_params ="作业计划号1{" + v_rec_pdo_proc.getPlan_no_1() + "} " + "入口钢卷号1{" +																																							
	              v_rec_pdo_proc.getIn_mat_no_1() + "} " + "炉内序号1{" +																																							
	              v_rec_pdo_proc.getIn_fur_seq_1() + "} " + "作业计划号2{" +																																							
	              v_rec_pdo_proc.getPlan_no_2() + "} " + "入口钢卷号2{" +																																							
	              v_rec_pdo_proc.getIn_mat_no_2() + "} " + "炉内序号2{" +																																							
	              v_rec_pdo_proc.getIn_fur_seq_2() + "} " + "作业计划号3{" +																																							
	              v_rec_pdo_proc.getPlan_no_3() + "} " + "入口钢卷号3{" +																																							
	              v_rec_pdo_proc.getIn_mat_no_3() + "} " + "炉内序号3{" +																																							
	              v_rec_pdo_proc.getIn_fur_seq_3() + "} " + "作业计划号4{" +																																							
	              v_rec_pdo_proc.getPlan_no_4() + "} " + "入口钢卷号4{" +																																							
	              v_rec_pdo_proc.getIn_mat_no_4() + "} " + "炉内序号4{" +																																							
	              v_rec_pdo_proc.getIn_fur_seq_4() + "} " + "作业计划号5{" +																																							
	              v_rec_pdo_proc.getPlan_no_5() + "} " + "入口钢卷号5{" +																																							
	              v_rec_pdo_proc.getIn_mat_no_5() + "} " + "炉内序号5{" +																																							
	              v_rec_pdo_proc.getIn_fur_seq_5() + "} " + "作业计划号6{" +																																							
	              v_rec_pdo_proc.getPlan_no_6() + "} " + "入口钢卷号6{" +																																							
	              v_rec_pdo_proc.getIn_mat_no_6() + "} " + "炉内序号6{" +																																							
	              v_rec_pdo_proc.getIn_fur_seq_6() + "} " + "作业计划号7{" +																																							
	              v_rec_pdo_proc.getPlan_no_7() + "} " + "入口钢卷号7{" +																																							
	              v_rec_pdo_proc.getIn_mat_no_7() + "} " + "炉内序号7{" +																																							
	              v_rec_pdo_proc.getIn_fur_seq_7() + "} " + "作业计划号8{" +																																							
	              v_rec_pdo_proc.getPlan_no_8() + "} " + "入口钢卷号8{" +																																							
	              v_rec_pdo_proc.getIn_mat_no_8() + "} " + "炉内序号8{" +																																							
	              v_rec_pdo_proc.getIn_fur_seq_8() + "} " + "炉次号{" +																																							
	              v_rec_pdo_proc.getFurnace_batch_no() + "}";																																			
		
		//  --(6)、写接口日志：与业务处理分开，单独的事务
		try{
			List<MesCrAnnealM> list = this.getMapper(MesCrAnnealMMapper.class).findWithCondition(null, "material_no='"+v_rec_pdo_proc.getIn_mat_no_1()+"'", "", 0, 0);
			if(list!=null && list.size()>0){
				v_params="机台代码【"+list.get(0).getMachine_code()+"】"+v_params;
			}
			this.getMapper(IfBaf01LogMapper.class).doInsert(null,"ReceiveBaf01Pdo_Proc",v_params,v_message);
		}catch(Exception e){
			e.printStackTrace();
		}
		return v_message;
	}	
	
	
	
	/**
	  	1)、	此函数为JAVA后台内调函数，可考虑将方法设为私有，由接口 ReceiveBaf01Pdo_Proc 调用；																																							
		2)、	接口参数 IN：V_REC_PDO_PROC（L2生产过程事件对象实例）																																							
		3)、	接口参数 OUT：V_MESSAGE（操作结果信息）																																							
	 * @param v_rec_pdo_proc
	 * @param v_message
	 * @return
	 * @throws Exception
	 */
	@Transactional(value="tm", rollbackFor=Exception.class)
	public String ReceiveBaf01Pdo_Proc_D(IfBaf01PdoProc v_rec_pdo_proc,
			String v_message) throws Exception{
		
		Integer v_cnt;
		//  --(1)、根据电文中，构建作业计划号、钢卷号、炉内序号集合
		List<String> v_plan_no=new ArrayList<>();
		List<String> v_material_no=new ArrayList<>();
		List<Long> v_fur_seq=new ArrayList<>();
		try{
			
		//  --炉内第1卷（炉内位置由下往上递增）
		if(v_rec_pdo_proc.getPlan_no_1()!=null && v_rec_pdo_proc.getIn_mat_no_1()!=null
				&& !"".equals(v_rec_pdo_proc.getPlan_no_1()) && !"".equals(v_rec_pdo_proc.getIn_mat_no_1())){
			v_plan_no.add(v_rec_pdo_proc.getPlan_no_1());
			v_material_no.add(v_rec_pdo_proc.getIn_mat_no_1());
			v_fur_seq.add(v_rec_pdo_proc.getIn_fur_seq_1());
		}
		//  --炉内第2卷（炉内位置由下往上递增）
		if(v_rec_pdo_proc.getPlan_no_2()!=null && v_rec_pdo_proc.getIn_mat_no_2()!=null
				&& !"".equals(v_rec_pdo_proc.getPlan_no_2()) && !"".equals(v_rec_pdo_proc.getIn_mat_no_2())){
			v_plan_no.add(v_rec_pdo_proc.getPlan_no_2());
			v_material_no.add(v_rec_pdo_proc.getIn_mat_no_2());
			v_fur_seq.add(v_rec_pdo_proc.getIn_fur_seq_2());
		}
		//  --炉内第3卷（炉内位置由下往上递增）
		if(v_rec_pdo_proc.getPlan_no_3()!=null && v_rec_pdo_proc.getIn_mat_no_3()!=null
				&& !"".equals(v_rec_pdo_proc.getPlan_no_3()) && !"".equals(v_rec_pdo_proc.getIn_mat_no_3())){
			v_plan_no.add(v_rec_pdo_proc.getPlan_no_3());
			v_material_no.add(v_rec_pdo_proc.getIn_mat_no_3());
			v_fur_seq.add(v_rec_pdo_proc.getIn_fur_seq_3());
		}
		//  --炉内第4卷（炉内位置由下往上递增）
		if(v_rec_pdo_proc.getPlan_no_4()!=null && v_rec_pdo_proc.getIn_mat_no_4()!=null
				&& !"".equals(v_rec_pdo_proc.getPlan_no_4()) && !"".equals(v_rec_pdo_proc.getIn_mat_no_4())){
			v_plan_no.add(v_rec_pdo_proc.getPlan_no_4());
			v_material_no.add(v_rec_pdo_proc.getIn_mat_no_4());
			v_fur_seq.add(v_rec_pdo_proc.getIn_fur_seq_4());
		}
		//  --炉内第5卷（炉内位置由下往上递增）
		if(v_rec_pdo_proc.getPlan_no_5()!=null && v_rec_pdo_proc.getIn_mat_no_5()!=null
				&& !"".equals(v_rec_pdo_proc.getPlan_no_5()) && !"".equals(v_rec_pdo_proc.getIn_mat_no_5())){
			v_plan_no.add(v_rec_pdo_proc.getPlan_no_5());
			v_material_no.add(v_rec_pdo_proc.getIn_mat_no_5());
			v_fur_seq.add(v_rec_pdo_proc.getIn_fur_seq_5());
		}		
		//  --炉内第6卷（炉内位置由下往上递增）
		if(v_rec_pdo_proc.getPlan_no_6()!=null && v_rec_pdo_proc.getIn_mat_no_6()!=null
				&& !"".equals(v_rec_pdo_proc.getPlan_no_6()) && !"".equals(v_rec_pdo_proc.getIn_mat_no_6())){
			v_plan_no.add(v_rec_pdo_proc.getPlan_no_6());
			v_material_no.add(v_rec_pdo_proc.getIn_mat_no_6());
			v_fur_seq.add(v_rec_pdo_proc.getIn_fur_seq_6());
		}		
		//  --炉内第7卷（炉内位置由下往上递增）
		if(v_rec_pdo_proc.getPlan_no_7()!=null && v_rec_pdo_proc.getIn_mat_no_7()!=null
				&& !"".equals(v_rec_pdo_proc.getPlan_no_7()) && !"".equals(v_rec_pdo_proc.getIn_mat_no_7())){
			v_plan_no.add(v_rec_pdo_proc.getPlan_no_7());
			v_material_no.add(v_rec_pdo_proc.getIn_mat_no_7());
			v_fur_seq.add(v_rec_pdo_proc.getIn_fur_seq_7());
		}		
		//  --炉内第8卷（炉内位置由下往上递增）
		if(v_rec_pdo_proc.getPlan_no_8()!=null && v_rec_pdo_proc.getIn_mat_no_8()!=null
				&& !"".equals(v_rec_pdo_proc.getPlan_no_8()) && !"".equals(v_rec_pdo_proc.getIn_mat_no_8())){
			v_plan_no.add(v_rec_pdo_proc.getPlan_no_8());
			v_material_no.add(v_rec_pdo_proc.getIn_mat_no_8());
			v_fur_seq.add(v_rec_pdo_proc.getIn_fur_seq_8());
		}		
		if(v_plan_no.size()<=0){
			v_message="电文中未包含钢卷信息，无法处理！";
			return v_message;
		}
		//  --(1.1)、验证事件ID的合法性
		if(v_rec_pdo_proc.getEvent_id()==null ||(
				!"0000".equals(v_rec_pdo_proc.getEvent_id()) &&
				!"0001".equals(v_rec_pdo_proc.getEvent_id()) &&
				!"0002".equals(v_rec_pdo_proc.getEvent_id()) &&
				!"0003".equals(v_rec_pdo_proc.getEvent_id()) &&
				!"0004".equals(v_rec_pdo_proc.getEvent_id()) &&
				!"0005".equals(v_rec_pdo_proc.getEvent_id()) &&
				!"0006".equals(v_rec_pdo_proc.getEvent_id()) &&
				!"0007".equals(v_rec_pdo_proc.getEvent_id()) &&
				!"0008".equals(v_rec_pdo_proc.getEvent_id()) &&
				!"0009".equals(v_rec_pdo_proc.getEvent_id()) &&
				!"0010".equals(v_rec_pdo_proc.getEvent_id()) &&
				!"0011".equals(v_rec_pdo_proc.getEvent_id()) &&
				!"0012".equals(v_rec_pdo_proc.getEvent_id())
			)	){
			v_message="电文中事件ID {"+v_rec_pdo_proc.getEvent_id()+"} 为空或无法识别！";
			return v_message;
		}
		Date v_event_time=null;
		//  --(1.2)、根据事件时刻，计算日期、班次
		if(v_rec_pdo_proc.getEvent_time()==null || "".equals(v_rec_pdo_proc.getEvent_time())){
			v_event_time=new Date();
		}else{
			//    --(1.2.1)、将生产开始时间的字符串，转换日期时间格式（可以在JAVA中转化，此处以PLSQL处理代替描述）
			try {
				List<MesCrAnnealM> li =this.getMapper(MesCrAnnealMMapper.class).doQueryDate(v_rec_pdo_proc.getEvent_time());
				if(li!=null && li.size()>0){
					v_event_time=li.get(0).getCreate_time();
				}
			} catch (Exception e) {
				e.printStackTrace();
				v_message="电文中事件时刻{"+v_rec_pdo_proc.getEvent_time()+"} 格式转化失败，无法计算日期班次！约定的标准格式【yyyyMMddHHmmss】";
				return v_message;
			}
		}
		
		String rmDb=DateUtil.formatDate(v_event_time, "yyyy-MM-dd HH:mm:ss");
		String v_event_date=null,v_event_ord=null;
		String dbTime=rmDb.substring(11);
		v_event_date=rmDb.substring(0,10);
		// --(1.2.2)、如果 v_event_time 的时间>=00:00:00并且<08:00:00，则 作业日期 = v_event_time 的日期（格式化为yyyy-MM-dd），班次 = "1"，即表示当天晚班；
		if(dbTime.compareTo(DateUtil.NBeginTime)>-1&&dbTime.compareTo(DateUtil.BeginTime)<0){
			v_event_ord="1";
		}else if(dbTime.compareTo(DateUtil.BeginTime)>-1&&dbTime.compareTo(DateUtil.EndTime)<0){
			v_event_ord="2";
		}else if(dbTime.compareTo(DateUtil.EndTime)>-1&&dbTime.compareTo(DateUtil.NEndTime)<0){
			v_event_ord="1";
			SimpleDateFormat formatYmd = new SimpleDateFormat("yyyy-MM-dd");
			Date date;
			try {
				date = formatYmd.parse(v_event_date);
			} catch (Exception e) {
				return "获取数据库时间失败，请稍后重试";
			}
			Calendar c = Calendar.getInstance();  
	        c.setTime(date);  
	        c.add(Calendar.DAY_OF_MONTH, 1);//日期+1 
	        v_event_date=formatYmd.format(c.getTime());
		}
		
		//2019-02-21
		/*
		检验批分批规则：
			同炉次号向下相同牌号、相同尺寸（厚度、宽度）的物料集合生成一个检验批号
			检验批号编码规则：炉次号+两位流水号，示例：2619000401） 
		 */
		List<MesCrAnnealM> v_rec_baf_mList = this.getMapper(MesCrAnnealMMapper.class).findWithCondition(null,"batch_no='"+v_rec_pdo_proc.getFurnace_batch_no()+"'", null, 0, 0);
		Map<String, List<MesCrAnnealM>> mc_list =new HashMap<String, List<MesCrAnnealM>>();
		if(v_rec_baf_mList!=null && v_rec_baf_mList.size()>0){
				try{
					mc_list = groupBillingDataByExcpBatchCode(v_rec_baf_mList);
				}catch(Exception e){
					
				}
		}
		
		//质量检验委托
		List<QcmJhySampleFromPlan> lqsfp=new ArrayList<>();
		//  --处理逻辑思路：类似页面“上料”按钮操作的相关处理逻辑
		//  --(2)、循环 { 作业计划号、原料卷号 } 集合中各元素
		for(int i=0;i<v_plan_no.size();i++){
			//    --(2.1)、验证罩退作业计划主记录存在
			v_cnt = this.getMapper(PlnAnnealPlanMapper.class).countWithCondition(null, "an_plan_no='"+v_plan_no.get(i)+"'");
			if(v_cnt<=0){
				v_message="作业计划号{"+v_plan_no.get(i)+"} 作业计划主记录不存在！";
				throw new Exception(v_message);
			}
			//    --(2.2)、验证罩退作业计划明细记录存在
			v_cnt=this.getMapper(PlnAnnealPlanDetailMapper.class).countWithCondition(null, "an_plan_no='"+v_plan_no.get(i)+"' and object_no='"+v_material_no.get(i)+"'");
			if(v_cnt<=0){
				v_message="作业计划号{"+v_plan_no.get(i)+"} 原料卷号{"+v_material_no.get(i)+"} 作业计划明细记录不存在！";
				throw new Exception(v_message);
			}else if(v_cnt>1){
				//      --计划表 pln_anneal_plan_detail 未设置唯一约束，考虑极端情况下程序BUG导致的数据错误
				v_message="作业计划号{"+v_plan_no.get(i)+"} 原料卷号{"+v_material_no.get(i)+"} 存在一条以上作业计划明细记录，无法处理！";
				throw new Exception(v_message);
			}
			List<PlnAnnealPlanDetail> v_rec_pln_d_list = this.getMapper(PlnAnnealPlanDetailMapper.class).findWithCondition(null, "an_plan_no='"+v_plan_no.get(i)+"' and object_no='"+v_material_no.get(i)+"'", null, 0, 0);
			PlnAnnealPlanDetail v_rec_pln_d=v_rec_pln_d_list.get(0);
			//    --(2.3)、如果已有生产实绩（人工操作或L2重复发送PDO情况下），且已交工，则返回（忽略此PDO生产过程事件）
			List<MesCrAnnealM> v_rec_baf_m_list = this.getMapper(MesCrAnnealMMapper.class).findWithCondition(null,"schedule_no='"+v_plan_no.get(i)+"' and material_no='"+v_material_no.get(i)+"'", null, 0, 0);
			MesCrAnnealM v_rec_baf_m=new MesCrAnnealM();
			if(v_rec_baf_m_list!=null && v_rec_baf_m_list.size()>0){
				if("1".equals(v_rec_baf_m_list.get(0).getHand_over_status())){
					v_message="作业计划号{"+v_plan_no.get(i)+"} 原料卷号{"+v_material_no.get(i)+"} 已生产交工，忽略此PDO生产过程事件！";
					throw new Exception(v_message);
				}
				v_rec_baf_m=v_rec_baf_m_list.get(0);
			}
			
			//    --(2.4)、验证机台基础信息存在
			v_cnt = this.getMapper(ComBaseMachineMapper.class).countWithCondition(null,"machine_code='"+v_rec_pln_d.getMachine_code()+"'");
			if(v_cnt<=0){
				v_message="作业计划号{"+v_plan_no.get(i)+"} 原料卷号{"+v_material_no.get(i)+"} 机台代码{"+v_rec_pln_d.getMachine_code()+"} 机台基础信息不存在！";
				throw new Exception(v_message);
			}
			//    --（2.5)、获取机台基础信息表中，配置的机台设备代号（设备编号，如1,2,3）
			List<ComBaseMachine> lcbm = this.getMapper(ComBaseMachineMapper.class).findWithCondition(null,
					"machine_code='"+v_rec_pln_d.getMachine_code()+"'", null, 0, 0);
			String v_mch_mark=lcbm.get(0).getMachine_mark();
			if(v_mch_mark==null){
				v_message="作业计划号{"+v_plan_no.get(i)+"} 原料卷号{"+v_material_no.get(i)+"} 机台代码{"+v_rec_pln_d.getMachine_code()+"} 设备编号未配置，无法处理！";
				throw new Exception(v_message);
			}
			//    --(2.6)、验证虚拟物料表中，原料卷计划信息存在
			List<PlnMaterielDetail> v_rec_mtr_in = this.getMapper(PlnMaterielDetailMapper.class).findWithCondition(null,"object_no_vt='"+v_rec_pln_d.getObject_no_vt()+"'", null, 0, 0);
			if(v_rec_mtr_in==null || v_rec_mtr_in.size()<=0){
				v_message="作业计划号{"+v_plan_no.get(i)+"} 原料卷号{"+v_material_no.get(i)+"} 虚拟卷号{"+v_rec_pln_d.getObject_no_vt()+"} 原料卷虚拟物料信息不存在！";
				throw new Exception(v_message);
			}
			//    --(2.7)、验证原料卷号库存明细记录存在
			List<YdmProductDetail> v_rec_ydm_d = this.getMapper(YdmProductDetailMapper.class).findWithCondition(null, "coilno='"+v_material_no.get(i)+"'", null, 0, 0);
			if(v_rec_ydm_d==null || v_rec_ydm_d.size()<=0){
				v_message="作业计划号{"+v_plan_no.get(i)+"} 原料卷号{"+v_material_no.get(i)+"} 原料卷库存明细记录不存在！";
				throw new Exception(v_message);
			}
			//    --(2.8)、验证虚拟物料表中，出口卷虚拟物料信息存在
			PlnMaterielDetail pmd2=new PlnMaterielDetail();
			pmd2.setMat_object_no_vt(v_rec_pln_d.getObject_no_vt());
			v_cnt = this.getMapper(PlnMaterielDetailMapper.class).count(pmd2);
			if (v_cnt<=0) {
				v_message="作业计划号{"+v_plan_no.get(i)+"} 原料卷号{"+v_material_no.get(i)+"} 虚拟卷号{"+v_rec_pln_d.getObject_no_vt()+"} 出口卷虚拟物料信息不存在！";
				throw new Exception(v_message);
			}
			List<PlnMaterielDetail> v_rec_mtr_out=this.getMapper(PlnMaterielDetailMapper.class).doQueryWeb2(v_rec_pln_d.getObject_no_vt(),"");
			
			//2018-11-29 只有是已下发状态的钢卷才能下发
			if(v_rec_pln_d!=null){
				if(!("5BAN02".equals(v_rec_pln_d.getStatus()) || "5BAN03".equals(v_rec_pln_d.getStatus()))){
					v_message="当前状态{"+v_rec_pln_d.getStatus()+"}错误";
					return v_message;
				}
			}
			
			//    --(2.9)、根据计算的投料日期班次，获取交接班记录的班组 
			MesShiftM msm=new MesShiftM();
			if(v_rec_pln_d.getMachine_code().equals("M0009")){
				msm.setMachine_code("M0005");
			}else{
				msm.setMachine_code(v_rec_pln_d.getMachine_code());
			}
			msm.setWrk_date(v_event_date);
			msm.setWrk_ord(v_event_ord);
			v_cnt=this.getMapper(MesShiftMMapper.class).count(msm);
			String v_event_grp=null;
			if(v_cnt<=0){
				 String l2_grp=v_rec_pdo_proc.getProd_shift_group(); //--无交接班记录，是使用电文中的生产班别
				  if("A".equals(l2_grp)){
					  v_event_grp = "1"; //--无交接班记录，是使用电文中的生产班别
				  }else if("B".equals(l2_grp)){
					  v_event_grp = "2"; //--无交接班记录，是使用电文中的生产班别
				  }else if("C".equals(l2_grp)){
					  v_event_grp = "3"; //--无交接班记录，是使用电文中的生产班别
				  }else if("D".equals(l2_grp)){
					  v_event_grp = "4"; //--无交接班记录，是使用电文中的生产班别
				  }
			}else{
				//    --否则获取交接班记录中的班组
				List<MesShiftM> lmsm = this.getMapper(MesShiftMMapper.class).find(msm, 0, 0);
				v_event_grp=lmsm.get(0).getWrk_grp();
			}
			
			//    --(2.10)、出口卷编码前缀：原料卷号（最初始原料卷号） + 1位工序代号（退火T）+ 2位设备代号（01-99）
			//String v_coil_no = v_material_no.get(i).substring(0, 8) + "T"+ lpad(v_mch_mark, 2, "0");
//			String v_coil_no=null;
//			if(v_rec_pdo_proc.getFurnace_no()!=null && !"".equals(v_rec_pdo_proc.getFurnace_no())){
//				v_coil_no = v_material_no.get(i).substring(0, 8) + "T"+ lpad(v_rec_pdo_proc.getFurnace_no(), 2, "0");
//			}else{
//				v_coil_no = v_material_no.get(i).substring(0, 8) + "T"+ lpad(v_mch_mark, 2, "0");
//			}
			String v_coil_no=null;
			String v_leo="";
			if(v_rec_pdo_proc.getFurnace_no()!=null && !"".equals(v_rec_pdo_proc.getFurnace_no())){
				int leo1x = Integer.parseInt(v_rec_pdo_proc.getFurnace_no());
				v_rec_pdo_proc.setFurnace_no(leo1x+"");
				String v_syh=lpad(v_rec_pdo_proc.getFurnace_no(), 2, "0");
				if(v_rec_baf_m.getCoil_no()!=null){
					v_leo=v_rec_baf_m.getCoil_no().substring(v_rec_baf_m.getCoil_no().length()-4, v_rec_baf_m.getCoil_no().length()-2);
					if(!v_syh.equals(v_leo)){
						v_coil_no = v_material_no.get(i).substring(0, 8) + "T"+ lpad(v_rec_pdo_proc.getFurnace_no(), 2, "0");
					}else{
						v_coil_no = v_material_no.get(i).substring(0, 8) + "T"+ lpad(v_rec_pdo_proc.getFurnace_no(), 2, "0");
					}
				}else{
					v_coil_no = v_material_no.get(i).substring(0, 8) + "T"+ lpad(v_rec_pdo_proc.getFurnace_no(), 2, "0");
				}
				
			}else{
				v_coil_no = v_material_no.get(i).substring(0, 8) + "T"+ lpad(v_mch_mark, 2, "0");
			}
			
			
			//    --(2.10.1)、获取当前起始流水号
			v_cnt=this.getMapper(MesCrAnnealMMapper.class).doQueryWeb6(v_coil_no,v_plan_no.get(i),v_material_no.get(i));
			if(v_cnt==null){
				v_cnt=1;
			}else if(v_cnt>99){
				v_message="作业计划号{"+v_plan_no.get(i)+"} 原料卷号{"+v_material_no.get(i)+"} 出口钢卷号超出规则范围，流水号超出最大值99！";
				throw new Exception(v_message);
			}
			//--(2.10.2)、出口卷编码规则：出口卷编码前缀【原料卷号（最初始原料卷号） + 1位工序代号（退火T）+ 2位设备代号（01-99）】+ 2位流水（01 - 99）																																						
			v_coil_no=v_coil_no+lpad(v_cnt+"",2,"0");
			
			//如果之前有，就用之前的
			if(v_rec_pdo_proc.getFurnace_no()!=null && !"".equals(v_rec_pdo_proc.getFurnace_no())){
				String v_syh=lpad(v_rec_pdo_proc.getFurnace_no(), 2, "0");
				if(v_rec_baf_m.getCoil_no()!=null){
					v_leo=v_rec_baf_m.getCoil_no().substring(v_rec_baf_m.getCoil_no().length()-4, v_rec_baf_m.getCoil_no().length()-2);
					if(v_syh.equals(v_leo)){
						v_coil_no=v_rec_baf_m.getCoil_no();
					}else{
						
					}
					
				}else{
					//v_rec_cam.setCoil_no(v_coil_no);
				}
				
			}
			
			
			//    --(2.11)、删除可能存在罩退作业实绩
			this.getMapper(MesCrAnnealMMapper.class).doDelete2(v_plan_no.get(i),v_material_no.get(i));
		   
			//--(2.12)、在 v_rec_baf_m 对象基础上，构建罩退主实绩，并插入记录																																							
		    //--(2.12.1)：v_rec_baf_m 对象可能不为空（之前实绩已存在），则更新部分信息，保留部分信息（未赋值的属性即是保留原有对象的属性值）																																							
		    //--(2.12.2)：v_rec_baf_m 对象如果为空，请先实例化此对象（plsql示例逻辑无此问题）																																							
			v_rec_baf_m.setSchedule_no(v_plan_no.get(i));//作业计划号																																							
			v_rec_baf_m.setMaterial_no(v_material_no.get(i));//原料卷号																																							
			v_rec_baf_m.setMaterial_no_vt(v_rec_pln_d.getObject_no_vt());//虚拟原料卷号																																							
			v_rec_baf_m.setPln_steel_code(v_rec_mtr_in.get(0).getSteel_code());//计划原料卷牌号																																							
			v_rec_baf_m.setPln_mtr_thk(v_rec_mtr_in.get(0).getThick());//计划原料卷厚度																																							
			v_rec_baf_m.setPln_mtr_wdt(v_rec_mtr_in.get(0).getWidth());//计划原料卷宽度																																							
			v_rec_baf_m.setPln_mtr_len(v_rec_mtr_in.get(0).getLength());//计划原料卷长度																																							
			v_rec_baf_m.setPln_mtr_inn_dia(v_rec_mtr_in.get(0).getDiameter_inn());//计划原料卷内径																																							
			v_rec_baf_m.setPln_mtr_out_dia(v_rec_mtr_in.get(0).getDiameter_out());//计划原料卷外径																																							
			v_rec_baf_m.setPln_mtr_thr_wgt(v_rec_mtr_in.get(0).getSingle_weight());//计划原料卷理重																																							
			v_rec_baf_m.setMaterial_no_src(v_rec_ydm_d.get(0).getMaterailcoilno());//原始卷号																																							
			v_rec_baf_m.setMtr_thk(v_rec_ydm_d.get(0).getThick());//原料卷厚度																																							
			v_rec_baf_m.setMtr_wdt(v_rec_ydm_d.get(0).getWidth());//原料卷宽度																																							
			v_rec_baf_m.setMtr_len(v_rec_ydm_d.get(0).getLength());//原料卷长度																																							
			v_rec_baf_m.setMtr_inn_dia(v_rec_ydm_d.get(0).getDiameter_inn());//原料卷内径																																							
			v_rec_baf_m.setMtr_out_dia(v_rec_ydm_d.get(0).getDiameter_out());//原料卷外径																																							
			v_rec_baf_m.setMtr_thr_wgt(v_rec_ydm_d.get(0).getTheoryweight());//原料卷理重																																							
			v_rec_baf_m.setMtr_act_wgt(v_rec_ydm_d.get(0).getFactweight());//原料卷实重																																							
			v_rec_baf_m.setSteel_code(v_rec_ydm_d.get(0).getSteelcode());//原料卷牌号																																							
			v_rec_baf_m.setMachine_code(v_rec_pln_d.getMachine_code());//机台号（区分厂家：艾伯纳、中冶南方、宝信）																																							
			v_rec_baf_m.setBatch_no(v_rec_pdo_proc.getFurnace_batch_no());//炉批号（2位炉座号+2位年份+4位流水号）																																							
			v_rec_baf_m.setFurnace_no(v_rec_pdo_proc.getFurnace_no());//炉座号（1-5艾伯纳，6-16中冶南方、17-26宝信）																																							
			v_rec_baf_m.setIn_fur_seq(v_fur_seq.get(i));//炉内位置		
			//注意:截取电文状态后两位
			//截取电文状态后两位，状态（00：组垛完成、01：上炉台、02：扣加热罩、03：加热开始、04：加热结束、
			//05：带罩冷却开始、06：带罩冷却结束、07：风冷开始、08：风冷结束、09：水冷开始、10：水冷结束、
			//11：出炉/上终冷台、12：下终冷台）
			v_rec_baf_m.setStatus(v_rec_pdo_proc.getEvent_id().substring(v_rec_pdo_proc.getEvent_id().length()-2));																																							

			
			if(("0001".equals(v_rec_pdo_proc.getEvent_id()) || "0002".equals(v_rec_pdo_proc.getEvent_id()))
					&& (v_rec_baf_m.getCharge_date()==null || v_rec_baf_m.getCharge_ord()==null || v_rec_baf_m.getCharge_grp()==null) ){																																							
				v_rec_baf_m.setCharge_date(v_event_date);//投料日期（YYYY-MM-DD）																																							
				v_rec_baf_m.setCharge_ord(v_event_ord);//投料班次（1晚班、2白班、3中班）																																							
				v_rec_baf_m.setCharge_grp(v_event_grp);//投料班组（1甲班、2乙班、3丙班、4丁班）																																							
				v_rec_baf_m.setCharge_time(v_event_time);//投料时间/生产开始时间																																							
			};																																							
																																										
			if("0012".equals(v_rec_pdo_proc.getEvent_id()) && 
				(v_rec_baf_m.getDischarge_date()==null || v_rec_baf_m.getDischarge_ord()==null || v_rec_baf_m.getDischarge_grp()==null)){																																					
				v_rec_baf_m.setDischarge_date(v_event_date);//产出日期（YYYY-MM-DD）																																							
				v_rec_baf_m.setDischarge_ord(v_event_ord);//产出班次（1晚班、2白班、3中班）																																							
				v_rec_baf_m.setDischarge_grp(v_event_grp);//产出班组（1甲班、2乙班、3丙班、4丁班）																																							
				v_rec_baf_m.setDischarge_time(v_event_time);//产出时间/生产结束时间																																							
			};																																							
			if("0000".equals(v_rec_pdo_proc.getEvent_id())){
				v_rec_baf_m.setEvent_time_batch(v_event_time);//事件时刻：组垛完成		
			}else if("0001".equals(v_rec_pdo_proc.getEvent_id())){
				v_rec_baf_m.setEvent_time_charge(v_event_time);//事件时刻：上炉台	
			}else if("0002".equals(v_rec_pdo_proc.getEvent_id())){
				v_rec_baf_m.setEvent_time_cover(v_event_time);//事件时刻：扣加热罩			
			}else if("0003".equals(v_rec_pdo_proc.getEvent_id())){
				v_rec_baf_m.setEvent_time_heat_str(v_event_time);//事件时刻：加热开始			
			}else if("0004".equals(v_rec_pdo_proc.getEvent_id())){
				v_rec_baf_m.setEvent_time_heat_end(v_event_time);//事件时刻：加热结束	
			}else if("0005".equals(v_rec_pdo_proc.getEvent_id())){
				v_rec_baf_m.setEvent_time_cvr_cool_str(v_event_time);//事件时刻：带罩冷却开始
			}else if("0006".equals(v_rec_pdo_proc.getEvent_id())){
				v_rec_baf_m.setEvent_time_cvr_cool_end(v_event_time);//事件时刻：带罩冷却结束	
			}else if("0007".equals(v_rec_pdo_proc.getEvent_id())){
				v_rec_baf_m.setEvent_time_air_cool_str(v_event_time);//事件时刻：风冷开始	
			}else if("0008".equals(v_rec_pdo_proc.getEvent_id())){
				v_rec_baf_m.setEvent_time_air_cool_end(v_event_time);//事件时刻：风冷结束
			}else if("0009".equals(v_rec_pdo_proc.getEvent_id())){
				v_rec_baf_m.setEvent_time_wtr_cool_str(v_event_time);//事件时刻：水冷开始	
			}else if("0010".equals(v_rec_pdo_proc.getEvent_id())){
				v_rec_baf_m.setEvent_time_wtr_cool_end(v_event_time);//事件时刻：水冷结束	
			}else if("0011".equals(v_rec_pdo_proc.getEvent_id())){
				v_rec_baf_m.setEvent_time_fnl_cool_str(v_event_time);//事件时刻：出炉/上终冷台	
			}else if("0012".equals(v_rec_pdo_proc.getEvent_id())){
				v_rec_baf_m.setEvent_time_fnl_cool_end(v_event_time);//事件时刻：下终冷台
			}
			
			if(v_rec_baf_m.getHeat_hood()!=null && !v_rec_baf_m.getHeat_hood().contains("-")){
				
			}else{
				v_rec_baf_m.setHeat_hood(v_rec_pdo_proc.getHeat_hood());//加热罩号		
			}
			if(v_rec_baf_m.getCool_hood()!=null && !v_rec_baf_m.getCool_hood().contains("-")){
				
			}else{
				v_rec_baf_m.setCool_hood(v_rec_pdo_proc.getCool_hood());//冷却罩号	
			}
			if(v_rec_baf_m.getFc_no()!=null && !v_rec_baf_m.getFc_no().contains("-")){
				
			}else{
				v_rec_baf_m.setFc_no(v_rec_pdo_proc.getFc_no());//终冷台号	
			}
			v_rec_baf_m.setCoil_no(v_coil_no);//产出卷号																																							
			v_rec_baf_m.setAim_thk(v_rec_mtr_out.get(0).getThick());//产出卷目标厚度																																							
			v_rec_baf_m.setAim_wdt(v_rec_mtr_out.get(0).getWidth());//产出卷目标宽度																																							
			v_rec_baf_m.setAim_len(v_rec_mtr_out.get(0).getLength());//产出卷目标长度																																							
			v_rec_baf_m.setAim_inn_dia(v_rec_mtr_out.get(0).getDiameter_inn());//产出卷目标内径																																							
			v_rec_baf_m.setAim_out_dia(v_rec_mtr_out.get(0).getDiameter_out());//产出卷目标外径																																							
			v_rec_baf_m.setAct_thk(v_rec_ydm_d.get(0).getThick());//产出卷厚度																																							
			v_rec_baf_m.setAct_wdt(v_rec_ydm_d.get(0).getWidth());//产出卷宽度																																							
			v_rec_baf_m.setAct_len(v_rec_ydm_d.get(0).getLength());//产出卷长度																																							
			v_rec_baf_m.setAct_inn_dia(v_rec_ydm_d.get(0).getDiameter_inn());//产出卷内径																																							
			v_rec_baf_m.setAct_out_dia(v_rec_ydm_d.get(0).getDiameter_out());//产出卷外径																																							
			v_rec_baf_m.setCoil_thr_wgt(v_rec_ydm_d.get(0).getTheoryweight());//产出卷理重																																							
			v_rec_baf_m.setCoil_act_wgt(v_rec_ydm_d.get(0).getFactweight());//产出卷实量																																							
			v_rec_baf_m.setProd_order_no(v_rec_mtr_out.get(0).getProd_order_no());//生产订单号																																							
			v_rec_baf_m.setOrder_no(v_rec_mtr_out.get(0).getOrder_no());//订单号																																							
			v_rec_baf_m.setMemo(null);//备注																																							
			v_rec_baf_m.setHand_over_status("0");//交工状态																																							
			v_rec_baf_m.setHand_over_time(null);//交工时间																																							
			v_rec_baf_m.setHand_over_opr(null);//交工人		
			//	--如果 v_rec_baf_m 对象为空（即之前无生产实绩），则：
			if(v_rec_baf_m.getCreate_opr()==null){
				v_rec_baf_m.setCreate_opr("L2_PDO");
				v_rec_baf_m.setCreate_time(new Date());
			}else{//    --如果 v_rec_baf_m 对象不为空（即之前存在生产实绩），则（创建人、创建时间保留原值）：
				v_rec_baf_m.setUpdate_opr("L2_PDO");
				v_rec_baf_m.setUpdate_time(new Date());
			}
			//2019-02-21
			if(mc_list!=null && mc_list.size()>0){
				for(Map.Entry<String, List<MesCrAnnealM>> grouplist :mc_list.entrySet()){
					String key = grouplist.getKey();
					List<MesCrAnnealM> listCes = grouplist.getValue();
					for(MesCrAnnealM mcam:listCes){
						String anm_key=v_rec_baf_m.getSteel_code()+"T"+v_rec_baf_m.getMtr_thk()+"T"+v_rec_baf_m.getMtr_wdt();
						if(anm_key.equals(key) && v_rec_baf_m.getMaterial_no().equals(mcam.getMaterial_no())){
							v_rec_baf_m.setInspection_lot(mcam.getInspection_lot());
							//this.getMapper(MesCrAnnealMMapper.class).update(v_rec_baf_m);
						}
					}
				}
			}
			
			//    --(2.12.3)、插入罩退实绩记录
			this.getMapper(MesCrAnnealMMapper.class).insert(v_rec_baf_m);
			
			//  --(2.13)、调用生产管理接口，执行业计划状态、物料进程状态相关操作（接口由生产管理模块提供）；；																																							
			//  --(2.13.1)、注意：可能在收到此PDO前，已执行过上料操作，并进行了此接口的操作，要求能正常处理，不能影响上述操作																																							
			  																																							
			//  --(2.14)、调用物流模块接口，执行原料卷生产投料出库相关操作（接口由物流模块提供）；																																							
			//  --(2.14.1)、注意：可能在收到此PDO前，已执行过上料操作，原料卷可能已投料出库，此时不能影响上述操作	
			MesCrAnnealM  mcsm=new MesCrAnnealM();
			mcsm.setMachine_code(v_rec_baf_m.getMachine_code());//机台号
			mcsm.setSchedule_no(v_rec_baf_m.getSchedule_no());//作业计划号
			mcsm.setMaterial_no(v_rec_baf_m.getMaterial_no());//投料卷号
			mcsm.setMaterial_no_vt(v_rec_baf_m.getMaterial_no_vt());//虚拟卷号 
			List<MesCrAnnealM> lmcsm=new ArrayList<MesCrAnnealM>();
			
			//时间
			SimpleDateFormat dfs = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");//设置日期格式
		    String date = dfs.format(new Date());// new Date()为获取当前系统时间，也可使用当前时间戳
		    mcsm.setMemo(date);
		    lmcsm.add(mcsm);
			
			//调用生产管理接口验证作业计划状态能执行此操作
			boolean flag=true;
			try{
				this.getBean(MesApiAnnealPlanImpl.class).MesCrAnnealMAddValid(lmcsm);
			}catch(Exception e){
				flag=false;
				e.printStackTrace();
			}
			if(flag){
				//调用生产管理接口，更改业计划状态（主表、从表）、原料虚拟物料进程状态
				this.getBean(MesApiAnnealPlanImpl.class).MesCrAnnealMAdd(lmcsm); 
			}
		    //--(18)、调用物流模块接口，执行原料卷生产投料出库相关操作（接口由物流模块提供）；																																							
			//--(18.1)、注意：可能在收到此PDO前，已执行过上料操作，原料卷可能已投料出库，此时不能影响上述操作	
			//判断原料卷是否已生产投料出库
			YdmProductOutlist ypo=new YdmProductOutlist();
			//ypo.setCoilno(v_rec_ydm_d.get(0).getCoilno());
			ypo.setCoilno(v_rec_baf_m.getMaterial_no());
			ypo.setOuttype("500501");
			v_cnt = this.getMapper(YdmProductOutlistMapper.class).count(ypo);
			if(v_cnt<=0){
				CommonPage<YdmProductDetail> cp2=new CommonPage<YdmProductDetail>();
				YdmProductDetail ypdu=new YdmProductDetail();
				//ypdu.setCoilno(v_rec_ydm_d.get(0).getCoilno());//注意
				ypdu.setCoilno(v_rec_baf_m.getMaterial_no());//注意
				// 传入操作时间字符串带毫秒
				ypdu.setMemo(date);
				cp2.setObject(ypdu);
				this.getBean(LmsApiServiceImpl.class).doOutStorage(cp2);
			}
			//=======================质量检验委托参数开始=============================
//			try{
//				QcmJhySampleFromPlan ajsfp=new QcmJhySampleFromPlan();
//				String prod_order_no=v_rec_mtr_out.get(0).getProd_order_no();
//				List<PlnProdorder> lpp = this.getMapper(PlnProdorderMapper.class).findWithCondition(null, "prod_order_no='"+prod_order_no+"'", null, 0, 0);
//				if(lpp!=null && lpp.size()>0){
//					ajsfp.setBatch_no(v_rec_baf_m.getBatch_no());//轧批号    炉次号
//					ajsfp.setContract_line_no(lpp.get(0).getContract_line_no());//合同行信息
//					ajsfp.setDesign_key(lpp.get(0).getDesign_key());//design_key的集合
//					//ajsfp.setGrade_code(lpp.get(0).getGrade_code());//炼钢牌号代码
//					//ajsfp.setGrade_name(grade_name);//炼钢牌号名称
//					ajsfp.setHeat_no(v_rec_baf_m.getBatch_no());//炉号       炉次号，？？
//					ajsfp.setInspection_lot(v_rec_baf_m.getBatch_no());//检验号    炉次号
//					ajsfp.setJudge("0");//用于判断是改判还是原判 0：原判；1：改判  no
//					ajsfp.setMaterial_no(v_rec_baf_m.getMaterial_no());//取样材料号   
//					ajsfp.setMsc_pline(lpp.get(0).getMsc_pline());//全程产线号  制成号
//					ajsfp.setOrder_no(lpp.get(0).getOrder_no());//销售订单号(合同号+订单行号，示例:YT-66G66001)
//					ComBaseMachine cbm = this.getMapper(ComBaseMachineMapper.class).findById(v_rec_baf_m.getMachine_code());
//					ComBasePline cbp = this.getMapper(ComBasePlineMapper.class).findById(cbm.getPline_code());
//					ajsfp.setPline_code(cbm.getPline_code());//产线代码
//					ajsfp.setPline_name(cbp.getPline_name());// 产线名称
//					//后期需要修改
//					ajsfp.setProcess_code("B");//工序代码    com_base_process表
//					ajsfp.setPsc(lpp.get(0).getPsc());//物料编码，
//					ajsfp.setPline_seq(3l);//产线顺序  计划上道工序?还是计划下道工序？  当前工序点代码 1 分条/2 开平/3 罩退/4 平整
//					// 获取工艺路径包含成分或者材质类
//					List<SlmOrdDesignMscPlSti> listSti=this.getMapper(SlmOrdDesignMscPlStiMapper.class).findWithCondition(null, 
//							" design_key = '"+lpp.get(0).getDesign_key()+"'  AND MSC_PLINE = '"+lpp.get(0).getMsc_pline()+"' and process_code = 'B' and PROCESS_POINT_TYPE in ('403201','403202')", "  BACKLOG_SEQ, PROCESS_POINT_SEQ", 0, 0);
//					if(listSti!=null && listSti.size()>0){
//						lqsfp.add(ajsfp);
//					}
//				}
//			}catch(Exception e){
//				e.printStackTrace();
//			}
			//==========================质量检验委托参数结束==================================
		}
		
		//=========调用质量检验委托接口==============================
//		try{
//			if(lqsfp!=null && lqsfp.size()>0){
//				CommonPage<QcmJhySampleFromPlan>  cpqjsfp=new CommonPage<QcmJhySampleFromPlan>();
//				cpqjsfp.setObjectList(lqsfp);
//				ResultModel reModel = this.getBean(QcmJhySampleConsignMServiceImpl.class).AutoGenerationSampleInfo(cpqjsfp);
//				if(reModel!=null){
//					System.out.println(reModel.getState());
//					System.out.println(reModel.getMsgInfo());
//				}
//			}
//		}catch(Exception e){
//			e.printStackTrace();
//		}
		v_message="L2生产过程事件电文处理完成！"	;
		}catch(Exception e){
			e.printStackTrace();
			if(v_message==null || "".equals(v_message)){
				if(e.getMessage()!=null && e.getMessage().length()>200){
					v_message="L2生产过程事件电文处理出错："+e.getMessage().substring(0,200);
				}else{
					v_message="L2生产过程事件电文处理出错："+e.getMessage();
				}
			}
			throw new Exception(v_message);
		}
		return v_message;
	}
	
	/**宝信
		1)、	此接口为纯后台逻辑，不与前端页面交互，收到罩退L2能耗实绩电文时调用；																																							
		2)、	此接口参数为JSON对象（对象结构见数据库表 IF_BAF01_PDO_ENERGY）；																																							
	 * @param json
	 * @return
	 */
	public String ReceiveBaf01Pdo_Energy(IfBaf01PdoEnergy json) throws Exception{
		String v_message="";
		if(json==null || "".equals(json.toString())){
			v_message="二级接口-宝信罩退炉PDO-能耗实绩为空";
			return v_message;
		}
		//  --(1)、函数参数为JSON对象，先转换为Java实体类，此处以 v_rec_pdo_energy 代替描述
		//暂定
		IfBaf01PdoEnergy v_rec_pdo_energy=json;
		//   --(2)、如果电文中（接口参数）未包含消息时间（MSG_TIME），或为空值，则赋值为当前时刻
		if(v_rec_pdo_energy.getMsg_time()==null){
			v_rec_pdo_energy.setMsg_time(new Date());
		}
		//  --(3)、将对象，插入PDO能耗实绩表（单独的事务）
		try{
			this.getMapper(IfBaf01PdoEnergyMapper.class).insert(v_rec_pdo_energy);
		}catch(Exception e){
			e.printStackTrace();
		}
		//  --(4)、调用处理PDO能耗实绩函数（事务在函数内）
		try{
			v_message=this.getBean(MesApiAnnealPdiPdoImpl.class).ReceiveBaf01Pdo_Energy_D(v_rec_pdo_energy, v_message);
		}catch(Exception e){
			e.printStackTrace();
			v_message=e.getMessage();
		}
		//  --(5)、拼接接口参数字符串
		 String v_params = "作业日期{"+v_rec_pdo_energy.getWrk_date()+"} 班次{"+v_rec_pdo_energy.getWrk_ord()+"}";
		//  --(6)、写接口日志：与业务处理分开，单独的事务
		try{
			 this.getMapper(IfBaf01LogMapper.class).doInsert(null,"ReceiveBaf01Pdo_Energy",v_params,v_message);
		}catch(Exception e){
			e.printStackTrace();
		}
		return v_message;
	}
	
	
	
	/**
	 *  1)、	此函数为JAVA后台内调函数，可考虑将方法设为私有，由接口 ReceiveBaf01Pdo_Energy 调用；																																							
		2)、	接口参数 IN：V_REC_PDO_ENERGY（L2能耗实绩对象实例）																																							
		3)、	接口参数 OUT：V_MESSAGE（操作结果信息）																																							
	 * @param v_rec_pdo_energy
	 * @param v_message
	 * @return
	 * @throws Exception
	 */
	@Transactional(value="tm", rollbackFor=Exception.class)
	public String ReceiveBaf01Pdo_Energy_D(IfBaf01PdoEnergy v_rec_pdo_energy,
			String v_message) throws Exception {
		
		//暂时 ??重要
		//  v_mch_code varchar2(20); --请定义为常量（3个厂家的罩退炉，3个接口，取各自代码）
		String v_mch_code = "M0004";//宝信
		try{
			//  --(1)、如果对象中作业日期为空，则返回错误信息
			if(v_rec_pdo_energy.getWrk_date()==null || "".equals(v_rec_pdo_energy.getWrk_date())){
				v_message="作业日期为空，无法处理！";
				return v_message;
			}
			//  --(2)、如果对象中班次为空，则返回错误信息
			if(v_rec_pdo_energy.getWrk_ord()==null || "".equals(v_rec_pdo_energy.getWrk_ord())){
				v_message="作业班次为空，无法处理！";
				return v_message;
			}
			//  --(3)、验证罩退能耗实绩是否存在
			MesCrAnnealEnergy mcae=new MesCrAnnealEnergy();
			mcae.setMachine_code(v_mch_code);
			mcae.setWrk_date(v_rec_pdo_energy.getWrk_date());
			mcae.setWrk_ord(v_rec_pdo_energy.getWrk_ord());
			List<MesCrAnnealEnergy> lmcae = this.getMapper(MesCrAnnealEnergyMapper.class).find(mcae, 0, 0);
			if(lmcae!=null && lmcae.size()>0){
				//    --(3.1)、存在则更新记录
				mcae.setCsm_gas(v_rec_pdo_energy.getCsm_gas());
				mcae.setCsm_h2(v_rec_pdo_energy.getCsm_h2());
				mcae.setCsm_n2(v_rec_pdo_energy.getCsm_n2());
				mcae.setCsm_ccl_water(v_rec_pdo_energy.getCsm_ccl_water());
				mcae.setCsm_acd_water(v_rec_pdo_energy.getCsm_acd_water());
				mcae.setCsm_cmpr_air(v_rec_pdo_energy.getCsm_cmpr_air());
				mcae.setCsm_elec(v_rec_pdo_energy.getCsm_elec());
				mcae.setUpdate_opr("L2_PDO");
				mcae.setUpdate_time(new Date());
				this.getMapper(MesCrAnnealEnergyMapper.class).update(mcae);
			}else{
				// --(3.2)、不存在则插入记录
				mcae.setCsm_gas(v_rec_pdo_energy.getCsm_gas());
				mcae.setCsm_h2(v_rec_pdo_energy.getCsm_h2());
				mcae.setCsm_n2(v_rec_pdo_energy.getCsm_n2());
				mcae.setCsm_ccl_water(v_rec_pdo_energy.getCsm_ccl_water());
				mcae.setCsm_acd_water(v_rec_pdo_energy.getCsm_acd_water());
				mcae.setCsm_cmpr_air(v_rec_pdo_energy.getCsm_cmpr_air());
				mcae.setCsm_elec(v_rec_pdo_energy.getCsm_elec());
				mcae.setCreate_opr("L2_PDO");
				mcae.setCreate_time(new Date());
				this.getMapper(MesCrAnnealEnergyMapper.class).insert(mcae);
			}
			//  --(4)、提交事务
			v_message="PDO能耗实绩处理完成！";
		}catch(Exception e){
			e.printStackTrace();
			if(e.getMessage()!=null && e.getMessage().length()>200){
				v_message="PDO能耗实绩处理出错："+e.getMessage().substring(0,200);
			}else{
				v_message="PDO能耗实绩处理出错："+e.getMessage();
			}
			throw new Exception(v_message);
		}
		return v_message;
	}
	
	/**南方
		1)、	此接口为纯后台逻辑，不与前端页面交互，收到罩退L2能耗实绩电文时调用；																																							
		2)、	此接口参数为JSON对象（对象结构见数据库表 IF_BAF01_PDO_ENERGY）；																																							
	 * @param json
	 * @return
	 */
	public String ReceiveBaf01Pdo_Energy_Nan(IfBaf01PdoEnergy json) throws Exception{
		String v_message="";
		if(json==null || "".equals(json.toString())){
			v_message="二级接口-宝信罩退炉PDO-能耗实绩为空";
			return v_message;
		}
		//  --(1)、函数参数为JSON对象，先转换为Java实体类，此处以 v_rec_pdo_energy 代替描述
		//暂定
		IfBaf01PdoEnergy v_rec_pdo_energy=json;
		//   --(2)、如果电文中（接口参数）未包含消息时间（MSG_TIME），或为空值，则赋值为当前时刻
		if(v_rec_pdo_energy.getMsg_time()==null){
			v_rec_pdo_energy.setMsg_time(new Date());
		}
		//  --(3)、将对象，插入PDO能耗实绩表（单独的事务）
		try{
			this.getMapper(IfBaf01PdoEnergyMapper.class).insert(v_rec_pdo_energy);
		}catch(Exception e){
			e.printStackTrace();
		}
		//  --(4)、调用处理PDO能耗实绩函数（事务在函数内）
		try{
			v_message=this.getBean(MesApiAnnealPdiPdoImpl.class).ReceiveBaf01Pdo_Energy_D_Nan(v_rec_pdo_energy, v_message);
		}catch(Exception e){
			e.printStackTrace();
			v_message=e.getMessage();
		}
		//  --(5)、拼接接口参数字符串
		 String v_params = "作业日期{"+v_rec_pdo_energy.getWrk_date()+"} 班次{"+v_rec_pdo_energy.getWrk_ord()+"}";
		//  --(6)、写接口日志：与业务处理分开，单独的事务
		try{
			 this.getMapper(IfBaf01LogMapper.class).doInsert(null,"ReceiveBaf01Pdo_Energy",v_params,v_message);
		}catch(Exception e){
			e.printStackTrace();
		}
		return v_message;
	}
	
	
	
	/**
	 *  1)、	此函数为JAVA后台内调函数，可考虑将方法设为私有，由接口 ReceiveBaf01Pdo_Energy 调用；																																							
		2)、	接口参数 IN：V_REC_PDO_ENERGY（L2能耗实绩对象实例）																																							
		3)、	接口参数 OUT：V_MESSAGE（操作结果信息）																																							
	 * @param v_rec_pdo_energy
	 * @param v_message
	 * @return
	 * @throws Exception
	 */
	@Transactional(value="tm", rollbackFor=Exception.class)
	public String ReceiveBaf01Pdo_Energy_D_Nan(IfBaf01PdoEnergy v_rec_pdo_energy,
			String v_message) throws Exception {
		
		//暂时 ??重要
		//  v_mch_code varchar2(20); --请定义为常量（3个厂家的罩退炉，3个接口，取各自代码）
		String v_mch_code = "M0005";//南方
		try{
			//  --(1)、如果对象中作业日期为空，则返回错误信息
			if(v_rec_pdo_energy.getWrk_date()==null || "".equals(v_rec_pdo_energy.getWrk_date())){
				v_message="作业日期为空，无法处理！";
				return v_message;
			}
			//  --(2)、如果对象中班次为空，则返回错误信息
			if(v_rec_pdo_energy.getWrk_ord()==null || "".equals(v_rec_pdo_energy.getWrk_ord())){
				v_message="作业班次为空，无法处理！";
				return v_message;
			}
			//  --(3)、验证罩退能耗实绩是否存在
			MesCrAnnealEnergy mcae=new MesCrAnnealEnergy();
			mcae.setMachine_code(v_mch_code);
			mcae.setWrk_date(v_rec_pdo_energy.getWrk_date());
			mcae.setWrk_ord(v_rec_pdo_energy.getWrk_ord());
			List<MesCrAnnealEnergy> lmcae = this.getMapper(MesCrAnnealEnergyMapper.class).find(mcae, 0, 0);
			if(lmcae!=null && lmcae.size()>0){
				//    --(3.1)、存在则更新记录
				mcae.setCsm_gas(v_rec_pdo_energy.getCsm_gas());
				mcae.setCsm_h2(v_rec_pdo_energy.getCsm_h2());
				mcae.setCsm_n2(v_rec_pdo_energy.getCsm_n2());
				mcae.setCsm_ccl_water(v_rec_pdo_energy.getCsm_ccl_water());
				mcae.setCsm_acd_water(v_rec_pdo_energy.getCsm_acd_water());
				mcae.setCsm_cmpr_air(v_rec_pdo_energy.getCsm_cmpr_air());
				mcae.setCsm_elec(v_rec_pdo_energy.getCsm_elec());
				mcae.setUpdate_opr("L2_PDO");
				mcae.setUpdate_time(new Date());
				this.getMapper(MesCrAnnealEnergyMapper.class).update(mcae);
			}else{
				// --(3.2)、不存在则插入记录
				mcae.setCsm_gas(v_rec_pdo_energy.getCsm_gas());
				mcae.setCsm_h2(v_rec_pdo_energy.getCsm_h2());
				mcae.setCsm_n2(v_rec_pdo_energy.getCsm_n2());
				mcae.setCsm_ccl_water(v_rec_pdo_energy.getCsm_ccl_water());
				mcae.setCsm_acd_water(v_rec_pdo_energy.getCsm_acd_water());
				mcae.setCsm_cmpr_air(v_rec_pdo_energy.getCsm_cmpr_air());
				mcae.setCsm_elec(v_rec_pdo_energy.getCsm_elec());
				mcae.setCreate_opr("L2_PDO");
				mcae.setCreate_time(new Date());
				this.getMapper(MesCrAnnealEnergyMapper.class).insert(mcae);
			}
			//  --(4)、提交事务
			v_message="PDO能耗实绩处理完成！";
		}catch(Exception e){
			e.printStackTrace();
			if(e.getMessage()!=null && e.getMessage().length()>200){
				v_message="PDO能耗实绩处理出错："+e.getMessage().substring(0,200);
			}else{
				v_message="PDO能耗实绩处理出错："+e.getMessage();
			}
			throw new Exception(v_message);
		}
		return v_message;
	}
	
	
	/**艾伯纳
		1)、	此接口为纯后台逻辑，不与前端页面交互，收到罩退L2能耗实绩电文时调用；																																							
		2)、	此接口参数为JSON对象（对象结构见数据库表 IF_BAF01_PDO_ENERGY）；																																							
	 * @param json
	 * @return
	 */
	public String ReceiveBaf01Pdo_Energy_Ai(IfBaf01PdoEnergy json) throws Exception{
		String v_message="";
		if(json==null || "".equals(json.toString())){
			v_message="二级接口-宝信罩退炉PDO-能耗实绩为空";
			return v_message;
		}
		//  --(1)、函数参数为JSON对象，先转换为Java实体类，此处以 v_rec_pdo_energy 代替描述
		//暂定
		IfBaf01PdoEnergy v_rec_pdo_energy=json;
		//   --(2)、如果电文中（接口参数）未包含消息时间（MSG_TIME），或为空值，则赋值为当前时刻
		if(v_rec_pdo_energy.getMsg_time()==null){
			v_rec_pdo_energy.setMsg_time(new Date());
		}
		//  --(3)、将对象，插入PDO能耗实绩表（单独的事务）
		try{
			this.getMapper(IfBaf01PdoEnergyMapper.class).insert(v_rec_pdo_energy);
		}catch(Exception e){
			e.printStackTrace();
		}
		//  --(4)、调用处理PDO能耗实绩函数（事务在函数内）
		try{
			v_message=this.getBean(MesApiAnnealPdiPdoImpl.class).ReceiveBaf01Pdo_Energy_D_Ai(v_rec_pdo_energy, v_message);
		}catch(Exception e){
			e.printStackTrace();
			v_message=e.getMessage();
		}
		//  --(5)、拼接接口参数字符串
		 String v_params = "作业日期{"+v_rec_pdo_energy.getWrk_date()+"} 班次{"+v_rec_pdo_energy.getWrk_ord()+"}";
		//  --(6)、写接口日志：与业务处理分开，单独的事务
		try{
			 this.getMapper(IfBaf01LogMapper.class).doInsert(null,"ReceiveBaf01Pdo_Energy",v_params,v_message);
		}catch(Exception e){
			e.printStackTrace();
		}
		return v_message;
	}
	
	
	
	/**
	 *  1)、	此函数为JAVA后台内调函数，可考虑将方法设为私有，由接口 ReceiveBaf01Pdo_Energy 调用；																																							
		2)、	接口参数 IN：V_REC_PDO_ENERGY（L2能耗实绩对象实例）																																							
		3)、	接口参数 OUT：V_MESSAGE（操作结果信息）																																							
	 * @param v_rec_pdo_energy
	 * @param v_message
	 * @return
	 * @throws Exception
	 */
	@Transactional(value="tm", rollbackFor=Exception.class)
	public String ReceiveBaf01Pdo_Energy_D_Ai(IfBaf01PdoEnergy v_rec_pdo_energy,
			String v_message) throws Exception {
		
		//暂时 ??重要
		//  v_mch_code varchar2(20); --请定义为常量（3个厂家的罩退炉，3个接口，取各自代码）
		String v_mch_code = "M0006";//艾伯纳
		try{
			//  --(1)、如果对象中作业日期为空，则返回错误信息
			if(v_rec_pdo_energy.getWrk_date()==null || "".equals(v_rec_pdo_energy.getWrk_date())){
				v_message="作业日期为空，无法处理！";
				return v_message;
			}
			//  --(2)、如果对象中班次为空，则返回错误信息
			if(v_rec_pdo_energy.getWrk_ord()==null || "".equals(v_rec_pdo_energy.getWrk_ord())){
				v_message="作业班次为空，无法处理！";
				return v_message;
			}
			//  --(3)、验证罩退能耗实绩是否存在
			MesCrAnnealEnergy mcae=new MesCrAnnealEnergy();
			mcae.setMachine_code(v_mch_code);
			mcae.setWrk_date(v_rec_pdo_energy.getWrk_date());
			mcae.setWrk_ord(v_rec_pdo_energy.getWrk_ord());
			List<MesCrAnnealEnergy> lmcae = this.getMapper(MesCrAnnealEnergyMapper.class).find(mcae, 0, 0);
			if(lmcae!=null && lmcae.size()>0){
				//    --(3.1)、存在则更新记录
				mcae.setCsm_gas(v_rec_pdo_energy.getCsm_gas());
				mcae.setCsm_h2(v_rec_pdo_energy.getCsm_h2());
				mcae.setCsm_n2(v_rec_pdo_energy.getCsm_n2());
				mcae.setCsm_ccl_water(v_rec_pdo_energy.getCsm_ccl_water());
				mcae.setCsm_acd_water(v_rec_pdo_energy.getCsm_acd_water());
				mcae.setCsm_cmpr_air(v_rec_pdo_energy.getCsm_cmpr_air());
				mcae.setCsm_elec(v_rec_pdo_energy.getCsm_elec());
				mcae.setUpdate_opr("L2_PDO");
				mcae.setUpdate_time(new Date());
				this.getMapper(MesCrAnnealEnergyMapper.class).update(mcae);
			}else{
				// --(3.2)、不存在则插入记录
				mcae.setCsm_gas(v_rec_pdo_energy.getCsm_gas());
				mcae.setCsm_h2(v_rec_pdo_energy.getCsm_h2());
				mcae.setCsm_n2(v_rec_pdo_energy.getCsm_n2());
				mcae.setCsm_ccl_water(v_rec_pdo_energy.getCsm_ccl_water());
				mcae.setCsm_acd_water(v_rec_pdo_energy.getCsm_acd_water());
				mcae.setCsm_cmpr_air(v_rec_pdo_energy.getCsm_cmpr_air());
				mcae.setCsm_elec(v_rec_pdo_energy.getCsm_elec());
				mcae.setCreate_opr("L2_PDO");
				mcae.setCreate_time(new Date());
				this.getMapper(MesCrAnnealEnergyMapper.class).insert(mcae);
			}
			//  --(4)、提交事务
			v_message="PDO能耗实绩处理完成！";
		}catch(Exception e){
			e.printStackTrace();
			if(e.getMessage()!=null && e.getMessage().length()>200){
				v_message="PDO能耗实绩处理出错："+e.getMessage().substring(0,200);
			}else{
				v_message="PDO能耗实绩处理出错："+e.getMessage();
			}
			throw new Exception(v_message);
		}
		return v_message;
	}
	
	/**
	 *  同炉次号向下相同牌号、相同尺寸（厚度、宽度）的物料集合生成一个检验批号
		检验批号编码规则：炉次号+两位流水号，示例：2619000401）
	 * @param billingList
	 * @return
	 * @throws Exception
	 */
	private Map<String, List<MesCrAnnealM>> groupBillingDataByExcpBatchCode(List<MesCrAnnealM> billingList) throws Exception{
		Map<String, List<MesCrAnnealM>> resultMap = new HashMap<String, List<MesCrAnnealM>>();
		try{
			int i=0;
			for(MesCrAnnealM tmExcpNew : billingList){
				String key=tmExcpNew.getSteel_code()+"T"+tmExcpNew.getMtr_thk()+"T"+tmExcpNew.getMtr_wdt();
				if(resultMap.containsKey(key)){//map中异常批次已存在，将该数据存放到同一个key（key存放的是异常批次）的map中
//					i++;
//					String inspection_lot=tmExcpNew.getBatch_no()+lpad(i+"", 2, "0");
//					tmExcpNew.setInspection_lot(inspection_lot);
//					resultMap.get(key).add(tmExcpNew);
//					String inspection_lot=schedule+lpad(i+"", 2, "0");
					List<MesCrAnnealM> list = resultMap.get(key);
					if(list!=null && list.size()>0){
						tmExcpNew.setInspection_lot(list.get(0).getInspection_lot());
					}
					resultMap.get(key).add(tmExcpNew);
				}else{//map中不存在，新建key，用来存放数据
					i++;
					String inspection_lot=tmExcpNew.getBatch_no()+lpad(i+"", 2, "0");
					tmExcpNew.setInspection_lot(inspection_lot);
					List<MesCrAnnealM> tmpList = new ArrayList<MesCrAnnealM>();
					tmpList.add(tmExcpNew);
					resultMap.put(key, tmpList);
				}
 
			}
		}catch(Exception e){
			throw new Exception("炉次号向下相同牌号、相同尺寸（厚度、宽度）的物料集合生成一个检验批号进行分组时出现异常", e);
		}
		return resultMap;
	}
	
	
	
	
//	public void testgetObjectJson(){
//		List<IfBaf01PdoM> list = this.getMapper(IfBaf01PdoMMapper.class).findWithCondition(null, "", "msg_time desc", 0, 0);
//		
//		JsonConfig jsonConfig=new JsonConfig();
//		jsonConfig.registerJsonValueProcessor(java.util.Date.class, new DateJsonValueProcessor("yyyy-MM-dd HH:mm:ss"));
//		jsonConfig.registerJsonValueProcessor(java.lang.Double.class, new DoubleJsonValueProcessor());
//		jsonConfig.registerJsonValueProcessor(java.lang.Long.class, new LongJsonValueProcessor());
//		jsonConfig.registerJsonValueProcessor(java.lang.Integer.class, new IntegerJsonValueProcessor());
//		JSONObject jsonObject=JSONObject.fromObject(list.get(0),jsonConfig);
//		System.out.println(jsonObject.toString());
//		
//	}
//	
//	public String ReceiveBaf01Pdo_M_TrancTest(IfBaf01PdoM json) throws Exception{
//		String v_message="";
//		if(json==null || "".equals(json.toString())){
//			v_message="二级接口-宝信罩退炉PDO-产出实绩为空";
//			return v_message;
//		}
//		//  --(1)、函数参数为JSON对象，先转换为Java实体类，此处以 v_rec_pdo 代替描述
//		//暂定
//		IfBaf01PdoM v_rec_pdo=json;
//		//  --(2)、如果电文中（接口参数）未包含消息时间（MSG_TIME），或为空值，则赋值为当前时刻
//		if(v_rec_pdo.getMsg_time()==null){
//			v_rec_pdo.setMsg_time(new Date());
//		}
//		//  --(3)、将对象，插入L2产出实绩表（单独的事务）  
//		try{
//			this.getMapper(IfBaf01PdoMMapper.class).insert(v_rec_pdo);
//		}catch(Exception e){
//			e.printStackTrace();
//		}
//		//  --(4)、调用处理L2产出实绩函数（事务在函数内）
//		try{
//			v_message=this.getBean(MesApiAnnealPdiPdoImpl.class).ReceiveTRCIFSLITLOG_TrancTest(v_rec_pdo, v_message);
//		}catch(Exception e){
//			e.printStackTrace();
//			v_message=e.getMessage();
//		}
//		//  --(5)、拼接接口参数字符串
//		String  v_params = ""; 																																			
//		
//		//  --(6)、写接口日志：与业务处理分开，单独的事务
//		try{
//			 this.getMapper(IfBaf01LogMapper.class).doInsert(null,"ReceiveBaf01Pdo_M",v_params,v_message);
//		}catch(Exception e){
//			e.printStackTrace();
//		}
//		return v_message;
//	}
//	
	/**
		过程分析：
		this.getBean(QcmJhySampleConsignMServiceImpl.class).insertIfSlitLog(cpqjsfp);中有
		@Transactional(propagation = Propagation.REQUIRES_NEW,value = "tm", rollbackFor = Exception.class)
		REQUIRES_NEW表示：不管是否存在事务,都创建一个新的事务,原来的挂起,新的执行完毕,继续执行老的事务
		即insertIfSlitLog是新的单独的事务。
		 此结果是this.getMapper(IfTpm01LogMapper.class).doInsert(XXX)会回滚（因为后面的int i=1/0);
	 	insertIfSlitLog方法里面没有报错的话，会插入this.getMapper(IfSlit01LogMapper.class).insert里面，方法报错的话，只针对insertIfSlitLog方法回滚。
	 	ReceiveTRCIFSLITLOG_TrancTest继续执行。
	**/
//	@Transactional(value="tm", rollbackFor=Exception.class)
//	public String ReceiveTRCIFSLITLOG_TrancTest(IfBaf01PdoM v_rec_pdo, String v_message) throws Exception {
//		Integer v_cnt;
//		//  --(1)、根据电文中，构建作业计划号、钢卷号、炉内序号集合
//		try{
//			IfSlit01Log ifs=new IfSlit01Log();
//			ifs.setCreate_time(new Date());
//			ifs.setResult_desc("2018-11-12测试多接口之间的事务回滚，可配置型的Spring事务。");
//			this.getMapper(IfTpm01LogMapper.class).doInsert(null,"测试多接口之间的事务回滚","1","2");
//			CommonPage<QcmJhySampleFromPlan>  cpqjsfp=new CommonPage<QcmJhySampleFromPlan>();
//			cpqjsfp.setObject(new QcmJhySampleFromPlan());
//			try{
//				this.getBean(QcmJhySampleConsignMServiceImpl.class).insertIfSlitLog(cpqjsfp);
//			}catch(Exception e){
//				e.printStackTrace();
//			}
//			int i=1/0;
//		    //  --(3)、提交事务
//			v_message="L2产出实绩处理完成！";
//		}catch(Exception e){
//			e.printStackTrace();
//			if(v_message==null || "".equals(v_message)){
//				if(e.getMessage()!=null && e.getMessage().length()>200){
//					v_message="L2产出实绩处理出错："+e.getMessage().substring(0,200);
//				}else{
//					v_message="L2产出实绩处理出错："+e.getMessage();
//				}
//			}
//			throw new Exception(v_message);
//		}
//		return v_message;
//	}
//	
//	@Transactional(propagation = Propagation.REQUIRES_NEW,value = "tm", rollbackFor = Exception.class)
//	public ResultModel insertIfSlitLog(CommonPage<QcmJhySampleFromPlan> sum) throws Exception {
//		ResultModel rm = new ResultModel();
//		try {
//			QcmJhySampleFromPlan sm = sum.getObject();
//			IfSlit01Log ifs=new IfSlit01Log();
//			ifs.setCreate_time(new Date());
//			ifs.setResult_desc("2018-11-12测试多接口之间的事务回滚，可配置型的Spring事务。");
//			this.getMapper(IfSlit01LogMapper.class).insert(ifs);
//			rm.setState("200");
//			//int i=1/0;
//		} catch (Exception e) {
//			rm.setState("500");
//			rm.setMsgInfo("插入失败！" + e.getMessage());
//			throw new Exception(e.getMessage());
//		}
//		return rm;
//	}
	
	
	// 补零
	public static String lpad(String str, int num, String pad) {
		String n_str = str;
		if (str == null && "".equals(str))
			n_str = " ";
		for (int i = str.length(); i < num; i++) {
			n_str = pad + n_str;
		}
		return n_str;
	}

}
