hfy 1 bulan lalu
induk
melakukan
ba22880e03

+ 30 - 4
src/main/java/com/jeesite/modules/mes/entity/MesProductCheckOne.java

@@ -5,6 +5,9 @@ import com.jeesite.common.entity.DataEntity;
 import com.jeesite.common.mybatis.annotation.Column;
 import com.jeesite.common.mybatis.annotation.Table;
 import com.jeesite.common.mybatis.mapper.query.QueryType;
+import com.jeesite.common.utils.excel.annotation.ExcelField;
+import com.jeesite.common.utils.excel.annotation.ExcelField.Align;
+import com.jeesite.common.utils.excel.annotation.ExcelFields;
 import lombok.Getter;
 
 import javax.validation.constraints.Size;
@@ -22,10 +25,10 @@ import java.util.List;
 		@Column(name="result", attrName="result", label="结果"),
 		@Column(name="remark", attrName="remark", label="备注"),
 		@Column(name="confirm_check", attrName="confirmCheck", label="确认检查", comment="确认检查(0待确认,1已确认)"),
-		@Column(name="create_by", attrName="createBy", label="create_by", isUpdate=false, isQuery=false),
-		@Column(name="create_date", attrName="createDate", label="create_date", isUpdate=false, isUpdateForce=true),
-		@Column(name="update_by", attrName="updateBy", label="update_by", isQuery=false),
-		@Column(name="update_date", attrName="updateDate", label="update_date", isQuery=false, isUpdateForce=true),
+		@Column(name="create_by", attrName="createBy", label="创建人", isUpdate=false, isQuery=false),
+		@Column(name="create_date", attrName="createDate", label="创建时间", isUpdate=false, isUpdateForce=true),
+		@Column(name="update_by", attrName="updateBy", label="更新人", isQuery=false),
+		@Column(name="update_date", attrName="updateDate", label="更新时间", isQuery=false, isUpdateForce=true),
 	}, orderBy="a.update_date DESC"
 )
 public class MesProductCheckOne extends DataEntity<MesProductCheckOne> {
@@ -41,6 +44,18 @@ public class MesProductCheckOne extends DataEntity<MesProductCheckOne> {
 	private String urlString;
 	private List img = ListUtils.newArrayList();
 
+	@ExcelFields({
+			@ExcelField(title = "工件码", attrName = "sn", align = Align.CENTER, sort = 20),
+			@ExcelField(title = "工位号", attrName = "oprno", align = Align.CENTER, sort = 30),
+			@ExcelField(title = "产线编号", attrName = "lineSn", align = Align.CENTER, sort = 40),
+			@ExcelField(title = "结果", attrName = "result", align = Align.CENTER, sort = 50),
+			@ExcelField(title = "确认检查", attrName = "confirmCheckLabel", align = Align.CENTER, sort = 60),
+			@ExcelField(title = "备注", attrName = "remark", align = Align.CENTER, sort = 70),
+			@ExcelField(title = "创建人", attrName = "createBy", align = Align.CENTER, sort = 80),
+			@ExcelField(title = "创建时间", attrName = "createDate", align = Align.CENTER, sort = 90, dataFormat = "yyyy-MM-dd hh:mm:ss"),
+			@ExcelField(title = "更新人", attrName = "updateBy", align = Align.CENTER, sort = 100),
+			@ExcelField(title = "更新时间", attrName = "updateDate", align = Align.CENTER, sort = 110, dataFormat = "yyyy-MM-dd hh:mm:ss"),
+	})
 	public MesProductCheckOne() {
 		this(null);
 	}
@@ -51,6 +66,7 @@ public class MesProductCheckOne extends DataEntity<MesProductCheckOne> {
 
 	public MesProductCheckOne(String id) {
 		super(id);
+		this.status = null;
 	}
 
 	@Size(min=0, max=50, message="工件码长度不能超过 50 个字符")
@@ -98,6 +114,16 @@ public class MesProductCheckOne extends DataEntity<MesProductCheckOne> {
 		this.confirmCheck = confirmCheck;
 	}
 
+	public String getConfirmCheckLabel() {
+		if ("1".equals(confirmCheck)) {
+			return "已确认";
+		}
+		if ("0".equals(confirmCheck)) {
+			return "未确认";
+		}
+		return confirmCheck;
+	}
+
 	public String getUrlString() {
 		return urlString;
 	}

+ 80 - 14
src/main/java/com/jeesite/modules/mes/service/MesProcessParamLimitCheckService.java

@@ -1,24 +1,19 @@
 package com.jeesite.modules.mes.service;
 
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.jeesite.common.lang.StringUtils;
-import com.jeesite.modules.mes.entity.MesProcessParamLimit;
-import com.jeesite.modules.mes.entity.MesProductArcWelding;
-import com.jeesite.modules.mes.entity.MesProductCmt;
-import com.jeesite.modules.mes.entity.MesProductProd;
-import com.jeesite.modules.mes.entity.MesProductQm;
-import com.jeesite.modules.mes.entity.MesWelderParamRecord;
+import com.jeesite.modules.mes.entity.*;
 import org.springframework.beans.BeanWrapperImpl;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
 /**
  * 工艺参数上下限校验Service
  * @author mes
@@ -61,7 +56,7 @@ public class MesProcessParamLimitCheckService {
 			return;
 		}
 		for (MesProductProd row : list) {
-			row.setLimitFlag(checkBeanRow(row, limitMap.get("prod")) ? "1" : "0");
+			row.setLimitFlag(checkBeanRow(row, limitMap.get(resolveProdProcessKey(row))) ? "1" : "0");
 		}
 	}
 
@@ -144,7 +139,7 @@ public class MesProcessParamLimitCheckService {
 	private Map<String, List<NormalizedLimit>> loadLimitMap() {
 		Map<String, List<NormalizedLimit>> map = new HashMap<>();
 		for (MesProcessParamLimit limit : mesProcessParamLimitService.findEnabledList()) {
-			String processKey = normalizeProcessKey(StringUtils.defaultString(limit.getProcessKey(), limit.getProcessName()));
+			String processKey = resolveLimitProcessKey(limit);
 			String paramCode = normalizeParamCode(StringUtils.defaultString(limit.getParamCode(), limit.getParamName()));
 			if (StringUtils.isBlank(processKey) || StringUtils.isBlank(paramCode)) {
 				continue;
@@ -155,6 +150,29 @@ public class MesProcessParamLimitCheckService {
 		return map;
 	}
 
+	private String resolveLimitProcessKey(MesProcessParamLimit limit) {
+		if (limit == null) {
+			return "";
+		}
+		String fromKey = normalizeProcessKey(limit.getProcessKey());
+		String fromName = normalizeProcessKey(limit.getProcessName());
+		if (isSpecificProdProcessKey(fromKey)) {
+			return fromKey;
+		}
+		if (isSpecificProdProcessKey(fromName)) {
+			return fromName;
+		}
+		if (StringUtils.isNotBlank(fromKey)) {
+			return fromKey;
+		}
+		return fromName;
+	}
+
+	private boolean isSpecificProdProcessKey(String processKey) {
+		return "prod115Front".equals(processKey) || "prod115Back".equals(processKey)
+				|| "prodHevFront".equals(processKey) || "prodHevBack".equals(processKey);
+	}
+
 	private boolean checkBeanRow(Object row, List<NormalizedLimit> limits) {
 		if (row == null || limits == null || limits.isEmpty()) {
 			return false;
@@ -344,6 +362,41 @@ public class MesProcessParamLimitCheckService {
 		return resolveArcProcessKey(row, weldingCategory, null);
 	}
 
+	private String resolveProdProcessKey(MesProductProd row) {
+		if (row == null) {
+			return "prod";
+		}
+		return resolveProdProcessKey(row.getOprno(), row.getLineSn());
+	}
+
+	private String resolveProdProcessKey(String oprno, String lineSn) {
+		String parent = normalizeProdOprno(oprno);
+		String line = StringUtils.upperCase(StringUtils.defaultString(lineSn));
+		if (StringUtils.contains(line, "115") && "OP130".equals(parent)) {
+			return "prod115Back";
+		}
+		if (StringUtils.contains(line, "115") && "OP150".equals(parent)) {
+			return "prod115Front";
+		}
+		if (StringUtils.contains(line, "HEV") && "OP210".equals(parent)) {
+			return "prodHevBack";
+		}
+		return "prod";
+	}
+
+	private String normalizeProdOprno(String oprno) {
+		String text = StringUtils.trim(oprno);
+		if (StringUtils.isBlank(text)) {
+			return "";
+		}
+		text = text.toUpperCase();
+		int opIndex = text.lastIndexOf("OP");
+		if (opIndex >= 0 && text.length() >= opIndex + 5) {
+			return text.substring(opIndex, opIndex + 5);
+		}
+		return text.length() >= 5 ? text.substring(0, 5) : text;
+	}
+
 	private String resolveArcProcessKey(MesProductArcWelding row, String weldingCategory, String processName) {
 		String category = normalizeProcessKey(processName);
 		if (!isArcProcessKey(category)) {
@@ -384,6 +437,19 @@ public class MesProcessParamLimitCheckService {
 		if ("assembly".equalsIgnoreCase(text) || "总成气密".equals(text)) {
 			return "assembly";
 		}
+		if ("prod115Front".equalsIgnoreCase(text) || "115拉铆框架正面".equals(text)
+				|| "115正面拉铆".equals(text)) {
+			return "prod115Front";
+		}
+		if ("prod115Back".equalsIgnoreCase(text) || "115液冷板装配拉铆".equals(text)
+				|| "115反面拉铆".equals(text)) {
+			return "prod115Back";
+		}
+		if ("prodHevFront".equalsIgnoreCase(text) || "HEV正面拉铆".equalsIgnoreCase(text)
+				|| "prodHevBack".equalsIgnoreCase(text) || "HEV拉铆".equalsIgnoreCase(text)
+				|| "HEV反面拉铆".equalsIgnoreCase(text)) {
+			return "prodHevBack";
+		}
 		if ("prod".equalsIgnoreCase(text) || "拉铆".equals(text)) {
 			return "prod";
 		}

+ 1 - 1
src/main/java/com/jeesite/modules/mes/service/MesProductRecordService.java

@@ -807,7 +807,7 @@ public class MesProductRecordService extends CrudService<MesProductRecordDao, Me
 				}
 
 				//查询首件检记录是否为OK或是确认状态
-				if ("1".equals(Global.getConfig("mes.check.one"))) {
+				if (CommonUitl.needCheckOne(oldOprno, lineSn)) {
 					MesShiftDataResp mesShiftDataResp = mesShiftService.getCurShift();
 					try {
 						DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");

+ 95 - 3
src/main/java/com/jeesite/modules/mes/util/CommonUitl.java

@@ -4,11 +4,8 @@ import com.alibaba.fastjson.JSONObject;
 import com.jeesite.common.config.Global;
 import com.jeesite.common.lang.StringUtils;
 import com.jeesite.modules.mes.req.MesSearchDateReq;
-import com.jeesite.modules.mes.service.MesProductModelService;
 import okhttp3.*;
 import org.apache.tomcat.util.codec.binary.Base64;
-import org.beetl.core.util.ArrayUtils;
-import org.springframework.beans.factory.annotation.Autowired;
 
 import java.io.*;
 import java.net.HttpURLConnection;
@@ -82,6 +79,101 @@ public class CommonUitl {
     }
 
     /**
+     * 判断当前工位是否需要首件检
+     * 仅 mes.check.one=1,且配置 mes.check.oneOprno(逗号分隔)命中时才需要
+     * 配置格式:产线:工位,产线:工位;也兼容旧的仅工位写法
+     */
+    public static boolean needCheckOne(String oprno) {
+        return needCheckOne(oprno, null);
+    }
+
+    /**
+     * 根据产线编号和工位号一起判断是否需要首件检
+     */
+    public static boolean needCheckOne(String oprno, String lineSn) {
+        if (!"1".equals(Global.getConfig("mes.check.one")) || StringUtils.isBlank(oprno)) {
+            return false;
+        }
+        String configOprnos = Global.getConfig("mes.check.oneOprno");
+        if (StringUtils.isBlank(configOprnos)) {
+            return false;
+        }
+        String current = oprno.trim();
+        String parentOprno = formatOprno(current);
+        String currentWithA = current;
+        if (currentWithA.length() == 5) {
+            currentWithA = currentWithA + "A";
+        }
+        String currentLine = StringUtils.isBlank(lineSn) ? "" : lineSn.trim();
+        for (String item : configOprnos.split(",")) {
+            if (StringUtils.isBlank(item)) {
+                continue;
+            }
+            String configItem = item.trim();
+            String configLine = null;
+            String configOprno = configItem;
+            int colonIndex = configItem.indexOf(':');
+            if (colonIndex >= 0) {
+                configLine = configItem.substring(0, colonIndex).trim();
+                configOprno = configItem.substring(colonIndex + 1).trim();
+            } else {
+                String[] parsed = splitLineAndOprno(configItem);
+                if (parsed != null) {
+                    configLine = parsed[0];
+                    configOprno = parsed[1];
+                }
+            }
+            if (StringUtils.isBlank(configOprno)) {
+                continue;
+            }
+            if (StringUtils.isNotBlank(configLine) && !matchLineSn(currentLine, configLine)) {
+                continue;
+            }
+            if (configOprno.equalsIgnoreCase(currentWithA)
+                    || configOprno.equalsIgnoreCase(current)
+                    || configOprno.equalsIgnoreCase(parentOprno)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static String[] splitLineAndOprno(String item) {
+        String[] prefixes = new String[] {"HEVXT", "115XT", "HEV", "115"};
+        String upper = item.toUpperCase();
+        for (String prefix : prefixes) {
+            if (upper.startsWith(prefix) && item.length() > prefix.length()) {
+                String remain = item.substring(prefix.length());
+                if (remain.toUpperCase().startsWith("OP")) {
+                    return new String[] {item.substring(0, prefix.length()), remain};
+                }
+            }
+        }
+        return null;
+    }
+
+    private static boolean matchLineSn(String currentLine, String configLine) {
+        if (StringUtils.isBlank(currentLine) || StringUtils.isBlank(configLine)) {
+            return false;
+        }
+        if (currentLine.equalsIgnoreCase(configLine)) {
+            return true;
+        }
+        return normalizeCheckLineSn(currentLine).equalsIgnoreCase(normalizeCheckLineSn(configLine));
+    }
+
+    private static String normalizeCheckLineSn(String lineSn) {
+        String trimmed = lineSn.trim();
+        if ("HEV".equalsIgnoreCase(trimmed)) {
+            return "HEVXT";
+        }
+        if ("115".equals(trimmed) || "欣旺达115".equals(trimmed)) {
+            return "115XT";
+        }
+        return trimmed;
+    }
+
+    /**
      * 获取几天前的时间
      * @param days
      * @return

+ 25 - 6
src/main/java/com/jeesite/modules/mes/web/MesProductCheckFirstController.java

@@ -39,7 +39,9 @@ import com.jeesite.common.utils.excel.annotation.ExcelField.Type;
 import org.springframework.web.multipart.MultipartFile;
 import com.jeesite.common.web.BaseController;
 import com.jeesite.modules.mes.entity.MesProductCheckFirst;
+import com.jeesite.modules.mes.entity.MesProductCheckOne;
 import com.jeesite.modules.mes.service.MesProductCheckFirstService;
+import com.jeesite.modules.mes.service.MesProductCheckOneService;
 
 /**
  * 首件检查记录Controller
@@ -52,6 +54,8 @@ public class MesProductCheckFirstController extends BaseController {
 
 	@Autowired
 	private MesProductCheckFirstService mesProductCheckFirstService;
+	@Autowired
+	private MesProductCheckOneService mesProductCheckOneService;
 
 	@Autowired
 	private MesProductRecordService mesProductRecordService;
@@ -73,20 +77,35 @@ public class MesProductCheckFirstController extends BaseController {
 	@RequiresPermissions("mes:mesProductCheckFirst:view")
 	@RequestMapping(value = {"list", ""})
 	public String list(MesProductCheckFirst mesProductCheckFirst, Model model) {
-		model.addAttribute("mesProductCheckFirst", mesProductCheckFirst);
-		return "modules/mes/mesProductCheckFirstList";
+		model.addAttribute("mesProductCheckOne", new MesProductCheckOne());
+		return "modules/mes/mesProductCheckOneList";
 	}
 	
 	/**
-	 * 查询列表数据
+	 * 查询列表数据(mes_product_check_one 全部记录)
 	 */
 	@RequiresPermissions("mes:mesProductCheckFirst:view")
 	@RequestMapping(value = "listData")
 	@ResponseBody
-	public Page<MesProductCheckFirst> listData(MesProductCheckFirst mesProductCheckFirst, HttpServletRequest request, HttpServletResponse response) {
+	public Page<MesProductCheckOne> listData(MesProductCheckOne mesProductCheckOne, HttpServletRequest request, HttpServletResponse response) {
+		mesProductCheckOne.setStatus(null);
+		mesProductCheckOne.setPage(new Page<>(request, response));
+		return mesProductCheckOneService.findPage(mesProductCheckOne);
+	}
+
+	@RequiresPermissions("mes:mesProductCheckFirst:view")
+	@RequestMapping(value = "firstList")
+	public String firstList(MesProductCheckFirst mesProductCheckFirst, Model model) {
+		model.addAttribute("mesProductCheckFirst", mesProductCheckFirst);
+		return "modules/mes/mesProductCheckFirstList";
+	}
+
+	@RequiresPermissions("mes:mesProductCheckFirst:view")
+	@RequestMapping(value = "firstListData")
+	@ResponseBody
+	public Page<MesProductCheckFirst> firstListData(MesProductCheckFirst mesProductCheckFirst, HttpServletRequest request, HttpServletResponse response) {
 		mesProductCheckFirst.setPage(new Page<>(request, response));
-		Page<MesProductCheckFirst> page = mesProductCheckFirstService.findPage(mesProductCheckFirst);
-		return page;
+		return mesProductCheckFirstService.findPage(mesProductCheckFirst);
 	}
 
 	/**

+ 131 - 0
src/main/java/com/jeesite/modules/mes/web/MesProductCheckOneController.java

@@ -0,0 +1,131 @@
+package com.jeesite.modules.mes.web;
+
+import java.util.List;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.shiro.authz.annotation.Logical;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import com.jeesite.common.config.Global;
+import com.jeesite.common.entity.Page;
+import com.jeesite.common.lang.DateUtils;
+import com.jeesite.common.lang.StringUtils;
+import com.jeesite.common.utils.excel.ExcelExport;
+import com.jeesite.common.web.BaseController;
+import com.jeesite.modules.mes.entity.MesProductCheckOne;
+import com.jeesite.modules.mes.service.MesProductCheckOneService;
+
+/**
+ * 首件检记录Controller
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/mes/mesProductCheckOne")
+public class MesProductCheckOneController extends BaseController {
+
+	@Autowired
+	private MesProductCheckOneService mesProductCheckOneService;
+
+	@ModelAttribute
+	public MesProductCheckOne get(String id, boolean isNewRecord) {
+		return mesProductCheckOneService.get(id, isNewRecord);
+	}
+
+	@RequiresPermissions(value = {"mes:mesProductCheckOne:view", "mes:mesProductCheckFirst:view"}, logical = Logical.OR)
+	@RequestMapping(value = {"list", ""})
+	public String list(MesProductCheckOne mesProductCheckOne, Model model) {
+		mesProductCheckOne.setStatus(null);
+		model.addAttribute("mesProductCheckOne", mesProductCheckOne);
+		return "modules/mes/mesProductCheckOneList";
+	}
+
+	@RequiresPermissions(value = {"mes:mesProductCheckOne:view", "mes:mesProductCheckFirst:view"}, logical = Logical.OR)
+	@RequestMapping(value = "listData")
+	@ResponseBody
+	public Page<MesProductCheckOne> listData(MesProductCheckOne mesProductCheckOne, HttpServletRequest request, HttpServletResponse response) {
+		mesProductCheckOne.setStatus(null);
+		mesProductCheckOne.setPage(new Page<>(request, response));
+		return mesProductCheckOneService.findPage(mesProductCheckOne);
+	}
+
+	@RequiresPermissions(value = {"mes:mesProductCheckOne:view", "mes:mesProductCheckFirst:view"}, logical = Logical.OR)
+	@RequestMapping(value = "form")
+	public String form(MesProductCheckOne mesProductCheckOne, Model model) {
+		model.addAttribute("mesProductCheckOne", mesProductCheckOne);
+		return "modules/mes/mesProductCheckOneForm";
+	}
+
+	@RequiresPermissions(value = {"mes:mesProductCheckOne:view", "mes:mesProductCheckFirst:view"}, logical = Logical.OR)
+	@RequestMapping(value = "info")
+	public String info(MesProductCheckOne mesProductCheckOne, Model model) {
+		model.addAttribute("mesProductCheckOne", mesProductCheckOne);
+		return "modules/mes/mesProductCheckOneInfo";
+	}
+
+	@RequiresPermissions(value = {"mes:mesProductCheckOne:edit", "mes:mesProductCheckFirst:edit"}, logical = Logical.OR)
+	@PostMapping(value = "save")
+	@ResponseBody
+	public String save(@Validated MesProductCheckOne mesProductCheckOne) {
+		if (StringUtils.isBlank(mesProductCheckOne.getId()) || mesProductCheckOne.getIsNewRecord()) {
+			return renderResult(Global.FALSE, text("记录不存在"));
+		}
+		MesProductCheckOne dbRecord = mesProductCheckOneService.get(mesProductCheckOne.getId());
+		if (dbRecord == null) {
+			return renderResult(Global.FALSE, text("记录不存在"));
+		}
+		String confirmCheck = StringUtils.trim(mesProductCheckOne.getConfirmCheck());
+		if (StringUtils.isBlank(confirmCheck)) {
+			confirmCheck = dbRecord.getConfirmCheck();
+		}
+		if (!"0".equals(confirmCheck) && !"1".equals(confirmCheck)) {
+			return renderResult(Global.FALSE, text("确认检查只能为未确认或已确认"));
+		}
+		String result = StringUtils.trim(mesProductCheckOne.getResult());
+		if (StringUtils.isBlank(result)) {
+			result = dbRecord.getResult();
+		} else {
+			result = result.toUpperCase();
+			if (!"OK".equals(result) && !"NG".equals(result) && !"UDF".equals(result)) {
+				return renderResult(Global.FALSE, text("结果只能为OK、NG或UDF"));
+			}
+		}
+		mesProductCheckOne.setSn(dbRecord.getSn());
+		mesProductCheckOne.setOprno(dbRecord.getOprno());
+		mesProductCheckOne.setLineSn(dbRecord.getLineSn());
+		mesProductCheckOne.setResult(result);
+		mesProductCheckOne.setConfirmCheck(confirmCheck);
+		mesProductCheckOneService.save(mesProductCheckOne);
+		return renderResult(Global.TRUE, text("保存首件检记录成功!"));
+	}
+
+	@RequiresPermissions(value = {"mes:mesProductCheckOne:edit", "mes:mesProductCheckFirst:edit"}, logical = Logical.OR)
+	@RequestMapping(value = "confirm")
+	@ResponseBody
+	public String confirm(MesProductCheckOne mesProductCheckOne) {
+		if (StringUtils.isBlank(mesProductCheckOne.getId()) || mesProductCheckOne.getIsNewRecord()) {
+			return renderResult(Global.FALSE, text("记录不存在"));
+		}
+		mesProductCheckOne.setConfirmCheck("1");
+		mesProductCheckOneService.update(mesProductCheckOne);
+		return renderResult(Global.TRUE, text("确认检查成功!"));
+	}
+
+	@RequiresPermissions(value = {"mes:mesProductCheckOne:view", "mes:mesProductCheckFirst:view"}, logical = Logical.OR)
+	@RequestMapping(value = "exportData")
+	public void exportData(MesProductCheckOne mesProductCheckOne, HttpServletResponse response) {
+		mesProductCheckOne.setStatus(null);
+		List<MesProductCheckOne> list = mesProductCheckOneService.findList(mesProductCheckOne);
+		String fileName = "首件检记录" + DateUtils.getDate("yyyyMMddHHmmss") + ".xlsx";
+		try (ExcelExport ee = new ExcelExport("首件检记录", MesProductCheckOne.class)) {
+			ee.setDataList(list).write(response, fileName);
+		}
+	}
+}

+ 2 - 2
src/main/java/com/jeesite/modules/mes/web/MesProductRecordController.java

@@ -1572,7 +1572,7 @@ public class MesProductRecordController extends BaseController {
 				}
 			}
 			//查询首件检记录是否为OK或是确认状态
-			if ("1".equals(Global.getConfig("mes.check.one"))) {
+			if (CommonUitl.needCheckOne(oldOprno, lineSn)) {
 				MesShiftDataResp mesShiftDataResp = mesShiftService.getCurShift();
 				try {
 					DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
@@ -4595,7 +4595,7 @@ public class MesProductRecordController extends BaseController {
 		}
 
 		//查询首件检记录是否为OK或是确认状态
-		if ("1".equals(Global.getConfig("mes.check.one"))){
+		if (CommonUitl.needCheckOne(oprno, lineSn)){
 			boolean checkOne=checkOne(sn,oprno,lineSn,userCode,resp);
 			if (checkOne==false){
 				return resp;

+ 15 - 2
src/main/resources/views/modules/mes/mesProcessParamLimitForm.html

@@ -74,10 +74,22 @@ const processLimitOptions = [
 		{code:'testPressure', name:'测试压'},
 		{code:'leakVal', name:'泄漏值'}
 	]},
-	{key:'prod', name:'拉铆', params:[
+	{key:'prod115Front', name:'115拉铆框架正面', params:[
 		{code:'fout', name:'拉力'},
 		{code:'sout', name:'行程'}
 	]},
+	{key:'prod115Back', name:'115液冷板装配拉铆', params:[
+			{code:'fout', name:'拉力'},
+			{code:'sout', name:'行程'}
+		]},
+	{key:'prodHevBack', name:'HEV拉铆', params:[
+			{code:'fout', name:'拉力'},
+			{code:'sout', name:'行程'}
+		]},
+/*	{key:'prodHevFront', name:'HEV正面拉铆', params:[
+			{code:'fout', name:'拉力'},
+			{code:'sout', name:'行程'}
+		]},*/
 	{key:'welder', name:'凸焊', params:[
 		{code:'capVoltage', name:'电容电压'},
 		{code:'weldPeakCurrent', name:'焊接峰值电流'}
@@ -106,7 +118,8 @@ const processLimitOptions = [
 	]}*/
 ];
 
-const findProcess = (key, name) => processLimitOptions.find(item => item.key === key || item.name === name);
+const findProcess = (key, name) => processLimitOptions.find(item => item.name === name)
+	|| processLimitOptions.find(item => item.key === key);
 const findParam = (processKey, code, name) => {
 	const process = findProcess(processKey);
 	const params = process ? process.params : [];

+ 139 - 0
src/main/resources/views/modules/mes/mesProductCheckOneForm.html

@@ -0,0 +1,139 @@
+<% layout('/layouts/default.html', {title: '首件检记录管理', libs: ['validate','fileupload']}){ %>
+<div class="main-content">
+	<div class="box box-main">
+		<div class="box-header with-border">
+			<div class="box-title">
+				<i class="fa icon-note"></i> ${text('编辑首件检记录')}
+			</div>
+			<div class="box-tools pull-right">
+				<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
+			</div>
+		</div>
+		<#form:form id="inputForm" model="${mesProductCheckOne}" action="${ctx}/mes/mesProductCheckOne/save" method="post" class="form-horizontal">
+			<div class="box-body">
+				<div class="form-unit">${text('基本信息')}</div>
+				<#form:hidden path="id"/>
+				<div class="row">
+					<div class="col-xs-6">
+						<div class="form-group">
+							<label class="control-label col-sm-4" title="">
+								<span class="required hide">*</span> ${text('工件码')}:<i class="fa icon-question hide"></i></label>
+							<div class="col-sm-8">
+								<#form:input path="sn" maxlength="50" readonly="true" class="form-control"/>
+							</div>
+						</div>
+					</div>
+					<div class="col-xs-6">
+						<div class="form-group">
+							<label class="control-label col-sm-4" title="">
+								<span class="required hide">*</span> ${text('工位号')}:<i class="fa icon-question hide"></i></label>
+							<div class="col-sm-8">
+								<#form:input path="oprno" maxlength="20" readonly="true" class="form-control"/>
+							</div>
+						</div>
+					</div>
+					<div class="col-xs-6">
+						<div class="form-group">
+							<label class="control-label col-sm-4" title="">
+								<span class="required hide">*</span> ${text('产线编号')}:<i class="fa icon-question hide"></i></label>
+							<div class="col-sm-8">
+								<#form:input path="lineSn" maxlength="20" readonly="true" class="form-control"/>
+							</div>
+						</div>
+					</div>
+					<div class="col-xs-6">
+						<div class="form-group">
+							<label class="control-label col-sm-4" title="">
+								<span class="required">*</span> ${text('结果')}:<i class="fa icon-question hide"></i></label>
+							<div class="col-sm-8">
+								<select name="result" class="form-control required">
+									<option value="">${text('请选择')}</option>
+									<option value="OK" ${mesProductCheckOne.result == 'OK' ? 'selected="selected"' : ''}>OK</option>
+									<option value="NG" ${mesProductCheckOne.result == 'NG' ? 'selected="selected"' : ''}>NG</option>
+									<option value="UDF" ${mesProductCheckOne.result == 'UDF' ? 'selected="selected"' : ''}>UDF</option>
+								</select>
+							</div>
+						</div>
+					</div>
+					<div class="col-xs-6">
+						<div class="form-group">
+							<label class="control-label col-sm-4" title="">
+								<span class="required">*</span> ${text('确认检查')}:<i class="fa icon-question hide"></i></label>
+							<div class="col-sm-8">
+								<select name="confirmCheck" class="form-control required">
+									<option value="">${text('请选择')}</option>
+									<option value="0" ${mesProductCheckOne.confirmCheck == '0' ? 'selected="selected"' : ''}>${text('未确认')}</option>
+									<option value="1" ${mesProductCheckOne.confirmCheck == '1' ? 'selected="selected"' : ''}>${text('已确认')}</option>
+								</select>
+							</div>
+						</div>
+					</div>
+					<div class="col-xs-6">
+						<div class="form-group">
+							<label class="control-label col-sm-4" title="">
+								<span class="required hide">*</span> ${text('备注')}:<i class="fa icon-question hide"></i></label>
+							<div class="col-sm-8">
+								<#form:input path="remark" maxlength="255" class="form-control"/>
+							</div>
+						</div>
+					</div>
+					<div class="col-xs-6">
+						<div class="form-group">
+							<label class="control-label col-sm-4" title="">
+								<span class="required hide">*</span> ${text('创建人')}:<i class="fa icon-question hide"></i></label>
+							<div class="col-sm-8">
+								<#form:input path="createBy" readonly="true" class="form-control"/>
+							</div>
+						</div>
+					</div>
+					<div class="col-xs-6">
+						<div class="form-group">
+							<label class="control-label col-sm-4" title="">
+								<span class="required hide">*</span> ${text('创建时间')}:<i class="fa icon-question hide"></i></label>
+							<div class="col-sm-8">
+								<#form:input path="createDate" readonly="true" maxlength="20" class="form-control" dataFormat="datetime"/>
+							</div>
+						</div>
+					</div>
+				</div>
+				<div class="row">
+					<div class="col-xs-12">
+						<div class="form-group">
+							<label class="control-label col-sm-2">
+								<span class="required hide">*</span> ${text('首件检图片')}:</label>
+							<div class="col-sm-10">
+								<#form:fileupload id="uploadImage" bizKey="${mesProductCheckOne.id}" bizType="mesProductCheckOne_image"
+									uploadType="image" class="" readonly="false" preview="true"/>
+							</div>
+						</div>
+					</div>
+				</div>
+			</div>
+			<div class="box-footer">
+				<div class="row">
+					<div class="col-sm-offset-2 col-sm-10">
+						<% if (hasPermi('mes:mesProductCheckOne:edit,mes:mesProductCheckFirst:edit')){ %>
+							<button type="submit" class="btn btn-sm btn-primary" id="btnSubmit"><i class="fa fa-check"></i> ${text('保 存')}</button>&nbsp;
+						<% } %>
+						<button type="button" class="btn btn-sm btn-default" id="btnCancel" onclick="js.closeCurrentTabPage()"><i class="fa fa-reply-all"></i> ${text('关 闭')}</button>
+					</div>
+				</div>
+			</div>
+		</#form:form>
+	</div>
+</div>
+<% } %>
+<script>
+$("#inputForm").validate({
+	submitHandler: function(form){
+		js.ajaxSubmitForm($(form), function(data){
+			js.showMessage(data.message);
+			if(data.result == Global.TRUE){
+				js.closeCurrentTabPage(function(contentWindow){
+					contentWindow.page();
+				});
+			}
+		}, "json");
+    }
+});
+</script>

+ 83 - 0
src/main/resources/views/modules/mes/mesProductCheckOneInfo.html

@@ -0,0 +1,83 @@
+<% layout('/layouts/default.html', {title: '首件检记录管理', libs: ['validate','fileupload']}){ %>
+<div class="main-content">
+	<div class="box box-main">
+		<div class="box-header with-border">
+			<div class="box-title">
+				<i class="fa icon-note"></i> ${text('首件检详情')}
+			</div>
+			<div class="box-tools pull-right">
+				<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
+			</div>
+		</div>
+		<div class="box-body">
+			<div class="form-unit">${text('基本信息')}</div>
+			<div class="row">
+				<div class="col-xs-12">
+					<table class="table table-bordered">
+						<tr>
+							<th class="mpc-header">${text('工件码')}</th>
+							<td>${mesProductCheckOne.sn}</td>
+						</tr>
+						<tr>
+							<th class="mpc-header">${text('工位号')}</th>
+							<td>${mesProductCheckOne.oprno}</td>
+						</tr>
+						<tr>
+							<th class="mpc-header">${text('产线编号')}</th>
+							<td>${mesProductCheckOne.lineSn}</td>
+						</tr>
+						<tr>
+							<th class="mpc-header">${text('结果')}</th>
+							<td>${mesProductCheckOne.result}</td>
+						</tr>
+						<tr>
+							<th class="mpc-header">${text('确认检查')}</th>
+							<td>
+								<% if (mesProductCheckOne.confirmCheck == '1'){ %>
+									${text('已确认')}
+								<% } else { %>
+									${text('未确认')}
+								<% } %>
+							</td>
+						</tr>
+						<tr>
+							<th class="mpc-header">${text('备注')}</th>
+							<td>${mesProductCheckOne.remark}</td>
+						</tr>
+						<tr>
+							<th class="mpc-header">${text('创建人')}</th>
+							<td>${mesProductCheckOne.createBy}</td>
+						</tr>
+						<tr>
+							<th class="mpc-header">${text('创建时间')}</th>
+							<td>${@DateUtils.formatDateTime(mesProductCheckOne.createDate)}</td>
+						</tr>
+						<tr>
+							<th class="mpc-header">${text('更新人')}</th>
+							<td>${mesProductCheckOne.updateBy}</td>
+						</tr>
+						<tr>
+							<th class="mpc-header">${text('更新时间')}</th>
+							<td>${@DateUtils.formatDateTime(mesProductCheckOne.updateDate)}</td>
+						</tr>
+						<tr>
+							<th class="mpc-header">${text('首件检图片')}</th>
+							<td>
+								<#form:fileupload id="uploadImage" bizKey="${mesProductCheckOne.id}" bizType="mesProductCheckOne_image"
+									uploadType="image" class="" readonly="true" preview="true"/>
+							</td>
+						</tr>
+					</table>
+				</div>
+			</div>
+		</div>
+		<div class="box-footer">
+			<div class="row">
+				<div class="col-sm-offset-2 col-sm-10">
+					<button type="button" class="btn btn-sm btn-default" id="btnCancel" onclick="js.closeCurrentTabPage()"><i class="fa fa-reply-all"></i> ${text('关 闭')}</button>
+				</div>
+			</div>
+		</div>
+	</div>
+</div>
+<% } %>

+ 129 - 0
src/main/resources/views/modules/mes/mesProductCheckOneList.html

@@ -0,0 +1,129 @@
+<% layout('/layouts/default.html', {title: '首件检记录管理', libs: ['dataGrid']}){ %>
+<div class="main-content">
+	<div class="box box-main">
+		<div class="box-header">
+			<div class="box-title">
+				<i class="fa icon-notebook"></i> ${text('首件检记录管理')}
+			</div>
+			<div class="box-tools pull-right">
+				<a href="#" class="btn btn-default" id="btnSearch" title="${text('查询')}"><i class="fa fa-filter"></i> ${text('查询')}</a>
+				<a href="#" class="btn btn-default" id="btnExport"><i class="glyphicon glyphicon-export"></i> ${text('导出')}</a>
+				<a href="#" class="btn btn-default" id="btnSetting" title="${text('设置')}"><i class="fa fa-navicon"></i></a>
+			</div>
+		</div>
+		<div class="box-body">
+			<#form:form id="searchForm" model="${mesProductCheckOne}" action="${ctx}/mes/mesProductCheckOne/listData" method="post" class="form-inline hide"
+					data-page-no="${parameter.pageNo}" data-page-size="${parameter.pageSize}" data-order-by="${parameter.orderBy}">
+				<div class="form-group">
+					<label class="control-label">${text('工件码')}:</label>
+					<div class="control-inline">
+						<#form:input path="sn" maxlength="50" class="form-control width-260"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('工位号')}:</label>
+					<div class="control-inline">
+						<#form:input path="oprno" maxlength="20" class="form-control width-120"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('产线编号')}:</label>
+					<div class="control-inline">
+						<#form:input path="lineSn" maxlength="20" class="form-control width-120"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('结果')}:</label>
+					<div class="control-inline width-120">
+						<select name="result" class="form-control">
+							<option value="">&nbsp;</option>
+							<option value="OK">OK</option>
+							<option value="NG">NG</option>
+							<option value="UDF">UDF</option>
+						</select>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('备注')}:</label>
+					<div class="control-inline">
+						<#form:input path="remark" maxlength="255" class="form-control width-180"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('确认检查')}:</label>
+					<div class="control-inline width-120">
+						<select name="confirmCheck" class="form-control">
+							<option value="">&nbsp;</option>
+							<option value="0">${text("未确认")}</option>
+							<option value="1">${text("已确认")}</option>
+						</select>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('创建时间')}:</label>
+					<div class="control-inline">
+						<#form:input path="createDate_gte" readonly="true" maxlength="20" class="form-control laydate width-datetime"
+							dataFormat="datetime" data-type="datetime" data-format="yyyy-MM-dd HH:mm" data-done="createDate_lte.click()"/>
+						&nbsp;-&nbsp;
+						<#form:input path="createDate_lte" readonly="true" maxlength="20" class="form-control laydate width-datetime"
+							dataFormat="datetime" data-type="datetime" data-format="yyyy-MM-dd HH:mm"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<button type="submit" class="btn btn-primary btn-sm">${text('查询')}</button>
+					<button type="reset" class="btn btn-default btn-sm">${text('重置')}</button>
+				</div>
+			</#form:form>
+			<table id="dataGrid"></table>
+			<div id="dataGridPage"></div>
+		</div>
+	</div>
+</div>
+<% } %>
+<script>
+$('#dataGrid').dataGrid({
+	searchForm: $("#searchForm"),
+	columnModel: [
+		{header:'${text("工件码")}', name:'sn', index:'a.sn', width:280, align:"center", frozen:true},
+		{header:'${text("工位号")}', name:'oprno', index:'a.oprno', width:100, align:"center"},
+		{header:'${text("产线编号")}', name:'lineSn', index:'a.line_sn', width:100, align:"center"},
+		{header:'${text("结果")}', name:'result', index:'a.result', width:90, align:"center", formatter: function(val){
+			if (val === 'OK') return '<span class="label label-success">OK</span>';
+			if (val === 'NG') return '<span class="label label-danger">NG</span>';
+			if (val === 'UDF') return '<span class="label label-warning">UDF</span>';
+			return val || '';
+		}},
+		{header:'${text("确认检查")}', name:'confirmCheck', index:'a.confirm_check', width:100, align:"center", formatter: function(val){
+			if (val === '1') return '<span class="label label-success">${text("已确认")}</span>';
+			return '<span class="label label-default">${text("未确认")}</span>';
+		}},
+		{header:'${text("备注")}', name:'remark', index:'a.remark', width:180, align:"center"},
+		{header:'${text("创建人")}', name:'createBy', index:'a.create_by', width:120, align:"center"},
+		{header:'${text("创建时间")}', name:'createDate', index:'a.create_date', width:160, align:"center"},
+		{header:'${text("更新人")}', name:'updateBy', index:'a.update_by', width:120, align:"center"},
+		{header:'${text("更新时间")}', name:'updateDate', index:'a.update_date', width:160, align:"center"},
+		{header:'${text("操作")}', name:'actions', width:120, align:"center", formatter: function(val, obj, row, act){
+			var actions = [];
+			//<% if(hasPermi('mes:mesProductCheckOne:view,mes:mesProductCheckFirst:view')){ %>
+				actions.push('<a href="${ctx}/mes/mesProductCheckOne/info?id='+row.id+'" class="btnList" title="${text("查看首件检记录")}"><i class="fa fa-eye"></i></a>&nbsp;');
+			//<% } %>
+			//<% if(hasPermi('mes:mesProductCheckOne:edit,mes:mesProductCheckFirst:edit')){ %>
+				actions.push('<a href="${ctx}/mes/mesProductCheckOne/form?id='+row.id+'" class="btnList" title="${text("编辑首件检记录")}"><i class="fa fa-pencil"></i></a>&nbsp;');
+				if (row.confirmCheck != '1') {
+					actions.push('<a href="${ctx}/mes/mesProductCheckOne/confirm?id='+row.id+'" class="btnList" title="${text("确认检查")}" data-confirm="${text("确认要将该首件检标记为已确认吗?")}"><i class="fa fa-check"></i></a>&nbsp;');
+				}
+			//<% } %>
+			return actions.join('');
+		}}
+	],
+	frozenCols: true,
+	ajaxSuccess: function(data){
+	}
+});
+$('#btnExport').click(function(){
+	js.ajaxSubmitForm($('#searchForm'), {
+		url:'${ctx}/mes/mesProductCheckOne/exportData',
+		downloadFile:true
+	});
+});
+</script>

+ 2 - 2
src/main/resources/views/modules/mes/mesProductProdList.html

@@ -24,13 +24,13 @@
 						<#form:input path="sn" maxlength="100" class="form-control width-260"/>
 					</div>
 				</div>
-				<div class="form-group">
+				<div class="form-group" style="display:none;">
 					<label class="control-label">${text('工位')}:</label>
 					<div class="control-inline">
 						<#form:input path="oprno" maxlength="100" class="form-control width-120"/>
 					</div>
 				</div>
-				<div class="form-group">
+				<div class="form-group" style="display:none;">
 					<label class="control-label">${text('产线编号')}:</label>
 					<div class="control-inline">
 						<#form:input path="lineSn" maxlength="100" class="form-control width-120"/>