jingbo hai 2 meses
pai
achega
0e2fd4d4f1
Modificáronse 32 ficheiros con 554 adicións e 127 borrados
  1. BIN=BIN
      _tmp_decompile/com/jeesite/modules/sys/service/support/EmpUserServiceSupport.class
  2. BIN=BIN
      _tmp_decompile/com/jeesite/modules/sys/service/support/OfficeServiceSupport.class
  3. BIN=BIN
      _tmp_decompile/com/jeesite/modules/sys/web/OfficeController.class
  4. BIN=BIN
      _tmp_decompile/com/jeesite/modules/sys/web/user/EmpUserController.class
  5. 119 0
      _tmp_decompile/mappings/modules/sys/EmpUserDao.xml
  6. 12 0
      src/main/java/com/jeesite/modules/mes/entity/MesBatchSn.java
  7. 2 1
      src/main/java/com/jeesite/modules/mes/entity/MesDevicePreventTask.java
  8. 10 0
      src/main/java/com/jeesite/modules/mes/entity/MesProductCmt.java
  9. 1 1
      src/main/java/com/jeesite/modules/mes/entity/MesScrap.java
  10. 13 2
      src/main/java/com/jeesite/modules/mes/service/MesProductCcdService.java
  11. 2 2
      src/main/java/com/jeesite/modules/mes/service/MesScrapService.java
  12. 80 17
      src/main/java/com/jeesite/modules/mes/service/MesTemplateItemsService.java
  13. 6 0
      src/main/java/com/jeesite/modules/mes/web/MesBatchSnController.java
  14. 55 39
      src/main/java/com/jeesite/modules/mes/web/MesDevicePreventTaskController.java
  15. 27 1
      src/main/java/com/jeesite/modules/mes/web/MesPieceSalaryReportController.java
  16. 53 2
      src/main/java/com/jeesite/modules/mes/web/MesProductCmtController.java
  17. 7 7
      src/main/java/com/jeesite/modules/mes/web/MesProductRecordController.java
  18. 35 5
      src/main/java/com/jeesite/modules/mes/web/MesStationPiecePriceController.java
  19. 4 3
      src/main/resources/config/application.yml
  20. 1 0
      src/main/resources/mappings/modules/mes/MesBatchSnDao.xml
  21. 57 7
      src/main/resources/mappings/modules/mes/MesPieceSalaryReportDao.xml
  22. 9 0
      src/main/resources/views/modules/mes/mesBatchSnForm.html
  23. 4 0
      src/main/resources/views/modules/mes/mesBatchSnInfo.html
  24. 9 0
      src/main/resources/views/modules/mes/mesBatchSnList.html
  25. 11 4
      src/main/resources/views/modules/mes/mesDevicePreventTaskForm.html
  26. 5 1
      src/main/resources/views/modules/mes/mesDeviceQrcode.html
  27. 3 3
      src/main/resources/views/modules/mes/mesPieceSalaryReportList.html
  28. 2 2
      src/main/resources/views/modules/mes/mesProductCmtForm.html
  29. 2 2
      src/main/resources/views/modules/mes/mesProductCmtInfo.html
  30. 4 3
      src/main/resources/views/modules/mes/mesProductCmtList.html
  31. 12 24
      src/main/resources/views/modules/mes/mesStationPiecePriceForm.html
  32. 9 1
      src/main/resources/views/modules/sys/officeForm.html

BIN=BIN
_tmp_decompile/com/jeesite/modules/sys/service/support/EmpUserServiceSupport.class


BIN=BIN
_tmp_decompile/com/jeesite/modules/sys/service/support/OfficeServiceSupport.class


BIN=BIN
_tmp_decompile/com/jeesite/modules/sys/web/OfficeController.class


BIN=BIN
_tmp_decompile/com/jeesite/modules/sys/web/user/EmpUserController.class


+ 119 - 0
_tmp_decompile/mappings/modules/sys/EmpUserDao.xml

@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.jeesite.modules.sys.dao.EmpUserDao">
+    
+    <!-- 查询数据  -->
+	<select id="findList" resultType="EmpUser">
+		SELECT ${sqlMap.column.toSql()}
+		FROM ${sqlMap.table.toSql()}
+		<if test="roleCode != null and roleCode != ''">
+			JOIN ${_prefix}sys_user_role ur2 ON ur2.user_code = a.user_code
+		</if>
+		<if test="employee.postCode != null and employee.postCode != ''">
+			JOIN ${_prefix}sys_employee_post ep ON e.emp_code = ep.emp_code
+		</if>
+		<where>
+			${sqlMap.where.toSql()}
+			<if test="roleCode != null and roleCode != ''">
+				AND ur2.role_code = #{roleCode}
+			</if>
+			<if test="employee.postCode != null and employee.postCode != ''">
+				AND (
+					ep.post_code = #{employee.postCode}
+					OR EXISTS (
+						SELECT 1 FROM ${_prefix}sys_employee_office
+						WHERE emp_code = e.emp_code
+							AND post_code = #{employee.postCode}
+					)
+				)
+			</if>
+			<!-- 附属部门查询,根据业务需要添加查询条件
+			<if test="employee.office.officeCode != null and employee.office.officeCode != ''">
+				OR EXISTS (
+					SELECT 1 FROM ${_prefix}sys_employee_office
+					WHERE emp_code = e.emp_code
+						AND office_code = #{employee.office.officeCode}
+				)
+			</if> -->
+		</where>
+		ORDER BY ${sqlMap.order.toSql()}
+	</select>
+	
+	<sql id="userColumns">
+		a.user_code as "userCode",
+		a.user_name as "userName"
+	</sql>
+	
+	<!-- 查询全部用户,仅返回基本信息  -->
+	<select id="findUserList" resultType="EmpUser">
+		SELECT 
+		    <include refid="userColumns"/>
+		FROM ${_prefix}sys_user a
+		WHERE a.status = #{STATUS_NORMAL}
+			AND a.user_type = #{USER_TYPE_EMPLOYEE}
+			<if test="global.useCorpModel">
+		    	AND a.corp_code = #{corpCode}
+		    </if>
+	</select>
+	
+	<!-- 根据部门编码查询用户,仅返回基本信息  -->
+	<select id="findUserListByOfficeCodes" resultType="EmpUser">
+		SELECT 
+		    <include refid="userColumns"/>
+		FROM ${_prefix}sys_user a
+		JOIN ${_prefix}sys_employee e ON e.emp_code = a.ref_code
+		JOIN ${_prefix}sys_office o ON o.office_code = e.office_code
+		WHERE a.status = #{STATUS_NORMAL}
+			AND a.user_type = #{USER_TYPE_EMPLOYEE}
+			<if test="global.useCorpModel">
+		    	AND a.corp_code = #{corpCode}
+		    </if>
+		    AND e.status = #{STATUS_NORMAL}
+		    AND o.status = #{STATUS_NORMAL}
+			AND o.office_code IN
+			<foreach item="code" index="index" collection="codes" open="(" separator="," close=")">
+				#{code}
+			</foreach>
+	</select>
+	
+	<!-- 根据角色编码查询用户,仅返回基本信息  -->
+	<select id="findUserListByRoleCodes" resultType="EmpUser">
+		SELECT 
+		    <include refid="userColumns"/>
+		FROM ${_prefix}sys_user a
+		JOIN ${_prefix}sys_user_role ur2 ON ur2.user_code = a.user_code
+		JOIN ${_prefix}sys_role r ON r.role_code = ur2.role_code
+		WHERE a.status = #{STATUS_NORMAL}
+			AND a.user_type = #{USER_TYPE_EMPLOYEE}
+			<if test="global.useCorpModel">
+		    	AND a.corp_code = #{corpCode}
+		    </if>
+		    AND r.status = #{STATUS_NORMAL}
+			AND r.role_code IN
+			<foreach item="code" index="index" collection="codes" open="(" separator="," close=")">
+				#{code}
+			</foreach>
+	</select>
+	
+	<!-- 根据岗位编码查询用户,仅返回基本信息  -->
+	<select id="findUserListByPostCodes" resultType="EmpUser">
+		SELECT 
+		    <include refid="userColumns"/>
+		FROM ${_prefix}sys_user a
+		JOIN ${_prefix}sys_employee e ON e.emp_code = a.ref_code
+		JOIN ${_prefix}sys_employee_post ep ON ep.emp_code = e.emp_code
+		JOIN ${_prefix}sys_post p ON p.post_code = ep.post_code
+		WHERE a.status = #{STATUS_NORMAL}
+			AND a.user_type = #{USER_TYPE_EMPLOYEE}
+			<if test="global.useCorpModel">
+		    	AND a.corp_code = #{corpCode}
+		    </if>
+		    AND e.status = #{STATUS_NORMAL}
+		    AND p.status = #{STATUS_NORMAL}
+			AND p.post_code IN
+			<foreach item="code" index="index" collection="codes" open="(" separator="," close=")">
+				#{code}
+			</foreach>
+	</select>
+	
+</mapper>

+ 12 - 0
src/main/java/com/jeesite/modules/mes/entity/MesBatchSn.java

@@ -20,6 +20,7 @@ import java.util.Date;
 		@Column(name="batch_sn", attrName="batchSn", label="批次码"),
 		@Column(name="nums", attrName="nums", label="已绑定数量", isUpdateForce=true),
 		@Column(name="is_js", attrName="isJs", label="是否用完"),
+		@Column(name="batch_status", attrName="batchStatus", label="状态"),
 		@Column(name="line_sn", attrName="lineSn"),
 		@Column(name="instock_status", attrName="instockStatus", label="ERP入库状态"),
 		@Column(name="mo_bill_no", attrName="moBillNo", label="生产订单号"),
@@ -39,6 +40,8 @@ public class MesBatchSn extends DataEntity<MesBatchSn> {
 	private String batchSn;		// 批次码
 	private Long nums;		// 已绑定数量
 	private String isJs;		// 是否用完
+	/** 状态:0仓库中(创建后) 1合格(发货检后) 2已发货 */
+	private String batchStatus;
 	private String lineSn;
 	/** ERP入库状态:0待入库 1已入库 */
 	private String instockStatus;
@@ -83,6 +86,15 @@ public class MesBatchSn extends DataEntity<MesBatchSn> {
 	public void setIsJs(String isJs) {
 		this.isJs = isJs;
 	}
+
+	@Size(min=0, max=1, message="状态长度不能超过 1 个字符")
+	public String getBatchStatus() {
+		return batchStatus;
+	}
+
+	public void setBatchStatus(String batchStatus) {
+		this.batchStatus = batchStatus;
+	}
 	
 	public Date getCreateDate_gte() {
 		return sqlMap.getWhere().getValue("create_date", QueryType.GTE);

+ 2 - 1
src/main/java/com/jeesite/modules/mes/entity/MesDevicePreventTask.java

@@ -100,7 +100,8 @@ public class MesDevicePreventTask extends DataEntity<MesDevicePreventTask> {
 		this.preventId = preventId;
 	}
 	
-	@Size(min=0, max=100, message="执行人员长度不能超过 100 个字符")
+	/** 新增时可多选,提交为逗号分隔;落库时按人拆成多条,单条仍为单个用户编码 */
+	@Size(min=0, max=2000, message="执行人员长度不能超过 2000 个字符")
 	public String getUserCode() {
 		return userCode;
 	}

+ 10 - 0
src/main/java/com/jeesite/modules/mes/entity/MesProductCmt.java

@@ -31,10 +31,12 @@ public class MesProductCmt extends DataEntity<MesProductCmt> {
 	private String oprno;		// 工位号
 	private String lineSn;		// 产线编号
 	private String content;		// 参数内容
+	private String oprnoTitle;	// 工位名称(非表字段,列表回填)
 
 	@ExcelFields({
 		@ExcelField(title="二维码", attrName="sn", align=Align.CENTER, sort=20),
 		@ExcelField(title="工位号", attrName="oprno", align=Align.CENTER, sort=30),
+		@ExcelField(title="工位名称", attrName="oprnoTitle", align=Align.CENTER, sort=35),
 		@ExcelField(title="产线编号", attrName="lineSn", align=Align.CENTER, sort=40),
 		@ExcelField(title="参数内容", attrName="content", align=Align.CENTER, sort=50),
 		@ExcelField(title="创建时间", attrName="createDate", align=Align.CENTER, sort=60, dataFormat="yyyy-MM-dd hh:mm"),
@@ -81,5 +83,13 @@ public class MesProductCmt extends DataEntity<MesProductCmt> {
 	public void setContent(String content) {
 		this.content = content;
 	}
+
+	public String getOprnoTitle() {
+		return oprnoTitle;
+	}
+
+	public void setOprnoTitle(String oprnoTitle) {
+		this.oprnoTitle = oprnoTitle;
+	}
 	
 }

+ 1 - 1
src/main/java/com/jeesite/modules/mes/entity/MesScrap.java

@@ -20,7 +20,7 @@ import java.util.List;
 		@Column(name="sn", attrName="sn", label="工件码"),
 		@Column(name="reason", attrName="reason", label="报废原因"),
 		@Column(name="product_cate", attrName="productCate", label="产品类型"),
-		@Column(name="status", attrName="status", label="状态", isInsert=false, isUpdate=false, isQuery=false),
+		@Column(name="status", attrName="status", label="状态", isUpdate=false),
 		@Column(name="create_by", attrName="createBy", label="create_by", isUpdate=false, isQuery=false),
 		@Column(name="create_date", attrName="createDate", label="create_date", isUpdate=false, isQuery=false, isUpdateForce=true),
 		@Column(name="update_by", attrName="updateBy", label="日期", isQuery=false),

+ 13 - 2
src/main/java/com/jeesite/modules/mes/service/MesProductCcdService.java

@@ -182,7 +182,7 @@ public class MesProductCcdService extends CrudService<MesProductCcdDao, MesProdu
 
 		String sn = parts[2];	//序号
 		String oprno = parts[3]; // OP290B
-		String lineSn = "HEVXT";	//产线编号
+		String lineSn = "115XT";	//产线编号
 		String title = parts[4];//设备名称
 		oprno = CommonUitl.formatOprno(oprno);
 		if(StringUtils.isEmpty(sn)){
@@ -248,9 +248,15 @@ public class MesProductCcdService extends CrudService<MesProductCcdDao, MesProdu
 
 		String sn = parts[2];
 		String oprno = parts[3];
-		String lineSn = "HEVXT";
+		String lineSn = "115XT";
 		String result = parts[7];
 		String userCode = parts[1];
+		// 绑定发货码,
+		String fhm = parts[6];
+		// 判断是否为空
+		if (StringUtils.isEmpty(fhm) || "".equals(fhm)){
+			return CommonUitl.getXml("NG;发货码不能为空;");
+		}
 		String craft = "100000";
 
 		if(StringUtils.isEmpty(sn)){
@@ -272,6 +278,11 @@ public class MesProductCcdService extends CrudService<MesProductCcdDao, MesProdu
 		paramsResp1.setResult("OK");
 		paramsResp1.setVal(userCode);
 		params.add(paramsResp1);
+		ParamsResp paramsResp2 = new ParamsResp();
+		paramsResp2.setCraft("400006");
+		paramsResp2.setResult("OK");
+		paramsResp2.setVal(fhm);
+		params.add(paramsResp2);
 
 		try{
 			// 2.判断物料批次是否符合绑定

+ 2 - 2
src/main/java/com/jeesite/modules/mes/service/MesScrapService.java

@@ -74,13 +74,13 @@ public class MesScrapService extends CrudService<MesScrapDao, MesScrap> {
 	}
 	
 	/**
-	 * 删除数据
+	 * 删除数据(物理删除,避免 status 字段配置导致逻辑删除后仍出现在列表)
 	 * @param mesScrap
 	 */
 	@Override
 	@Transactional
 	public void delete(MesScrap mesScrap) {
-		super.delete(mesScrap);
+		dao.deleteByEntity(mesScrap);
 	}
 	
 }

+ 80 - 17
src/main/java/com/jeesite/modules/mes/service/MesTemplateItemsService.java

@@ -1,24 +1,26 @@
 package com.jeesite.modules.mes.service;
 
-import java.util.List;
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import com.alibaba.fastjson.JSON;
 import com.jeesite.common.cache.CacheUtils;
 import com.jeesite.common.collect.ListUtils;
 import com.jeesite.common.lang.StringUtils;
-import com.jeesite.common.lang.ObjectUtils;
-import com.jeesite.modules.mes.entity.MesTemplate;
+import com.jeesite.modules.mes.dao.MesProductCateDao;
+import com.jeesite.modules.mes.dao.MesTemplateItemsDao;
+import com.jeesite.modules.mes.entity.MesLine;
 import com.jeesite.modules.mes.entity.MesLineProcess;
+import com.jeesite.modules.mes.entity.MesProductCate;
+import com.jeesite.modules.mes.entity.MesTemplateItems;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import com.jeesite.common.entity.Page;
 import com.jeesite.common.service.CrudService;
-import com.jeesite.modules.mes.entity.MesTemplateItems;
-import com.jeesite.modules.mes.dao.MesTemplateItemsDao;
 
 /**
  * 模板清单Service
@@ -34,6 +36,12 @@ public class MesTemplateItemsService extends CrudService<MesTemplateItemsDao, Me
 	@Autowired
 	private MesLineProcessService mesLineProcessService;
 
+	@Autowired
+	private MesLineService mesLineService;
+
+	@Autowired
+	private MesProductCateDao mesProductCateDao;
+
 	/**
 	 * 获取单条数据
 	 * @param mesTemplateItems
@@ -73,26 +81,81 @@ public class MesTemplateItemsService extends CrudService<MesTemplateItemsDao, Me
 		return list;
 	}
 
+	/**
+	 * 按模板关联产线填充工位名称,避免不同产线同工位号互相串名
+	 */
 	private void fillOprnoName(List<MesTemplateItems> list) {
 		if (ListUtils.isEmpty(list)) {
 			return;
 		}
-		MesLineProcess query = new MesLineProcess();
-		query.setStatus(MesLineProcess.STATUS_NORMAL);
-		List<MesLineProcess> processList = mesLineProcessService.findList(query);
-		if (ListUtils.isEmpty(processList)) {
-			return;
+		Map<String, List<MesTemplateItems>> byTemplate = new HashMap<>();
+		for (MesTemplateItems item : list) {
+			String templateId = StringUtils.defaultString(item.getTemplateId());
+			List<MesTemplateItems> items = byTemplate.get(templateId);
+			if (items == null) {
+				items = new ArrayList<>();
+				byTemplate.put(templateId, items);
+			}
+			items.add(item);
 		}
-		Map<String, String> processMap = new HashMap<>();
-		for (MesLineProcess process : processList) {
-			if (StringUtils.isNotBlank(process.getOprno()) && StringUtils.isNotBlank(process.getTitle())
-					&& !processMap.containsKey(process.getOprno())) {
-				processMap.put(process.getOprno(), process.getTitle());
+		for (Map.Entry<String, List<MesTemplateItems>> entry : byTemplate.entrySet()) {
+			Map<String, String> processMap = buildOprnoNameMapByTemplate(entry.getKey());
+			for (MesTemplateItems item : entry.getValue()) {
+				item.setOprnoName(processMap.get(item.getOprno()));
 			}
 		}
-		for (MesTemplateItems item : list) {
-			item.setOprnoName(processMap.get(item.getOprno()));
+	}
+
+	/**
+	 * 根据模板找到关联产线,再按产线工位构建 工位号->名称 映射
+	 */
+	private Map<String, String> buildOprnoNameMapByTemplate(String templateId) {
+		Map<String, String> processMap = new HashMap<>();
+		if (StringUtils.isBlank(templateId)) {
+			return processMap;
+		}
+		MesProductCate cateQuery = new MesProductCate();
+		cateQuery.setTemplateId(templateId);
+		cateQuery.setStatus(MesProductCate.STATUS_NORMAL);
+		List<MesProductCate> cateList = mesProductCateDao.findList(cateQuery);
+		if (ListUtils.isEmpty(cateList)) {
+			return processMap;
+		}
+		for (MesProductCate cate : cateList) {
+			if (StringUtils.isBlank(cate.getSn())) {
+				continue;
+			}
+			MesLine lineQuery = new MesLine();
+			lineQuery.setProductCate(cate.getSn());
+			lineQuery.setStatus(MesLine.STATUS_NORMAL);
+			List<MesLine> lineList = mesLineService.findList(lineQuery);
+			if (ListUtils.isEmpty(lineList)) {
+				continue;
+			}
+			for (MesLine line : lineList) {
+				if (StringUtils.isBlank(line.getId())) {
+					continue;
+				}
+				MesLineProcess processQuery = new MesLineProcess();
+				processQuery.setLineId(line.getId());
+				processQuery.setStatus(MesLineProcess.STATUS_NORMAL);
+				List<MesLineProcess> processList = mesLineProcessService.findList(processQuery);
+				if (ListUtils.isEmpty(processList)) {
+					continue;
+				}
+				for (MesLineProcess process : processList) {
+					if (StringUtils.isBlank(process.getOprno()) || StringUtils.isBlank(process.getTitle())) {
+						continue;
+					}
+					boolean isParent = StringUtils.isBlank(process.getPid());
+					// 同工位号优先使用父工位名称
+					if (!processMap.containsKey(process.getOprno()) || isParent) {
+						processMap.put(process.getOprno(), process.getTitle());
+					}
+				}
+			}
 		}
+		return processMap;
 	}
 
 	public List<MesTemplateItems> findListItems(String templateId){

+ 6 - 0
src/main/java/com/jeesite/modules/mes/web/MesBatchSnController.java

@@ -180,6 +180,10 @@ public class MesBatchSnController extends BaseController {
 			if (StringUtils.isBlank(mesBatchSn.getIsJs())) {
 				mesBatchSn.setIsJs("1");
 			}
+			// 创建后默认:仓库中
+			if (StringUtils.isBlank(mesBatchSn.getBatchStatus())) {
+				mesBatchSn.setBatchStatus("0");
+			}
 		}
 		mesBatchSnService.save(mesBatchSn);
 		return renderResult(Global.TRUE, text("保存批次码成功!"));
@@ -315,6 +319,8 @@ public class MesBatchSnController extends BaseController {
 		mesBatchSn.setNums(0L);
 		mesBatchSn.setLineSn(lineSn);
 		mesBatchSn.setBatchSn(orderNumber);
+		// 创建后默认:仓库中
+		mesBatchSn.setBatchStatus("0");
 
 		mesBatchSnService.save(mesBatchSn);
 		map.put("batchSn",mesBatchSn.getBatchSn());

+ 55 - 39
src/main/java/com/jeesite/modules/mes/web/MesDevicePreventTaskController.java

@@ -9,7 +9,6 @@ import com.jeesite.common.entity.Page;
 import com.jeesite.common.lang.DateUtils;
 import com.jeesite.common.lang.ObjectUtils;
 import com.jeesite.common.lang.StringUtils;
-import com.jeesite.common.mybatis.mapper.query.QueryType;
 import com.jeesite.common.service.ServiceException;
 import com.jeesite.common.utils.excel.ExcelExport;
 import com.jeesite.common.utils.excel.ExcelImport;
@@ -65,12 +64,6 @@ public class MesDevicePreventTaskController extends BaseController {
 	private MesDeviceService mesDeviceService;
 	@Resource
 	private MesDevicePreventService mesDevicePreventService;
-	@Autowired
-	private MesSkillService mesSkillService;
-	@Autowired
-	private MesLineProcessService mesLineProcessService;
-	@Autowired
-	private	MesLineService mesLineService;
 	/**
 	 * 获取数据
 	 */
@@ -125,55 +118,78 @@ public class MesDevicePreventTaskController extends BaseController {
 
 	/**
 	 * 保存数据
+	 * 新增时执行人员支持多选:按逗号拆分,为每人生成一条计划
+	 * 说明:维护性任务由管理员指派,不校验产线工位操作权限/技能(与上岗扫码场景不同)
 	 */
 	@RequiresPermissions("mes:mesDevicePreventTask:edit")
 	@PostMapping(value = "save")
 	@ResponseBody
+	@Transactional
 	public String save(@Validated MesDevicePreventTask mesDevicePreventTask) {
-		String userCode = mesDevicePreventTask.getUserCode();
-		//1.根据设备查出产线编号
 		MesDevice mesDevice = new MesDevice();
 		mesDevice.setTreeCode(mesDevicePreventTask.getDeviceId());
 		MesDevice mesDevice1 = mesDeviceService.getByEntity(mesDevice);
-		String gw = mesDevice1.getGw();
-		String lineSn = mesDevice1.getLineSn();
-		//判断执行人员是否有操作该工位的权限
-		MesLineProcessUser mesLineProcessUser = new MesLineProcessUser();
-		User user = new User();
-		user.setUserCode(userCode);
-		mesLineProcessUser.setUserCode(user.getUserCode());
-		String type = "0";
-		if (type.equals("1")) { // 质量
-			String[] ids = new String[]{"1", "2"};
-			mesLineProcessUser.getSqlMap().getWhere().and("auth", QueryType.IN, ids);
-		} else { // 生产
-			String[] ids = new String[]{"0", "2"};
-			mesLineProcessUser.getSqlMap().getWhere().and("auth", QueryType.IN, ids);
+		if (ObjectUtils.isEmpty(mesDevice1)) {
+			return renderResult(Global.FALSE, text("保存失败,设备不存在!"));
 		}
-		List<MesLineProcessUser> list = mesLineProcessService.findSubListOrder(mesLineProcessUser);
 
-		List<String> mlps = new ArrayList<>();
-		for(MesLineProcessUser mesLineProcessUser1:list){
-			mlps.add(mesLineProcessUser1.getLineProcessId());
+		// 新增:支持多选执行人,每人一条计划
+		if (mesDevicePreventTask.getIsNewRecord()) {
+			List<String> userCodes = parseUserCodes(mesDevicePreventTask.getUserCode());
+			if (userCodes.isEmpty()) {
+				return renderResult(Global.FALSE, text("请选择执行人员!"));
+			}
+			int saveCount = 0;
+			for (String userCode : userCodes) {
+				MesDevicePreventTask saveTask = new MesDevicePreventTask();
+				BeanUtil.copyProperties(mesDevicePreventTask, saveTask, "id", "isNewRecord");
+				saveTask.setIsNewRecord(true);
+				saveTask.setUserCode(userCode);
+				mesDevicePreventTaskService.save(saveTask);
+				saveCount++;
+			}
+			return renderResult(Global.TRUE, text("保存预防性维修计划成功!共" + saveCount + "条"));
 		}
 
-		MesLineProcess mesLineProcess = new MesLineProcess();
-		mesLineProcess.getSqlMap().getWhere().and("id", QueryType.IN,mlps);
-		mesLineProcess.setOprno(gw);
-		mesLineProcess.setLineSn(lineSn);
-		MesLineProcess mesLineProcess1 = mesLineProcessService.findInfo(mesLineProcess);
-		if(ObjectUtils.isEmpty(mesLineProcess1)){
-			return renderResult(Global.FALSE, text("保存失败,该执行人员暂无操作该设备权限!"));
+		// 编辑:按单人保存
+		String userCode = StringUtils.trim(mesDevicePreventTask.getUserCode());
+		if (StringUtils.isBlank(userCode)) {
+			return renderResult(Global.FALSE, text("请选择执行人员!"));
 		}
-
-		//工人技能检验
-		if (!mesSkillService.checkUserSkill(lineSn, gw, userCode)) {
-			return renderResult(Global.FALSE, text("保存失败,该执行人员具备该设备技能不足!"));
+		User user = UserUtils.get(userCode);
+		if (user == null || StringUtils.isBlank(user.getUserCode())) {
+			return renderResult(Global.FALSE, text("保存失败,执行人员不存在!"));
 		}
-
+		mesDevicePreventTask.setUserCode(user.getUserCode());
 		mesDevicePreventTaskService.save(mesDevicePreventTask);
 		return renderResult(Global.TRUE, text("保存预防性维修计划成功!"));
 	}
+
+	/**
+	 * 解析多选执行人(过滤机构节点,仅保留用户)
+	 */
+	private List<String> parseUserCodes(String userCodeStr) {
+		List<String> result = new ArrayList<>();
+		String[] userCodes = StringUtils.split(StringUtils.trim(userCodeStr), ",");
+		if (userCodes == null) {
+			return result;
+		}
+		for (String code : userCodes) {
+			String userCode = StringUtils.trim(code);
+			if (StringUtils.isBlank(userCode)) {
+				continue;
+			}
+			User user = UserUtils.get(userCode);
+			if (user == null || StringUtils.isBlank(user.getUserCode())) {
+				continue;
+			}
+			String realCode = user.getUserCode();
+			if (!result.contains(realCode)) {
+				result.add(realCode);
+			}
+		}
+		return result;
+	}
 	
 	/**
 	 * 删除数据

+ 27 - 1
src/main/java/com/jeesite/modules/mes/web/MesPieceSalaryReportController.java

@@ -1,5 +1,9 @@
 package com.jeesite.modules.mes.web;
 
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
 import java.util.List;
 
 import javax.servlet.http.HttpServletRequest;
@@ -14,24 +18,29 @@ import org.springframework.web.bind.annotation.ResponseBody;
 
 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.MesPieceSalaryReport;
 import com.jeesite.modules.mes.service.MesPieceSalaryReportService;
 
 /**
- * Piece salary accounting controller.
+ * 计件工资核算Controller
  */
 @Controller
 @RequestMapping(value = "${adminPath}/mes/mesPieceSalaryReport")
 public class MesPieceSalaryReportController extends BaseController {
 
+	private static final DateTimeFormatter DATE_TIME_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
+
 	@Autowired
 	private MesPieceSalaryReportService mesPieceSalaryReportService;
 
 	@RequiresPermissions("mes:mesPieceSalaryReport:view")
 	@RequestMapping(value = {"list", ""})
 	public String list(MesPieceSalaryReport report, Model model) {
+		// 默认按当月统计
+		fillDefaultMonthRange(report);
 		model.addAttribute("mesPieceSalaryReport", report);
 		return "modules/mes/mesPieceSalaryReportList";
 	}
@@ -61,4 +70,21 @@ public class MesPieceSalaryReportController extends BaseController {
 	public List<MesPieceSalaryReport> detailData(MesPieceSalaryReport report) {
 		return mesPieceSalaryReportService.findDetailList(report);
 	}
+
+	/**
+	 * 起止时间为空时,默认填充当月第一天 00:00 至当月最后一天 23:59
+	 */
+	private void fillDefaultMonthRange(MesPieceSalaryReport report) {
+		if (report == null) {
+			return;
+		}
+		if (StringUtils.isNotBlank(report.getStartDate()) || StringUtils.isNotBlank(report.getEndDate())) {
+			return;
+		}
+		LocalDate today = LocalDate.now();
+		LocalDateTime monthStart = LocalDateTime.of(today.withDayOfMonth(1), LocalTime.of(0, 0));
+		LocalDateTime monthEnd = LocalDateTime.of(today.withDayOfMonth(today.lengthOfMonth()), LocalTime.of(23, 59));
+		report.setStartDate(monthStart.format(DATE_TIME_FMT));
+		report.setEndDate(monthEnd.format(DATE_TIME_FMT));
+	}
 }

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

@@ -1,14 +1,19 @@
 package com.jeesite.modules.mes.web;
 
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.jeesite.common.lang.ObjectUtils;
 import com.jeesite.common.lang.StringUtils;
+import com.jeesite.modules.mes.entity.MesLineProcess;
 import com.jeesite.modules.mes.req.MesSearchDateReq;
+import com.jeesite.modules.mes.service.MesLineProcessService;
 import com.jeesite.modules.mes.util.CommonUitl;
 import org.apache.shiro.authz.annotation.RequiresPermissions;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -40,6 +45,9 @@ public class MesProductCmtController extends BaseController {
 
 	@Autowired
 	private MesProductCmtService mesProductCmtService;
+
+	@Autowired
+	private MesLineProcessService mesLineProcessService;
 	
 	/**
 	 * 获取数据
@@ -71,10 +79,52 @@ public class MesProductCmtController extends BaseController {
 	public Page<MesProductCmt> listData(MesProductCmt mesProductCmt, HttpServletRequest request, HttpServletResponse response) {
 		mesProductCmt.setPage(new Page<>(request, response));
 		Page<MesProductCmt> page = mesProductCmtService.findPage(mesProductCmt);
+		fillOprnoTitle(page.getList());
 		return page;
 	}
 
 	/**
+	 * 按产线+工位回填工位名称(兼容 OP040 / OP040A)
+	 */
+	private void fillOprnoTitle(List<MesProductCmt> list) {
+		if (ListUtils.isEmpty(list)) {
+			return;
+		}
+		Map<String, String> oprnoTitleMap = new HashMap<>();
+		for (MesProductCmt record : list) {
+			if (StringUtils.isNotBlank(record.getOprnoTitle())) {
+				continue;
+			}
+			if (StringUtils.isBlank(record.getLineSn()) || StringUtils.isBlank(record.getOprno())) {
+				record.setOprnoTitle("");
+				continue;
+			}
+			String key = record.getLineSn() + "|" + record.getOprno();
+			if (!oprnoTitleMap.containsKey(key)) {
+				oprnoTitleMap.put(key, findOprnoTitle(record.getLineSn(), record.getOprno()));
+			}
+			record.setOprnoTitle(oprnoTitleMap.get(key));
+		}
+	}
+
+	private String findOprnoTitle(String lineSn, String oprno) {
+		MesLineProcess mesLineProcess = new MesLineProcess();
+		mesLineProcess.setLineSn(lineSn);
+		mesLineProcess.setOprno(oprno);
+		MesLineProcess mesLineProcess1 = mesLineProcessService.findInfo(mesLineProcess);
+		if (!ObjectUtils.isEmpty(mesLineProcess1)) {
+			return mesLineProcess1.getTitle();
+		}
+		String formattedOprno = CommonUitl.formatOprno(oprno);
+		if (StringUtils.equals(oprno, formattedOprno)) {
+			return "";
+		}
+		mesLineProcess.setOprno(formattedOprno);
+		mesLineProcess1 = mesLineProcessService.findInfo(mesLineProcess);
+		return ObjectUtils.isEmpty(mesLineProcess1) ? "" : mesLineProcess1.getTitle();
+	}
+
+	/**
 	 * 查看编辑表单
 	 */
 	@RequiresPermissions("mes:mesProductCmt:view")
@@ -102,8 +152,9 @@ public class MesProductCmtController extends BaseController {
 	@RequestMapping(value = "exportData")
 	public void exportData(MesProductCmt mesProductCmt, HttpServletResponse response) {
 		List<MesProductCmt> list = mesProductCmtService.findList(mesProductCmt);
-		String fileName = "CMT过程参数" + DateUtils.getDate("yyyyMMddHHmmss") + ".xlsx";
-		try(ExcelExport ee = new ExcelExport("CMT过程参数", MesProductCmt.class)){
+		fillOprnoTitle(list);
+		String fileName = "弧焊过程参数" + DateUtils.getDate("yyyyMMddHHmmss") + ".xlsx";
+		try(ExcelExport ee = new ExcelExport("弧焊过程参数", MesProductCmt.class)){
 			ee.setDataList(list).write(response, fileName);
 		}
 	}

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

@@ -4100,7 +4100,7 @@ public class MesProductRecordController extends BaseController {
 				}
 				String sn = commands[2];
 				String oprno = commands[3]; // OP290B
-				String lineSn = "HEVXT";
+				String lineSn = "115XT";
 				String oldOprno = oprno;
 				oprno = CommonUitl.formatOprno(oprno);
 				if (StringUtils.isEmpty(sn)) {
@@ -4893,12 +4893,12 @@ public class MesProductRecordController extends BaseController {
 		// 根据lineSn获取产品信息(mesProductCate表)
 		MesProductCate mesProductCate = mesProductCateService.findBySn(lineSn);
 		// 按照规格检查工件码是否合规(根据)
-		Boolean ret =  CommonUitl.checkSnByModel(sn,mesProductCate.getSpec(),mesProductCate.getSpecStart(),mesProductCate.getLength());
-		if (!ret){
-			resp.setResult(Global.FALSE);
-			resp.setMessage("图号不正确,请重新扫码");
-			return resp;
-		}
+//		Boolean ret =  CommonUitl.checkSnByModel(sn,mesProductCate.getSpec(),mesProductCate.getSpecStart(),mesProductCate.getLength());
+//		if (!ret){
+//			resp.setResult(Global.FALSE);
+//			resp.setMessage("图号不正确,请重新扫码");
+//			return resp;
+//		}
 
 
 

+ 35 - 5
src/main/java/com/jeesite/modules/mes/web/MesStationPiecePriceController.java

@@ -24,13 +24,15 @@ import com.jeesite.common.lang.StringUtils;
 import com.jeesite.common.utils.excel.ExcelExport;
 import com.jeesite.common.utils.excel.annotation.ExcelField.Type;
 import com.jeesite.common.web.BaseController;
+import com.jeesite.modules.mes.entity.MesLine;
 import com.jeesite.modules.mes.entity.MesLineProcess;
 import com.jeesite.modules.mes.entity.MesStationPiecePrice;
 import com.jeesite.modules.mes.service.MesLineProcessService;
+import com.jeesite.modules.mes.service.MesLineService;
 import com.jeesite.modules.mes.service.MesStationPiecePriceService;
 
 /**
- * Station piece price controller.
+ * 工位计件单价Controller
  */
 @Controller
 @RequestMapping(value = "${adminPath}/mes/mesStationPiecePrice")
@@ -42,6 +44,9 @@ public class MesStationPiecePriceController extends BaseController {
 	@Autowired
 	private MesLineProcessService mesLineProcessService;
 
+	@Autowired
+	private MesLineService mesLineService;
+
 	@ModelAttribute
 	public MesStationPiecePrice get(String id, boolean isNewRecord) {
 		return mesStationPiecePriceService.get(id, isNewRecord);
@@ -67,6 +72,10 @@ public class MesStationPiecePriceController extends BaseController {
 	@RequestMapping(value = "form")
 	public String form(MesStationPiecePrice mesStationPiecePrice, Model model) {
 		model.addAttribute("mesStationPiecePrice", mesStationPiecePrice);
+		// 产线下拉选项
+		MesLine mesLine = new MesLine();
+		mesLine.setStatus(MesLine.STATUS_NORMAL);
+		model.addAttribute("lineList", mesLineService.findList(mesLine));
 		return "modules/mes/mesStationPiecePriceForm";
 	}
 
@@ -119,11 +128,14 @@ public class MesStationPiecePriceController extends BaseController {
 		}
 	}
 
+	/**
+	 * 按产线查询父工位列表(pid 为空)
+	 */
 	@RequiresPermissions("mes:mesStationPiecePrice:view")
 	@RequestMapping(value = "stationList")
 	@ResponseBody
 	public List<MesLineProcess> stationList(String lineSn) {
-		return mesLineProcessService.findOprnoListByLineSn(lineSn);
+		return findParentStationList(lineSn);
 	}
 
 	@RequiresPermissions("mes:mesStationPiecePrice:view")
@@ -133,11 +145,29 @@ public class MesStationPiecePriceController extends BaseController {
 		if (StringUtils.isBlank(lineSn) || StringUtils.isBlank(oprno)) {
 			return null;
 		}
-		for (MesLineProcess item : mesLineProcessService.findOprnoListByLineSn(lineSn)) {
-			if (oprno.trim().equals(item.getOprno())) {
+		String targetOprno = oprno.trim();
+		for (MesLineProcess item : findParentStationList(lineSn)) {
+			if (targetOprno.equals(item.getOprno())) {
 				return item;
 			}
 		}
-		return mesLineProcessService.findInfoByOprnoLineSn(oprno, lineSn);
+		return null;
+	}
+
+	/**
+	 * 根据产线编号查询父工位
+	 */
+	private List<MesLineProcess> findParentStationList(String lineSn) {
+		if (StringUtils.isBlank(lineSn)) {
+			return ListUtils.newArrayList();
+		}
+		MesLine query = new MesLine();
+		query.setSn(lineSn.trim());
+		query.setStatus(MesLine.STATUS_NORMAL);
+		MesLine line = mesLineService.findInfo(query);
+		if (line == null || StringUtils.isBlank(line.getId())) {
+			return ListUtils.newArrayList();
+		}
+		return mesLineProcessService.findParentListByLine(line.getId(), lineSn.trim());
 	}
 }

+ 4 - 3
src/main/resources/config/application.yml

@@ -852,11 +852,12 @@ shiro:
     ${adminPath}/mes/mesProductProgress/pdaOut= anon
     ${adminPath}/mes/mesMaterialKw/kwList= anon
     ${adminPath}/mes/mesJbLog/getBatchInfo= anon
-    ${adminPath}/mes/mesScrap/add= anon
-    ${adminPath}/mes/mesScrap/ulist= anon
-    ${adminPath}/mes/mesScrap/info= anon
     ${adminPath}/** = user
 
+  # 以下为已注释的 scrap 匿名接口(勿写在 | 块顶格,否则会破坏 YAML)
+  # ${adminPath}/mes/mesScrap/add= anon
+  # ${adminPath}/mes/mesScrap/ulist= anon
+  # ${adminPath}/mes/mesScrap/info= anon
 
 #  # URI 权限过滤器定义(以下参考,必须登录user可访问的地址和不需要登录anon可访问地址)
 #  filterChainDefinitions: |

+ 1 - 0
src/main/resources/mappings/modules/mes/MesBatchSnDao.xml

@@ -28,6 +28,7 @@
 			a.batch_sn AS "batchSn",
 			a.nums AS "nums",
 			a.is_js AS "isJs",
+			a.batch_status AS "batchStatus",
 			a.line_sn AS "lineSn",
 			a.instock_status AS "instockStatus",
 			a.mo_bill_no AS "moBillNo",

+ 57 - 7
src/main/resources/mappings/modules/mes/MesPieceSalaryReportDao.xml

@@ -8,15 +8,65 @@
 			COALESCE(u.user_name, e.emp_name, r.ucode) AS userName,
 			r.line_sn AS lineSn,
 			r.oprno AS oprno,
-			COALESCE(MAX(p.oprno_name), r.oprno) AS oprnoName,
+			COALESCE((
+				SELECT lp.title
+				FROM mes_line l
+				INNER JOIN mes_line_process lp
+					ON lp.line_id = l.id
+					AND lp.status = '0'
+				WHERE l.sn = r.line_sn
+					AND l.status = '0'
+					AND (
+						lp.oprno = r.oprno
+						OR lp.oprno = LEFT(r.oprno, 5)
+						OR LEFT(lp.oprno, 5) = LEFT(r.oprno, 5)
+					)
+				ORDER BY
+					CASE WHEN IFNULL(lp.pid, '') = '' THEN 0 ELSE 1 END,
+					CASE WHEN lp.oprno = r.oprno THEN 0 ELSE 1 END
+				LIMIT 1
+			), (
+				SELECT p.oprno_name
+				FROM mes_station_piece_price p
+				WHERE p.line_sn = r.line_sn
+					AND p.status = '0'
+					AND (
+						p.oprno = r.oprno
+						OR p.oprno = LEFT(r.oprno, 5)
+						OR LEFT(p.oprno, 5) = r.oprno
+					)
+					AND IFNULL(p.oprno_name, '') != ''
+				ORDER BY CASE WHEN p.oprno = r.oprno THEN 0 ELSE 1 END
+				LIMIT 1
+			), r.oprno) AS oprnoName,
 			COUNT(1) AS pieceCount,
-			COALESCE(MAX(p.unit_price), 0) AS unitPrice,
-			COUNT(1) * COALESCE(MAX(p.unit_price), 0) AS salaryAmount
+			COALESCE((
+				SELECT p.unit_price
+				FROM mes_station_piece_price p
+				WHERE p.line_sn = r.line_sn
+					AND p.status = '0'
+					AND (
+						p.oprno = r.oprno
+						OR p.oprno = LEFT(r.oprno, 5)
+						OR LEFT(p.oprno, 5) = r.oprno
+					)
+				ORDER BY CASE WHEN p.oprno = r.oprno THEN 0 ELSE 1 END
+				LIMIT 1
+			), 0) AS unitPrice,
+			COUNT(1) * COALESCE((
+				SELECT p.unit_price
+				FROM mes_station_piece_price p
+				WHERE p.line_sn = r.line_sn
+					AND p.status = '0'
+					AND (
+						p.oprno = r.oprno
+						OR p.oprno = LEFT(r.oprno, 5)
+						OR LEFT(p.oprno, 5) = r.oprno
+					)
+				ORDER BY CASE WHEN p.oprno = r.oprno THEN 0 ELSE 1 END
+				LIMIT 1
+			), 0) AS salaryAmount
 		FROM mes_pda_scan_record r
-		LEFT JOIN mes_station_piece_price p
-			ON p.line_sn = r.line_sn
-			AND p.oprno = r.oprno
-			AND p.status = '0'
 		LEFT JOIN js_sys_user u
 			ON u.login_code = r.ucode
 			AND u.status IN ('0', '3')

+ 9 - 0
src/main/resources/views/modules/mes/mesBatchSnForm.html

@@ -51,6 +51,15 @@
 							</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:select path="batchStatus" dictType="mes_batch_sn_status" blankOption="true" class="form-control" />
+							</div>
+						</div>
+					</div>
 					<% } %>
 				</div>
 			</div>

+ 4 - 0
src/main/resources/views/modules/mes/mesBatchSnInfo.html

@@ -23,6 +23,10 @@
 						<th class="mpc-header">产线编号</th>
 						<td>${mesBatchSn.lineSn}</td>
 					</tr>
+					<tr>
+						<th class="mpc-header">状态</th>
+						<td>${@DictUtils.getDictLabel('mes_batch_sn_status', mesBatchSn.batchStatus, '未知')}</td>
+					</tr>
 
 					<tr>
 						<th class="mpc-header">产品信息</th>

+ 9 - 0
src/main/resources/views/modules/mes/mesBatchSnList.html

@@ -34,6 +34,12 @@
 					</div>
 				</div>
 				<div class="form-group">
+					<label class="control-label">${text('状态')}:</label>
+					<div class="control-inline width-120">
+						<#form:select path="batchStatus" dictType="mes_batch_sn_status" blankOption="true" class="form-control"/>
+					</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"
@@ -67,6 +73,9 @@ $('#dataGrid').dataGrid({
 		{header:'${text("是否用完")}', name:'isJs', index:'a.is_js', width:150, align:"center", formatter: function(val, obj, row, act){
 			return js.getDictLabel(${@DictUtils.getDictListJson('mes_batch_sn_is_js')}, val, '${text("未知")}', true);
 		}},
+		{header:'${text("状态")}', name:'batchStatus', index:'a.batch_status', width:120, align:"center", formatter: function(val, obj, row, act){
+			return js.getDictLabel(${@DictUtils.getDictListJson('mes_batch_sn_status')}, val, '${text("未知")}', true);
+		}},
 		{header:'${text("创建人")}', name:'createBy', index:'a.create_by', width:150, align:"center"},
 		{header:'${text("创建时间")}', name:'createDate', index:'a.create_date', width:150, align:"center"},
 		{header:'${text("更新人")}', name:'updateBy', index:'a.update_by', width:150, align:"center"},

+ 11 - 4
src/main/resources/views/modules/mes/mesDevicePreventTaskForm.html

@@ -31,10 +31,17 @@
 							<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:treeselect id="userCode" title="${text('用户选择')}"
-								path="userCode" labelPath="userName"
-								url="${ctx}/sys/office/treeData?isLoadUser=true"
-								class=" required" allowClear="true"/>
+								<% if (mesDevicePreventTask.isNewRecord){ %>
+									<#form:treeselect id="userCode" title="${text('用户选择')}"
+									path="userCode" labelPath="userName"
+									url="${ctx}/sys/office/treeData?isLoadUser=true"
+									class=" required" allowClear="true" checkbox="true"/>
+								<% } else { %>
+									<#form:treeselect id="userCode" title="${text('用户选择')}"
+									path="userCode" labelPath="userName"
+									url="${ctx}/sys/office/treeData?isLoadUser=true"
+									class=" required" allowClear="true"/>
+								<% } %>
 							</div>
 						</div>
 					</div>

+ 5 - 1
src/main/resources/views/modules/mes/mesDeviceQrcode.html

@@ -11,8 +11,12 @@
 		</div>
 		<div class="box-body">
 			<div class="row">
-				<div id="printer">
+				<div id="printer" style="text-align:center;">
 					<div id="qrcode" style="width: 256px;height: 256px;margin: 0 auto;"></div>
+					<!-- 二维码下方显示设备名称,便于核对与打印 -->
+					<div id="qrcodeText" style="margin-top:12px;font-size:18px;font-weight:bold;letter-spacing:1px;">
+						${mesDevice.treeName!}
+					</div>
 				</div>
 			</div>
 		</div>

+ 3 - 3
src/main/resources/views/modules/mes/mesPieceSalaryReportList.html

@@ -15,16 +15,16 @@
 			</div>
 		</div>
 		<div class="box-body">
-			<#form:form id="searchForm" model="${mesPieceSalaryReport}" action="${ctx}/mes/mesPieceSalaryReport/listData" method="post" class="form-inline hide"
+			<#form:form id="searchForm" model="${mesPieceSalaryReport}" action="${ctx}/mes/mesPieceSalaryReport/listData" method="post" class="form-inline"
 					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="startDate" readonly="true" maxlength="20" class="form-control laydate width-datetime"
-							dataFormat="datetime" data-type="datetime" data-format="yyyy-MM-dd HH:mm" data-done="endDate.click()"/>
+							data-type="datetime" data-format="yyyy-MM-dd HH:mm" data-done="endDate.click()"/>
 						&nbsp;-&nbsp;
 						<#form:input path="endDate" readonly="true" maxlength="20" class="form-control laydate width-datetime"
-							dataFormat="datetime" data-type="datetime" data-format="yyyy-MM-dd HH:mm"/>
+							data-type="datetime" data-format="yyyy-MM-dd HH:mm"/>
 					</div>
 				</div>
 				<div class="form-group">

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

@@ -1,9 +1,9 @@
-<% layout('/layouts/default.html', {title: 'CMT过程参数管理', libs: ['validate']}){ %>
+<% layout('/layouts/default.html', {title: '弧焊过程参数管理', libs: ['validate']}){ %>
 <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(mesProductCmt.isNewRecord ? '新增CMT过程参数' : '编辑CMT过程参数')}
+				<i class="fa icon-note"></i> ${text(mesProductCmt.isNewRecord ? '新增弧焊过程参数' : '编辑弧焊过程参数')}
 			</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>

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

@@ -1,9 +1,9 @@
-<% layout('/layouts/default.html', {title: 'CMT过程参数管理', libs: ['validate']}){ %>
+<% layout('/layouts/default.html', {title: '弧焊过程参数管理', libs: ['validate']}){ %>
 <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(mesProductCmt.isNewRecord ? '新增CMT过程参数管理' : 'CMT过程参数管理详情')}
+                <i class="fa icon-note"></i> ${text(mesProductCmt.isNewRecord ? '新增弧焊过程参数' : '弧焊过程参数详情')}
             </div>
             <div class="box-tools pull-right">
                 <button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i>

+ 4 - 3
src/main/resources/views/modules/mes/mesProductCmtList.html

@@ -1,9 +1,9 @@
-<% layout('/layouts/default.html', {title: 'CMT过程参数管理', libs: ['dataGrid']}){ %>
+<% 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('CMT过程参数管理')}
+				<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>
@@ -65,6 +65,7 @@ $('#dataGrid').dataGrid({
 	columnModel: [
 		{header:'${text("工件码")}', name:'sn', index:'a.sn', width:280, align:"center", frozen:true},
 		{header:'${text("工位号")}', name:'oprno', index:'a.oprno', width:150, align:"center"},
+		{header:'${text("工位名称")}', name:'oprnoTitle', width:180, align:"center", sortable:false},
 		{header:'${text("产线编号")}', name:'lineSn', index:'a.line_sn', width:150, align:"center"},
 		// {header:'${text("参数内容")}', name:'content', index:'a.content', width:350, align:"center"},
 		{header:'${text("创建时间")}', name:'createDate', index:'a.create_date', width:150, align:"center"},
@@ -95,7 +96,7 @@ $('#btnImport').click(function(){
 	js.layer.open({
 		type: 1,
 		area: ['400px'],
-		title: '${text("导入CMT过程参数")}',
+		title: '${text("导入弧焊过程参数")}',
 		resize: false,
 		scrollbar: true,
 		content: js.template('importTpl'),

+ 12 - 24
src/main/resources/views/modules/mes/mesStationPiecePriceForm.html

@@ -18,12 +18,8 @@
 						<div class="form-group">
 							<label class="control-label col-sm-4"><span class="required">*</span> ${text('产线编号')}:</label>
 							<div class="col-sm-8">
-								<div class="input-group">
-									<#form:input path="lineSn" maxlength="64" class="form-control required"/>
-									<span class="input-group-btn">
-										<button type="button" class="btn btn-default" id="btnSelectStation"><i class="fa fa-list"></i> ${text('选取')}</button>
-									</span>
-								</div>
+								<#form:select path="lineSn" items="${lineList}" itemLabel="title" itemValue="sn"
+									blankOption="true" class="form-control required"/>
 							</div>
 						</div>
 					</div>
@@ -31,7 +27,12 @@
 						<div class="form-group">
 							<label class="control-label col-sm-4"><span class="required">*</span> ${text('工位号')}:</label>
 							<div class="col-sm-8">
-								<#form:input path="oprno" maxlength="64" class="form-control required"/>
+								<div class="input-group">
+									<#form:input path="oprno" maxlength="64" class="form-control required" readonly="true"/>
+									<span class="input-group-btn">
+										<button type="button" class="btn btn-default" id="btnSelectStation"><i class="fa fa-list"></i> ${text('选取')}</button>
+									</span>
+								</div>
 							</div>
 						</div>
 					</div>
@@ -39,7 +40,7 @@
 						<div class="form-group">
 							<label class="control-label col-sm-4">${text('工位名称')}:</label>
 							<div class="col-sm-8">
-								<#form:input path="oprnoName" maxlength="100" class="form-control"/>
+								<#form:input path="oprnoName" maxlength="100" class="form-control" readonly="true"/>
 							</div>
 						</div>
 					</div>
@@ -94,23 +95,10 @@ $('#lineSn').on('change', function(){
 	$('#oprnoName').val('');
 });
 
-$('#oprno').on('blur', function(){
-	var lineSn = $.trim($('#lineSn').val());
-	var oprno = $.trim($('#oprno').val());
-	if (!lineSn || !oprno) {
-		return;
-	}
-	$.getJSON('${ctx}/mes/mesStationPiecePrice/stationInfo', {lineSn: lineSn, oprno: oprno}, function(data){
-		if (data && data.title) {
-			$('#oprnoName').val(data.title);
-		}
-	});
-});
-
 $('#btnSelectStation').click(function(){
 	var lineSn = $.trim($('#lineSn').val());
 	if (!lineSn) {
-		js.showMessage('${text("请先输入产线编号")}', null, 'warning');
+		js.showMessage('${text("请先选择产线")}', null, 'warning');
 		return;
 	}
 	$.getJSON('${ctx}/mes/mesStationPiecePrice/stationList', {lineSn: lineSn}, function(list){
@@ -123,7 +111,7 @@ $('#btnSelectStation').click(function(){
 					+ '</tr>');
 			});
 		} else {
-			rows.push('<tr><td colspan="2" class="text-center text-muted">${text("该产线未找到工位")}</td></tr>');
+			rows.push('<tr><td colspan="2" class="text-center text-muted">${text("该产线未找到父工位")}</td></tr>');
 		}
 		var content = '<div style="padding:10px;max-height:420px;overflow:auto;">'
 			+ '<table class="table table-hover table-striped table-bordered mb0">'
@@ -132,7 +120,7 @@ $('#btnSelectStation').click(function(){
 		js.layer.open({
 			type: 1,
 			area: ['560px', '520px'],
-			title: '${text("选择工位")} - ' + lineSn,
+			title: '${text("选择父工位")} - ' + lineSn,
 			content: content,
 			success: function(layero, index){
 				layero.find('.station-row').css('cursor', 'pointer').click(function(){

+ 9 - 1
src/main/resources/views/modules/sys/officeForm.html

@@ -57,7 +57,15 @@
 							</div>
 						</div>
 					</div>
-					<% /* 机构类型:表单已简化隐藏,保存时自动赋默认值,避免后端校验 officeType 不能为空 */ %>
+					<% /* 机构类型/排序号:页面已简化隐藏;新增时补默认值,避免 officeType 为空校验失败(Beetl 用属性赋值,勿调 setXxx) */ %>
+					<%
+						if (isBlank(office.officeType)) {
+							office.officeType = '2';
+						}
+						if (office.treeSort == null) {
+							office.treeSort = 30;
+						}
+					%>
 					<#form:hidden path="officeType"/>
 					<#form:hidden path="treeSort"/>
 <!--					<div class="col-xs-6">-->