Bläddra i källkod

Merge branch 'master' of http://121.36.46.135:3000/mes-ljz/mescloud

sunxianglong 4 månader sedan
förälder
incheckning
49e7827157

+ 7 - 31
src/main/java/com/jeesite/modules/mes/entity/MesDeviceAlarm.java

@@ -3,7 +3,6 @@ package com.jeesite.modules.mes.entity;
 import javax.validation.constraints.NotBlank;
 import javax.validation.constraints.Size;
 
-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.JoinTable;
@@ -25,18 +24,16 @@ import java.util.Date;
 		@Column(name="type", attrName="type", label="报警类型"),
 		@Column(name="content", attrName="content", label="报警额外参数", isQuery=false),
 		@Column(name="state", attrName="state", label="状态"),
-		@Column(name="fault_time", attrName="faultTime", label="故障发生时间", isUpdateForce=true),
-		@Column(name="recovery_time", attrName="recoveryTime", label="恢复生产时间", isUpdateForce=true),
 		@Column(name="remark", attrName="remark", label="备注"),
 		@Column(name="create_by", attrName="createBy", label="create_by", isUpdate=false, isQuery=false),
 		@Column(name="create_date", attrName="createDate", label="创建时间", isUpdate=false, isUpdateForce=true),
 		@Column(name="update_by", attrName="updateBy", label="update_by", isQuery=false),
 		@Column(name="update_date", attrName="updateDate", label="处理时间", isQuery=false, isUpdateForce=true),
 	}, joinTable={
-		@JoinTable(type=Type.LEFT_JOIN, entity=MesDevice.class, attrName="device", alias="b",
+		@JoinTable(type=Type.LEFT_JOIN, entity=MesDevice.class, attrName="mes_device", alias="b",
 				on="a.device_id = b.tree_code", columns={
 				@Column(name="tree_name", attrName="deviceName", label="报警设备名称", isQuery=false),
-				@Column(name="sn", attrName="deviceOnlySn", label="设备唯一编号", isQuery=false),
+				@Column(name="device_code", attrName="deviceCode", label="设备编号", isQuery=false),
 		}),
 	}, orderBy="a.update_date DESC"
 )
@@ -46,14 +43,10 @@ public class MesDeviceAlarm extends DataEntity<MesDeviceAlarm> {
 	private String deviceSn;		// 设备编号
 	private String deviceId;		// 报警设备(设备结构ID,外键关联 mes_device.tree_code)
 	private String deviceName;		// 报警设备名称(关联查询)
-	private String deviceOnlySn;		// 设备唯一编号(关联查询 mes_device.sn)
+	private String deviceCode;		// 设备编号(关联查询 mes_device.device_code)
 	private String type;		// 报警类型
 	private String content;		// 报警额外参数
 	private String state;		// 状态
-	@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
-	private Date faultTime;		// 故障发生时间
-	@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
-	private Date recoveryTime;		// 恢复生产时间
 	private String remark;		// 备注
 
 	public MesDeviceAlarm() {
@@ -64,7 +57,6 @@ public class MesDeviceAlarm extends DataEntity<MesDeviceAlarm> {
 		super(id);
 	}
 	
-	@NotBlank(message="设备编号不能为空")
 	@Size(min=0, max=100, message="设备编号长度不能超过 100 个字符")
 	public String getDeviceSn() {
 		return deviceSn;
@@ -91,12 +83,12 @@ public class MesDeviceAlarm extends DataEntity<MesDeviceAlarm> {
 		this.deviceName = deviceName;
 	}
 
-	public String getDeviceOnlySn() {
-		return deviceOnlySn;
+	public String getDeviceCode() {
+		return deviceCode;
 	}
 
-	public void setDeviceOnlySn(String deviceOnlySn) {
-		this.deviceOnlySn = deviceOnlySn;
+	public void setDeviceCode(String deviceCode) {
+		this.deviceCode = deviceCode;
 	}
 
 	@NotBlank(message="报警类型不能为空")
@@ -126,22 +118,6 @@ public class MesDeviceAlarm extends DataEntity<MesDeviceAlarm> {
 		this.state = state;
 	}
 
-	public Date getFaultTime() {
-		return faultTime;
-	}
-
-	public void setFaultTime(Date faultTime) {
-		this.faultTime = faultTime;
-	}
-
-	public Date getRecoveryTime() {
-		return recoveryTime;
-	}
-
-	public void setRecoveryTime(Date recoveryTime) {
-		this.recoveryTime = recoveryTime;
-	}
-	
 	@Size(min=0, max=255, message="备注长度不能超过 255 个字符")
 	public String getRemark() {
 		return remark;

+ 163 - 49
src/main/java/com/jeesite/modules/mes/entity/MesDeviceMaintenance.java

@@ -6,39 +6,67 @@ import javax.validation.constraints.Size;
 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.JoinTable;
+import com.jeesite.common.mybatis.annotation.JoinTable.Type;
 import com.jeesite.common.mybatis.annotation.Table;
 
 /**
- * 设备保养Entity
+ * 设备维保记录Entity
  * @author mes
- * @version 2026-06-26
+ * @version 2026-06-28
  */
-@Table(name="mes_device_maintenance", alias="a", label="设备保养信息", columns={
+@Table(name="mes_device_maintenance", alias="a", label="设备维保记录信息", columns={
 		@Column(name="id", attrName="id", label="id", isPK=true),
-		@Column(name="name", attrName="name", label="名称", isQuery=true),
-		@Column(name="code", attrName="code", label="编号", isQuery=true),
-		@Column(name="maintenance_category", attrName="maintenanceCategory", label="保养类别", isQuery=true),
-		@Column(name="maintenance_date", attrName="maintenanceDate", label="保养日期", isQuery=true),
-		@Column(name="content", attrName="content", label="保养内容"),
-		@Column(name="maintenance_user", attrName="maintenanceUser", label="保养人", isQuery=true),
-		@Column(name="maintenance_status", attrName="maintenanceStatus", label="保养状态", isQuery=true),
+		@Column(name="device_tree_code", attrName="deviceTreeCode", label="设备编码", isQuery=true),
+		@Column(name="maintenance_date", attrName="maintenanceDate", label="维保日期", isQuery=true),
+		@Column(name="fault_time", attrName="faultTime", label="故障发生时间"),
+		@Column(name="resume_production_time", attrName="resumeProductionTime", label="恢复生产时间"),
+		@Column(name="downtime", attrName="downtime", label="停机时长"),
+		@Column(name="repair_start_time", attrName="repairStartTime", label="维修开始时间"),
+		@Column(name="repair_end_time", attrName="repairEndTime", label="维修结束时间"),
+		@Column(name="repair_duration", attrName="repairDuration", label="维修时长"),
+		@Column(name="fault_phenomenon", attrName="faultPhenomenon", label="故障现象"),
+		@Column(name="repair_measure", attrName="repairMeasure", label="维修措施"),
+		@Column(name="fault_category", attrName="faultCategory", label="故障类别", isQuery=true),
+		@Column(name="root_cause_analysis", attrName="rootCauseAnalysis", label="根本原因分析"),
+		@Column(name="spare_part_name", attrName="sparePartName", label="备件名称"),
+		@Column(name="quantity", attrName="quantity", label="数量"),
+		@Column(name="repair_user", attrName="repairUser", label="维修人", isQuery=true),
 		@Column(name="remarks", attrName="remarks", label="备注"),
 		@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="update_by", isQuery=false),
 		@Column(name="update_date", attrName="updateDate", label="update_date", isQuery=false, isUpdateForce=true),
+}, joinTable={
+		@JoinTable(type=Type.LEFT_JOIN, entity=MesDevice.class, attrName="this", alias="b",
+				on="a.device_tree_code = b.tree_code", columns={
+				@Column(name="tree_name", attrName="deviceName", label="设备名称"),
+				@Column(name="device_code", attrName="deviceCode", label="机台号"),
+		}),
 }, orderBy="a.maintenance_date DESC"
 )
 public class MesDeviceMaintenance extends DataEntity<MesDeviceMaintenance> {
 
 	private static final long serialVersionUID = 1L;
-	private String name;				// 名称
-	private String code;				// 编号
-	private String maintenanceCategory;	// 保养类别
-	private Date maintenanceDate;		// 保养日期
-	private String content;				// 保养内容
-	private String maintenanceUser;		// 保养人
-	private String maintenanceStatus;	// 保养状态
+	private String deviceTreeCode;		// 设备编码(关联mes_device.tree_code)
+	private Date maintenanceDate;		// 维保日期
+	private Date faultTime;			// 故障发生时间
+	private Date resumeProductionTime;	// 恢复生产时间
+	private String downtime;			// 停机时长
+	private Date repairStartTime;		// 维修开始时间
+	private Date repairEndTime;		// 维修结束时间
+	private String repairDuration;		// 维修时长
+	private String faultPhenomenon;	// 故障现象
+	private String repairMeasure;		// 维修措施
+	private String faultCategory;		// 故障类别
+	private String rootCauseAnalysis;	// 根本原因分析
+	private String sparePartName;		// 备件名称
+	private Integer quantity;			// 数量
+	private String repairUser;			// 维修人
+
+	// JoinTable 关联字段
+	private String deviceName;			// 设备名称(来自设备结构表 tree_name)
+	private String deviceCode;			// 机台号(来自设备结构表 device_code)
 
 	public MesDeviceMaintenance() {
 		this(null);
@@ -48,64 +76,150 @@ public class MesDeviceMaintenance extends DataEntity<MesDeviceMaintenance> {
 		super(id);
 	}
 
-	@Size(min=0, max=255, message="名称长度不能超过 255 个字符")
-	public String getName() {
-		return name;
+	@Size(min=0, max=64, message="设备编码长度不能超过 64 个字符")
+	public String getDeviceTreeCode() {
+		return deviceTreeCode;
 	}
 
-	public void setName(String name) {
-		this.name = name;
+	public void setDeviceTreeCode(String deviceTreeCode) {
+		this.deviceTreeCode = deviceTreeCode;
 	}
 
-	@Size(min=0, max=100, message="编号长度不能超过 100 个字符")
-	public String getCode() {
-		return code;
+	@JsonFormat(pattern = "yyyy-MM-dd")
+	public Date getMaintenanceDate() {
+		return maintenanceDate;
 	}
 
-	public void setCode(String code) {
-		this.code = code;
+	public void setMaintenanceDate(Date maintenanceDate) {
+		this.maintenanceDate = maintenanceDate;
 	}
 
-	@Size(min=0, max=100, message="保养类别长度不能超过 100 个字符")
-	public String getMaintenanceCategory() {
-		return maintenanceCategory;
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	public Date getFaultTime() {
+		return faultTime;
 	}
 
-	public void setMaintenanceCategory(String maintenanceCategory) {
-		this.maintenanceCategory = maintenanceCategory;
+	public void setFaultTime(Date faultTime) {
+		this.faultTime = faultTime;
 	}
 
 	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-	public Date getMaintenanceDate() {
-		return maintenanceDate;
+	public Date getResumeProductionTime() {
+		return resumeProductionTime;
 	}
 
-	public void setMaintenanceDate(Date maintenanceDate) {
-		this.maintenanceDate = maintenanceDate;
+	public void setResumeProductionTime(Date resumeProductionTime) {
+		this.resumeProductionTime = resumeProductionTime;
+	}
+
+	@Size(min=0, max=100, message="停机时长长度不能超过 100 个字符")
+	public String getDowntime() {
+		return downtime;
+	}
+
+	public void setDowntime(String downtime) {
+		this.downtime = downtime;
+	}
+
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	public Date getRepairStartTime() {
+		return repairStartTime;
+	}
+
+	public void setRepairStartTime(Date repairStartTime) {
+		this.repairStartTime = repairStartTime;
+	}
+
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	public Date getRepairEndTime() {
+		return repairEndTime;
+	}
+
+	public void setRepairEndTime(Date repairEndTime) {
+		this.repairEndTime = repairEndTime;
+	}
+
+	@Size(min=0, max=100, message="维修时长长度不能超过 100 个字符")
+	public String getRepairDuration() {
+		return repairDuration;
+	}
+
+	public void setRepairDuration(String repairDuration) {
+		this.repairDuration = repairDuration;
+	}
+
+	public String getFaultPhenomenon() {
+		return faultPhenomenon;
+	}
+
+	public void setFaultPhenomenon(String faultPhenomenon) {
+		this.faultPhenomenon = faultPhenomenon;
+	}
+
+	public String getRepairMeasure() {
+		return repairMeasure;
+	}
+
+	public void setRepairMeasure(String repairMeasure) {
+		this.repairMeasure = repairMeasure;
+	}
+
+	@Size(min=0, max=100, message="故障类别长度不能超过 100 个字符")
+	public String getFaultCategory() {
+		return faultCategory;
+	}
+
+	public void setFaultCategory(String faultCategory) {
+		this.faultCategory = faultCategory;
+	}
+
+	public String getRootCauseAnalysis() {
+		return rootCauseAnalysis;
+	}
+
+	public void setRootCauseAnalysis(String rootCauseAnalysis) {
+		this.rootCauseAnalysis = rootCauseAnalysis;
+	}
+
+	@Size(min=0, max=255, message="备件名称长度不能超过 255 个字符")
+	public String getSparePartName() {
+		return sparePartName;
+	}
+
+	public void setSparePartName(String sparePartName) {
+		this.sparePartName = sparePartName;
+	}
+
+	public Integer getQuantity() {
+		return quantity;
+	}
+
+	public void setQuantity(Integer quantity) {
+		this.quantity = quantity;
 	}
 
-	public String getContent() {
-		return content;
+	@Size(min=0, max=100, message="维修人长度不能超过 100 个字符")
+	public String getRepairUser() {
+		return repairUser;
 	}
 
-	public void setContent(String content) {
-		this.content = content;
+	public void setRepairUser(String repairUser) {
+		this.repairUser = repairUser;
 	}
 
-	@Size(min=0, max=100, message="保养人长度不能超过 100 个字符")
-	public String getMaintenanceUser() {
-		return maintenanceUser;
+	public String getDeviceName() {
+		return deviceName;
 	}
 
-	public void setMaintenanceUser(String maintenanceUser) {
-		this.maintenanceUser = maintenanceUser;
+	public void setDeviceName(String deviceName) {
+		this.deviceName = deviceName;
 	}
 
-	public String getMaintenanceStatus() {
-		return maintenanceStatus;
+	public String getDeviceCode() {
+		return deviceCode;
 	}
 
-	public void setMaintenanceStatus(String maintenanceStatus) {
-		this.maintenanceStatus = maintenanceStatus;
+	public void setDeviceCode(String deviceCode) {
+		this.deviceCode = deviceCode;
 	}
 }

+ 3 - 8
src/main/java/com/jeesite/modules/mes/service/MesDeviceMaintenanceService.java

@@ -1,6 +1,5 @@
 package com.jeesite.modules.mes.service;
 
-import java.util.Date;
 import java.util.List;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -9,12 +8,11 @@ import com.jeesite.common.entity.Page;
 import com.jeesite.common.service.CrudService;
 import com.jeesite.modules.mes.entity.MesDeviceMaintenance;
 import com.jeesite.modules.mes.dao.MesDeviceMaintenanceDao;
-import com.jeesite.modules.sys.utils.UserUtils;
 
 /**
- * 设备保养Service
+ * 设备维保记录Service
  * @author mes
- * @version 2026-06-26
+ * @version 2026-06-28
  */
 @Service
 public class MesDeviceMaintenanceService extends CrudService<MesDeviceMaintenanceDao, MesDeviceMaintenance> {
@@ -52,15 +50,12 @@ public class MesDeviceMaintenanceService extends CrudService<MesDeviceMaintenanc
 
 	/**
 	 * 保存数据(插入或更新)
+	 * 维保日期、维修人等字段均由用户在表单中填写,不再自动赋值
 	 * @param mesDeviceMaintenance
 	 */
 	@Override
 	@Transactional
 	public void save(MesDeviceMaintenance mesDeviceMaintenance) {
-		if (mesDeviceMaintenance.getIsNewRecord()) {
-			mesDeviceMaintenance.setMaintenanceDate(new Date());
-			mesDeviceMaintenance.setMaintenanceUser(UserUtils.getUser().getUserName());
-		}
 		super.save(mesDeviceMaintenance);
 	}
 

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

@@ -79,7 +79,7 @@ public class MesDeviceMaintenanceController extends BaseController {
 	@ResponseBody
 	public String save(@Validated MesDeviceMaintenance mesDeviceMaintenance) {
 		mesDeviceMaintenanceService.save(mesDeviceMaintenance);
-		return renderResult(Global.TRUE, text("保存设备保养记录成功!"));
+		return renderResult(Global.TRUE, text("保存设备维保记录成功!"));
 	}
 
 	/**
@@ -90,7 +90,7 @@ public class MesDeviceMaintenanceController extends BaseController {
 	@ResponseBody
 	public String delete(MesDeviceMaintenance mesDeviceMaintenance) {
 		mesDeviceMaintenanceService.delete(mesDeviceMaintenance);
-		return renderResult(Global.TRUE, text("删除设备保养记录成功!"));
+		return renderResult(Global.TRUE, text("删除设备维保记录成功!"));
 	}
 
 }

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

@@ -20,7 +20,7 @@ s<% layout('/layouts/default.html', {title: '设备报警记录管理', libs: ['
 						<table class="table table-bordered">
 							<tr>
 								<th class="mpc-header">设备编号</th>
-								<td>${mesDeviceAlarm.deviceSn}</td>
+							<td>${mesDeviceAlarm.deviceCode}</td>
 							</tr>
 							<tr>
 								<th class="mpc-header">报警类型</th>

+ 7 - 29
src/main/resources/views/modules/mes/mesDeviceAlarmForm.html

@@ -45,38 +45,16 @@
 					</div>
 				</div>
 				<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="faultTime" 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="recoveryTime" readonly="true" maxlength="20" class="form-control laydate"
-									dataFormat="datetime" data-type="datetime" data-format="yyyy-MM-dd HH:mm"/>
-							</div>
-						</div>
-					</div>
-				</div>
-				<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="remark" maxlength="255" class="form-control"/>
-							</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">

+ 7 - 15
src/main/resources/views/modules/mes/mesDeviceAlarmInfo.html

@@ -21,21 +21,13 @@
 					<td>${mesDeviceAlarm.type}</td>
 				</tr>
 				<tr>
-					<th class="mpc-header">报警额外参数</th>
-					<td>${mesDeviceAlarm.content}</td>
-				</tr>
-				<tr>
-					<th class="mpc-header">故障发生时间</th>
-					<td>${@DateUtils.formatDate(mesDeviceAlarm.faultTime,'yyyy-MM-dd HH:mm')}</td>
-				</tr>
-				<tr>
-					<th class="mpc-header">恢复生产时间</th>
-					<td>${@DateUtils.formatDate(mesDeviceAlarm.recoveryTime,'yyyy-MM-dd HH:mm')}</td>
-				</tr>
-				<tr>
-					<th class="mpc-header">备注</th>
-					<td>${mesDeviceAlarm.remark}</td>
-				</tr>
+				<th class="mpc-header">报警额外参数</th>
+				<td>${mesDeviceAlarm.content}</td>
+			</tr>
+			<tr>
+				<th class="mpc-header">备注</th>
+				<td>${mesDeviceAlarm.remark}</td>
+			</tr>
 				<tr>
 					<th class="mpc-header">状态</th>
 					<td>${@DictUtils.getDictLabel("mes_device_alarm_state",mesDeviceAlarm.state,"未知")}</td>

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

@@ -66,7 +66,7 @@
 $('#dataGrid').dataGrid({
 	searchForm: $("#searchForm"),
 	columnModel: [
-		{header:'${text("设备编号")}', name:'deviceOnlySn', index:'b.sn', width:150, align:"center", frozen:true, formatter: function(val, obj, row, act){
+		{header:'${text("设备编号")}', name:'deviceSn', index:'b.device_code', width:150, align:"center", frozen:true, formatter: function(val, obj, row, act){
 			return '<a href="${ctx}/mes/mesDeviceAlarm/info?id='+row.id+'" class="btnList" data-title="${text("编辑设备报警记录")}">'+(val||row.id)+'</a>';
 		}},
 		{header:'${text("报警设备")}', name:'type', index:'a.type', width:150, align:"center"},
@@ -74,8 +74,6 @@ $('#dataGrid').dataGrid({
 		{header:'${text("状态")}', name:'state', index:'a.state', width:150, align:"center", formatter: function(val, obj, row, act){
 			return js.getDictLabel(${@DictUtils.getDictListJson('mes_device_alarm_state')}, val, '${text("未知")}', true);
 		}},
-		{header:'${text("故障发生时间")}', name:'faultTime', index:'a.fault_time', width:160, align:"center"},
-		{header:'${text("恢复生产时间")}', name:'recoveryTime', index:'a.recovery_time', width:160, align:"center"},
 		{header:'${text("备注")}', name:'remark', index:'a.remark', 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"},

+ 236 - 22
src/main/resources/views/modules/mes/mesDeviceMaintenanceForm.html

@@ -1,9 +1,9 @@
-<% layout('/layouts/default.html', {title: '设备保养管理', libs: ['validate','dataGrid']}){ %>
+<% layout('/layouts/default.html', {title: '设备维保记录管理', libs: ['validate','dataGrid','laydate']}){ %>
 <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(mesDeviceMaintenance.isNewRecord ? '新增设备保养记录' : '编辑设备保养记录')}
+				<i class="fa icon-note"></i> ${text(mesDeviceMaintenance.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>
@@ -17,49 +17,171 @@
 					<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>
+								<span class="required ">*</span> ${text('维保日期')}:<i class="fa icon-question hide"></i></label>
 							<div class="col-sm-8">
-								<#form:input path="name" maxlength="255" class="form-control required"/>
+								<#form:input path="maintenanceDate" id="maintenanceDate" readonly="true" maxlength="20" class="form-control required"/>
 							</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>
+								<span class="required ">*</span> ${text('设备名称')}:<i class="fa icon-question hide"></i></label>
 							<div class="col-sm-8">
-								<#form:input path="code" maxlength="100" class="form-control required"/>
+								<#form:treeselect id="deviceTreeCode" title="${text('设备')}"
+								path="deviceTreeCode" labelPath="deviceName"
+								url="${ctx}/mes/mesDevice/treeData"
+								class="form-control required"
+								allowClear="true"
+								canSelectRoot="true"
+								canSelectParent="true"
+								callbackFuncName="deviceSelectCallback"/>
 							</div>
 						</div>
 					</div>
 				</div>
 				<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:select path="maintenanceCategory" dictType="mes_device_maintenance_category" blankOption="true" class="form-control required"/>
+					<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="deviceCode" readonly="true" class="form-control"/>
+							</div>
+						</div>
+					</div>
+					<div class="col-xs-6">
+						<div class="form-group">
+							<label class="control-label col-sm-4" title="">
+								<span class="required hide">*</span> ${text('故障类别')}:<i class="fa icon-question hide"></i></label>
+							<div class="col-sm-8">
+								<#form:input path="faultCategory" maxlength="100" class="form-control"/>
+							</div>
 						</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="maintenanceStatus" dictType="mes_device_maintenance_status" blankOption="true" class="form-control required"/>
+				<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" title="">
+								<span class="required hide">*</span> ${text('故障发生时间')}:<i class="fa icon-question hide"></i></label>
+							<div class="col-sm-8">
+								<#form:input path="faultTime" id="faultTime" readonly="true" maxlength="20" 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="resumeProductionTime" id="resumeProductionTime" readonly="true" maxlength="20" class="form-control"/>
+							</div>
+						</div>
+					</div>
+				</div>
+				<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="downtime" readonly="true" class="form-control" placeholder="${text('自动计算')}"/>
+							</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="repairUser" maxlength="100" class="form-control"/>
+							</div>
+						</div>
+					</div>
+				</div>
+				<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" title="">
+								<span class="required hide">*</span> ${text('维修开始时间')}:<i class="fa icon-question hide"></i></label>
+							<div class="col-sm-8">
+								<#form:input path="repairStartTime" id="repairStartTime" readonly="true" maxlength="20" 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="repairEndTime" id="repairEndTime" readonly="true" maxlength="20" class="form-control"/>
+							</div>
+						</div>
+					</div>
+				</div>
+				<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="repairDuration" readonly="true" class="form-control" placeholder="${text('自动计算')}"/>
+							</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="quantity" maxlength="9" class="form-control digits"/>
+							</div>
+						</div>
+					</div>
+				</div>
+				<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="sparePartName" maxlength="255" class="form-control"/>
+							</div>
 						</div>
 					</div>
 				</div>
-			</div>
 				<div class="row">
 					<div class="col-xs-12">
 						<div class="form-group">
 							<label class="control-label col-sm-2" title="">
-								<span class="required hide">*</span> ${text('保养内容')}:<i class="fa icon-question hide"></i></label>
+								<span class="required hide">*</span> ${text('故障现象')}:<i class="fa icon-question hide"></i></label>
 							<div class="col-sm-10">
-								<#form:textarea path="content" rows="4" class="form-control"/>
+								<#form:textarea path="faultPhenomenon" rows="3" 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" title="">
+								<span class="required hide">*</span> ${text('维修措施')}:<i class="fa icon-question hide"></i></label>
+							<div class="col-sm-10">
+								<#form:textarea path="repairMeasure" rows="3" 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" title="">
+								<span class="required hide">*</span> ${text('根本原因分析')}:<i class="fa icon-question hide"></i></label>
+							<div class="col-sm-10">
+								<#form:textarea path="rootCauseAnalysis" rows="3" class="form-control"/>
 							</div>
 						</div>
 					</div>
@@ -70,7 +192,7 @@
 							<label class="control-label col-sm-2" title="">
 								<span class="required hide">*</span> ${text('备注')}:<i class="fa icon-question hide"></i></label>
 							<div class="col-sm-10">
-								<#form:textarea path="remarks" rows="3" class="form-control"/>
+								<#form:textarea path="remarks" rows="2" class="form-control"/>
 							</div>
 						</div>
 					</div>
@@ -91,6 +213,98 @@
 </div>
 <% } %>
 <script>
+// 设备选择回调:根据所选设备 tree_code 查询设备识别码并回填到机台号字段
+function deviceSelectCallback(id, act, index, layero, nodes) {
+	if (act == 'ok') {
+		if (nodes.length > 0) {
+			var treeCode = nodes[0].id;
+			$.ajax({
+				url: '${ctx}/mes/mesDevice/listData',
+				data: { treeCode: treeCode, pageSize: 1, pageNo: 1 },
+				dataType: 'json',
+				success: function(data) {
+					if (data.list && data.list.length > 0) {
+						$('#deviceCode').val(data.list[0].deviceCode || '');
+					}
+				}
+			});
+		}
+	} else if (act == 'clear') {
+		$('#deviceCode').val('');
+	}
+}
+
+// 计算两个时间之间的时长(格式:X小时Y分钟)
+function calcDuration(startVal, endVal) {
+	if (!startVal || !endVal) { return ''; }
+	var start = new Date(startVal.replace(/-/g, '/'));
+	var end = new Date(endVal.replace(/-/g, '/'));
+	if (isNaN(start.getTime()) || isNaN(end.getTime()) || end <= start) { return ''; }
+	var ms = end - start;
+	var totalMin = Math.floor(ms / 60000);
+	var hours = Math.floor(totalMin / 60);
+	var mins = totalMin % 60;
+	if (hours > 0 && mins > 0) {
+		return hours + '小时' + mins + '分钟';
+	} else if (hours > 0) {
+		return hours + '小时';
+	} else {
+		return mins + '分钟';
+	}
+}
+
+// 更新停机时长
+function updateDowntime() {
+	$('#downtime').val(calcDuration($('#faultTime').val(), $('#resumeProductionTime').val()));
+}
+// 更新维修时长
+function updateRepairDuration() {
+	$('#repairDuration').val(calcDuration($('#repairStartTime').val(), $('#repairEndTime').val()));
+}
+
+$(function(){
+	// 手动渲染 laydate(框架自动初始化不会触发 change 事件,改用 done 回调)
+	// 维保日期(date 类型,不参与时长计算)
+	laydate.render({
+		elem: '#maintenanceDate',
+		type: 'date',
+		format: 'yyyy-MM-dd',
+		trigger: 'click'
+	});
+	// 故障发生时间(datetime 类型,选值后自动计算停机时长)
+	laydate.render({
+		elem: '#faultTime',
+		type: 'datetime',
+		format: 'yyyy-MM-dd HH:mm:ss',
+		trigger: 'click',
+		done: function(){ updateDowntime(); }
+	});
+	// 恢复生产时间(datetime 类型,选值后自动计算停机时长)
+	laydate.render({
+		elem: '#resumeProductionTime',
+		type: 'datetime',
+		format: 'yyyy-MM-dd HH:mm:ss',
+		trigger: 'click',
+		done: function(){ updateDowntime(); }
+	});
+	// 维修开始时间(datetime 类型,选值后自动计算维修时长)
+	laydate.render({
+		elem: '#repairStartTime',
+		type: 'datetime',
+		format: 'yyyy-MM-dd HH:mm:ss',
+		trigger: 'click',
+		done: function(){ updateRepairDuration(); }
+	});
+	// 维修结束时间(datetime 类型,选值后自动计算维修时长)
+	laydate.render({
+		elem: '#repairEndTime',
+		type: 'datetime',
+		format: 'yyyy-MM-dd HH:mm:ss',
+		trigger: 'click',
+		done: function(){ updateRepairDuration(); }
+	});
+});
+
 $("#inputForm").validate({
 	submitHandler: function(form){
 		js.ajaxSubmitForm($(form), function(data){

+ 39 - 32
src/main/resources/views/modules/mes/mesDeviceMaintenanceList.html

@@ -1,14 +1,14 @@
-<% layout('/layouts/default.html', {title: '设备保养管理', 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('设备保养管理')}
+				<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:mesDeviceMaintenance:edit')){ %>
-					<a href="${ctx}/mes/mesDeviceMaintenance/form" class="btn btn-default btnTool" title="${text('新增设备保养记录')}"><i class="fa fa-plus"></i> ${text('新增')}</a>
+					<a href="${ctx}/mes/mesDeviceMaintenance/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>
@@ -17,33 +17,34 @@
 			<#form:form id="searchForm" model="${mesDeviceMaintenance}" action="${ctx}/mes/mesDeviceMaintenance/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>
+					<label class="control-label">${text('维保日期')}:</label>
 					<div class="control-inline">
-						<#form:input path="name" maxlength="255" class="form-control width-120"/>
+						<#form:input path="maintenanceDate" readonly="true" maxlength="20" class="form-control laydate width-120"
+							dataFormat="date" data-type="date" data-format="yyyy-MM-dd"/>
 					</div>
 				</div>
 				<div class="form-group">
-					<label class="control-label">${text('编号')}:</label>
-					<div class="control-inline">
-						<#form:input path="code" maxlength="100" class="form-control width-120"/>
-					</div>
-				</div>
-				<div class="form-group">
-					<label class="control-label">${text('保养类别')}:</label>
-					<div class="control-inline">
-						<#form:select path="maintenanceCategory" dictType="mes_device_maintenance_category" class="form-control width-120"/>
+					<label class="control-label">${text('设备名称')}:</label>
+					<div class="control-inline width-120">
+						<#form:treeselect id="searchDeviceTreeCode" title="${text('设备')}"
+						path="deviceTreeCode" labelPath="deviceName"
+						url="${ctx}/mes/mesDevice/treeData"
+						class="form-control"
+						allowClear="true"
+						canSelectRoot="true"
+						canSelectParent="true"/>
 					</div>
 				</div>
 				<div class="form-group">
-					<label class="control-label">${text('保养人')}:</label>
+					<label class="control-label">${text('故障类别')}:</label>
 					<div class="control-inline">
-						<#form:input path="maintenanceUser" maxlength="100" class="form-control width-120"/>
+						<#form:input path="faultCategory" maxlength="100" class="form-control width-120"/>
 					</div>
 				</div>
 				<div class="form-group">
-					<label class="control-label">${text('保养状态')}:</label>
+					<label class="control-label">${text('维修人')}:</label>
 					<div class="control-inline">
-						<#form:select path="maintenanceStatus" dictType="mes_device_maintenance_status" class="form-control width-120"/>
+						<#form:input path="repairUser" maxlength="100" class="form-control width-120"/>
 					</div>
 				</div>
 				<div class="form-group">
@@ -62,23 +63,29 @@
 $('#dataGrid').dataGrid({
 	searchForm: $("#searchForm"),
 	columnModel: [
-		{header:'${text("名称")}', name:'name', index:'a.name', width:150, align:"center"},
-		{header:'${text("编号")}', name:'code', index:'a.code', width:150, align:"center"},
-		{header:'${text("保养类别")}', name:'maintenanceCategory', index:'a.maintenance_category', width:120, align:"center", formatter: function(val){
-			return js.getDictLabel(${@DictUtils.getDictListJson('mes_device_maintenance_category')}, val, '${text("未知")}', true);
-		}},
-		{header:'${text("保养日期")}', name:'maintenanceDate', index:'a.maintenance_date', width:150, align:"center"},
-		{header:'${text("保养内容")}', name:'content', index:'a.content', width:200, align:"center"},
-		{header:'${text("保养人")}', name:'maintenanceUser', index:'a.maintenance_user', width:120, align:"center"},
-		{header:'${text("保养状态")}', name:'maintenanceStatus', index:'a.maintenance_status', width:100, align:"center", formatter: function(val){
-			return js.getDictLabel(${@DictUtils.getDictListJson('mes_device_maintenance_status')}, val, '${text("未知")}', true);
+		{header:'${text("维保日期")}', name:'maintenanceDate', index:'a.maintenance_date', width:110, align:"center", formatter: function(val){
+			return val ? val.substring(0,10) : '';
 		}},
-		{header:'${text("备注")}', name:'remarks', index:'a.remarks', width:150, align:"center"},
-		{header:'${text("操作")}', name:'actions', width:120, formatter: function(val, obj, row, act){
+		{header:'${text("设备名称")}', name:'deviceName', index:'b.tree_name', width:150, align:"center"},
+		{header:'${text("机台号")}', name:'deviceCode', index:'b.device_code', width:120, align:"center"},
+		{header:'${text("故障发生时间")}', name:'faultTime', index:'a.fault_time', width:150, align:"center"},
+		{header:'${text("恢复生产时间")}', name:'resumeProductionTime', index:'a.resume_production_time', width:150, align:"center"},
+		{header:'${text("停机时长")}', name:'downtime', index:'a.downtime', width:100, align:"center"},
+		{header:'${text("维修开始时间")}', name:'repairStartTime', index:'a.repair_start_time', width:150, align:"center"},
+		{header:'${text("维修结束时间")}', name:'repairEndTime', index:'a.repair_end_time', width:150, align:"center"},
+		{header:'${text("维修时长")}', name:'repairDuration', index:'a.repair_duration', width:100, align:"center"},
+		{header:'${text("故障现象")}', name:'faultPhenomenon', index:'a.fault_phenomenon', width:200, align:"center"},
+		{header:'${text("维修措施")}', name:'repairMeasure', index:'a.repair_measure', width:200, align:"center"},
+		{header:'${text("故障类别")}', name:'faultCategory', index:'a.fault_category', width:100, align:"center"},
+		{header:'${text("根本原因分析")}', name:'rootCauseAnalysis', index:'a.root_cause_analysis', width:200, align:"center"},
+		{header:'${text("备件名称")}', name:'sparePartName', index:'a.spare_part_name', width:120, align:"center"},
+		{header:'${text("数量")}', name:'quantity', index:'a.quantity', width:60, align:"center"},
+		{header:'${text("维修人")}', name:'repairUser', index:'a.repair_user', width:100, align:"center"},
+		{header:'${text("操作")}', name:'actions', width:120, fixed:true, formatter: function(val, obj, row, act){
 			var actions = [];
 			//<% if(hasPermi('mes:mesDeviceMaintenance:edit')){ %>
-				actions.push('<a href="${ctx}/mes/mesDeviceMaintenance/form?id='+row.id+'" class="btnList" title="${text("编辑设备保养记录")}"><i class="fa fa-pencil"></i></a>&nbsp;');
-				actions.push('<a href="${ctx}/mes/mesDeviceMaintenance/delete?id='+row.id+'" class="btnList" title="${text("删除设备保养记录")}" data-confirm="${text("确认要删除该设备保养记录吗?")}"><i class="fa fa-trash-o"></i></a>&nbsp;');
+				actions.push('<a href="${ctx}/mes/mesDeviceMaintenance/form?id='+row.id+'" class="btnList" title="${text("编辑设备维保记录")}"><i class="fa fa-pencil"></i></a>&nbsp;');
+				actions.push('<a href="${ctx}/mes/mesDeviceMaintenance/delete?id='+row.id+'" class="btnList" title="${text("删除设备维保记录")}" data-confirm="${text("确认要删除该设备维保记录吗?")}"><i class="fa fa-trash-o"></i></a>&nbsp;');
 			//<% } %>
 			return actions.join('');
 		}}