feat(base): 添加工单执行状态跟踪和工艺快照功能

- 在BaseOrderInfo实体类中新增执行状态、生产时间、操作员、实际完工数量等字段
- 实现工单开始生产、完工提报、数量更新等生产执行相关接口
- 添加按工单编号查询、获取运行中工单等功能
- 新增ProcessSnapshot实体类用于记录设备参数快照
- 实现工艺快照的创建、查询、对比、备份等管理功能
- 在工单管理中集成设备编号和执行状态过滤条件
- 完善工单信息的数据库映射和增删改查操作
master
zangch@mesnac.com 2 weeks ago
parent 51de048067
commit 481cb96885

@ -13,6 +13,7 @@ import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.aucma.common.annotation.Log;
import com.aucma.common.core.controller.BaseController;
@ -98,4 +99,68 @@ public class BaseOrderInfoController extends BaseController {
public AjaxResult remove(@PathVariable Long[] objIds) {
return toAjax(baseOrderInfoService.deleteBaseOrderInfoByObjIds(objIds));
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('base:orderInfo:query')")
@GetMapping("/byCode/{orderCode}")
public AjaxResult getByOrderCode(@PathVariable("orderCode") String orderCode) {
return success(baseOrderInfoService.selectBaseOrderInfoByOrderCode(orderCode));
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('base:orderInfo:start')")
@Log(title = "工单执行", businessType = BusinessType.UPDATE)
@PostMapping("/startProduction")
public AjaxResult startProduction(@RequestParam String orderCode, @RequestParam String operator) {
int result = baseOrderInfoService.startProduction(orderCode, operator);
return result > 0 ? success("开始生产成功") : error("工单不存在");
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('base:orderInfo:complete')")
@Log(title = "工单执行", businessType = BusinessType.UPDATE)
@PostMapping("/completeProduction")
public AjaxResult completeProduction(@RequestParam String orderCode,
@RequestParam Long completeQty,
@RequestParam Long defectQty) {
int result = baseOrderInfoService.completeProduction(orderCode, completeQty, defectQty);
return result > 0 ? success("完工提报成功") : error("工单不存在");
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('base:orderInfo:updateQty')")
@Log(title = "工单执行", businessType = BusinessType.UPDATE)
@PostMapping("/updateQuantity")
public AjaxResult updateQuantity(@RequestParam String orderCode,
@RequestParam Long completeQty,
@RequestParam Long defectQty) {
int result = baseOrderInfoService.updateQuantity(orderCode, completeQty, defectQty);
return result > 0 ? success("更新数量成功") : error("工单不存在");
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('base:orderInfo:list')")
@GetMapping("/running")
public AjaxResult getRunningOrders() {
return success(baseOrderInfoService.getRunningOrders());
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('base:orderInfo:query')")
@GetMapping("/running/{deviceCode}")
public AjaxResult getRunningOrderByDevice(@PathVariable String deviceCode) {
return success(baseOrderInfoService.getRunningOrderByDevice(deviceCode));
}
}

@ -0,0 +1,178 @@
package com.aucma.base.controller;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.aucma.common.annotation.Log;
import com.aucma.common.core.controller.BaseController;
import com.aucma.common.core.domain.AjaxResult;
import com.aucma.common.enums.BusinessType;
import com.aucma.base.domain.ProcessSnapshot;
import com.aucma.base.service.IProcessSnapshotService;
import com.aucma.common.utils.poi.ExcelUtil;
import com.aucma.common.core.page.TableDataInfo;
/**
* Controller
*
* @author Cascade
* @date 2026-01-19
*/
@RestController
@RequestMapping("/base/processSnapshot")
public class ProcessSnapshotController extends BaseController {
@Autowired
private IProcessSnapshotService processSnapshotService;
/**
*
*/
@PreAuthorize("@ss.hasPermi('base:processSnapshot:list')")
@GetMapping("/list")
public TableDataInfo list(ProcessSnapshot processSnapshot) {
startPage();
List<ProcessSnapshot> list = processSnapshotService.selectProcessSnapshotList(processSnapshot);
return getDataTable(list);
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('base:processSnapshot:export')")
@Log(title = "工艺快照", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, ProcessSnapshot processSnapshot) {
List<ProcessSnapshot> list = processSnapshotService.selectProcessSnapshotList(processSnapshot);
ExcelUtil<ProcessSnapshot> util = new ExcelUtil<ProcessSnapshot>(ProcessSnapshot.class);
util.exportExcel(response, list, "工艺快照数据");
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('base:processSnapshot:query')")
@GetMapping("/detail/{snapshotId}")
public AjaxResult detail(@PathVariable("snapshotId") Long snapshotId) {
return success(processSnapshotService.selectSnapshotDetail(snapshotId));
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('base:processSnapshot:query')")
@GetMapping(value = "/{snapshotId}")
public AjaxResult getInfo(@PathVariable("snapshotId") Long snapshotId) {
return success(processSnapshotService.selectProcessSnapshotBySnapshotId(snapshotId));
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('base:processSnapshot:add')")
@Log(title = "工艺快照", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody ProcessSnapshot processSnapshot) {
return toAjax(processSnapshotService.insertProcessSnapshot(processSnapshot));
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('base:processSnapshot:edit')")
@Log(title = "工艺快照", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody ProcessSnapshot processSnapshot) {
return toAjax(processSnapshotService.updateProcessSnapshot(processSnapshot));
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('base:processSnapshot:remove')")
@Log(title = "工艺快照", businessType = BusinessType.DELETE)
@DeleteMapping("/{snapshotIds}")
public AjaxResult remove(@PathVariable Long[] snapshotIds) {
return toAjax(processSnapshotService.deleteProcessSnapshotBySnapshotIds(snapshotIds));
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('base:processSnapshot:query')")
@GetMapping("/compare")
public AjaxResult compare(@RequestParam("snapshotId1") Long snapshotId1,
@RequestParam("snapshotId2") Long snapshotId2) {
List<Map<String, Object>> result = processSnapshotService.compareSnapshots(snapshotId1, snapshotId2);
if (result == null) {
return error("快照不存在或设备不一致,无法对比");
}
return success(result);
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('base:processSnapshot:createBackup')")
@Log(title = "调试备份", businessType = BusinessType.INSERT)
@PostMapping("/createBackup")
public AjaxResult createBackup(@RequestParam String deviceCode,
@RequestParam String moldCode,
@RequestParam String productCode,
@RequestParam String backupName) {
int result = processSnapshotService.createDebugBackup(deviceCode, moldCode, productCode, backupName);
return result > 0 ? success("备份创建成功") : error("备份创建失败");
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('base:processSnapshot:list')")
@GetMapping("/backupList")
public AjaxResult getBackupList(@RequestParam(required = false) String moldCode,
@RequestParam(required = false) String deviceCode,
@RequestParam(required = false) String productCode) {
return success(processSnapshotService.getDebugBackups(moldCode, deviceCode, productCode));
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('base:processSnapshot:query')")
@GetMapping("/defaultBackup")
public AjaxResult getDefaultBackup(@RequestParam String moldCode,
@RequestParam String deviceCode,
@RequestParam String productCode) {
return success(processSnapshotService.getDefaultBackup(moldCode, deviceCode, productCode));
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('base:processSnapshot:setDefault')")
@Log(title = "调试备份", businessType = BusinessType.UPDATE)
@PutMapping("/setDefault/{snapshotId}")
public AjaxResult setDefaultBackup(@PathVariable Long snapshotId) {
int result = processSnapshotService.setDefaultBackup(snapshotId);
return result > 0 ? success("设置成功") : error("备份不存在");
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('base:processSnapshot:query')")
@GetMapping("/applyBackup/{snapshotId}")
public AjaxResult applyBackup(@PathVariable Long snapshotId) {
return success(processSnapshotService.applyDebugBackup(snapshotId));
}
}

@ -168,6 +168,50 @@ public class BaseOrderInfo extends BaseEntity {
*/
private String manualUpdateFlag;
/**
* PENDING-/RUNNING-/COMPLETED-/PAUSED-
*/
@Excel(name = "执行状态")
private String executionStatus;
/**
*
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "开始生产时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date startTime;
/**
*
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "完工时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date finishTime;
/**
*
*/
@Excel(name = "操作员")
private String executionOperator;
/**
*
*/
@Excel(name = "实际完工数量")
private Long actualCompleteQty;
/**
*
*/
@Excel(name = "实际不良数量")
private Long actualDefectQty;
/**
* /
*/
@Excel(name = "设备编号")
private String deviceCode;
public Long getReplaceAmount() {
return replaceAmount;
}
@ -184,6 +228,62 @@ public class BaseOrderInfo extends BaseEntity {
this.manualUpdateFlag = manualUpdateFlag;
}
public String getExecutionStatus() {
return executionStatus;
}
public void setExecutionStatus(String executionStatus) {
this.executionStatus = executionStatus;
}
public Date getStartTime() {
return startTime;
}
public void setStartTime(Date startTime) {
this.startTime = startTime;
}
public Date getFinishTime() {
return finishTime;
}
public void setFinishTime(Date finishTime) {
this.finishTime = finishTime;
}
public String getExecutionOperator() {
return executionOperator;
}
public void setExecutionOperator(String executionOperator) {
this.executionOperator = executionOperator;
}
public Long getActualCompleteQty() {
return actualCompleteQty;
}
public void setActualCompleteQty(Long actualCompleteQty) {
this.actualCompleteQty = actualCompleteQty;
}
public Long getActualDefectQty() {
return actualDefectQty;
}
public void setActualDefectQty(Long actualDefectQty) {
this.actualDefectQty = actualDefectQty;
}
public String getDeviceCode() {
return deviceCode;
}
public void setDeviceCode(String deviceCode) {
this.deviceCode = deviceCode;
}
public String getWorkCenterCode() {
return workCenterCode;
}
@ -391,6 +491,13 @@ public class BaseOrderInfo extends BaseEntity {
.append("updatedBy", getUpdatedBy())
.append("updatedTime", getUpdatedTime())
.append("completeDate", getCompleteDate())
.append("executionStatus", getExecutionStatus())
.append("startTime", getStartTime())
.append("finishTime", getFinishTime())
.append("executionOperator", getExecutionOperator())
.append("actualCompleteQty", getActualCompleteQty())
.append("actualDefectQty", getActualDefectQty())
.append("deviceCode", getDeviceCode())
.toString();
}
}

@ -0,0 +1,182 @@
package com.aucma.base.domain;
import java.util.Date;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.aucma.common.annotation.Excel;
import com.aucma.common.core.domain.BaseEntity;
/**
* process_snapshot
*
* @author Cascade
* @date 2026-01-19
*/
public class ProcessSnapshot extends BaseEntity {
private static final long serialVersionUID = 1L;
/** 快照ID */
private Long snapshotId;
/** 设备编号 */
@Excel(name = "设备编号")
private String deviceCode;
/** 设备名称(非表字段,关联查询) */
@Excel(name = "设备名称")
private String deviceName;
/** 快照时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "快照时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date snapshotTime;
/** 快照类型START-开始生产/END-结束生产/MANUAL-手动创建/CHANGE-参数变化 */
@Excel(name = "快照类型")
private String snapshotType;
/** 关联工单号 */
@Excel(name = "工单号")
private String orderCode;
/** 删除标志 */
private String isFlag;
/** 模具编号(调试备份专用) */
@Excel(name = "模具编号")
private String moldCode;
/** 产品编号(调试备份专用) */
@Excel(name = "产品编号")
private String productCode;
/** 备份名称(调试备份专用) */
@Excel(name = "备份名称")
private String backupName;
/** 是否默认备份1-是/0-否(调试备份专用) */
private String isDefault;
/** 快照详情参数列表(非表字段) */
private List<BaseDeviceParamVal> paramList;
public void setSnapshotId(Long snapshotId) {
this.snapshotId = snapshotId;
}
public Long getSnapshotId() {
return snapshotId;
}
public void setDeviceCode(String deviceCode) {
this.deviceCode = deviceCode;
}
public String getDeviceCode() {
return deviceCode;
}
public void setDeviceName(String deviceName) {
this.deviceName = deviceName;
}
public String getDeviceName() {
return deviceName;
}
public void setSnapshotTime(Date snapshotTime) {
this.snapshotTime = snapshotTime;
}
public Date getSnapshotTime() {
return snapshotTime;
}
public void setSnapshotType(String snapshotType) {
this.snapshotType = snapshotType;
}
public String getSnapshotType() {
return snapshotType;
}
public void setOrderCode(String orderCode) {
this.orderCode = orderCode;
}
public String getOrderCode() {
return orderCode;
}
public void setIsFlag(String isFlag) {
this.isFlag = isFlag;
}
public String getIsFlag() {
return isFlag;
}
public String getMoldCode() {
return moldCode;
}
public void setMoldCode(String moldCode) {
this.moldCode = moldCode;
}
public String getProductCode() {
return productCode;
}
public void setProductCode(String productCode) {
this.productCode = productCode;
}
public String getBackupName() {
return backupName;
}
public void setBackupName(String backupName) {
this.backupName = backupName;
}
public String getIsDefault() {
return isDefault;
}
public void setIsDefault(String isDefault) {
this.isDefault = isDefault;
}
public List<BaseDeviceParamVal> getParamList() {
return paramList;
}
public void setParamList(List<BaseDeviceParamVal> paramList) {
this.paramList = paramList;
}
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("snapshotId", getSnapshotId())
.append("deviceCode", getDeviceCode())
.append("deviceName", getDeviceName())
.append("snapshotTime", getSnapshotTime())
.append("snapshotType", getSnapshotType())
.append("orderCode", getOrderCode())
.append("remark", getRemark())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("isFlag", getIsFlag())
.append("moldCode", getMoldCode())
.append("productCode", getProductCode())
.append("backupName", getBackupName())
.append("isDefault", getIsDefault())
.toString();
}
}

@ -0,0 +1,86 @@
package com.aucma.base.mapper;
import java.util.Date;
import java.util.List;
import java.util.Map;
import com.aucma.base.domain.ProcessSnapshot;
import com.aucma.base.domain.BaseDeviceParamVal;
import org.apache.ibatis.annotations.Param;
/**
* Mapper
*
* @author Cascade
* @date 2026-01-19
*/
public interface ProcessSnapshotMapper {
/**
*
*
* @param snapshotId ID
* @return
*/
public ProcessSnapshot selectProcessSnapshotBySnapshotId(Long snapshotId);
/**
*
*
* @param processSnapshot
* @return
*/
public List<ProcessSnapshot> selectProcessSnapshotList(ProcessSnapshot processSnapshot);
/**
*
*
* @param processSnapshot
* @return
*/
public int insertProcessSnapshot(ProcessSnapshot processSnapshot);
/**
*
*
* @param processSnapshot
* @return
*/
public int updateProcessSnapshot(ProcessSnapshot processSnapshot);
/**
*
*
* @param snapshotId ID
* @return
*/
public int deleteProcessSnapshotBySnapshotId(Long snapshotId);
/**
*
*
* @param snapshotIds ID
* @return
*/
public int deleteProcessSnapshotBySnapshotIds(Long[] snapshotIds);
/**
*
*
* @param deviceCode
* @param snapshotTime
* @return
*/
public List<BaseDeviceParamVal> selectParamsBySnapshotTime(@Param("deviceCode") String deviceCode,
@Param("snapshotTime") Date snapshotTime);
/**
*
*
* @param deviceCode
* @param snapshotTime1 1
* @param snapshotTime2 2
* @return
*/
public List<Map<String, Object>> compareSnapshots(@Param("deviceCode") String deviceCode,
@Param("snapshotTime1") Date snapshotTime1,
@Param("snapshotTime2") Date snapshotTime2);
}

@ -66,4 +66,56 @@ public interface IBaseOrderInfoService {
* @return
*/
public int deleteBaseOrderInfoByObjId(Long objId);
/**
*
*
* @param orderCode
* @return
*/
public BaseOrderInfo selectBaseOrderInfoByOrderCode(String orderCode);
/**
*
*
* @param orderCode
* @param operator
* @return
*/
public int startProduction(String orderCode, String operator);
/**
*
*
* @param orderCode
* @param completeQty
* @param defectQty
* @return
*/
public int completeProduction(String orderCode, Long completeQty, Long defectQty);
/**
*
*
* @param orderCode
* @param completeQty
* @param defectQty
* @return
*/
public int updateQuantity(String orderCode, Long completeQty, Long defectQty);
/**
*
*
* @return
*/
public List<BaseOrderInfo> getRunningOrders();
/**
*
*
* @param deviceCode
* @return
*/
public BaseOrderInfo getRunningOrderByDevice(String deviceCode);
}

@ -0,0 +1,126 @@
package com.aucma.base.service;
import java.util.List;
import java.util.Map;
import com.aucma.base.domain.ProcessSnapshot;
import com.aucma.base.domain.BaseDeviceParamVal;
/**
* Service
*
* @author Cascade
* @date 2026-01-19
*/
public interface IProcessSnapshotService {
/**
*
*
* @param snapshotId ID
* @return
*/
public ProcessSnapshot selectProcessSnapshotBySnapshotId(Long snapshotId);
/**
*
*
* @param processSnapshot
* @return
*/
public List<ProcessSnapshot> selectProcessSnapshotList(ProcessSnapshot processSnapshot);
/**
*
*
* @param processSnapshot
* @return
*/
public int insertProcessSnapshot(ProcessSnapshot processSnapshot);
/**
*
*
* @param processSnapshot
* @return
*/
public int updateProcessSnapshot(ProcessSnapshot processSnapshot);
/**
*
*
* @param snapshotId ID
* @return
*/
public int deleteProcessSnapshotBySnapshotId(Long snapshotId);
/**
*
*
* @param snapshotIds ID
* @return
*/
public int deleteProcessSnapshotBySnapshotIds(Long[] snapshotIds);
/**
*
*
* @param snapshotId ID
* @return
*/
public ProcessSnapshot selectSnapshotDetail(Long snapshotId);
/**
*
*
* @param snapshotId1 ID1
* @param snapshotId2 ID2
* @return
*/
public List<Map<String, Object>> compareSnapshots(Long snapshotId1, Long snapshotId2);
/**
*
*
* @param deviceCode
* @param moldCode
* @param productCode
* @param backupName
* @return
*/
public int createDebugBackup(String deviceCode, String moldCode, String productCode, String backupName);
/**
*
*
* @param moldCode
* @param deviceCode
* @param productCode
* @return
*/
public List<ProcessSnapshot> getDebugBackups(String moldCode, String deviceCode, String productCode);
/**
*
*
* @param moldCode
* @param deviceCode
* @param productCode
* @return
*/
public ProcessSnapshot getDefaultBackup(String moldCode, String deviceCode, String productCode);
/**
*
*
* @param snapshotId ID
* @return
*/
public int setDefaultBackup(Long snapshotId);
/**
*
*
* @param snapshotId ID
* @return
*/
public ProcessSnapshot applyDebugBackup(Long snapshotId);
}

@ -1,5 +1,6 @@
package com.aucma.base.service.impl;
import java.util.Date;
import java.util.List;
import com.aucma.common.utils.DateUtils;
@ -98,4 +99,85 @@ public class BaseOrderInfoServiceImpl implements IBaseOrderInfoService {
public int deleteBaseOrderInfoByObjId(Long objId) {
return baseOrderInfoMapper.deleteBaseOrderInfoByObjId(objId);
}
/**
*
*/
@Override
public BaseOrderInfo selectBaseOrderInfoByOrderCode(String orderCode) {
BaseOrderInfo query = new BaseOrderInfo();
query.setOrderCode(orderCode);
List<BaseOrderInfo> list = baseOrderInfoMapper.selectAllOrderInfoList(query);
return list != null && !list.isEmpty() ? list.get(0) : null;
}
/**
*
*/
@Override
public int startProduction(String orderCode, String operator) {
BaseOrderInfo order = selectBaseOrderInfoByOrderCode(orderCode);
if (order == null) {
return 0;
}
order.setExecutionStatus("RUNNING");
order.setStartTime(new Date());
order.setExecutionOperator(operator);
order.setUpdatedTime(DateUtils.getNowDate());
return baseOrderInfoMapper.updateBaseOrderInfo(order);
}
/**
*
*/
@Override
public int completeProduction(String orderCode, Long completeQty, Long defectQty) {
BaseOrderInfo order = selectBaseOrderInfoByOrderCode(orderCode);
if (order == null) {
return 0;
}
order.setExecutionStatus("COMPLETED");
order.setFinishTime(new Date());
order.setActualCompleteQty(completeQty);
order.setActualDefectQty(defectQty);
order.setUpdatedTime(DateUtils.getNowDate());
return baseOrderInfoMapper.updateBaseOrderInfo(order);
}
/**
*
*/
@Override
public int updateQuantity(String orderCode, Long completeQty, Long defectQty) {
BaseOrderInfo order = selectBaseOrderInfoByOrderCode(orderCode);
if (order == null) {
return 0;
}
order.setActualCompleteQty(completeQty);
order.setActualDefectQty(defectQty);
order.setUpdatedTime(DateUtils.getNowDate());
return baseOrderInfoMapper.updateBaseOrderInfo(order);
}
/**
*
*/
@Override
public List<BaseOrderInfo> getRunningOrders() {
BaseOrderInfo query = new BaseOrderInfo();
query.setExecutionStatus("RUNNING");
return baseOrderInfoMapper.selectAllOrderInfoList(query);
}
/**
*
*/
@Override
public BaseOrderInfo getRunningOrderByDevice(String deviceCode) {
BaseOrderInfo query = new BaseOrderInfo();
query.setDeviceCode(deviceCode);
query.setExecutionStatus("RUNNING");
List<BaseOrderInfo> list = baseOrderInfoMapper.selectAllOrderInfoList(query);
return list != null && !list.isEmpty() ? list.get(0) : null;
}
}

@ -0,0 +1,188 @@
package com.aucma.base.service.impl;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.aucma.base.mapper.ProcessSnapshotMapper;
import com.aucma.base.domain.ProcessSnapshot;
import com.aucma.base.domain.BaseDeviceParamVal;
import com.aucma.base.service.IProcessSnapshotService;
import com.aucma.common.utils.DateUtils;
import com.aucma.common.utils.SecurityUtils;
/**
* Service
*
* @author Cascade
* @date 2026-01-19
*/
@Service
public class ProcessSnapshotServiceImpl implements IProcessSnapshotService {
@Autowired
private ProcessSnapshotMapper processSnapshotMapper;
@Override
public ProcessSnapshot selectProcessSnapshotBySnapshotId(Long snapshotId) {
return processSnapshotMapper.selectProcessSnapshotBySnapshotId(snapshotId);
}
@Override
public List<ProcessSnapshot> selectProcessSnapshotList(ProcessSnapshot processSnapshot) {
return processSnapshotMapper.selectProcessSnapshotList(processSnapshot);
}
@Override
public int insertProcessSnapshot(ProcessSnapshot processSnapshot) {
if (processSnapshot.getSnapshotTime() == null) {
processSnapshot.setSnapshotTime(new Date());
}
if (processSnapshot.getIsFlag() == null || processSnapshot.getIsFlag().isEmpty()) {
processSnapshot.setIsFlag("1");
}
processSnapshot.setCreateBy(SecurityUtils.getUsername());
processSnapshot.setCreateTime(DateUtils.getNowDate());
return processSnapshotMapper.insertProcessSnapshot(processSnapshot);
}
@Override
public int updateProcessSnapshot(ProcessSnapshot processSnapshot) {
processSnapshot.setUpdateBy(SecurityUtils.getUsername());
processSnapshot.setUpdateTime(DateUtils.getNowDate());
return processSnapshotMapper.updateProcessSnapshot(processSnapshot);
}
@Override
public int deleteProcessSnapshotBySnapshotId(Long snapshotId) {
return processSnapshotMapper.deleteProcessSnapshotBySnapshotId(snapshotId);
}
@Override
public int deleteProcessSnapshotBySnapshotIds(Long[] snapshotIds) {
return processSnapshotMapper.deleteProcessSnapshotBySnapshotIds(snapshotIds);
}
@Override
public ProcessSnapshot selectSnapshotDetail(Long snapshotId) {
ProcessSnapshot snapshot = processSnapshotMapper.selectProcessSnapshotBySnapshotId(snapshotId);
if (snapshot != null && snapshot.getDeviceCode() != null && snapshot.getSnapshotTime() != null) {
List<BaseDeviceParamVal> paramList = processSnapshotMapper.selectParamsBySnapshotTime(
snapshot.getDeviceCode(), snapshot.getSnapshotTime());
snapshot.setParamList(paramList);
}
return snapshot;
}
@Override
public List<Map<String, Object>> compareSnapshots(Long snapshotId1, Long snapshotId2) {
ProcessSnapshot snapshot1 = processSnapshotMapper.selectProcessSnapshotBySnapshotId(snapshotId1);
ProcessSnapshot snapshot2 = processSnapshotMapper.selectProcessSnapshotBySnapshotId(snapshotId2);
if (snapshot1 == null || snapshot2 == null) {
return null;
}
if (!snapshot1.getDeviceCode().equals(snapshot2.getDeviceCode())) {
return null;
}
return processSnapshotMapper.compareSnapshots(
snapshot1.getDeviceCode(),
snapshot1.getSnapshotTime(),
snapshot2.getSnapshotTime());
}
/**
*
*/
@Override
public int createDebugBackup(String deviceCode, String moldCode, String productCode, String backupName) {
ProcessSnapshot snapshot = new ProcessSnapshot();
snapshot.setDeviceCode(deviceCode);
snapshot.setSnapshotTime(new Date());
snapshot.setSnapshotType("BACKUP");
snapshot.setMoldCode(moldCode);
snapshot.setProductCode(productCode);
snapshot.setBackupName(backupName);
snapshot.setIsDefault("0");
snapshot.setIsFlag("1");
snapshot.setCreateBy(SecurityUtils.getUsername());
snapshot.setCreateTime(DateUtils.getNowDate());
return processSnapshotMapper.insertProcessSnapshot(snapshot);
}
/**
*
*/
@Override
public List<ProcessSnapshot> getDebugBackups(String moldCode, String deviceCode, String productCode) {
ProcessSnapshot query = new ProcessSnapshot();
query.setSnapshotType("BACKUP");
if (moldCode != null && !moldCode.isEmpty()) {
query.setMoldCode(moldCode);
}
if (deviceCode != null && !deviceCode.isEmpty()) {
query.setDeviceCode(deviceCode);
}
if (productCode != null && !productCode.isEmpty()) {
query.setProductCode(productCode);
}
return processSnapshotMapper.selectProcessSnapshotList(query);
}
/**
*
*/
@Override
public ProcessSnapshot getDefaultBackup(String moldCode, String deviceCode, String productCode) {
ProcessSnapshot query = new ProcessSnapshot();
query.setSnapshotType("BACKUP");
query.setMoldCode(moldCode);
query.setDeviceCode(deviceCode);
query.setProductCode(productCode);
query.setIsDefault("1");
List<ProcessSnapshot> list = processSnapshotMapper.selectProcessSnapshotList(query);
return list != null && !list.isEmpty() ? list.get(0) : null;
}
/**
*
*/
@Override
public int setDefaultBackup(Long snapshotId) {
ProcessSnapshot current = processSnapshotMapper.selectProcessSnapshotBySnapshotId(snapshotId);
if (current == null || !"BACKUP".equals(current.getSnapshotType())) {
return 0;
}
// 取消其他备份的默认状态
ProcessSnapshot query = new ProcessSnapshot();
query.setSnapshotType("BACKUP");
query.setMoldCode(current.getMoldCode());
query.setDeviceCode(current.getDeviceCode());
query.setProductCode(current.getProductCode());
query.setIsDefault("1");
List<ProcessSnapshot> defaultList = processSnapshotMapper.selectProcessSnapshotList(query);
for (ProcessSnapshot ps : defaultList) {
ps.setIsDefault("0");
ps.setUpdateBy(SecurityUtils.getUsername());
ps.setUpdateTime(DateUtils.getNowDate());
processSnapshotMapper.updateProcessSnapshot(ps);
}
// 设置当前备份为默认
current.setIsDefault("1");
current.setUpdateBy(SecurityUtils.getUsername());
current.setUpdateTime(DateUtils.getNowDate());
return processSnapshotMapper.updateProcessSnapshot(current);
}
/**
*
*/
@Override
public ProcessSnapshot applyDebugBackup(Long snapshotId) {
return selectSnapshotDetail(snapshotId);
}
}

@ -29,6 +29,13 @@
<result property="workCenterCode" column="work_center_code"/>
<result property="routingCode" column="routing_code"/>
<result property="manualUpdateFlag" column="manual_update_flag"/>
<result property="executionStatus" column="execution_status"/>
<result property="startTime" column="start_time"/>
<result property="finishTime" column="finish_time"/>
<result property="executionOperator" column="execution_operator"/>
<result property="actualCompleteQty" column="actual_complete_qty"/>
<result property="actualDefectQty" column="actual_defect_qty"/>
<result property="deviceCode" column="device_code"/>
</resultMap>
<sql id="selectBaseOrderInfoVo">
@ -51,6 +58,13 @@
oi.work_center_code,
oi.routing_code,
oi.manual_update_flag,
oi.execution_status,
oi.start_time,
oi.finish_time,
oi.execution_operator,
oi.actual_complete_qty,
oi.actual_defect_qty,
oi.device_code,
oi.created_by,
oi.created_time,
oi.updated_by,
@ -79,6 +93,8 @@
<if test="orderStatus != null and orderStatus != '' and orderStatus != 'RELCRTD'">and oi.order_status LIKE #{orderStatus} || '%'</if>
<if test="orderStatus != null and orderStatus != '' and orderStatus == 'RELCRTD'">and (oi.order_status LIKE 'REL%' OR oi.order_status LIKE 'CRTD%')</if>
<if test="manualUpdateFlag != null and manualUpdateFlag != ''">and oi.manual_update_flag = #{manualUpdateFlag}</if>
<if test="executionStatus != null and executionStatus != ''">and oi.execution_status = #{executionStatus}</if>
<if test="deviceCode != null and deviceCode != ''">and oi.device_code = #{deviceCode}</if>
<if test="beginDate != null ">and oi.begin_date = #{beginDate}</if>
<if test="endDate != null ">and oi.end_date = #{endDate}</if>
<if test="factoryCode != null and factoryCode != ''">and oi.factory_code = #{factoryCode}</if>
@ -146,6 +162,13 @@
<if test="workCenterCode != null">work_center_code,</if>
<if test="routingCode != null">routing_code,</if>
<if test="manualUpdateFlag != null">manual_update_flag,</if>
<if test="executionStatus != null">execution_status,</if>
<if test="startTime != null">start_time,</if>
<if test="finishTime != null">finish_time,</if>
<if test="executionOperator != null">execution_operator,</if>
<if test="actualCompleteQty != null">actual_complete_qty,</if>
<if test="actualDefectQty != null">actual_defect_qty,</if>
<if test="deviceCode != null">device_code,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="objId != null">#{objId},</if>
@ -172,6 +195,13 @@
<if test="workCenterCode != null">#{workCenterCode},</if>
<if test="routingCode != null">#{routingCode},</if>
<if test="manualUpdateFlag != null">#{manualUpdateFlag},</if>
<if test="executionStatus != null">#{executionStatus},</if>
<if test="startTime != null">#{startTime},</if>
<if test="finishTime != null">#{finishTime},</if>
<if test="executionOperator != null">#{executionOperator},</if>
<if test="actualCompleteQty != null">#{actualCompleteQty},</if>
<if test="actualDefectQty != null">#{actualDefectQty},</if>
<if test="deviceCode != null">#{deviceCode},</if>
</trim>
</insert>
@ -201,6 +231,13 @@
<if test="workCenterCode != null">work_center_code = #{workCenterCode},</if>
<if test="routingCode != null">routing_code = #{routingCode},</if>
<if test="manualUpdateFlag != null">manual_update_flag = #{manualUpdateFlag},</if>
<if test="executionStatus != null">execution_status = #{executionStatus},</if>
<if test="startTime != null">start_time = #{startTime},</if>
<if test="finishTime != null">finish_time = #{finishTime},</if>
<if test="executionOperator != null">execution_operator = #{executionOperator},</if>
<if test="actualCompleteQty != null">actual_complete_qty = #{actualCompleteQty},</if>
<if test="actualDefectQty != null">actual_defect_qty = #{actualDefectQty},</if>
<if test="deviceCode != null">device_code = #{deviceCode},</if>
</trim>
where obj_id = #{objId}
</update>

@ -0,0 +1,179 @@
<?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.aucma.base.mapper.ProcessSnapshotMapper">
<resultMap type="ProcessSnapshot" id="ProcessSnapshotResult">
<result property="snapshotId" column="snapshot_id"/>
<result property="deviceCode" column="device_code"/>
<result property="deviceName" column="device_name"/>
<result property="snapshotTime" column="snapshot_time"/>
<result property="snapshotType" column="snapshot_type"/>
<result property="orderCode" column="order_code"/>
<result property="remark" column="remarks"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="isFlag" column="is_flag"/>
<result property="moldCode" column="mold_code"/>
<result property="productCode" column="product_code"/>
<result property="backupName" column="backup_name"/>
<result property="isDefault" column="is_default"/>
</resultMap>
<sql id="selectProcessSnapshotVo">
SELECT s.snapshot_id, s.device_code, d.device_name, s.snapshot_time, s.snapshot_type,
s.order_code, s.remarks, s.create_by, s.create_time, s.update_by, s.update_time, s.is_flag,
s.mold_code, s.product_code, s.backup_name, s.is_default
FROM process_snapshot s
LEFT JOIN base_deviceledger d ON s.device_code = d.device_code
</sql>
<select id="selectProcessSnapshotList" parameterType="ProcessSnapshot" resultMap="ProcessSnapshotResult">
<include refid="selectProcessSnapshotVo"/>
<where>
s.is_flag = '1'
<if test="deviceCode != null and deviceCode != ''">AND s.device_code = #{deviceCode}</if>
<if test="snapshotType != null and snapshotType != ''">AND s.snapshot_type = #{snapshotType}</if>
<if test="orderCode != null and orderCode != ''">AND s.order_code = #{orderCode}</if>
<if test="moldCode != null and moldCode != ''">AND s.mold_code = #{moldCode}</if>
<if test="productCode != null and productCode != ''">AND s.product_code = #{productCode}</if>
<if test="isDefault != null and isDefault != ''">AND s.is_default = #{isDefault}</if>
<if test="params != null and params.beginTime != null and params.endTime != null">
AND s.snapshot_time BETWEEN #{params.beginTime} AND #{params.endTime}
</if>
</where>
ORDER BY s.snapshot_time DESC
</select>
<select id="selectProcessSnapshotBySnapshotId" parameterType="Long" resultMap="ProcessSnapshotResult">
<include refid="selectProcessSnapshotVo"/>
WHERE s.snapshot_id = #{snapshotId}
</select>
<insert id="insertProcessSnapshot" parameterType="ProcessSnapshot">
<selectKey keyProperty="snapshotId" resultType="long" order="BEFORE">
SELECT seq_process_snapshot_index.NEXTVAL as snapshotId FROM DUAL
</selectKey>
INSERT INTO process_snapshot
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="snapshotId != null">snapshot_id,</if>
<if test="deviceCode != null">device_code,</if>
<if test="snapshotTime != null">snapshot_time,</if>
<if test="snapshotType != null">snapshot_type,</if>
<if test="orderCode != null">order_code,</if>
<if test="remark != null">remarks,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="isFlag != null">is_flag,</if>
<if test="moldCode != null">mold_code,</if>
<if test="productCode != null">product_code,</if>
<if test="backupName != null">backup_name,</if>
<if test="isDefault != null">is_default,</if>
</trim>
<trim prefix="VALUES (" suffix=")" suffixOverrides=",">
<if test="snapshotId != null">#{snapshotId},</if>
<if test="deviceCode != null">#{deviceCode},</if>
<if test="snapshotTime != null">#{snapshotTime},</if>
<if test="snapshotType != null">#{snapshotType},</if>
<if test="orderCode != null">#{orderCode},</if>
<if test="remark != null">#{remark},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="isFlag != null">#{isFlag},</if>
<if test="moldCode != null">#{moldCode},</if>
<if test="productCode != null">#{productCode},</if>
<if test="backupName != null">#{backupName},</if>
<if test="isDefault != null">#{isDefault},</if>
</trim>
</insert>
<update id="updateProcessSnapshot" parameterType="ProcessSnapshot">
UPDATE process_snapshot
<trim prefix="SET" suffixOverrides=",">
<if test="deviceCode != null">device_code = #{deviceCode},</if>
<if test="snapshotTime != null">snapshot_time = #{snapshotTime},</if>
<if test="snapshotType != null">snapshot_type = #{snapshotType},</if>
<if test="orderCode != null">order_code = #{orderCode},</if>
<if test="remark != null">remarks = #{remark},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="moldCode != null">mold_code = #{moldCode},</if>
<if test="productCode != null">product_code = #{productCode},</if>
<if test="backupName != null">backup_name = #{backupName},</if>
<if test="isDefault != null">is_default = #{isDefault},</if>
</trim>
WHERE snapshot_id = #{snapshotId}
</update>
<delete id="deleteProcessSnapshotBySnapshotId" parameterType="Long">
UPDATE process_snapshot SET is_flag = '0' WHERE snapshot_id = #{snapshotId}
</delete>
<delete id="deleteProcessSnapshotBySnapshotIds" parameterType="String">
UPDATE process_snapshot SET is_flag = '0' WHERE snapshot_id IN
<foreach item="snapshotId" collection="array" open="(" separator="," close=")">
#{snapshotId}
</foreach>
</delete>
<!-- 根据快照时间点查询参数值时间窗口60秒内最接近的记录 -->
<select id="selectParamsBySnapshotTime" resultType="BaseDeviceParamVal">
SELECT * FROM (
SELECT
v.record_id AS recordId,
v.param_code AS paramCode,
v.device_code AS deviceCode,
v.device_id AS deviceId,
v.param_name AS paramName,
v.param_value AS paramValue,
v.collect_time AS collectTime,
v.record_time AS recordTime,
ROW_NUMBER() OVER (PARTITION BY v.param_code ORDER BY ABS(v.collect_time - #{snapshotTime})) AS rn
FROM base_device_param_val v
WHERE v.device_code = #{deviceCode}
AND v.collect_time BETWEEN #{snapshotTime} - INTERVAL '1' MINUTE AND #{snapshotTime} + INTERVAL '1' MINUTE
) WHERE rn = 1
ORDER BY paramCode
</select>
<!-- 对比两个快照的参数差异 -->
<select id="compareSnapshots" resultType="java.util.Map">
WITH snapshot1_params AS (
SELECT * FROM (
SELECT
v.param_code,
v.param_name,
v.param_value,
ROW_NUMBER() OVER (PARTITION BY v.param_code ORDER BY ABS(v.collect_time - #{snapshotTime1})) AS rn
FROM base_device_param_val v
WHERE v.device_code = #{deviceCode}
AND v.collect_time BETWEEN #{snapshotTime1} - INTERVAL '1' MINUTE AND #{snapshotTime1} + INTERVAL '1' MINUTE
) WHERE rn = 1
),
snapshot2_params AS (
SELECT * FROM (
SELECT
v.param_code,
v.param_name,
v.param_value,
ROW_NUMBER() OVER (PARTITION BY v.param_code ORDER BY ABS(v.collect_time - #{snapshotTime2})) AS rn
FROM base_device_param_val v
WHERE v.device_code = #{deviceCode}
AND v.collect_time BETWEEN #{snapshotTime2} - INTERVAL '1' MINUTE AND #{snapshotTime2} + INTERVAL '1' MINUTE
) WHERE rn = 1
)
SELECT
NVL(a.param_code, b.param_code) AS paramCode,
NVL(a.param_name, b.param_name) AS paramName,
a.param_value AS beforeValue,
b.param_value AS afterValue,
CASE WHEN NVL(a.param_value, 'NULL') != NVL(b.param_value, 'NULL') THEN 'Y' ELSE 'N' END AS isChanged
FROM snapshot1_params a
FULL OUTER JOIN snapshot2_params b ON a.param_code = b.param_code
ORDER BY NVL(a.param_code, b.param_code)
</select>
</mapper>
Loading…
Cancel
Save