Browse Source

微浦MES,增加飞达校验,等飞达相关修改

xiaost 3 days ago
parent
commit
a397b84a46

+ 11 - 11
src/com/uas/mes/api/pda/PdaSMTController.java

@@ -344,7 +344,7 @@ public class PdaSMTController extends BaseApiController{
 	}
 
 	/**
-	 * 品质校验 站位料卷校验记录日志
+	 * 品质校验--改名叫品质套料 站位料卷校验记录日志
 	 * @param dsl 校验 type:loading (上料)、join(接料),dsl_location :站位,dsl_prodcode:物料编号,success:boolean true or false
 	 * @param deviceLineMake 线别等信息
 	 */
@@ -403,21 +403,21 @@ public class PdaSMTController extends BaseApiController{
 	}
 
 	/**
-	 * 已经上线更换飞达之后需要进行校验:一进入上料界面,自动发送请求获取未校验站位
+	 * 已经上线更换飞达之后需要进行校验:一进入上料界面,自动发送请求获取未校验飞达
 	 */
 	@RequestMapping(value="/quaGetUnCheckFeeder.action",method = RequestMethod.GET)
-	public ModelMap quaGetUnCheckFeeder (String linecode){
-		//return success(pdaSMTService.quaGetUnCheckFeeder(linecode));
-		return success();
+	public ModelMap quaGetUnCheckFeeder (String linecode,String table){
+		return success(pdaSMTService.quaGetUnCheckFeeder(linecode,table));
 	}
 
 	/**
-	 * 品质校验点击开始校验按钮,自动发送请求,清空校验站位,返回未校验信息
+	 * 飞达更新换之后校验
+	 *  @param deviceLineMake 线别等信息
+	 *  @param fe_code 采集的飞达编号
 	 */
-	@RequestMapping(value="/quaCheckFeederData.action",method = RequestMethod.GET)
-	public ModelMap quaCheckFeederData (String linecode){
-		//return success(pdaSMTService.quaCheckFeederData(linecode));
-		return success();
+	@RequestMapping(value="/quaCheckFeederData.action",method = RequestMethod.POST)
+	public ModelMap quaCheckFeederData (String deviceLineMake,String fe_code){
+		return success(pdaSMTService.quaCheckFeederData(deviceLineMake,fe_code));
 	}
 
 	/**
@@ -457,7 +457,7 @@ public class PdaSMTController extends BaseApiController{
 	}
 
 	/**
-	 * 校验和品质套料校验
+	 * 校验和品质套料校验 ,先判断站位存不存在
 	 * @param li_code
 	 * @param ma_code
 	 * @param dl_table

+ 5 - 0
src/com/uas/mes/pda/service/PdaSMTService.java

@@ -39,6 +39,7 @@ public interface PdaSMTService {
 	List<Map<String, Object>> fuzzySearchProduct(String pr_code);
 	
 	void joinForecastDataCheck(String dsl,String deviceLineMake);
+
 	void ForecastDataCheck(String dsl,String deviceLineMake);
 	
 	Map<String, Object> getUnLoadingLocation (String linecode);
@@ -94,4 +95,8 @@ public interface PdaSMTService {
 	Map<String, Object> loadingCheckLoc(String li_code,String ma_code,String dl_table,String location);
 
 	Map<String, Object> quaCheckLoc(String li_code,String ma_code,String dl_table,String location);
+
+	Map<String, Object> quaGetUnCheckFeeder(String linecode,String table);
+
+	Map<String, Object> quaCheckFeederData(String deviceLineMake,String fe_code);
 }

+ 310 - 122
src/com/uas/mes/pda/service/impl/PdaSMTServiceImpl.java

@@ -184,58 +184,58 @@ public class PdaSMTServiceImpl implements PdaSMTService {
 		String pr_code = null;
 		SqlRowList rs1 = null;
 		String psl_prodcode = null;
-		double bar_remain =0;
+		double bar_remain = 0;
 		//传的字段 DL_ID,DL_DECODE,DL_LINECODE,DL_MACODE,DL_TABLE,DL_STATUSCODE,DL_STATUS,PS_ID,MA_ID
 		SqlRowList rs = null;
 		//判断料卷号工单号不为空
 		Object dl_macode = map.get("DL_MACODE");
-		Object linecode= map.get("DL_LINECODE");
+		Object linecode = map.get("DL_LINECODE");
 		Object table = map.get("DL_TABLE");
 		Object location = map1.get("dsl_location");
 		Object fe_code = "";//= map1.get("dsl_barcode");
 		Object bar_code = map1.get("dsl_barcode");
-		String type="barcode",ps_prodcode = null;
-		int has_make=0;
+		String type = "barcode", ps_prodcode = null;
+		int has_make = 0;
 		String handleType = "上料";
 		boolean bool = baseDao.isDBSetting("smthandleerrlog");
 		String mainline = "";
-		rs = baseDao.queryForRowSet("select dl_macode,dl_hasmake,dl_statuscode,dl_prodcode,dl_mainline from deviceline where dl_linecode =? ",linecode);
-		if(rs.next()){
+		rs = baseDao.queryForRowSet("select dl_macode,dl_hasmake,dl_statuscode,dl_prodcode,dl_mainline from deviceline where dl_linecode =? ", linecode);
+		if (rs.next()) {
 			mainline = rs.getGeneralString("dl_mainline");
-			if(StringUtil.hasText(mainline)){
-				handleType ="备料上料";
+			if (StringUtil.hasText(mainline)) {
+				handleType = "备料上料";
 			}
 			has_make = rs.getInt("dl_hasmake");
 			ps_prodcode = rs.getString("dl_prodcode");
-			if(rs.getString("dl_macode") == null || (rs.getString("dl_macode")!= null &&!rs.getString("dl_macode").equals(dl_macode))){
-				showSmtError(APIErrorCode.DATA_NOT_FOUND,"当前线别在线工单["+dl_macode+"]与需要上线操作的工单不一致",handleType,linecode,location,ps_prodcode,"",bool,table);
-			}else if(("STARTED").equals(rs.getString("dl_statuscode"))){
-				showSmtError(APIErrorCode.DATA_NOT_FOUND,"启动状态不允许上料",handleType,linecode,location,ps_prodcode,"",bool,table);
-	    	}
-		}else{
-			showSmtError(APIErrorCode.DATA_NOT_FOUND,"当前线别"+linecode+"没有绑定工单",handleType,linecode,location,ps_prodcode,"",bool,table);
+			if (rs.getString("dl_macode") == null || (rs.getString("dl_macode") != null && !rs.getString("dl_macode").equals(dl_macode))) {
+				showSmtError(APIErrorCode.DATA_NOT_FOUND, "当前线别在线工单[" + dl_macode + "]与需要上线操作的工单不一致", handleType, linecode, location, ps_prodcode, "", bool, table);
+			} else if (("STARTED").equals(rs.getString("dl_statuscode"))) {
+				showSmtError(APIErrorCode.DATA_NOT_FOUND, "启动状态不允许上料", handleType, linecode, location, ps_prodcode, "", bool, table);
+			}
+		} else {
+			showSmtError(APIErrorCode.DATA_NOT_FOUND, "当前线别" + linecode + "没有绑定工单", handleType, linecode, location, ps_prodcode, "", bool, table);
 		}
 
 		int ps_id = 0;
 		//查询是否存在排位表
 		rs = baseDao.queryForRowSet("select ps_id,ps_devcode from productsmt left join productsmtlocation on ps_id = psl_psid" +
-				"  where ps_prodcode = ? and ps_linecode=? and psl_table = ? and ps_statuscode='AUDITED'",
-				ps_prodcode,StringUtil.hasText(mainline)?mainline:linecode,table);   //线别+物料唯一
-		if(rs.next()){
-           ps_id = rs.getInt("ps_id");
-		}else{
-			showSmtError(APIErrorCode.DATA_NOT_FOUND,"当前线别"+linecode+"+产品:"+ps_prodcode+"+板面:"+table+",未维护已审核的排位表,无法上料",handleType,linecode,location,ps_prodcode,"",bool,table);
+						"  where ps_prodcode = ? and ps_linecode=? and psl_table = ? and ps_statuscode='AUDITED'",
+				ps_prodcode, StringUtil.hasText(mainline) ? mainline : linecode, table);   //线别+物料唯一
+		if (rs.next()) {
+			ps_id = rs.getInt("ps_id");
+		} else {
+			showSmtError(APIErrorCode.DATA_NOT_FOUND, "当前线别" + linecode + "+产品:" + ps_prodcode + "+板面:" + table + ",未维护已审核的排位表,无法上料", handleType, linecode, location, ps_prodcode, "", bool, table);
 		}
 		//是否启动飞达绑定站位
-        boolean feederBindLocation = baseDao.isDBSetting("MESSetting","FeederBindLocation");
-		if(feederBindLocation){
-			rs = baseDao.queryForRowSet("select fe_code,fe_location from feeder where (fe_code=? or fe_location=?) and fe_code is not null",location,location);
-			if(rs.next()){
+		boolean feederBindLocation = baseDao.isDBSetting("MESSetting", "FeederBindLocation");
+		if (feederBindLocation) {
+			rs = baseDao.queryForRowSet("select fe_code,fe_location from feeder where (fe_code=? or fe_location=?) and fe_code is not null", location, location);
+			if (rs.next()) {
 				fe_code = rs.getString("fe_code");
-				if(StringUtil.hasText(rs.getString("fe_location"))){
+				if (StringUtil.hasText(rs.getString("fe_location"))) {
 					location = rs.getString("fe_location");
-				}else{
-					throw new APIErrorException(APIErrorCode.DATA_NOT_FOUND, "采集的飞达:"+location+"未绑定站位,无法上料" );
+				} else {
+					throw new APIErrorException(APIErrorCode.DATA_NOT_FOUND, "采集的飞达:" + location + "未绑定站位,无法上料");
 				}
 			}
 			//判断站位是否在站位表
@@ -243,30 +243,32 @@ public class PdaSMTServiceImpl implements PdaSMTService {
 					+ " where psl_psid=? and psl_location=? and psl_table=? ", ps_id, location, map.get("DL_TABLE"));
 			if (rs.next()) {
 				psl_prodcode = rs.getString("psl_prodcode");
-			}else{
-				throw new APIErrorException(APIErrorCode.DATA_NOT_FOUND, "站位:"+location+"不在排位表中!" );
+			} else {
+				throw new APIErrorException(APIErrorCode.DATA_NOT_FOUND, "站位:" + location + "不在排位表中!");
 			}
+
 			//判断站位是否一定要绑定飞达才可以操作
-			if("".equals(fe_code)) { //说明采集的是站位上料
+			if ("".equals(fe_code)) { //说明采集的是站位上料
 				//站位和飞达一定要有绑定关系才可以操作
 				boolean feederMustBindLocation = baseDao.isDBSetting("MESSetting", "FeederMustBindLocation");
-				if (feederMustBindLocation){
-					throw new APIErrorException(APIErrorCode.DATA_NOT_FOUND, "站位:"+location+"未绑定飞达不允许上料!" );
+				if (feederMustBindLocation) {
+					throw new APIErrorException(APIErrorCode.DATA_NOT_FOUND, "站位:" + location + "未绑定飞达不允许上料!");
 				}
 			}
-			rs = baseDao.queryForRowSet("select bar_code from barcode where bar_code=?",bar_code);
+
+			rs = baseDao.queryForRowSet("select bar_code from barcode where bar_code=?", bar_code);
 			if (rs.next()) {
 				bar_code = rs.getString("bar_code");
 			} else {
 				throw new APIErrorException(APIErrorCode.DATA_NOT_FOUND, "料卷" + bar_code + "不存在");
 			}
-		}else{
+		} else {
 			rs = baseDao.queryForRowSet("select psl_baseqty,psl_prodcode,psl_repcode,psl_feeder,psl_id from productsmtlocation "
 					+ " where psl_psid=? and psl_location=? and psl_table=? ", ps_id, location, map.get("DL_TABLE"));
 			if (rs.next()) {
 				psl_prodcode = rs.getString("psl_prodcode");
-			}else{
-				throw new APIErrorException(APIErrorCode.DATA_NOT_FOUND, "站位:"+location+"不在排位表中!" );
+			} else {
+				throw new APIErrorException(APIErrorCode.DATA_NOT_FOUND, "站位:" + location + "不在排位表中!");
 			}
 			rs = baseDao.queryForRowSet("select dsl_id,dsl_barcode,dsl_prodcode from devSMTLocation where dsl_linecode=? and dsl_makecode=? and dsl_location=? and dsl_status=0 and dsl_table=?", linecode, dl_macode, location, map.get("DL_TABLE"));
 			if (rs.next()) {
@@ -296,15 +298,15 @@ public class PdaSMTServiceImpl implements PdaSMTService {
 			}
 		}
 
-		rs = baseDao.queryForRowSet("select bar_remain,nvl(bar_place,1)bar_place,bar_prodcode,bar_code from barcode where bar_code=? ",bar_code);
-		if(rs.next()){
+		rs = baseDao.queryForRowSet("select bar_remain,nvl(bar_place,1)bar_place,bar_prodcode,bar_code from barcode where bar_code=? ", bar_code);
+		if (rs.next()) {
 			rs1 = baseDao.queryForRowSet("select psl_baseqty,psl_prodcode,psl_repcode,psl_feeder,psl_id from productsmtlocation "
-					+" where psl_psid=? and psl_location=? and psl_table=? and (psl_prodcode=? or psl_repcode=?)",ps_id,location,map.get("DL_TABLE"),rs.getString("bar_prodcode"),rs.getString("bar_prodcode"));
-			if(!rs1.next()){
-				rs1 = baseDao.queryForRowSet("select bo_mothercode,bd_soncode,pre_repcode from wp_replace_view@WP where bo_mothercode = ? and bd_soncode = ? and pre_repcode = ?",ps_prodcode,psl_prodcode,rs.getString("bar_prodcode"));
-				if(!rs1.next()){
-					rs1 = baseDao.queryForRowSet("select bd_mothercode,bd_soncode,prr_reprodcode from PRODUCTRELATION left join bomdetail on bd_id = prr_bdid where bd_mothercode = ? and bd_soncode = ? and prr_reprodcode = ?",ps_prodcode,psl_prodcode,rs.getString("bar_prodcode"));
-					if(!rs1.next()) {
+					+ " where psl_psid=? and psl_location=? and psl_table=? and (psl_prodcode=? or psl_repcode=?)", ps_id, location, map.get("DL_TABLE"), rs.getString("bar_prodcode"), rs.getString("bar_prodcode"));
+			if (!rs1.next()) {
+				rs1 = baseDao.queryForRowSet("select bo_mothercode,bd_soncode,pre_repcode from wp_replace_view@WP where bo_mothercode = ? and bd_soncode = ? and pre_repcode = ?", ps_prodcode, psl_prodcode, rs.getString("bar_prodcode"));
+				if (!rs1.next()) {
+					rs1 = baseDao.queryForRowSet("select bd_mothercode,bd_soncode,prr_reprodcode from PRODUCTRELATION left join bomdetail on bd_id = prr_bdid where bd_mothercode = ? and bd_soncode = ? and prr_reprodcode = ?", ps_prodcode, psl_prodcode, rs.getString("bar_prodcode"));
+					if (!rs1.next()) {
 						rs1 = baseDao.queryForRowSet("select MM_MOTHERCODE,mm_prodcode,mm_repprodcode,mm_code from MakeMaterial@WP where mm_code = ?  and mm_prodcode = ? and mm_repprodcode like '%" + rs.getString("bar_prodcode") + "%'", dl_macode, psl_prodcode);
 						if (!rs1.next()) {
 							rs1 = baseDao.queryForRowSet("select MM_MOTHERCODE,mm_prodcode,mm_repprodcode,mm_code from MakeMaterial@HY where mm_code = ?  and mm_prodcode = ? and mm_repprodcode like '%" + rs.getString("bar_prodcode") + "%'", dl_macode, psl_prodcode);
@@ -315,15 +317,15 @@ public class PdaSMTServiceImpl implements PdaSMTService {
 					}
 				}
 			}
-			if(rs.getDouble("bar_remain") <= 0){
-				showSmtError(APIErrorCode.DATA_NOT_FOUND,"料卷号数量必须大于0",handleType,linecode,location,ps_prodcode,"料卷"+bar_code,bool,table);
-			}else if(!"1".equals(rs.getString("bar_place"))){
-				showSmtError(APIErrorCode.DATA_NOT_FOUND,"料卷已被单据["+rs.getString("bar_place")+"]使用",handleType,linecode,location,ps_prodcode,"料卷"+bar_code,bool,table);
+			if (rs.getDouble("bar_remain") <= 0) {
+				showSmtError(APIErrorCode.DATA_NOT_FOUND, "料卷号数量必须大于0", handleType, linecode, location, ps_prodcode, "料卷" + bar_code, bool, table);
+			} else if (!"1".equals(rs.getString("bar_place"))) {
+				showSmtError(APIErrorCode.DATA_NOT_FOUND, "料卷已被单据[" + rs.getString("bar_place") + "]使用", handleType, linecode, location, ps_prodcode, "料卷" + bar_code, bool, table);
 			}
 			pr_code = rs.getString("bar_prodcode");
 			bar_remain = rs.getDouble("bar_remain");
-		}else{
-//			rs = baseDao.queryForRowSet("select psl_baseqty,psl_prodcode,psl_repcode,psl_feeder,psl_id from productsmtlocation "
+		} else {
+/*			rs = baseDao.queryForRowSet("select psl_baseqty,psl_prodcode,psl_repcode,psl_feeder,psl_id from productsmtlocation "
 //					+" where psl_psid=? and psl_location=? and psl_table=? and (psl_prodcode=? or psl_repcode=?)",ps_id,location,map.get("DL_TABLE"),bar_code,bar_code);
 //			if(rs.next()){
 //				pr_code = (String) bar_code;
@@ -351,16 +353,23 @@ public class PdaSMTServiceImpl implements PdaSMTService {
 //				}else{
 //					showSmtError(APIErrorCode.DATA_NOT_FOUND,"物料["+bar_code+"]不是该站位需要上料的物料",handleType,linecode,location,ps_prodcode,"料号"+bar_code,bool,table);
 //		        }
-//			}
-			showSmtError(APIErrorCode.DATA_NOT_FOUND,"物料["+bar_code+"]不是该站位需要上料的物料",handleType,linecode,location,ps_prodcode,"料号"+bar_code,bool,table);
+//			}*/
+			showSmtError(APIErrorCode.DATA_NOT_FOUND, "物料[" + bar_code + "]不是该站位需要上料的物料", handleType, linecode, location, ps_prodcode, "料号" + bar_code, bool, table);
 		}
 
 		//如果是飞达绑定料卷的 ,更新飞达所在站位
-		if(!feederBindLocation && StringUtil.hasText(fe_code)) {
-			baseDao.updateByCondition("feeder", "fe_location='" + location + "'", "fe_code='" + fe_code + "'");
-			baseDao.execute("insert into feederlog(fl_id,fl_fecode,fl_feid,fl_type,fl_remark,fl_item,fl_man,fl_date)" +
-					" select  feederlog_seq.nextval,'" + fe_code + "',fe_id,'上料','上料至工单:" + dl_macode + ",站位:" + location + "','条码:" + bar_code + "','" + SystemSession.getUser().getEm_name() + "',sysdate from feeder where fe_code = '" + fe_code + "'");
-		}
+		if (StringUtil.hasText(fe_code)) {
+			if (!feederBindLocation) { //原来逻辑
+				baseDao.updateByCondition("feeder", "fe_location='" + location + "'", "fe_code='" + fe_code + "'");
+				baseDao.execute("insert into feederlog(fl_id,fl_fecode,fl_feid,fl_type,fl_remark,fl_item,fl_man,fl_date)" +
+						" select  feederlog_seq.nextval,'" + fe_code + "',fe_id,'上料','上料至工单:" + dl_macode + ",站位:" + location + "','条码:" + bar_code + "','" + SystemSession.getUser().getEm_name() + "',sysdate from feeder where fe_code = '" + fe_code + "'");
+			}else if(feederBindLocation && !StringUtil.hasText(mainline)){ //非备料 更新成 上线 新的站位和飞达绑定的逻辑
+				baseDao.execute("update feeder set fe_usestatus='上线',fe_lastonlinetime=sysdate,fe_lastofflinetime=null where fe_code=?",fe_code);
+			    baseDao.execute("insert into feederlog(FL_ID, FL_FECODE, FL_FEID, FL_TYPE, FL_ITEM, FL_MAN, FL_DATE,FL_LOCATION,FL_LICODE,FL_MACODE,FL_TABLE,fl_isvirtualline) " +
+							" select feederlog_seq.nextval,?,?,?,?,?,sysdate,?,?,?,?,? from dual",
+						fe_code,map.get("FE_ID"),"上线","站位:"+location,SystemSession.getUser().getEm_name(),location,linecode,dl_macode,table,0);
+		   }
+	    }
 		double ma_qty=0;
 		rs = baseDao.queryForRowSet("select ma_qty from make where ma_id=?",map.get("MA_ID"));
 		if(rs.next()){
@@ -440,12 +449,16 @@ public class PdaSMTServiceImpl implements PdaSMTService {
 		Object ma_code = map.get("DL_MACODE");
 		Object table = map.get("DL_TABLE");
 		Object pr_code = null;
+		int has_make=0;
+		int isVir = 0;  //是否虚拟备料线
 		boolean bool = baseDao.isDBSetting("smthandleerrlog");
-		rs = baseDao.queryForRowSet("select dl_statuscode,dl_prodcode,dl_mainline from deviceline where dl_linecode =?",linecode);
+		rs = baseDao.queryForRowSet("select dl_statuscode,dl_prodcode,dl_mainline,dl_hasmake from deviceline where dl_linecode =?",linecode);
 		if(rs.next()){
 			if(StringUtil.hasText(rs.getGeneralString("dl_mainline"))){
 				handleType = "备料下料";
+				isVir = -1;
 			}
+			has_make=rs.getInt("dl_hasmake");
 			pr_code = rs.getString("dl_prodcode");
 			if(("STARTED").equals(rs.getString("dl_statuscode"))){
 				showSmtError(APIErrorCode.BUSINESS_FAILED,"启动状态不允许下料",handleType,linecode,"",pr_code,"",bool,table);
@@ -454,7 +467,7 @@ public class PdaSMTServiceImpl implements PdaSMTService {
 			showSmtError(APIErrorCode.DATA_NOT_FOUND,"当前线别"+linecode+"没有绑定工单/产品编号",handleType,linecode,"",pr_code,"",bool,table);
 		}
 		String fecode="";
-		rsReturn = baseDao.queryForRowSet("select dsl_location,dsl_fecode from devsmtlocation where dsl_linecode=? and dsl_makecode=? and dsl_table=? and dsl_status=0 and (dsl_location =? or dsl_barcode = ? or dsl_fecode=?)",linecode,map.get("DL_MACODE"),map.get("DL_TABLE"),code,code,code);
+		rsReturn = baseDao.queryForRowSet("select dsl_location,dsl_fecode from devsmtlocation where dsl_linecode=? and dsl_makecode=? and dsl_table=? and dsl_status=0 and (dsl_location =? or dsl_barcode = ? or dsl_fecode=?)",linecode,ma_code,table,code,code,code);
 		if(rsReturn.next()){
 			dsl_location = rsReturn.getString("dsl_location"); //站位,一个站位统一下料
 			fecode = rsReturn.getGeneralString("dsl_fecode");
@@ -472,58 +485,69 @@ public class PdaSMTServiceImpl implements PdaSMTService {
 		}*/
 		boolean feederBindLocation = baseDao.isDBSetting("MESSetting","FeederBindLocation");
 		rsReturn = baseDao.queryForRowSet("select max(dsl_location) dsl_location,max(dsl_remainqty) dsl_remainqty,max(dsl_id) dsl_id,max(dsl_barcode) dsl_barcode,max(dsl_fespec) dsl_fespec,max(dsl_prodcode) dsl_prodcode,wm_concat(nvl(dsl_barcode,dsl_prodcode)) dsl_return from devsmtlocation "
-				+ " where dsl_linecode=? and dsl_makecode=? and dsl_status=0 and dsl_location =? and dsl_table =? ",linecode,map.get("DL_MACODE"),dsl_location,map.get("DL_TABLE"));
+				+ " where dsl_linecode=? and dsl_makecode=? and dsl_status=0 and dsl_location =? and dsl_table =? ",linecode,ma_code,dsl_location,table);
 		if(rsReturn.next()){
 			rs = baseDao.queryForRowSet("select sum(dsl_remainqty) dsl_remainqty,max(dsl_id) dsl_id, count(1) cn from"
-					+" devsmtlocation where dsl_linecode=? and dsl_makecode=? and dsl_status=0 and dsl_table=? and dsl_location =? ",linecode,ma_code,map.get("DL_TABLE"),dsl_location);
+					+" devsmtlocation where dsl_linecode=? and dsl_makecode=? and dsl_status=0 and dsl_table=? and dsl_location =? ",linecode,ma_code,ma_code,dsl_location);
 			if(rs.next()){
 				remain = rs.getDouble("dsl_remainqty");  //将第一个料卷剩余料加给第二个料卷
-					if(rs.getInt("cn") == 1){
-						if(rsReturn.getString("dsl_barcode") !=null && !("").equals(rsReturn.getString("dsl_barcode"))){
-							sqls.add("update barcode set bar_place=1 where bar_code='"+rsReturn.getString("dsl_barcode")+"' and bar_place='"+ma_code+"'");
-						}
-					}else{
-						sqls.add("update barcode set bar_place=1 where bar_code in (select dsl_barcode from devsmtlocation"
-								+" where dsl_linecode='"+linecode+"' and dsl_makecode='"+ma_code+"' and dsl_status=0 and dsl_location='"+dsl_location+"' and dsl_table ='"+map.get("DL_TABLE")+"' and dsl_id<>"+rs.getInt("dsl_id")+")  and bar_place='"+ma_code+"'");
-						sqls.add("update barcode set bar_place=1 where bar_code=(select dsl_barcode from devsmtlocation "
-								+" where dsl_id="+rs.getInt("dsl_id")+" and dsl_linecode='"+linecode+"' and dsl_location='"+dsl_location+"' and dsl_makecode='"+ma_code+"' and dsl_status=0 and dsl_table= '"+map.get("DL_TABLE")+"' ) and bar_place='"+ma_code+"'");
-					}
-					    sqls.add("update devsmtlocation set dsl_status=-1,dsl_cutman='"+SystemSession.getUser().getEm_name()+"',dsl_invalidtime=sysdate"
-							+" where dsl_linecode='"+linecode+"' and dsl_makecode='"+ma_code+"' and dsl_status=0 and dsl_location ='"+dsl_location+"' and dsl_table='"+map.get("DL_TABLE")+"' and dsl_invalidtime is  null");
-				        sqls.add("update devsmtlocation set dsl_status=-1,DSL_USABLE = 2 "
-						+" where dsl_linecode='"+linecode+"' and dsl_makecode='"+ma_code+"' and dsl_status=0 and dsl_location ='"+dsl_location+"' and dsl_table='"+map.get("DL_TABLE")+"' ");
-				    //记录日志下料
-				    rs = baseDao.queryForRowSet("select dl_macode,dl_hasmake from deviceline where dl_linecode =?",linecode);
-					int has_make=0;
-					if(rs.next()){
-						has_make=rs.getInt("dl_hasmake");
+				if(rs.getInt("cn") == 1){
+					if(rsReturn.getString("dsl_barcode") !=null && !("").equals(rsReturn.getString("dsl_barcode"))){
+						sqls.add("update barcode set bar_place=1 where bar_code='"+rsReturn.getString("dsl_barcode")+"' and bar_place='"+ma_code+"'");
 					}
-					//把飞达和站位解绑,Untying=-1飞达和条码号解绑
-					if(feederBindLocation){
-						if(StringUtil.hasText(fecode)){
-							sqls.add("update feeder set fe_location='' where  fe_location='"+dsl_location+"' and fe_code='"+fecode+"'");
-						}
-					}else{
-						if(Untying==-1){
-							sqls.add("update feeder set fe_location='',fe_barcode='' where fe_location='"+dsl_location+"'");
-						}else {
-							sqls.add("update feeder set fe_location='' where  fe_location='"+dsl_location+"' and fe_code='"+fecode+"'");
+				}else{
+					sqls.add("update barcode set bar_place=1 where bar_code in (select dsl_barcode from devsmtlocation"
+							+" where dsl_linecode='"+linecode+"' and dsl_makecode='"+ma_code+"' and dsl_status=0 and dsl_location='"+dsl_location+"' and dsl_table ='"+table+"' and dsl_id<>"+rs.getInt("dsl_id")+")  and bar_place='"+ma_code+"'");
+					sqls.add("update barcode set bar_place=1 where bar_code=(select dsl_barcode from devsmtlocation "
+							+" where dsl_id="+rs.getInt("dsl_id")+" and dsl_linecode='"+linecode+"' and dsl_location='"+dsl_location+"' and dsl_makecode='"+ma_code+"' and dsl_status=0 and dsl_table= '"+table+"' ) and bar_place='"+ma_code+"'");
+				}
+					sqls.add("update devsmtlocation set dsl_status=-1,dsl_cutman='"+SystemSession.getUser().getEm_name()+"',dsl_invalidtime=sysdate"
+						+" where dsl_linecode='"+linecode+"' and dsl_makecode='"+ma_code+"' and dsl_status=0 and dsl_location ='"+dsl_location+"' and dsl_table='"+table+"' and dsl_invalidtime is  null");
+					sqls.add("update devsmtlocation set dsl_status=-1,DSL_USABLE = 2 "
+					+" where dsl_linecode='"+linecode+"' and dsl_makecode='"+ma_code+"' and dsl_status=0 and dsl_location ='"+dsl_location+"' and dsl_table='"+table+"' ");
+				//记录日志下料
+				//把飞达和站位解绑,Untying=-1飞达和条码号解绑
+				if(feederBindLocation){
+					if(StringUtil.hasText(fecode)){
+						String type = "下线";
+						String sql = "update feeder set fe_location=''";
+						//非虚拟的 更新飞达状态,上线时间等,插入日志??
+						if(isVir == 0){
+							sql += ",fe_lastofflinetime=sysdate," +
+									"fe_usetotalmin=nvl(fe_usetotalmin,0)+(case when fe_lastonlinetime is not null then" +
+									"  round((sysdate-fe_lastonlinetime)*24*60) else 0 end)," +
+									" fe_lastonlinetime=null,fe_usestatus='未使用' ";
+						}else{
+							type = "解绑站位";
+							isVir = -1;
 						}
+						sqls.add("insert into feederlog(FL_ID,FL_FECODE,FL_FEID, FL_TYPE, FL_ITEM, FL_MAN, FL_DATE,FL_LOCATION,FL_LICODE,FL_MACODE,FL_TABLE,fl_isvirtualline) "
+								+" select feederlog_seq.nextval,'"+fecode+"',fe_id,'"+type+"','站位:"+dsl_location+","+handleType+"','"+SystemSession.getUser().getEm_name()+"',"
+								+" sysdate,'"+dsl_location+"','"+linecode+"','"+ma_code+"','"+table+"',"+isVir+" from feeder where fe_code='"+fecode+"' and fe_location='"+dsl_location+"'");
+						sql += " where fe_location='"+dsl_location+"' and fe_code='"+fecode+"'";
+						sqls.add(sql);
 					}
-					//备料下料就删除数据
-					if(handleType.equals("备料下料")){
-						sqls.add("insert into makesmtlocation(msl_id,msl_maid,msl_makecode,msl_mcid,msl_mccode,msl_mmdetno,msl_location,msl_prodcode,msl_repcode,msl_fespec,"
-								+"msl_baseqty,msl_table,msl_needqty,msl_getqty,msl_remainqty,msl_fecode,msl_barcode,msl_linecode,msl_devcode,msl_status"
-								+",msl_indate,msl_ifcheck,msl_validtime,msl_invalidtime,msl_smtid,msl_inman,msl_cutman,msl_fprodcode,msl_usable,msl_madeqty,msl_aoimadeqty,MSL_QUAIFCHECK)"
-								+"select makesmtlocation_seq.nextval,dsl_maid,dsl_makecode,dsl_mcid,dsl_mccode,dsl_mmdetno,dsl_location,dsl_prodcode,dsl_repcode,dsl_fespec,"
-								+"dsl_baseqty,dsl_table,dsl_needqty,dsl_getqty,dsl_remainqty,dsl_fecode,dsl_barcode,dsl_linecode,dsl_devcode,dsl_status"
-								+",dsl_indate,dsl_ifcheck,dsl_validtime,dsl_invalidtime,dsl_smtid,dsl_inman,dsl_cutman,dsl_fprodcode,dsl_usable,dsl_madeqty,dsl_aoimadeqty," +
-								" DSL_QUAIFCHECK from devsmtlocation where dsl_linecode='"+linecode+"' and dsl_makecode='"+ma_code+"' and dsl_status=-1 and dsl_location='"+dsl_location+"'");
-						sqls.add("delete from devsmtlocation where dsl_linecode='"+linecode+"' and dsl_makecode='"+ma_code+"' and dsl_status=-1 and dsl_location='"+dsl_location+"'");
+				}else{
+					if(Untying==-1){
+						sqls.add("update feeder set fe_location='',fe_barcode='' where fe_location='"+dsl_location+"'");
+					}else {
+						sqls.add("update feeder set fe_location='' where  fe_location='"+dsl_location+"' and fe_code='"+fecode+"'");
 					}
-                    baseDao.execute(sqls);
-				    baseDao.execute(INSERT_SMTLOG,SystemSession.getUser().getEm_name(),handleType,"下料成功,"+(has_make == -1 ? "工单":"产品")+":"+ma_code+",料卷号或站位:"+code,linecode,dsl_location,0,pr_code,rsReturn.getString("dsl_return"),map.get("DL_TABLE"),has_make == -1?ma_code:"",fecode);
-				    return rsReturn.getResultList();
+				}
+				//备料下料就删除数据
+				if(handleType.equals("备料下料")){
+					sqls.add("insert into makesmtlocation(msl_id,msl_maid,msl_makecode,msl_mcid,msl_mccode,msl_mmdetno,msl_location,msl_prodcode,msl_repcode,msl_fespec,"
+							+"msl_baseqty,msl_table,msl_needqty,msl_getqty,msl_remainqty,msl_fecode,msl_barcode,msl_linecode,msl_devcode,msl_status"
+							+",msl_indate,msl_ifcheck,msl_validtime,msl_invalidtime,msl_smtid,msl_inman,msl_cutman,msl_fprodcode,msl_usable,msl_madeqty,msl_aoimadeqty,MSL_QUAIFCHECK)"
+							+"select makesmtlocation_seq.nextval,dsl_maid,dsl_makecode,dsl_mcid,dsl_mccode,dsl_mmdetno,dsl_location,dsl_prodcode,dsl_repcode,dsl_fespec,"
+							+"dsl_baseqty,dsl_table,dsl_needqty,dsl_getqty,dsl_remainqty,dsl_fecode,dsl_barcode,dsl_linecode,dsl_devcode,dsl_status"
+							+",dsl_indate,dsl_ifcheck,dsl_validtime,dsl_invalidtime,dsl_smtid,dsl_inman,dsl_cutman,dsl_fprodcode,dsl_usable,dsl_madeqty,dsl_aoimadeqty," +
+							" DSL_QUAIFCHECK from devsmtlocation where dsl_linecode='"+linecode+"' and dsl_makecode='"+ma_code+"' and dsl_status=-1 and dsl_location='"+dsl_location+"'");
+					sqls.add("delete from devsmtlocation where dsl_linecode='"+linecode+"' and dsl_makecode='"+ma_code+"' and dsl_status=-1 and dsl_location='"+dsl_location+"'");
+				}
+				baseDao.execute(sqls);
+				baseDao.execute(INSERT_SMTLOG,SystemSession.getUser().getEm_name(),handleType,"下料成功,"+(has_make == -1 ? "工单":"产品")+":"+ma_code+",料卷号或站位:"+code,linecode,dsl_location,0,pr_code,rsReturn.getString("dsl_return"),map.get("DL_TABLE"),has_make == -1?ma_code:"",fecode);
+				return rsReturn.getResultList();
 			}else{
 				showSmtError(APIErrorCode.DATA_NOT_FOUND,"机台+工单+"+code+" 无上料数据,无需下料",handleType,linecode,dsl_location,pr_code,"",bool,table);
 			}
@@ -542,6 +566,7 @@ public class PdaSMTServiceImpl implements PdaSMTService {
 		String dl_table="",dl_devcode = "",dl_prodcode,dl_mainline;
 		int dl_checkcount,dl_smtid,dl_hasmake,dl_id,dl_quacheckcount;
 		String handType = "全部下料";
+		int isVir = 0; //是否虚拟备料线
 		//先判断传过来的值dl_madeqty,必须大于0,并且介于dl_madeqty和ma_qty之间
 		if(dl_madeqty<0){
 			throw new APIErrorException(APIErrorCode.BUSINESS_FAILED,"产出数不允许小于0");
@@ -561,8 +586,9 @@ public class PdaSMTServiceImpl implements PdaSMTService {
 				dl_mainline = rs.getGeneralString("dl_mainline");
 				if(StringUtil.hasText(dl_mainline)){
 					handType ="备料全部下料";
+					isVir = -1 ;
 				}
-//				if(dl_madeqty < madeqty ){
+/*				if(dl_madeqty < madeqty ){
 //					throw new APIErrorException(APIErrorCode.BUSINESS_FAILED,"数量不能小于产出数");
 //				}else{
 //					if(rs.getInt("dl_hasmake")==-1){
@@ -580,7 +606,7 @@ public class PdaSMTServiceImpl implements PdaSMTService {
 //							}
 //						}
 //					}
-//				}
+//				}*/
 			}else{
 				throw new APIErrorException(APIErrorCode.BUSINESS_FAILED,"当前线别+板面无在线工单,无需全部下料!");
 			}
@@ -609,10 +635,9 @@ public class PdaSMTServiceImpl implements PdaSMTService {
 			double remainAddQty,dsl_remainqty;
 			String dsl_location;
 			while(rs.next()){
-				remainAddQty = 0;
 				dsl_remainqty = rs.getDouble("dsl_remainqty");
 				dsl_location = rs.getString("dsl_location");
-				remainAddQty = rs.getDouble("remainAddQty");
+				remainAddQty = rs.getGeneralDouble("remainAddQty");
 
 				//dsl_remainqty -= remainAddQty;
 				if(rs.getInt("cn")==1){//只有一条记录
@@ -620,7 +645,24 @@ public class PdaSMTServiceImpl implements PdaSMTService {
 					sqls.add("update devsmtlocation set dsl_remainqty="+dsl_remainqty+" where dsl_id="+rs.getInt("dsl_id"));
 					sqls.add("update barcode set bar_place=1,bar_forcastremain="+dsl_remainqty+",bar_remain="+dsl_remainqty+" where bar_code='"+rs.getString("dsl_barcode")+"' and bar_place='"+dl_macode+"'");
                     if(feederBindLocation && StringUtil.hasText(rs.getString("dsl_fecode"))){
-						sqls.add("update feeder set fe_location='' where fe_location='" + dsl_location + "' AND FE_CODE='"+rs.getString("dsl_fecode")+"'");
+						String fecode = rs.getString("dsl_fecode");
+						String type = "下线";
+						String sql = "update feeder set fe_location=''";
+						//非虚拟的 更新飞达状态,上线时间等,插入日志??
+						if(isVir == 0){
+							sql += ",fe_lastofflinetime=sysdate," +
+									"fe_usetotalmin=nvl(fe_usetotalmin,0)+(case when fe_lastonlinetime is not null then" +
+									"  round((sysdate-fe_lastonlinetime)*24*60) else 0 end)," +
+									" fe_lastonlinetime=null,fe_usestatus='未使用' ";
+						}else{
+							type = "解绑站位";
+							isVir = -1;
+						}
+						sqls.add("insert into feederlog(FL_ID,FL_FECODE,FL_FEID, FL_TYPE, FL_ITEM, FL_MAN, FL_DATE,FL_LOCATION,FL_LICODE,FL_MACODE,FL_TABLE,fl_isvirtualline) "
+								+" select feederlog_seq.nextval,'"+fecode+"',fe_id,'"+type+"','站位:"+dsl_location+","+handType+"','"+SystemSession.getUser().getEm_name()+"',"
+								+" sysdate,'"+dsl_location+"','"+dl_linecode+"','"+dl_macode+"','"+dl_table+"',"+isVir+" from feeder where fe_code='"+fecode+"' and fe_location='"+dsl_location+"'");
+						sql += " where fe_location='"+dsl_location+"' and fe_code='"+fecode+"'";
+						sqls.add(sql);
 					}else {
 						if (Untying == -1) {
 							sqls.add("update feeder set fe_location='',fe_barcode='' where fe_location='" + dsl_location + "'");
@@ -652,7 +694,24 @@ public class PdaSMTServiceImpl implements PdaSMTService {
 					}
 					//把飞达和站位解绑,Untying=-1飞达和条码号解绑
 					if(feederBindLocation && StringUtil.hasText(rs.getString("dsl_fecode"))){
-						sqls.add("update feeder set fe_location='' where fe_location='" + dsl_location + "' AND FE_CODE='"+rs.getString("dsl_fecode")+"'");
+						String fecode = rs.getString("dsl_fecode");
+						String type = "下线";
+						String sql = "update feeder set fe_location=''";
+						//非虚拟的 更新飞达状态,上线时间等,插入日志??
+						if(isVir == 0){
+							sql += ",fe_lastofflinetime=sysdate," +
+									"fe_usetotalmin=nvl(fe_usetotalmin,0)+(case when fe_lastonlinetime is not null then" +
+									"  round((sysdate-fe_lastonlinetime)*24*60) else 0 end)," +
+									" fe_usestatus='未使用' ";
+						}else{
+							type = "解绑站位";
+							isVir = -1;
+						}
+						sqls.add("insert into feederlog(FL_ID,FL_FECODE,FL_FEID, FL_TYPE, FL_ITEM, FL_MAN, FL_DATE,FL_LOCATION,FL_LICODE,FL_MACODE,FL_TABLE,fl_isvirtualline) "
+								+" select feederlog_seq.nextval,'"+fecode+"',fe_id,'"+type+"','站位:"+dsl_location+","+handType+"','"+SystemSession.getUser().getEm_name()+"',"
+								+" sysdate,'"+dsl_location+"','"+dl_linecode+"','"+dl_macode+"','"+dl_table+"',"+isVir+" from feeder where fe_code='"+fecode+"' and fe_location='"+dsl_location+"'");
+						sql += " where fe_location='"+dsl_location+"' and fe_code='"+fecode+"'";
+						sqls.add(sql);
 					}else {
 						if (Untying == -1) {
 							sqls.add("update feeder set fe_location='',fe_barcode='' where fe_location='" + dsl_location + "'");
@@ -1361,8 +1420,8 @@ public class PdaSMTServiceImpl implements PdaSMTService {
 		}
 		rs0 = baseDao.queryForRowSet("select wm_concat(distinct psl_location) psl_location,count(1) cn from"
 				+" productsmt left join productsmtlocation on ps_id=psl_psid where ps_linecode=? and ps_prodcode=? and psl_table=?"
-				+" and  psl_location not in (select dsl_location  from devsmtlocation where dsl_linecode=? and dsl_makecode=? and dsl_table=?"
-				+" and dsl_status=0  ) and rownum<30",map.get("DL_LINECODE"),ma_prodcode,map.get("DL_TABLE"),map.get("DL_LINECODE"),
+				+" and  psl_location not in (select dsl_location from devsmtlocation where dsl_linecode=? and dsl_makecode=? and dsl_table=?"
+				+" and dsl_status=0 ) and rownum<30",map.get("DL_LINECODE"),ma_prodcode,map.get("DL_TABLE"),map.get("DL_LINECODE"),
 				map.get("DL_MACODE"),map.get("DL_TABLE"));
 		if(rs0.next() && rs0.getInt("cn") > 0){
 			unloadLocation = rs0.getString("psl_location");
@@ -2416,7 +2475,8 @@ public class PdaSMTServiceImpl implements PdaSMTService {
 	 */
 	@Override
 	public Map<String, Object> getFeederBindCheck(String fecode,String type) {
-		SqlRowList rs = baseDao.queryForRowSet("select fe_id,fe_festatus,fe_location,fe_barcode,fe_code from feeder where fe_code=?",fecode);
+		SqlRowList rs = baseDao.queryForRowSet("select fe_id,fe_festatus,fe_location,fe_barcode,fe_code," +
+				"   round(case when nvl(fe_lastmaintain,sysdate-10000) = sysdate-10000 then 0 else fe_lastmaintain+30-sysdate end) remainday,fe_usestatus from feeder where fe_code=?",fecode);
 		if(rs.next()){
 			if(type.equals("bind")) { //绑定
 				if (!rs.getString("fe_festatus").contains("正常")) {
@@ -2425,6 +2485,10 @@ public class PdaSMTServiceImpl implements PdaSMTService {
 				if(StringUtil.hasText(rs.getString("fe_location"))) {
 					throw new APIErrorException(APIErrorCode.DATA_NOT_FOUND, "飞达:"+fecode+"已绑定站位"+rs.getString("fe_location")+"!");
 				}
+				//判断飞达剩余需要绑定时间,如果是负数
+				if(rs.getGeneralInt("remainday")<0){
+					throw new APIErrorException(APIErrorCode.DATA_NOT_FOUND, "飞达:"+fecode+"保养倒计时出现负数【"+rs.getGeneralInt("remainday")+"】!");
+				}
 			}
 			if(type.equals("unbind")) { //解绑
 				if(!StringUtil.hasText(rs.getString("fe_location"))) {
@@ -2447,6 +2511,7 @@ public class PdaSMTServiceImpl implements PdaSMTService {
 	@Transactional
 	public Map<String, Object> feederBindLocation(String fecode, String location) {
 		Map<String, Object> map = getFeederBindCheck(fecode,"bind");
+		String type = "绑定站位";
 		//判断站位是否存在,DeviceLocation
 		SqlRowList rs = baseDao.queryForRowSet("select * from DeviceLocation where DL_LOCATION=?",location);
 		if(rs.next()){
@@ -2456,11 +2521,31 @@ public class PdaSMTServiceImpl implements PdaSMTService {
 				throw new APIErrorException(APIErrorCode.DATA_NOT_FOUND, "站位:"+location+"已经绑定飞达:"+bfeeder);
 			}
 			baseDao.execute("update feeder set fe_location=? where fe_code=?",location,fecode);
+
 			//如果站位是在线的devsmtlocation 表里面并且dsl_status=0,并且线别非虚拟线别 未校验不可以接料
-			baseDao.execute("update devsmtlocation set dsl_iffeedcheck=-1,DSL_FECODE=? where dsl_id in (select dsl_id from devsmtlocation left join line on dsl_linecode=li_code " +
-					"where dsl_location=? and dsl_status=0 and nvl(li_isvirtual,0)=0)",fecode,location);
-			baseDao.execute("insert into feederlog(FL_ID, FL_FECODE, FL_FEID, FL_TYPE, FL_ITEM, FL_MAN, FL_DATE) " +
-					" select feederlog_seq.nextval,?,?,'绑定站位',?,?,sysdate from dual",fecode,map.get("FE_ID"),"站位:"+location,SystemSession.getUser().getEm_name());
+			baseDao.execute("update devsmtlocation set DSL_FECODE=? where dsl_id in (select dsl_id from devsmtlocation " +
+					"where dsl_location=? and dsl_status=0 )",fecode,location);
+
+			//非虚拟线才更新是否飞达校验
+			baseDao.execute("update devsmtlocation set dsl_iffeedcheck=-1 where dsl_id in (select dsl_id from devsmtlocation left join line on dsl_linecode=li_code " +
+					"where dsl_location=? and dsl_status=0 and nvl(li_isvirtual,0)=0) and DSL_FECODE=?",location,fecode);
+
+            SqlRowList rs1 = baseDao.queryForRowSet("select DSL_MAKECODE,DSL_TABLE,DSL_LINECODE,nvl(li_isvirtual,0)li_isvirtual  from devsmtlocation left join line on dsl_linecode=li_code " +
+					" where dsl_location=? and dsl_status=0 and DSL_FECODE=? ",location,fecode);
+			if(rs1.next()){
+               if(rs1.getInt("li_isvirtual") == 0 ){ //非虚拟线,描述为上线绑定站位
+                  type = "上线绑定站位";
+				  //更新飞达状态为上线,最近一次上次日期,下线日期更新为空
+				  baseDao.execute("update feeder set fe_usestatus='上线',fe_lastonlinetime=sysdate,fe_lastofflinetime=null where fe_code=?",fecode);
+			   }
+				baseDao.execute("insert into feederlog(FL_ID, FL_FECODE, FL_FEID, FL_TYPE, FL_ITEM, FL_MAN, FL_DATE,FL_LOCATION,FL_LICODE,FL_MACODE,FL_TABLE,fl_isvirtualline) " +
+								" select feederlog_seq.nextval,?,?,?,?,?,sysdate,?,?,?,?,? from dual",
+						fecode,map.get("FE_ID"),type,"站位:"+location,SystemSession.getUser().getEm_name(),location,rs1.getString("dsl_linecode"),rs1.getString("dsl_makecode"),rs1.getString("dsl_table"),rs1.getInt("li_isvirtual"));
+			}else{
+				baseDao.execute("insert into feederlog(FL_ID, FL_FECODE, FL_FEID, FL_TYPE, FL_ITEM, FL_MAN, FL_DATE,FL_LOCATION) " +
+								" select feederlog_seq.nextval,?,?,?,?,?,sysdate,? from dual",
+						fecode,map.get("FE_ID"),type,"站位:"+location,SystemSession.getUser().getEm_name(),location);
+			}
 			Map<String, Object> rmap = new HashMap<>();
 			rmap.put("location",location);
 			rmap.put("fecode",fecode);
@@ -2480,15 +2565,35 @@ public class PdaSMTServiceImpl implements PdaSMTService {
 	@Transactional
 	public Map<String, Object> feederUnBindLocation(String fecode, String location) {
 		Map<String, Object> map = getFeederBindCheck(fecode,"unbind");
+		String type = "解绑站位";
 		if(!location.equals(map.get("FE_LOCATION"))){
 			throw new APIErrorException(APIErrorCode.DATA_NOT_FOUND, "站位:"+location+"和飞达非绑定关系!绑定的飞达为:"+map.get("FE_LOCATION"));
 		}
-		baseDao.execute("update feeder set fe_location=null where fe_code=?",fecode);
+		String sql = "update feeder set fe_location=null ";
+		if("上线".equals(map.get("FE_USESTATUS"))){   //更新飞达最近一次下线时间,累计使用时间
+			sql += ",fe_lastofflinetime=sysdate," +
+					"fe_usetotalmin=nvl(fe_usetotalmin,0)+(case when fe_lastonlinetime is not null then round((sysdate-fe_lastonlinetime)*24*60) else 0 end)," +
+					"fe_lastonlinetime=null,fe_usestatus='未使用'";
+		}
+		baseDao.execute(sql + " where fe_code=?",fecode);
+
+		SqlRowList rs1 = baseDao.queryForRowSet("select DSL_MAKECODE,DSL_TABLE,DSL_LINECODE,nvl(li_isvirtual,0)li_isvirtual  from devsmtlocation left join line on dsl_linecode=li_code " +
+				" where dsl_location=? and dsl_status=0 and DSL_FECODE=? ",location,fecode);
+		if(rs1.next()){
+			if(rs1.getInt("li_isvirtual") == 0 ) { //非虚拟线,描述为上线绑定站位
+				type = "下线解绑站位";
+			}
+			baseDao.execute("insert into feederlog(FL_ID, FL_FECODE, FL_FEID, FL_TYPE, FL_ITEM, FL_MAN, FL_DATE,FL_LOCATION,FL_LICODE,FL_MACODE,FL_TABLE,fl_isvirtualline) " +
+							" select feederlog_seq.nextval,?,?,?,?,?,sysdate,?,?,?,?,? from dual",
+					fecode,map.get("FE_ID"),type,"站位:"+location,SystemSession.getUser().getEm_name(),location,rs1.getString("dsl_linecode"),rs1.getString("dsl_makecode"),rs1.getString("dsl_table"),rs1.getInt("li_isvirtual"));
+		}else{
+			baseDao.execute("insert into feederlog(FL_ID, FL_FECODE, FL_FEID, FL_TYPE, FL_ITEM, FL_MAN, FL_DATE,FL_LOCATION) " +
+							" select feederlog_seq.nextval,?,?,?,?,?,sysdate,? from dual",
+					fecode,map.get("FE_ID"),type,"站位:"+location,SystemSession.getUser().getEm_name(),location);
+		}
 		//如果站位是在线的devsmtlocation 表里面并且dsl_status=0,并且线别非虚拟线别 未校验不可以接料
 		baseDao.execute("update devsmtlocation set dsl_iffeedcheck=0,DSL_FECODE=null where dsl_id in (select dsl_id from devsmtlocation left join line on dsl_linecode=li_code " +
-				"where dsl_location=? and dsl_status=0 and nvl(li_isvirtual,0)=0)",location);
-		baseDao.execute("insert into feederlog(FL_ID, FL_FECODE, FL_FEID, FL_TYPE, FL_ITEM, FL_MAN, FL_DATE) " +
-				" select feederlog_seq.nextval,?,?,'解绑站位',?,?,sysdate from dual",fecode,map.get("FE_ID"),"站位:"+location,SystemSession.getUser().getEm_name());
+				"where dsl_location=? and dsl_status=0)",location); //and nvl(li_isvirtual,0)=0 虚拟非虚拟线解绑都更新
 		Map<String, Object> rmap = new HashMap<>();
 		rmap.put("location",location);
 		rmap.put("fecode",fecode);
@@ -2659,13 +2764,26 @@ public class PdaSMTServiceImpl implements PdaSMTService {
 				if(count == 0){
 					throw new APIErrorException(APIErrorCode.BUSINESS_FAILED,"无在线的备料数据,无法上线!");
 				}
-				 //	baseDao.execute("update deviceline set dl_macode=? ,dl_table=?,dl_hasmake=?,dl_smtid=?,dl_prodcode=?,
+				//飞达的保养倒计时为负数,不允许上线
+				String err = baseDao.getJdbcTemplate().queryForObject("select LOB_CONCAT(DSL_FECODE) from devsmtlocation left join feeder on fe_code=DSL_FECODE" +
+						" where dsl_linecode=? and dsl_makecode=? and dsl_table=? and fe_id>0 " +
+						" and round(case when nvl(fe_lastmaintain,sysdate-10000) = sysdate-10000 then 0 else fe_lastmaintain+30-sysdate end)<0 ",String.class,liCode,maCode,dlTable);
+				if(StringUtil.hasText(err)){
+					throw new APIErrorException(APIErrorCode.BUSINESS_FAILED,"存在飞达的保养倒计时为负数,无法上线!飞达编号:"+err);
+				}
+				//	baseDao.execute("update deviceline set dl_macode=? ,dl_table=?,dl_hasmake=?,dl_smtid=?,dl_prodcode=?,
 				//	dl_madeqty=0,dl_actmadeqty=0,dl_checkcount=0,dl_decode=?,dl_quacheckcount=0,dl_mainline=? where dl_linecode=?",
 				//	ma_code,dl_table,has_make,rs0.getInt("ps_id"),ma_prodcode,rs0.getString("ps_devcode"),mainlicode,li_code);
 				 baseDao.execute("update deviceline set dl_linecode=? where dl_linecode=?",liCode,mainline);
                  baseDao.execute("update deviceline set dl_mainline=null,dl_linecode=? where dl_id=?",mainline,rs.getGeneralInt("dl_id"));
 				 baseDao.execute("update devsmtlocation set dsl_linecode=? where dsl_linecode=? and dsl_makecode=? and dsl_table=?",mainline,liCode,maCode,dlTable);
 				 baseDao.execute(INSERT_SMTLOG,SystemSession.getUser().getEm_name(),"备料上线","备料上线,工单:"+maCode+",备料线别:"+liCode+",实际线别:"+mainline,mainline,"",0,rs.getString("dl_prodcode"),"",dlTable,maCode,"");
+				//更新飞达的在线状态、插入日志为备料上线等
+				baseDao.execute("insert into feederlog(FL_ID, FL_FECODE, FL_FEID, FL_TYPE, FL_ITEM, FL_MAN, FL_DATE,FL_LOCATION,FL_LICODE,FL_MACODE,FL_TABLE) " +
+								" select feederlog_seq.nextval,DSL_FECODE,fe_id,'上线','备料转上线,备料线别:"+liCode+"',?,sysdate,dsl_location,dsl_linecode,dsl_makecode,dsl_table from devsmtlocation left join feeder on fe_code=dsl_fecode" +
+								" where dsl_linecode=? and dsl_makecode=? and dsl_table=? and nvl(DSL_FECODE,' ')<>' ' ",
+						SystemSession.getUser().getEm_name(),mainline,maCode,dlTable);
+                baseDao.execute("update feeder set fe_usestatus='上线',fe_lastonlinetime=sysdate,fe_lastofflinetime=null where fe_code in (select dsl_fecode from devsmtlocation where dsl_linecode=? and dsl_makecode=? and dsl_table=? and nvl(DSL_FECODE,' ')<>' ')",mainline,maCode,dlTable);
 			}else{
 				throw new APIErrorException(APIErrorCode.BUSINESS_FAILED,"备料线别["+liCode+"]备料对应的实际线别["+rs.getString("dl_mainline")+"],在线别表中不存在!");
 			}
@@ -2783,6 +2901,76 @@ public class PdaSMTServiceImpl implements PdaSMTService {
 		}
 	}
 
+	/**
+	 * 获取未校验飞达
+	 * @param linecode
+	 * @return
+	 */
+	@Override
+	public Map<String, Object> quaGetUnCheckFeeder(String linecode,String dltable) {
+		SqlRowList rs = null;
+		Object macode = null;
+		Object table = null;
+		Object ps_prodcode = null;
+		String mainline = null;
+		Map<String,Object> mapR = new HashMap<String,Object>();
+		rs = baseDao.queryForRowSet("select dl_macode,dl_table,dl_prodcode from deviceline where dl_linecode = ? and dl_table=?",linecode,dltable);
+		if(rs.next()){
+			macode = rs.getString("dl_macode");
+			table = rs.getString("dl_table");
+			ps_prodcode = rs.getString("dl_prodcode");
+		}
+		//是否存在有校验记录,或者点了重新校验recheck==1
+		int cn = baseDao.getJdbcTemplate().queryForObject("select count(1) FROM (select dsl_location,dsl_fecode from devsmtlocation where " +
+				"  dsl_linecode=? and dsl_makecode=? and dsl_table=? and dsl_status=0 and dsl_iffeedcheck = -1 GROUP BY dsl_location,dsl_fecode) ",
+				Integer.class,linecode,macode,table);
+		if(cn>0) {
+			//未校验站位前二十条
+			rs = baseDao.queryForRowSet("select * from (select dsl_location,dsl_fecode from devsmtlocation where " +
+					"  dsl_linecode=? and dsl_makecode=? and dsl_table=? and dsl_status=0 and dsl_iffeedcheck = -1"
+					+" group by dsl_location,dsl_fecode) where rownum<=20 ",
+					linecode,macode, table);
+			if (rs.next()) {
+				mapR.put("NotCheckFeeder", rs.getResultList());
+			} else {
+				mapR.put("NotCheckFeeder", "");
+			}
+			//未校验站位数量
+			mapR.put("NotCheckCount",cn);
+		}else{
+			mapR.put("NotCheckFeeder", "");
+			mapR.put("NotCheckCount", 0);
+		}
+		return mapR;
+	}
+
+	/**
+	 * 飞达校验
+	 * @param fe_code 采集的飞达编号
+	 * @return
+	 */
+	@Override
+	public Map<String, Object> quaCheckFeederData(String deviceLineMake,String fe_code) {
+		Map<Object, Object> map = FlexJsonUtil.fromJson(deviceLineMake);
+		String ma_code = String.valueOf(map.get("DL_MACODE"));
+		String linecode = String.valueOf(map.get("DL_LINECODE"));
+		Object dl_prodcode = map.get("DL_PRODCODE");
+		Object dl_table = map.get("DL_TABLE");
+		SqlRowList rs = baseDao.queryForRowSet("select * from devsmtlocation where dsl_linecode=? " +
+				" and dsl_table =? and dsl_fecode = ? and dsl_makecode=? ",linecode,dl_table,fe_code,ma_code);
+		if(rs.next()){
+			baseDao.execute("update devsmtlocation set dsl_iffeedcheck=0 where dsl_linecode=? and dsl_makecode=? " +
+					" and dsl_fecode=? and dsl_table=?",linecode,ma_code,fe_code,dl_table);
+			baseDao.execute(INSERT_SMTLOG,SystemSession.getUser().getEm_name(),"飞达校验","校验成功,飞达:"+fe_code,linecode
+					,rs.getString("dsl_location"),0, dl_prodcode,"料卷:"+rs.getString("dsl_barcode"),dl_table,ma_code,fe_code);
+		}else{
+			baseDao.execute(INSERT_SMTLOG,SystemSession.getUser().getEm_name(),"飞达校验","校验失败,飞达:"+fe_code+"未绑定站位", linecode,
+					null,-1,dl_prodcode,"",dl_table,ma_code,fe_code);
+			throw new APIErrorException(APIErrorCode.BUSINESS_FAILED,"线别:"+linecode+",板面:"+dl_table+",工单:"+ma_code+"飞达:"+fe_code+"无上料记录!");
+		}
+		return quaGetUnCheckFeeder(linecode,String.valueOf(dl_table));
+	}
+
 
 	//因为需要调用两次,所以封装了一个获取未校验站位的方法
 	private Map<String, Object> quaUnLoading(String linecode,int recheck){