浏览代码

物品借用归还和变化点

sunxianglong 5 月之前
父节点
当前提交
8102e03ab5
共有 21 个文件被更改,包括 2156 次插入 和 12 次删除
  1. 67 0
      src/main/java/com/jeesite/modules/mes/api/MesItemControllerApi.java
  2. 15 0
      src/main/java/com/jeesite/modules/mes/dao/MesChangePointDao.java
  3. 15 0
      src/main/java/com/jeesite/modules/mes/dao/MesItemDao.java
  4. 8 0
      src/main/java/com/jeesite/modules/mes/dao/MesProductDao.java
  5. 270 0
      src/main/java/com/jeesite/modules/mes/entity/MesChangePoint.java
  6. 145 0
      src/main/java/com/jeesite/modules/mes/entity/MesItem.java
  7. 241 0
      src/main/java/com/jeesite/modules/mes/service/MesChangePointService.java
  8. 84 0
      src/main/java/com/jeesite/modules/mes/service/MesItemService.java
  9. 8 1
      src/main/java/com/jeesite/modules/mes/service/MesProductService.java
  10. 156 0
      src/main/java/com/jeesite/modules/mes/web/MesChangePointController.java
  11. 112 0
      src/main/java/com/jeesite/modules/mes/web/MesItemController.java
  12. 64 0
      src/main/java/com/jeesite/modules/mes/web/MesProductController.java
  13. 15 0
      src/main/resources/mappings/modules/mes/MesChangePointDao.xml
  14. 15 0
      src/main/resources/mappings/modules/mes/MesItemDao.xml
  15. 6 0
      src/main/resources/mappings/modules/mes/MesProductDao.xml
  16. 152 0
      src/main/resources/views/modules/mes/mesChangePointConfirmForm.html
  17. 150 0
      src/main/resources/views/modules/mes/mesChangePointForm.html
  18. 240 0
      src/main/resources/views/modules/mes/mesChangePointList.html
  19. 152 0
      src/main/resources/views/modules/mes/mesItemForm.html
  20. 143 0
      src/main/resources/views/modules/mes/mesItemList.html
  21. 98 11
      src/main/resources/views/modules/mes/mesProductList.html

+ 67 - 0
src/main/java/com/jeesite/modules/mes/api/MesItemControllerApi.java

@@ -0,0 +1,67 @@
+package com.jeesite.modules.mes.api;
+
+import com.jeesite.common.config.Global;
+import com.jeesite.modules.erp.entity.MesProductOrder;
+import com.jeesite.modules.mes.entity.MesInbound;
+import com.jeesite.modules.mes.entity.MesItem;
+import com.jeesite.modules.mes.resp.CommonResp;
+import com.jeesite.modules.mes.service.MesItemService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
+@Controller
+@RequestMapping(value = "${adminPath}/mes/MesItemControllerApi")
+public class MesItemControllerApi {
+    @Autowired
+    private MesItemService mesItemService;
+
+    @PostMapping(value = "itemSave")
+    @ResponseBody
+    public CommonResp itemSave(@Validated MesItem mesItem, HttpServletRequest request, HttpServletResponse response) {
+        CommonResp<List<MesProductOrder>> resp = new CommonResp<>();
+        //展示所有未结束的订单
+        String itemName = request.getParameter("itemName");//物品名
+        String itemJf = request.getParameter("itemJf");//借用方
+        String jyTime = request.getParameter("jyTime");//借用时间
+        String xzTime = request.getParameter("xzTime");//校准时间
+        String reason = request.getParameter("reason");//原因
+        String remark = request.getParameter("remark");//备注
+
+        if (itemName.isEmpty()||itemJf.isEmpty()||jyTime.isEmpty()||xzTime.isEmpty()||reason.isEmpty()){
+            resp.setResult(Global.FALSE);
+            resp.setMessage("参数不能为空!");
+            return resp;
+        }
+
+        long count = mesItemService.findCount(mesItem);
+        if (count>0){
+            resp.setResult(Global.FALSE);
+            resp.setMessage("该物品正在进行借用流程!");
+            return resp;
+        }
+
+        mesItemService.save(mesItem);
+        resp.setResult(Global.TRUE);
+        resp.setMessage("操作成功!");
+        return resp;
+    }
+
+    @PostMapping(value = "mesItemList")
+    @ResponseBody
+    public CommonResp mesItemList(@Validated MesItem mesItem, HttpServletRequest request, HttpServletResponse response) {
+        CommonResp<List<MesItem>> resp = new CommonResp<>();
+        List<MesItem> list = mesItemService.findList(mesItem);
+        resp.setResult(Global.TRUE);
+        resp.setData(list);
+        resp.setMessage("操作成功!");
+        return resp;
+    }
+}

+ 15 - 0
src/main/java/com/jeesite/modules/mes/dao/MesChangePointDao.java

@@ -0,0 +1,15 @@
+package com.jeesite.modules.mes.dao;
+
+import com.jeesite.common.dao.CrudDao;
+import com.jeesite.common.mybatis.annotation.MyBatisDao;
+import com.jeesite.modules.mes.entity.MesChangePoint;
+
+/**
+ * 生产变化点表DAO接口
+ * @author sxl
+ * @version 2026-05-29
+ */
+@MyBatisDao
+public interface MesChangePointDao extends CrudDao<MesChangePoint> {
+	
+}

+ 15 - 0
src/main/java/com/jeesite/modules/mes/dao/MesItemDao.java

@@ -0,0 +1,15 @@
+package com.jeesite.modules.mes.dao;
+
+import com.jeesite.common.dao.CrudDao;
+import com.jeesite.common.mybatis.annotation.MyBatisDao;
+import com.jeesite.modules.mes.entity.MesItem;
+
+/**
+ * 物品借用归还表DAO接口
+ * @author sxl
+ * @version 2026-05-28
+ */
+@MyBatisDao
+public interface MesItemDao extends CrudDao<MesItem> {
+	
+}

+ 8 - 0
src/main/java/com/jeesite/modules/mes/dao/MesProductDao.java

@@ -3,6 +3,7 @@ package com.jeesite.modules.mes.dao;
 import com.jeesite.common.dao.CrudDao;
 import com.jeesite.common.mybatis.annotation.MyBatisDao;
 import com.jeesite.modules.mes.entity.MesProduct;
+import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
 
@@ -15,4 +16,11 @@ import java.util.List;
 public interface MesProductDao extends CrudDao<MesProduct> {
     MesProduct findInfo(MesProduct mesProduct);
     List<MesProduct> findByCount(MesProduct mesProduct);
+
+    /**
+     * 按创建时间范围批量更新产品状态
+     */
+    int updateStateByCreateDateRange(@Param("createDateGte") String createDateGte,
+                                     @Param("createDateLte") String createDateLte,
+                                     @Param("state") String state);
 }

+ 270 - 0
src/main/java/com/jeesite/modules/mes/entity/MesChangePoint.java

@@ -0,0 +1,270 @@
+package com.jeesite.modules.mes.entity;
+
+import javax.validation.constraints.Size;
+import java.util.Date;
+import com.jeesite.common.mybatis.annotation.JoinTable;
+import com.jeesite.common.mybatis.annotation.JoinTable.Type;
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+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;
+
+/**
+ * 生产变化点表Entity
+ * @author sxl
+ * @version 2026-05-29
+ */
+@Table(name="mes_change_point", alias="a", label="生产变化点表信息", columns={
+		@Column(name="id", attrName="id", label="id", isPK=true),
+		@Column(name="code", attrName="code", label="编号"),
+		@Column(name="line_name", attrName="lineName", label="车间名称", queryType=QueryType.LIKE),
+		@Column(name="proposer", attrName="proposer", label="提出人"),
+		@Column(name="product_name", attrName="productName", label="产品名称", queryType=QueryType.LIKE),
+		@Column(name="model_number", attrName="modelNumber", label="模号"),
+		@Column(name="start_time", attrName="startTime", label="变化点开始时间", isUpdateForce=true),
+		@Column(name="type", attrName="type", label="类别", comment="类别(设备)"),
+		@Column(name="description", attrName="description", label="变化点描述"),
+		@Column(name="end_sn", attrName="endSn", label="异常发生末件二维码"),
+		@Column(name="start_sn", attrName="startSn", label="异常发生首件二维码"),
+		@Column(name="importance", attrName="importance", label="重要性"),
+		@Column(name="is_retrace", attrName="isRetrace", label="是否追溯", comment="是否追溯(0表示是 1表示否)"),
+		@Column(name="retrace_start_time", attrName="retraceStartTime", label="首件追溯时间", isUpdateForce=true),
+		@Column(name="retrace_end_time", attrName="retraceEndTime", label="末件产品追溯时间", isUpdateForce=true),
+		@Column(name="retrace_number", attrName="retraceNumber", label="追溯范围数量", isUpdateForce=true),
+		@Column(name="bhg_count", attrName="bhgCount", label="不合格产品数量"),
+		@Column(name="production_confirmer", attrName="productionConfirmer", label="生产确认人"),
+		@Column(name="quality_confirmer", attrName="qualityConfirmer", label="质量确认人"),
+		@Column(name="end_time", attrName="endTime", label="关闭时间", isUpdateForce=true),
+		@Column(name="status", attrName="status", label="状态", comment="状态(0正常 1删除 2停用)", isUpdate=false),
+		@Column(name="create_by", attrName="createBy", label="创建人", isUpdate=false, isQuery=false),
+		@Column(name="create_date", attrName="createDate", label="创建时间", isUpdate=false, isQuery=false, isUpdateForce=true),
+		@Column(name="update_by", attrName="updateBy", label="修改人", isQuery=false),
+		@Column(name="update_date", attrName="updateDate", label="修改时间", isQuery=false, isUpdateForce=true),
+		@Column(name="mes_shift_title", attrName="mesShiftTitle", label="班次", queryType=QueryType.LIKE),
+		@Column(name="change_state", attrName="changeState", label="变化点状态", comment="变化点状态(0 待品质处理、1待生产确认、2待品质确认、3结束)"),
+	}, orderBy="a.update_date DESC"
+)
+public class MesChangePoint extends DataEntity<MesChangePoint> {
+	
+	private static final long serialVersionUID = 1L;
+	private String code;		// 编号
+	private String lineName;		// 车间名称
+	private String proposer;		// 提出人
+	private String productName;		// 产品名称
+	private String modelNumber;		// 模号
+	private Date startTime;		// 变化点开始时间
+	private String type;		// 类别(设备)
+	private String description;		// 变化点描述
+	private String endSn;		// 异常发生末件二维码
+	private String startSn;		// 异常发生首件二维码
+	private String importance;		// 重要性
+	private String isRetrace;		// 是否追溯(0表示是 1表示否)
+	private Date retraceStartTime;		// 首件追溯时间
+	private Date retraceEndTime;		// 末件产品追溯时间
+	private Long retraceNumber;		// 追溯范围数量
+	private String bhgCount;		// 不合格产品数量
+	private String productionConfirmer;		// 生产确认人
+	private String qualityConfirmer;		// 质量确认人
+	private Date endTime;		// 关闭时间
+	private String mesShiftTitle;		// 班次
+	private String changeState;		// 变化点状态(0 待品质处理、1待生产确认、2待品质确认、3结束)
+
+	public MesChangePoint() {
+		this(null);
+	}
+	
+	public MesChangePoint(String id){
+		super(id);
+	}
+	
+	@Size(min=0, max=255, message="编号长度不能超过 255 个字符")
+	public String getCode() {
+		return code;
+	}
+
+	public void setCode(String code) {
+		this.code = code;
+	}
+	
+	@Size(min=0, max=255, message="车间名称长度不能超过 255 个字符")
+	public String getLineName() {
+		return lineName;
+	}
+
+	public void setLineName(String lineName) {
+		this.lineName = lineName;
+	}
+	
+	@Size(min=0, max=255, message="提出人长度不能超过 255 个字符")
+	public String getProposer() {
+		return proposer;
+	}
+
+	public void setProposer(String proposer) {
+		this.proposer = proposer;
+	}
+	
+	@Size(min=0, max=255, message="产品名称长度不能超过 255 个字符")
+	public String getProductName() {
+		return productName;
+	}
+
+	public void setProductName(String productName) {
+		this.productName = productName;
+	}
+	
+	@Size(min=0, max=255, message="模号长度不能超过 255 个字符")
+	public String getModelNumber() {
+		return modelNumber;
+	}
+
+	public void setModelNumber(String modelNumber) {
+		this.modelNumber = modelNumber;
+	}
+	
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	public Date getStartTime() {
+		return startTime;
+	}
+
+	public void setStartTime(Date startTime) {
+		this.startTime = startTime;
+	}
+	
+	@Size(min=0, max=255, message="类别长度不能超过 255 个字符")
+	public String getType() {
+		return type;
+	}
+
+	public void setType(String type) {
+		this.type = type;
+	}
+	
+	@Size(min=0, max=255, message="变化点描述长度不能超过 255 个字符")
+	public String getDescription() {
+		return description;
+	}
+
+	public void setDescription(String description) {
+		this.description = description;
+	}
+	
+	@Size(min=0, max=255, message="异常发生末件二维码长度不能超过 255 个字符")
+	public String getEndSn() {
+		return endSn;
+	}
+
+	public void setEndSn(String endSn) {
+		this.endSn = endSn;
+	}
+	
+	@Size(min=0, max=255, message="异常发生首件二维码长度不能超过 255 个字符")
+	public String getStartSn() {
+		return startSn;
+	}
+
+	public void setStartSn(String startSn) {
+		this.startSn = startSn;
+	}
+	
+	@Size(min=0, max=255, message="重要性长度不能超过 255 个字符")
+	public String getImportance() {
+		return importance;
+	}
+
+	public void setImportance(String importance) {
+		this.importance = importance;
+	}
+	
+	@Size(min=0, max=255, message="是否追溯长度不能超过 255 个字符")
+	public String getIsRetrace() {
+		return isRetrace;
+	}
+
+	public void setIsRetrace(String isRetrace) {
+		this.isRetrace = isRetrace;
+	}
+	
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	public Date getRetraceStartTime() {
+		return retraceStartTime;
+	}
+
+	public void setRetraceStartTime(Date retraceStartTime) {
+		this.retraceStartTime = retraceStartTime;
+	}
+	
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	public Date getRetraceEndTime() {
+		return retraceEndTime;
+	}
+
+	public void setRetraceEndTime(Date retraceEndTime) {
+		this.retraceEndTime = retraceEndTime;
+	}
+	
+	public Long getRetraceNumber() {
+		return retraceNumber;
+	}
+
+	public void setRetraceNumber(Long retraceNumber) {
+		this.retraceNumber = retraceNumber;
+	}
+	
+	@Size(min=0, max=255, message="不合格产品数量长度不能超过 255 个字符")
+	public String getBhgCount() {
+		return bhgCount;
+	}
+
+	public void setBhgCount(String bhgCount) {
+		this.bhgCount = bhgCount;
+	}
+	
+	@Size(min=0, max=255, message="生产确认人长度不能超过 255 个字符")
+	public String getProductionConfirmer() {
+		return productionConfirmer;
+	}
+
+	public void setProductionConfirmer(String productionConfirmer) {
+		this.productionConfirmer = productionConfirmer;
+	}
+	
+	@Size(min=0, max=255, message="质量确认人长度不能超过 255 个字符")
+	public String getQualityConfirmer() {
+		return qualityConfirmer;
+	}
+
+	public void setQualityConfirmer(String qualityConfirmer) {
+		this.qualityConfirmer = qualityConfirmer;
+	}
+	
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	public Date getEndTime() {
+		return endTime;
+	}
+
+	public void setEndTime(Date endTime) {
+		this.endTime = endTime;
+	}
+	
+	@Size(min=0, max=255, message="班次长度不能超过 255 个字符")
+	public String getMesShiftTitle() {
+		return mesShiftTitle;
+	}
+
+	public void setMesShiftTitle(String mesShiftTitle) {
+		this.mesShiftTitle = mesShiftTitle;
+	}
+	
+	@Size(min=0, max=255, message="变化点状态长度不能超过 255 个字符")
+	public String getChangeState() {
+		return changeState;
+	}
+
+	public void setChangeState(String changeState) {
+		this.changeState = changeState;
+	}
+	
+}

+ 145 - 0
src/main/java/com/jeesite/modules/mes/entity/MesItem.java

@@ -0,0 +1,145 @@
+package com.jeesite.modules.mes.entity;
+
+import javax.validation.constraints.Size;
+import java.util.Date;
+import com.jeesite.common.mybatis.annotation.JoinTable;
+import com.jeesite.common.mybatis.annotation.JoinTable.Type;
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+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;
+
+/**
+ * 物品借用归还表Entity
+ * @author sxl
+ * @version 2026-05-28
+ */
+@Table(name="mes_item", alias="a", label="物品借用归还表信息", columns={
+		@Column(name="id", attrName="id", label="id", isPK=true),
+		@Column(name="item_jf", attrName="itemJf", label="借方"),
+		@Column(name="item_hf", attrName="itemHf", label="还方"),
+		@Column(name="reason", attrName="reason", label="原因"),
+		@Column(name="state", attrName="state", label="0=审核中 1=借用中 2=已归还"),
+		@Column(name="jy_time", attrName="jyTime", label="上报日期", isUpdateForce=true),
+		@Column(name="sh_time", attrName="shTime", label="审核通过日期", isUpdateForce=true),
+		@Column(name="gh_time", attrName="ghTime", label="归还日期", isUpdateForce=true),
+		@Column(name="xz_time", attrName="xzTime", label="校准日期", isUpdateForce=true),
+		@Column(name="item_name", attrName="itemName", label="物品名称", queryType=QueryType.LIKE),
+		@Column(name="remark", attrName="remark", label="备注"),
+	}, orderBy="a.id DESC"
+)
+public class MesItem extends DataEntity<MesItem> {
+	
+	private static final long serialVersionUID = 1L;
+	private String itemJf;		// 借方
+	private String itemHf;		// 还方
+	private String reason;		// 原因
+	private String state;		// 0=审核中 1=借用中 2=已归还
+	private Date jyTime;		// 上报日期
+	private Date shTime;		// 审核通过日期
+	private Date ghTime;		// 归还日期
+	private Date xzTime;		// 校准日期
+	private String itemName;		// 物品名称
+	private String remark;		// 备注
+
+	public MesItem() {
+		this(null);
+	}
+	
+	public MesItem(String id){
+		super(id);
+	}
+	
+	@Size(min=0, max=64, message="借方长度不能超过 64 个字符")
+	public String getItemJf() {
+		return itemJf;
+	}
+
+	public void setItemJf(String itemJf) {
+		this.itemJf = itemJf;
+	}
+	
+	@Size(min=0, max=64, message="还方长度不能超过 64 个字符")
+	public String getItemHf() {
+		return itemHf;
+	}
+
+	public void setItemHf(String itemHf) {
+		this.itemHf = itemHf;
+	}
+	
+	@Size(min=0, max=255, message="原因长度不能超过 255 个字符")
+	public String getReason() {
+		return reason;
+	}
+
+	public void setReason(String reason) {
+		this.reason = reason;
+	}
+	
+	@Size(min=0, max=1, message="0=审核中 1=借用中 2=已归还长度不能超过 1 个字符")
+	public String getState() {
+		return state;
+	}
+
+	public void setState(String state) {
+		this.state = state;
+	}
+	
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	public Date getJyTime() {
+		return jyTime;
+	}
+
+	public void setJyTime(Date jyTime) {
+		this.jyTime = jyTime;
+	}
+	
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	public Date getShTime() {
+		return shTime;
+	}
+
+	public void setShTime(Date shTime) {
+		this.shTime = shTime;
+	}
+	
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	public Date getGhTime() {
+		return ghTime;
+	}
+
+	public void setGhTime(Date ghTime) {
+		this.ghTime = ghTime;
+	}
+	
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	public Date getXzTime() {
+		return xzTime;
+	}
+
+	public void setXzTime(Date xzTime) {
+		this.xzTime = xzTime;
+	}
+	
+	@Size(min=0, max=255, message="物品名称长度不能超过 255 个字符")
+	public String getItemName() {
+		return itemName;
+	}
+
+	public void setItemName(String itemName) {
+		this.itemName = itemName;
+	}
+	
+	@Size(min=0, max=255, message="备注长度不能超过 255 个字符")
+	public String getRemark() {
+		return remark;
+	}
+
+	public void setRemark(String remark) {
+		this.remark = remark;
+	}
+	
+}

+ 241 - 0
src/main/java/com/jeesite/modules/mes/service/MesChangePointService.java

@@ -0,0 +1,241 @@
+package com.jeesite.modules.mes.service;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.shiro.subject.Subject;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.jeesite.common.entity.Page;
+import com.jeesite.common.lang.StringUtils;
+import com.jeesite.common.mybatis.mapper.query.QueryType;
+import com.jeesite.common.service.CrudService;
+import com.jeesite.common.service.ServiceException;
+import com.jeesite.modules.mes.entity.MesChangePoint;
+import com.jeesite.modules.mes.dao.MesChangePointDao;
+import com.jeesite.modules.sys.entity.User;
+import com.jeesite.modules.sys.utils.UserUtils;
+
+/**
+ * 生产变化点表Service
+ * @author sxl
+ * @version 2026-05-29
+ */
+@Service
+public class MesChangePointService extends CrudService<MesChangePointDao, MesChangePoint> {
+
+	/** 查看全部变化点状态 */
+	public static final String PERM_VIEW_ALL = "mes:mesChangePoint:viewAll";
+	/** 按变化点状态查看:0待品质处理、1待生产确认、2待品质确认、3结束 */
+	public static final String PERM_VIEW_STATE_0 = "mes:mesChangePoint:viewState0";
+	public static final String PERM_VIEW_STATE_1 = "mes:mesChangePoint:viewState1";
+	public static final String PERM_VIEW_STATE_2 = "mes:mesChangePoint:viewState2";
+	public static final String PERM_VIEW_STATE_3 = "mes:mesChangePoint:viewState3";
+	private static final String NO_PERMISSION_MARKER = "__NO_PERMISSION__";
+	
+	/**
+	 * 获取单条数据
+	 * @param mesChangePoint
+	 * @return
+	 */
+	@Override
+	public MesChangePoint get(MesChangePoint mesChangePoint) {
+		return super.get(mesChangePoint);
+	}
+	
+	/**
+	 * 查询分页数据
+	 * @param mesChangePoint 查询条件
+	 * @param mesChangePoint.page 分页对象
+	 * @return
+	 */
+	@Override
+	public Page<MesChangePoint> findPage(MesChangePoint mesChangePoint) {
+		return super.findPage(mesChangePoint);
+	}
+
+	/**
+	 * 按当前用户权限过滤变化点状态后分页查询
+	 */
+	public Page<MesChangePoint> findPageByUser(MesChangePoint mesChangePoint) {
+		applyChangeStateScope(mesChangePoint);
+		return super.findPage(mesChangePoint);
+	}
+
+	/**
+	 * 校验当前用户是否有权查看/操作指定变化点状态
+	 */
+	public void checkChangeStatePermission(String changeState) {
+		if (canViewChangeState(changeState)) {
+			return;
+		}
+		throw new ServiceException(text("无权查看或操作该状态的变化点"));
+	}
+
+	private boolean canViewChangeState(String changeState) {
+		User user = UserUtils.getUser();
+		if (user != null && user.isAdmin()) {
+			return true;
+		}
+		Subject subject = UserUtils.getSubject();
+		if (subject.isPermitted(PERM_VIEW_ALL)) {
+			return true;
+		}
+		List<String> allowedStates = getAllowedChangeStates(subject);
+		if (allowedStates.isEmpty()) {
+			return true;
+		}
+		return allowedStates.contains(StringUtils.defaultIfBlank(changeState, "0"));
+	}
+
+	private List<String> getAllowedChangeStates(Subject subject) {
+		List<String> states = new ArrayList<>();
+		if (subject.isPermitted(PERM_VIEW_STATE_0)) {
+			states.add("0");
+		}
+		if (subject.isPermitted(PERM_VIEW_STATE_1)) {
+			states.add("1");
+		}
+		if (subject.isPermitted(PERM_VIEW_STATE_2)) {
+			states.add("2");
+		}
+		if (subject.isPermitted(PERM_VIEW_STATE_3)) {
+			states.add("3");
+		}
+		return states;
+	}
+
+	private void applyChangeStateScope(MesChangePoint mesChangePoint) {
+		User user = UserUtils.getUser();
+		if (user != null && user.isAdmin()) {
+			return;
+		}
+		Subject subject = UserUtils.getSubject();
+		if (subject.isPermitted(PERM_VIEW_ALL)) {
+			return;
+		}
+		List<String> allowedStates = getAllowedChangeStates(subject);
+		if (allowedStates.isEmpty()) {
+			return;
+		}
+		String searchState = mesChangePoint.getChangeState();
+		if (StringUtils.isNotBlank(searchState)) {
+			if (!allowedStates.contains(searchState)) {
+				mesChangePoint.getSqlMap().getWhere().and("a.change_state", QueryType.EQ, NO_PERMISSION_MARKER);
+			}
+			return;
+		}
+		if (allowedStates.size() == 1) {
+			mesChangePoint.setChangeState(allowedStates.get(0));
+		} else {
+			mesChangePoint.getSqlMap().getWhere().and("a.change_state", QueryType.IN, allowedStates.toArray(new String[0]));
+		}
+	}
+	
+	/**
+	 * 查询列表数据
+	 * @param mesChangePoint
+	 * @return
+	 */
+	@Override
+	public List<MesChangePoint> findList(MesChangePoint mesChangePoint) {
+		return super.findList(mesChangePoint);
+	}
+	
+	/**
+	 * 保存数据(插入或更新)
+	 * @param mesChangePoint
+	 */
+	@Override
+	@Transactional
+	public void save(MesChangePoint mesChangePoint) {
+		super.save(mesChangePoint);
+	}
+
+	/**
+	 * 保存新增/编辑基础信息
+	 */
+	@Transactional
+	public void saveBasic(MesChangePoint mesChangePoint) {
+		if (mesChangePoint.getIsNewRecord()) {
+			mesChangePoint.setChangeState("0");
+			if (StringUtils.isBlank(mesChangePoint.getProductName())) {
+				mesChangePoint.setProductName("AD06");
+			}
+			super.save(mesChangePoint);
+			return;
+		}
+		MesChangePoint entity = get(mesChangePoint);
+		if (entity == null) {
+			throw new ServiceException(text("生产变化点不存在"));
+		}
+		checkChangeStatePermission(entity.getChangeState());
+		entity.setCode(mesChangePoint.getCode());
+		entity.setLineName(mesChangePoint.getLineName());
+		entity.setProposer(mesChangePoint.getProposer());
+		entity.setProductName(mesChangePoint.getProductName());
+		entity.setModelNumber(mesChangePoint.getModelNumber());
+		entity.setMesShiftTitle(mesChangePoint.getMesShiftTitle());
+		entity.setStartTime(mesChangePoint.getStartTime());
+		entity.setType(mesChangePoint.getType());
+		entity.setDescription(mesChangePoint.getDescription());
+		entity.setEndSn(mesChangePoint.getEndSn());
+		entity.setStartSn(mesChangePoint.getStartSn());
+		super.save(entity);
+	}
+
+	/**
+	 * 分阶段确认保存并推进变化点状态
+	 */
+	@Transactional
+	public void confirmSave(MesChangePoint mesChangePoint) {
+		MesChangePoint entity = get(mesChangePoint);
+		if (entity == null) {
+			throw new ServiceException(text("生产变化点不存在"));
+		}
+		String changeState = StringUtils.defaultIfBlank(entity.getChangeState(), "0");
+		checkChangeStatePermission(changeState);
+		if ("0".equals(changeState)) {
+			entity.setImportance(mesChangePoint.getImportance());
+			entity.setIsRetrace(mesChangePoint.getIsRetrace());
+			entity.setRetraceStartTime(mesChangePoint.getRetraceStartTime());
+			entity.setRetraceEndTime(mesChangePoint.getRetraceEndTime());
+			entity.setRetraceNumber(mesChangePoint.getRetraceNumber());
+			entity.setBhgCount(mesChangePoint.getBhgCount());
+			entity.setChangeState("1");
+		} else if ("1".equals(changeState)) {
+			entity.setProductionConfirmer(mesChangePoint.getProductionConfirmer());
+			entity.setChangeState("2");
+		} else if ("2".equals(changeState)) {
+			entity.setQualityConfirmer(mesChangePoint.getQualityConfirmer());
+			entity.setChangeState("3");
+			entity.setEndTime(new Date());
+		} else {
+			throw new ServiceException(text("当前状态不可确认"));
+		}
+		super.save(entity);
+	}
+	
+	/**
+	 * 更新状态
+	 * @param mesChangePoint
+	 */
+	@Override
+	@Transactional
+	public void updateStatus(MesChangePoint mesChangePoint) {
+		super.updateStatus(mesChangePoint);
+	}
+	
+	/**
+	 * 删除数据
+	 * @param mesChangePoint
+	 */
+	@Override
+	@Transactional
+	public void delete(MesChangePoint mesChangePoint) {
+		super.delete(mesChangePoint);
+	}
+	
+}

+ 84 - 0
src/main/java/com/jeesite/modules/mes/service/MesItemService.java

@@ -0,0 +1,84 @@
+package com.jeesite.modules.mes.service;
+
+import java.util.List;
+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.MesItem;
+import com.jeesite.modules.mes.dao.MesItemDao;
+import com.jeesite.modules.file.utils.FileUploadUtils;
+
+/**
+ * 物品借用归还表Service
+ * @author sxl
+ * @version 2026-05-28
+ */
+@Service
+public class MesItemService extends CrudService<MesItemDao, MesItem> {
+	
+	/**
+	 * 获取单条数据
+	 * @param mesItem
+	 * @return
+	 */
+	@Override
+	public MesItem get(MesItem mesItem) {
+		return super.get(mesItem);
+	}
+	
+	/**
+	 * 查询分页数据
+	 * @param mesItem 查询条件
+	 * @param mesItem.page 分页对象
+	 * @return
+	 */
+	@Override
+	public Page<MesItem> findPage(MesItem mesItem) {
+		return super.findPage(mesItem);
+	}
+	
+	/**
+	 * 查询列表数据
+	 * @param mesItem
+	 * @return
+	 */
+	@Override
+	public List<MesItem> findList(MesItem mesItem) {
+		return super.findList(mesItem);
+	}
+	
+	/**
+	 * 保存数据(插入或更新)
+	 * @param mesItem
+	 */
+	@Override
+	@Transactional
+	public void save(MesItem mesItem) {
+		super.save(mesItem);
+		// 保存上传图片
+		FileUploadUtils.saveFileUpload(mesItem, mesItem.getId(), "mesItem_image");
+	}
+	
+	/**
+	 * 更新状态
+	 * @param mesItem
+	 */
+	@Override
+	@Transactional
+	public void updateStatus(MesItem mesItem) {
+		super.updateStatus(mesItem);
+	}
+	
+	/**
+	 * 删除数据
+	 * @param mesItem
+	 */
+	@Override
+	@Transactional
+	public void delete(MesItem mesItem) {
+		super.delete(mesItem);
+	}
+	
+}

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

@@ -106,5 +106,12 @@ public class MesProductService extends CrudService<MesProductDao, MesProduct> {
 		return dao.findInfo(m1);
 	}
 
-	
+	/**
+	 * 按创建时间范围批量更新产品状态
+	 */
+	@Transactional
+	public int updateStateByCreateDateRange(String createDateGte, String createDateLte, String state) {
+		return dao.updateStateByCreateDateRange(createDateGte, createDateLte, state);
+	}
+
 }

+ 156 - 0
src/main/java/com/jeesite/modules/mes/web/MesChangePointController.java

@@ -0,0 +1,156 @@
+package com.jeesite.modules.mes.web;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+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.StringUtils;
+import com.jeesite.common.service.ServiceException;
+import com.jeesite.common.web.BaseController;
+import com.jeesite.modules.mes.entity.MesChangePoint;
+import com.jeesite.modules.mes.service.MesChangePointService;
+
+/**
+ * 生产变化点表Controller
+ * @author sxl
+ * @version 2026-05-29
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/mes/mesChangePoint")
+public class MesChangePointController extends BaseController {
+
+	@Autowired
+	private MesChangePointService mesChangePointService;
+
+	/**
+	 * 获取数据
+	 */
+	@ModelAttribute
+	public MesChangePoint get(String id, boolean isNewRecord) {
+		return mesChangePointService.get(id, isNewRecord);
+	}
+
+	/**
+	 * 查询列表
+	 */
+	@RequiresPermissions("mes:mesChangePoint:view")
+	@RequestMapping(value = {"list", ""})
+	public String list(MesChangePoint mesChangePoint, Model model) {
+		model.addAttribute("mesChangePoint", mesChangePoint);
+		return "modules/mes/mesChangePointList";
+	}
+
+
+	/**
+	 * 查询列表数据
+	 */
+	@RequiresPermissions("mes:mesChangePoint:view")
+	@RequestMapping(value = "listData")
+	@ResponseBody
+	public Page<MesChangePoint> listData(MesChangePoint mesChangePoint, HttpServletRequest request, HttpServletResponse response) {
+		mesChangePoint.setPage(new Page<>(request, response));
+		Page<MesChangePoint> page = mesChangePointService.findPageByUser(mesChangePoint);
+		return page;
+	}
+
+	/**
+	 * 查看编辑表单
+	 */
+	@RequiresPermissions("mes:mesChangePoint:view")
+	@RequestMapping(value = "form")
+	public String form(MesChangePoint mesChangePoint, Model model) {
+		if (mesChangePoint.getIsNewRecord()) {
+			mesChangePoint.setChangeState("0");
+			if (StringUtils.isBlank(mesChangePoint.getProductName())) {
+				mesChangePoint.setProductName("AD06");
+			}
+		} else {
+			mesChangePointService.checkChangeStatePermission(mesChangePoint.getChangeState());
+		}
+		model.addAttribute("mesChangePoint", mesChangePoint);
+		return "modules/mes/mesChangePointForm";
+	}
+
+	/**
+	 * 分阶段确认表单
+	 */
+	@RequiresPermissions("mes:mesChangePoint:view")
+	@RequestMapping(value = "confirmForm")
+	public String confirmForm(MesChangePoint mesChangePoint, Model model) {
+		if (mesChangePoint.getIsNewRecord()) {
+			throw new ServiceException(text("生产变化点不存在"));
+		}
+		String changeState = StringUtils.defaultIfBlank(mesChangePoint.getChangeState(), "0");
+		if ("3".equals(changeState)) {
+			throw new ServiceException(text("该变化点已结束,无需确认"));
+		}
+		if (!"0".equals(changeState) && !"1".equals(changeState) && !"2".equals(changeState)) {
+			throw new ServiceException(text("当前状态不可确认"));
+		}
+		mesChangePointService.checkChangeStatePermission(changeState);
+		model.addAttribute("mesChangePoint", mesChangePoint);
+		model.addAttribute("confirmStep", changeState);
+		if ("0".equals(changeState)) {
+			model.addAttribute("confirmTitle", text("品质处理确认"));
+		} else if ("1".equals(changeState)) {
+			model.addAttribute("confirmTitle", text("生产确认"));
+		} else {
+			model.addAttribute("confirmTitle", text("质量确认"));
+		}
+		return "modules/mes/mesChangePointConfirmForm";
+	}
+
+	/**
+	 * 保存基础信息
+	 */
+	@RequiresPermissions("mes:mesChangePoint:edit")
+	@PostMapping(value = "save")
+	@ResponseBody
+	public String save(@Validated MesChangePoint mesChangePoint) {
+		try {
+			mesChangePointService.saveBasic(mesChangePoint);
+			return renderResult(Global.TRUE, text("保存生产变化点成功!"));
+		} catch (ServiceException e) {
+			return renderResult(Global.FALSE, e.getMessage());
+		}
+	}
+
+	/**
+	 * 分阶段确认保存
+	 */
+	@RequiresPermissions("mes:mesChangePoint:edit")
+	@PostMapping(value = "confirmSave")
+	@ResponseBody
+	public String confirmSave(@Validated MesChangePoint mesChangePoint) {
+		try {
+			mesChangePointService.confirmSave(mesChangePoint);
+			return renderResult(Global.TRUE, text("确认保存成功!"));
+		} catch (ServiceException e) {
+			return renderResult(Global.FALSE, e.getMessage());
+		}
+	}
+
+	/**
+	 * 删除数据
+	 */
+	@RequiresPermissions("mes:mesChangePoint:edit")
+	@RequestMapping(value = "delete")
+	@ResponseBody
+	public String delete(MesChangePoint mesChangePoint) {
+		mesChangePointService.checkChangeStatePermission(mesChangePoint.getChangeState());
+		mesChangePointService.delete(mesChangePoint);
+		return renderResult(Global.TRUE, text("删除生产变化点表成功!"));
+	}
+
+}

+ 112 - 0
src/main/java/com/jeesite/modules/mes/web/MesItemController.java

@@ -0,0 +1,112 @@
+package com.jeesite.modules.mes.web;
+
+import java.util.Date;
+import java.util.List;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+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.web.BaseController;
+import com.jeesite.modules.mes.entity.MesItem;
+import com.jeesite.modules.mes.service.MesItemService;
+
+/**
+ * 物品借用归还表Controller
+ * @author sxl
+ * @version 2026-05-28
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/mes/mesItem")
+public class MesItemController extends BaseController {
+
+	@Autowired
+	private MesItemService mesItemService;
+
+	/**
+	 * 获取数据
+	 */
+	@ModelAttribute
+	public MesItem get(String id, boolean isNewRecord) {
+		return mesItemService.get(id, isNewRecord);
+	}
+
+	/**
+	 * 查询列表
+	 */
+	@RequiresPermissions("mes:mesItem:view")
+	@RequestMapping(value = {"list", ""})
+	public String list(MesItem mesItem, Model model) {
+		model.addAttribute("mesItem", mesItem);
+		return "modules/mes/mesItemList";
+	}
+
+	/**
+	 * 查询列表数据
+	 */
+	@RequiresPermissions("mes:mesItem:view")
+	@RequestMapping(value = "listData")
+	@ResponseBody
+	public Page<MesItem> listData(MesItem mesItem, HttpServletRequest request, HttpServletResponse response) {
+		mesItem.setPage(new Page<>(request, response));
+		Page<MesItem> page = mesItemService.findPage(mesItem);
+		return page;
+	}
+	/**
+	 * 审核通过物品借用
+	 */
+	@RequiresPermissions("mes:mesItem:edit")
+	@RequestMapping(value = "audit")
+	@ResponseBody
+	public String audit(MesItem mesItem) {
+		// 这里的 mesItem 已经接收到了前端传来的 id 和 state=1
+		// 你需要调用 Service 层更新数据库中的状态,可能还需要顺便更新审核通过时间(shTime)
+		mesItem.setShTime(new Date()); // 可选:记录审核通过的时间
+		mesItemService.update(mesItem);
+
+		return renderResult(Global.TRUE, text("审核通过成功!"));
+	}
+	/**
+	 * 查看编辑表单
+	 */
+	@RequiresPermissions("mes:mesItem:view")
+	@RequestMapping(value = "form")
+	public String form(MesItem mesItem, Model model) {
+		model.addAttribute("mesItem", mesItem);
+		return "modules/mes/mesItemForm";
+	}
+
+	/**
+	 * 保存数据
+	 */
+	@RequiresPermissions("mes:mesItem:edit")
+	@PostMapping(value = "save")
+	@ResponseBody
+	public String save(@Validated MesItem mesItem) {
+		mesItemService.save(mesItem);
+		return renderResult(Global.TRUE, text("保存物品借用归还表成功!"));
+	}
+
+	/**
+	 * 删除数据
+	 */
+	@RequiresPermissions("mes:mesItem:edit")
+	@RequestMapping(value = "delete")
+	@ResponseBody
+	public String delete(MesItem mesItem) {
+		mesItemService.delete(mesItem);
+		return renderResult(Global.TRUE, text("删除物品借用归还表成功!"));
+	}
+
+
+}

+ 64 - 0
src/main/java/com/jeesite/modules/mes/web/MesProductController.java

@@ -143,6 +143,70 @@ public class MesProductController extends BaseController {
 		mesProductService.save(mesProduct);
 		return renderResult(Global.TRUE, text("保存产品成功!"));
 	}
+
+	/**
+	 * 冻结产品(状态改为5)
+	 */
+	@RequiresPermissions("mes:mesProduct:dg")
+	@RequestMapping(value = "freeze")
+	@ResponseBody
+	public String freeze(MesProduct mesProduct) {
+		MesProduct entity = mesProductService.get(mesProduct);
+		if (entity == null) {
+			return renderResult(Global.FALSE, text("产品不存在"));
+		}
+		entity.setState("5");
+		mesProductService.save(entity);
+		return renderResult(Global.TRUE, text("冻结成功"));
+	}
+
+	/**
+	 * 解冻产品(状态改为0)
+	 */
+	@RequiresPermissions("mes:mesProduct:dg")
+	@RequestMapping(value = "unfreeze")
+	@ResponseBody
+	public String unfreeze(MesProduct mesProduct) {
+		MesProduct entity = mesProductService.get(mesProduct);
+		if (entity == null) {
+			return renderResult(Global.FALSE, text("产品不存在"));
+		}
+		entity.setState("0");
+		mesProductService.save(entity);
+		return renderResult(Global.TRUE, text("解冻成功"));
+	}
+
+	/**
+	 * 按创建时间范围统一冻结(状态改为5)
+	 */
+	@RequiresPermissions("mes:mesProduct:dg")
+	@PostMapping(value = "batchFreeze")
+	@ResponseBody
+	public String batchFreeze(HttpServletRequest request) {
+		return batchUpdateStateByCreateDate(request, "5", text("冻结"));
+	}
+
+	/**
+	 * 按创建时间范围统一解冻(状态改为0)
+	 */
+	@RequiresPermissions("mes:mesProduct:dg")
+	@PostMapping(value = "batchUnfreeze")
+	@ResponseBody
+	public String batchUnfreeze(HttpServletRequest request) {
+		return batchUpdateStateByCreateDate(request, "0", text("解冻"));
+	}
+	private String batchUpdateStateByCreateDate(HttpServletRequest request, String state, String actionName) {
+		String createDateGte = request.getParameter("createDate_gte");
+		String createDateLte = request.getParameter("createDate_lte");
+		if (StringUtils.isBlank(createDateGte) || StringUtils.isBlank(createDateLte)) {
+			return renderResult(Global.FALSE, text("请选择起止时间"));
+		}
+		if (createDateGte.compareTo(createDateLte) > 0) {
+			return renderResult(Global.FALSE, text("开始时间不能晚于结束时间"));
+		}
+		int count = mesProductService.updateStateByCreateDateRange(createDateGte, createDateLte, state);
+		return renderResult(Global.TRUE, text("批量") + actionName + text("成功,共处理 ") + count + text(" 条产品"));
+	}
 	@RequestMapping(value = "infoByRepair")
 	@ResponseBody
 	public CommonResp infoByRepair(HttpServletRequest req) {

+ 15 - 0
src/main/resources/mappings/modules/mes/MesChangePointDao.xml

@@ -0,0 +1,15 @@
+<?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.mes.dao.MesChangePointDao">
+	
+	<!-- 查询数据
+	<select id="findList" resultType="MesChangePoint">
+		SELECT ${sqlMap.column.toSql()}
+		FROM ${sqlMap.table.toSql()}
+		<where>
+			${sqlMap.where.toSql()}
+		</where>
+		ORDER BY ${sqlMap.order.toSql()}
+	</select> -->
+	
+</mapper>

+ 15 - 0
src/main/resources/mappings/modules/mes/MesItemDao.xml

@@ -0,0 +1,15 @@
+<?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.mes.dao.MesItemDao">
+	
+	<!-- 查询数据
+	<select id="findList" resultType="MesItem">
+		SELECT ${sqlMap.column.toSql()}
+		FROM ${sqlMap.table.toSql()}
+		<where>
+			${sqlMap.where.toSql()}
+		</where>
+		ORDER BY ${sqlMap.order.toSql()}
+	</select> -->
+	
+</mapper>

+ 6 - 0
src/main/resources/mappings/modules/mes/MesProductDao.xml

@@ -26,4 +26,10 @@
 		WHERE batch_sn=#{batchSn}
 	</select>
 
+	<update id="updateStateByCreateDateRange">
+		UPDATE mes_product
+		SET state = #{state}, update_date = NOW()
+		WHERE create_date &gt;= #{createDateGte} AND create_date &lt;= #{createDateLte}
+	</update>
+
 </mapper>

+ 152 - 0
src/main/resources/views/modules/mes/mesChangePointConfirmForm.html

@@ -0,0 +1,152 @@
+<% 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 fa-check-circle"></i> ${text(confirmTitle)}
+			</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="${mesChangePoint}" action="${ctx}/mes/mesChangePoint/confirmSave" method="post" class="form-horizontal">
+			<div class="box-body">
+				<#form:hidden path="id"/>
+				<div class="form-unit">${text('变化点信息')}</div>
+				<div class="row">
+					<div class="col-xs-6">
+						<div class="form-group">
+							<label class="control-label col-sm-4">${text('编号')}:</label>
+							<div class="col-sm-8">
+								<p class="form-control-static">${mesChangePoint.code}</p>
+							</div>
+						</div>
+					</div>
+					<div class="col-xs-6">
+						<div class="form-group">
+							<label class="control-label col-sm-4">${text('产品名称')}:</label>
+							<div class="col-sm-8">
+								<p class="form-control-static">${mesChangePoint.productName}</p>
+							</div>
+						</div>
+					</div>
+				</div>
+				<div class="form-unit">${text('确认信息')}</div>
+				<div class="row">
+					<% if(confirmStep == '0'){ %>
+					<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 id="importance" name="importance" class="form-control required">
+									<option value="">${text('请选择')}</option>
+									<option value="高" ${mesChangePoint.importance=='高'?'selected':''}>${text('高')}</option>
+									<option value="中" ${mesChangePoint.importance=='中'?'selected':''}>${text('中')}</option>
+									<option value="低" ${mesChangePoint.importance=='低'?'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">*</span> ${text('是否追溯')}:<i class="fa icon-question hide"></i></label>
+							<div class="col-sm-8">
+								<select id="isRetrace" name="isRetrace" class="form-control required">
+									<option value="">${text('请选择')}</option>
+									<option value="0" ${mesChangePoint.isRetrace=='0'?'selected':''}>${text('是')}</option>
+									<option value="1" ${mesChangePoint.isRetrace=='1'?'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">*</span> ${text('首件追溯时间')}:<i class="fa icon-question hide"></i></label>
+							<div class="col-sm-8">
+								<#form:input path="retraceStartTime" readonly="true" maxlength="20" class="form-control laydate required"
+									dataFormat="datetime" data-type="datetime" data-format="yyyy-MM-dd HH:mm"/>
+							</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">
+								<#form:input path="retraceEndTime" readonly="true" maxlength="20" class="form-control laydate required"
+									dataFormat="datetime" data-type="datetime" data-format="yyyy-MM-dd HH:mm"/>
+							</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">
+								<#form:input path="retraceNumber" maxlength="9" class="form-control required digits"/>
+							</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">
+								<#form:input path="bhgCount" maxlength="255" class="form-control required"/>
+							</div>
+						</div>
+					</div>
+					<% } else if(confirmStep == '1'){ %>
+					<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">
+								<#form:input path="productionConfirmer" maxlength="255" class="form-control required"/>
+							</div>
+						</div>
+					</div>
+					<% } else if(confirmStep == '2'){ %>
+					<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">
+								<#form:input path="qualityConfirmer" maxlength="255" class="form-control required"/>
+							</div>
+						</div>
+					</div>
+					<% } %>
+				</div>
+			</div>
+			<div class="box-footer">
+				<div class="row">
+					<div class="col-sm-offset-2 col-sm-10">
+						<% if (hasPermi('mes:mesChangePoint: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>

+ 150 - 0
src/main/resources/views/modules/mes/mesChangePointForm.html

@@ -0,0 +1,150 @@
+<% 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(mesChangePoint.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>
+			</div>
+		</div>
+		<#form:form id="inputForm" model="${mesChangePoint}" action="${ctx}/mes/mesChangePoint/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="code" 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="lineName" 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="proposer" 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="productName" maxlength="255" class="form-control" defaultValue="AD06"/>
+							</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="modelNumber" 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">*</span> ${text('班次')}:<i class="fa icon-question hide"></i></label>
+							<div class="col-sm-8">
+								<select id="mesShiftTitle" name="mesShiftTitle" class="form-control required">
+									<option value="">${text('请选择')}</option>
+									<option value="白班" ${mesChangePoint.mesShiftTitle=='白班'?'selected':''}>${text('白班')}</option>
+									<option value="晚班" ${mesChangePoint.mesShiftTitle=='晚班'?'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="startTime" readonly="true" maxlength="20" class="form-control laydate"
+									dataFormat="datetime" data-type="datetime" data-format="yyyy-MM-dd HH:mm"/>
+							</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="type" 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="description" 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="endSn" 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="startSn" maxlength="255" class="form-control"/>
+							</div>
+						</div>
+					</div>
+				</div>
+			</div>
+			<div class="box-footer">
+				<div class="row">
+					<div class="col-sm-offset-2 col-sm-10">
+						<% if (hasPermi('mes:mesChangePoint: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>

+ 240 - 0
src/main/resources/views/modules/mes/mesChangePointList.html

@@ -0,0 +1,240 @@
+<% 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>
+				<% if(hasPermi('mes:mesChangePoint:xz')){ %>
+					<a href="${ctx}/mes/mesChangePoint/form" class="btn btn-default btnTool" title="${text('新增生产变化点表')}"><i class="fa fa-plus"></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="${mesChangePoint}" action="${ctx}/mes/mesChangePoint/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="code" maxlength="255" class="form-control width-120"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('车间名称')}:</label>
+					<div class="control-inline">
+						<#form:input path="lineName" maxlength="255" class="form-control width-120"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('提出人')}:</label>
+					<div class="control-inline">
+						<#form:input path="proposer" maxlength="255" class="form-control width-120"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('产品名称')}:</label>
+					<div class="control-inline">
+						<#form:input path="productName" maxlength="255" class="form-control width-120"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('模号')}:</label>
+					<div class="control-inline">
+						<#form:input path="modelNumber" maxlength="255" class="form-control width-120"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('变化点开始时间')}:</label>
+					<div class="control-inline">
+						<#form:input path="startTime" 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">
+					<label class="control-label">${text('类别')}:</label>
+					<div class="control-inline">
+						<#form:input path="type" maxlength="255" class="form-control width-120"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('变化点描述')}:</label>
+					<div class="control-inline">
+						<#form:input path="description" maxlength="255" class="form-control width-120"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('异常发生末件二维码')}:</label>
+					<div class="control-inline">
+						<#form:input path="endSn" maxlength="255" class="form-control width-120"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('异常发生首件二维码')}:</label>
+					<div class="control-inline">
+						<#form:input path="startSn" maxlength="255" class="form-control width-120"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('重要性')}:</label>
+					<div class="control-inline">
+						<#form:input path="importance" maxlength="255" class="form-control width-120"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('是否追溯')}:</label>
+					<div class="control-inline">
+						<#form:input path="isRetrace" maxlength="255" class="form-control width-120"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('首件追溯时间')}:</label>
+					<div class="control-inline">
+						<#form:input path="retraceStartTime" 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">
+					<label class="control-label">${text('末件产品追溯时间')}:</label>
+					<div class="control-inline">
+						<#form:input path="retraceEndTime" 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">
+					<label class="control-label">${text('追溯范围数量')}:</label>
+					<div class="control-inline">
+						<#form:input path="retraceNumber" maxlength="9" class="form-control width-120"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('不合格产品数量')}:</label>
+					<div class="control-inline">
+						<#form:input path="bhgCount" maxlength="255" class="form-control width-120"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('生产确认人')}:</label>
+					<div class="control-inline">
+						<#form:input path="productionConfirmer" maxlength="255" class="form-control width-120"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('质量确认人')}:</label>
+					<div class="control-inline">
+						<#form:input path="qualityConfirmer" maxlength="255" class="form-control width-120"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('关闭时间')}:</label>
+					<div class="control-inline">
+						<#form:input path="endTime" 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">
+					<label class="control-label">${text('状态')}:</label>
+					<div class="control-inline width-120">
+						<#form:select path="status" dictType="sys_search_status" blankOption="true" class="form-control isQuick"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('班次')}:</label>
+					<div class="control-inline">
+						<#form:input path="mesShiftTitle" maxlength="255" class="form-control width-120"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('变化点状态')}:</label>
+					<div class="control-inline">
+						<#form:input path="changeState" maxlength="255" class="form-control width-120"/>
+					</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').dataGrid({
+	searchForm: $("#searchForm"),
+	columnModel: [
+		{header:'${text("编号")}', name:'code', index:'a.code', width:150, align:"left", frozen:true, formatter: function(val, obj, row, act){
+			return '<a href="${ctx}/mes/mesChangePoint/form?id='+row.id+'" class="btnList" data-title="${text("编辑生产变化点")}">'+(val||row.id)+'</a>';
+		}},
+		{header:'${text("车间名称")}', name:'lineName', index:'a.line_name', width:150, align:"left"},
+		{header:'${text("提出人")}', name:'proposer', index:'a.proposer', width:150, align:"left"},
+		{header:'${text("产品名称")}', name:'productName', index:'a.product_name', width:150, align:"left"},
+		{header:'${text("模号")}', name:'modelNumber', index:'a.model_number', width:150, align:"left"},
+		{header:'${text("变化点开始时间")}', name:'startTime', index:'a.start_time', width:150, align:"center"},
+		{header:'${text("类别")}', name:'type', index:'a.type', width:150, align:"left"},
+		{header:'${text("变化点描述")}', name:'description', index:'a.description', width:150, align:"left"},
+		{header:'${text("异常发生末件二维码")}', name:'endSn', index:'a.end_sn', width:150, align:"left"},
+		{header:'${text("异常发生首件二维码")}', name:'startSn', index:'a.start_sn', width:150, align:"left"},
+		{header:'${text("重要性")}', name:'importance', index:'a.importance', width:100, align:"center"},
+		{header:'${text("是否追溯")}', name:'isRetrace', index:'a.is_retrace', width:100, align:"center", formatter: function(val, obj, row, act){
+			if (val == '0' || val === 0) return '${text("是")}';
+			if (val == '1' || val === 1) return '${text("否")}';
+			return val || '';
+		}},
+		{header:'${text("首件追溯时间")}', name:'retraceStartTime', index:'a.retrace_start_time', width:150, align:"center"},
+		{header:'${text("末件产品追溯时间")}', name:'retraceEndTime', index:'a.retrace_end_time', width:150, align:"center"},
+		{header:'${text("追溯范围数量")}', name:'retraceNumber', index:'a.retrace_number', width:150, align:"center"},
+		{header:'${text("不合格产品数量")}', name:'bhgCount', index:'a.bhg_count', width:150, align:"left"},
+		{header:'${text("生产确认人")}', name:'productionConfirmer', index:'a.production_confirmer', width:150, align:"left"},
+		{header:'${text("质量确认人")}', name:'qualityConfirmer', index:'a.quality_confirmer', width:150, align:"left"},
+		{header:'${text("关闭时间")}', name:'endTime', index:'a.end_time', width:150, align:"center"},
+		{header:'${text("状态")}', name:'status', index:'a.status', width:150, align:"center", formatter: function(val, obj, row, act){
+			return js.getDictLabel(${@DictUtils.getDictListJson('sys_search_status')}, val, '${text("未知")}', true);
+		}},
+		{header:'${text("修改时间")}', name:'updateDate', index:'a.update_date', width:150, align:"center"},
+		{header:'${text("班次")}', name:'mesShiftTitle', index:'a.mes_shift_title', width:150, align:"left"},
+		{header:'${text("变化点状态")}', name:'changeState', index:'a.change_state', width:120, align:"center", formatter: function(val, obj, row, act){
+			if (val == '0' || val == 0) return '${text("待品质处理")}';
+			if (val == '1' || val == 1) return '${text("待生产确认")}';
+			if (val == '2' || val == 2) return '${text("待品质确认")}';
+			if (val == '3' || val == 3) return '${text("结束")}';
+			return val || '';
+		}},
+		{header:'${text("操作")}', name:'actions', width:120, formatter: function(val, obj, row, act){
+			var actions = [];
+			//<% if(hasPermi('mes:mesChangePoint:edit')){ %>
+				actions.push('<a href="${ctx}/mes/mesChangePoint/form?id='+row.id+'" class="btnList" title="${text("编辑生产变化点")}"><i class="fa fa-pencil"></i></a>&nbsp;');
+				var cs = row.changeState;
+				var showConfirm = false;
+				if (cs == '0' || cs === 0) {
+					//<% if(hasPermi('mes:mesChangePoint:viewAll') || hasPermi('mes:mesChangePoint:viewState0')){ %>
+					showConfirm = true;
+					//<% } %>
+				} else if (cs == '1' || cs === 1) {
+					//<% if(hasPermi('mes:mesChangePoint:viewAll') || hasPermi('mes:mesChangePoint:viewState1')){ %>
+					showConfirm = true;
+					//<% } %>
+				} else if (cs == '2' || cs === 2) {
+					//<% if(hasPermi('mes:mesChangePoint:viewAll') || hasPermi('mes:mesChangePoint:viewState2')){ %>
+					showConfirm = true;
+					//<% } %>
+				}
+				if (showConfirm) {
+					actions.push('<a href="${ctx}/mes/mesChangePoint/confirmForm?id='+row.id+'" class="btnList" title="${text("进行确认")}"><i class="fa fa-check-circle"></i></a>&nbsp;');
+				}
+				actions.push('<a href="${ctx}/mes/mesChangePoint/delete?id='+row.id+'" class="btnList" title="${text("删除生产变化点")}" data-confirm="${text("确认要删除该生产变化点吗?")}"><i class="fa fa-trash-o"></i></a>&nbsp;');
+			//<% } %>
+			return actions.join('');
+		}}
+	],
+	// 加载成功后执行事件
+	ajaxSuccess: function(data){
+
+	}
+});
+</script>

+ 152 - 0
src/main/resources/views/modules/mes/mesItemForm.html

@@ -0,0 +1,152 @@
+<% 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(mesItem.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>
+			</div>
+		</div>
+		<#form:form id="inputForm" model="${mesItem}" action="${ctx}/mes/mesItem/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="itemJf" maxlength="64" 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="itemHf" maxlength="64" 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="reason" 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('0=审核中 1=借用中 2=已归还')}:<i class="fa icon-question hide"></i></label>
+							<div class="col-sm-8">
+								<#form:input path="state" maxlength="1" 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="jyTime" readonly="true" maxlength="20" class="form-control laydate"
+									dataFormat="datetime" data-type="datetime" data-format="yyyy-MM-dd HH:mm"/>
+							</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="shTime" readonly="true" maxlength="20" class="form-control laydate"
+									dataFormat="datetime" data-type="datetime" data-format="yyyy-MM-dd HH:mm"/>
+							</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="ghTime" readonly="true" maxlength="20" class="form-control laydate"
+									dataFormat="datetime" data-type="datetime" data-format="yyyy-MM-dd HH:mm"/>
+							</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="xzTime" readonly="true" maxlength="20" class="form-control laydate"
+									dataFormat="datetime" data-type="datetime" data-format="yyyy-MM-dd HH:mm"/>
+							</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="itemName" 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="remark" maxlength="255" class="form-control"/>
+							</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="${mesItem.id}" bizType="mesItem_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:mesItem: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>

+ 143 - 0
src/main/resources/views/modules/mes/mesItemList.html

@@ -0,0 +1,143 @@
+<% 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>
+				<% if(hasPermi('mes:mesItem:edit')){ %>
+					<a href="${ctx}/mes/mesItem/form" class="btn btn-default btnTool" title="${text('新增物品借用归还表')}"><i class="fa fa-plus"></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="${mesItem}" action="${ctx}/mes/mesItem/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="itemJf" maxlength="64" class="form-control width-120"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('还方')}:</label>
+					<div class="control-inline">
+						<#form:input path="itemHf" maxlength="64" class="form-control width-120"/>
+					</div>
+				</div>
+<!--				<div class="form-group">-->
+<!--					<label class="control-label">${text('原因')}:</label>-->
+<!--					<div class="control-inline">-->
+<!--						<#form:input path="reason" maxlength="255" 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="state" class="form-control">
+						<option value="">${text('全部')}</option>
+						<option value="0" ${mesItem.state == '0' ? 'selected' : ''}>${text('审核中')}</option>
+						<option value="1" ${mesItem.state == '1' ? 'selected' : ''}>${text('借用中')}</option>
+						<option value="2" ${mesItem.state == '2' ? 'selected' : ''}>${text('已归还')}</option>
+					</select>
+				</div>
+			</div>
+				<div class="form-group">
+					<label class="control-label">${text('上报日期')}:</label>
+					<div class="control-inline">
+						<#form:input path="jyTime" 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">
+					<label class="control-label">${text('审核通过日期')}:</label>
+					<div class="control-inline">
+						<#form:input path="shTime" 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">
+					<label class="control-label">${text('归还日期')}:</label>
+					<div class="control-inline">
+						<#form:input path="ghTime" 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">
+					<label class="control-label">${text('校准日期')}:</label>
+					<div class="control-inline">
+						<#form:input path="xzTime" 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">-->
+<!--					<label class="control-label">${text('物品名称')}:</label>-->
+<!--					<div class="control-inline">-->
+<!--						<#form:input path="itemName" maxlength="255" class="form-control width-120"/>-->
+<!--					</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-120"/>
+					</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').dataGrid({
+	searchForm: $("#searchForm"),
+	columnModel: [
+		{header:'${text("借方")}', name:'itemJf', index:'a.item_jf', width:150, align:"center", frozen:true, formatter: function(val, obj, row, act){
+			return '<a href="${ctx}/mes/mesItem/form?id='+row.id+'" class="btnList" data-title="${text("编辑物品借用归还表")}">'+(val||row.id)+'</a>';
+		}},
+		{header:'${text("还方")}', name:'itemHf', index:'a.item_hf', width:150, align:"center"},
+		{header:'${text("物品名称")}', name:'itemName', index:'a.item_name', width:150, align:"center"},
+		{header:'${text("原因")}', name:'reason', index:'a.reason', width:150, align:"center"},
+		{header:'${text("状态")}', name:'state', index:'a.state', width:150, align:"center", formatter: function(val, obj, row, act){
+				var stateMap = {
+					'0': '${text("审核中")}',
+					'1': '${text("借用中")}',
+					'2': '${text("已归还")}'
+				};
+				// 将值转为字符串去匹配,匹配不到则显示原值或“未知”
+				return stateMap[String(val)] || '${text("未知")}';
+			}},
+		{header:'${text("上报日期")}', name:'jyTime', index:'a.jy_time', width:150, align:"center"},
+		{header:'${text("审核通过日期")}', name:'shTime', index:'a.sh_time', width:150, align:"center"},
+		{header:'${text("归还日期")}', name:'ghTime', index:'a.gh_time', width:150, align:"center"},
+		{header:'${text("校准日期")}', name:'xzTime', index:'a.xz_time', width:150, align:"center"},
+		{header:'${text("备注")}', name:'remark', index:'a.remark', width:150, align:"left"},
+		{header:'${text("操作")}', name:'actions', width:120, formatter: function(val, obj, row, act){
+				var actions = [];
+				//<% if(hasPermi('mes:mesItem:edit')){ %>
+				// 如果状态为 0 (审核中),显示审核按钮
+				if (row.state == '0' || row.state == 0) {
+					// 点击后会弹出 data-confirm 中的提示,点击确认后向后台发送带 id 和 state=1 的请求
+					actions.push('<a href="${ctx}/mes/mesItem/audit?id='+row.id+'&state=1" class="btnList" title="${text("审核通过")}" data-confirm="${text("确认审核通过此物品借用吗?")}"><i class="fa fa-check-square-o"></i></a>&nbsp;');
+				}
+				actions.push('<a href="${ctx}/mes/mesItem/form?id='+row.id+'" class="btnList" title="${text("编辑物品借用归还表")}"><i class="fa fa-pencil"></i></a>&nbsp;');
+				actions.push('<a href="${ctx}/mes/mesItem/delete?id='+row.id+'" class="btnList" title="${text("删除物品借用归还表")}" data-confirm="${text("确认要删除该物品借用归还表吗?")}"><i class="fa fa-trash-o"></i></a>&nbsp;');
+				//<% } %>
+				return actions.join('');
+			}}
+	],
+	// 加载成功后执行事件
+	ajaxSuccess: function(data){
+
+	}
+});
+</script>

+ 98 - 11
src/main/resources/views/modules/mes/mesProductList.html

@@ -7,10 +7,12 @@
 			</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>
+				<% if(hasPermi('mes:mesProduct:dg')){ %>
+				<a href="#" class="btn btn-default" id="btnBatchFreeze">${text('统一冻结')}</a>
+				<a href="#" class="btn btn-default" id="btnBatchUnfreeze">${text('统一解冻')}</a>
+				<% } %>
 				<a href="#" class="btn btn-default" id="btnExport"><i class="glyphicon glyphicon-export"></i> 导出</a>
-				<% if(hasPermi('mes:mesProduct:edit')){ %>
 <!--					<a href="${ctx}/mes/mesProduct/form" class="btn btn-default btnTool" title="${text('新增产品')}"><i class="fa fa-plus"></i> ${text('新增')}</a>-->
-				<% } %>
 				<a href="#" class="btn btn-default" id="btnSetting" title="${text('设置')}"><i class="fa fa-navicon"></i></a>
 			</div>
 		</div>
@@ -121,17 +123,21 @@ $('#dataGrid').dataGrid({
 		// {header:'${text("包装人")}', name:'bindBy', index:'a.bind_by', width:150, align:"center"},
 		{header:'${text("创建日期")}', name:'createDate', index:'a.create_date', width:150, align:"center" },
 		{header:'${text("更新时间")}', name:'updateDate', index:'a.update_date', width:150, align:"center"},
-		// {header:'${text("操作")}', name:'actions', width:120, formatter: function(val, obj, row, act){
-		// 	var actions = [];
-		// 	//<% if(hasPermi('mes:mesProduct:edit')){ %>
-		// 	// 	actions.push('<a href="${ctx}/mes/mesProduct/form?id='+row.id+'" class="btnList" title="${text("编辑产品")}"><i class="fa fa-pencil"></i></a>&nbsp;');
-		// 	//<% } %>
-		// 	return actions.join('');
-		// }}
+		{header:'${text("操作")}', name:'actions', width:100, align:"center", formatter: function(val, obj, row, act){
+			var actions = [];
+			<% if(hasPermi('mes:mesProduct:dg')){ %> 
+			if (row.state == '5' || row.state == 5){
+				actions.push('<a href="${ctx}/mes/mesProduct/unfreeze?id='+row.id+'" class="btnList" title="${text("解冻")}" data-confirm="${text("确认要解冻该产品吗?")}">${text("解冻")}</a>');
+			} else {
+				actions.push('<a href="${ctx}/mes/mesProduct/freeze?id='+row.id+'" class="btnList" title="${text("冻结")}" data-confirm="${text("确认要冻结该产品吗?")}">${text("冻结")}</a>');
+			}
+			<% } %>
+			return actions.join('');
+		}}
 	],
 	// 加载成功后执行事件
 	ajaxSuccess: function(data){
-		
+
 	}
 });
 
@@ -141,4 +147,85 @@ $('#btnExport').click(function(){
 		downloadFile:true
 	});
 });
-</script>
+
+function openBatchStateDialog(action) {
+	var isFreeze = action === 'freeze';
+	var title = isFreeze ? '${text("统一冻结")}' : '${text("统一解冻")}';
+	var confirmBtn = isFreeze ? '${text("确认冻结")}' : '${text("确认解冻")}';
+	var url = isFreeze ? '${ctx}/mes/mesProduct/batchFreeze' : '${ctx}/mes/mesProduct/batchUnfreeze';
+	var confirmMsg = isFreeze ? '${text("确认要冻结所选创建时间段内的全部产品吗?")}' : '${text("确认要解冻所选创建时间段内的全部产品吗?")}';
+	js.layer.open({
+		type: 1,
+		area: ['520px'],
+		title: title,
+		resize: false,
+		scrollbar: true,
+		content: js.template('batchStateTpl'),
+		success: function(layero, index) {
+			var laydateApi = (window.top.laydate || window.laydate);
+			var $gte = layero.find('input[name=createDate_gte]');
+			var $lte = layero.find('input[name=createDate_lte]');
+			function bindBatchLaydate($input, openNext) {
+				$input.off('click.batchState').on('click.batchState', function() {
+					laydateApi.render({
+						elem: $input[0],
+						type: 'datetime',
+						format: 'yyyy-MM-dd HH:mm',
+						show: true,
+						closeStop: $input[0],
+						zIndex: 99999999,
+						done: function(value) {
+							$input.val(value);
+							if (openNext) {
+								setTimeout(function() { $lte.trigger('click.batchState'); }, 200);
+							}
+						}
+					});
+				});
+			}
+			bindBatchLaydate($gte, true);
+			bindBatchLaydate($lte, false);
+		},
+		btn: ['<i class="fa fa-check"></i> ' + confirmBtn, '<i class="fa fa-remove"></i> ${text("关闭")}'],
+		btn1: function(index, layero) {
+			var createDateGte = layero.find('input[name=createDate_gte]').val();
+			var createDateLte = layero.find('input[name=createDate_lte]').val();
+			if (!createDateGte || !createDateLte) {
+				js.showMessage('${text("请选择起止时间")}', null, 'warning');
+				return false;
+			}
+			if (createDateGte > createDateLte) {
+				js.showMessage('${text("开始时间不能晚于结束时间")}', null, 'warning');
+				return false;
+			}
+			js.confirm(confirmMsg, function() {
+				$.post(url, {createDate_gte: createDateGte, createDate_lte: createDateLte}, function(data) {
+					js.showMessage(data.message);
+					if (data.result == Global.TRUE) {
+						js.layer.close(index);
+						$('#dataGrid').dataGrid('refresh');
+					}
+				}, 'json');
+			});
+			return false;
+		}
+	});
+}
+$('#btnBatchFreeze').click(function(e) { e.preventDefault(); openBatchStateDialog('freeze'); });
+$('#btnBatchUnfreeze').click(function(e) { e.preventDefault(); openBatchStateDialog('unfreeze'); });
+</script>
+<script id="batchStateTpl" type="text/template">//<!--
+<form id="batchStateForm" class="form-inline mt20 mb10 pl20 pr20">
+	<div class="form-group">
+		<label class="control-label">${text('创建日期')}:</label>
+		<div class="control-inline">
+			<input type="text" name="createDate_gte" readonly="true" maxlength="20" class="form-control width-datetime"/>
+			&nbsp;-&nbsp;
+			<input type="text" name="createDate_lte" readonly="true" maxlength="20" class="form-control width-datetime"/>
+		</div>
+	</div>
+	<div class="form-group" style="color:#999;">
+		${text('将对该创建时间段内的全部产品执行批量操作')}
+	</div>
+</form>
+//--></script>