设备点检记录新增

This commit is contained in:
2026-05-21 17:54:57 +08:00
parent c09ca584c3
commit 2496d05349
25 changed files with 2188 additions and 12 deletions

View File

@@ -0,0 +1,411 @@
package org.jeecg.modules.xslmes.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.xslmes.entity.MesXslEquipInspectConfig;
import org.jeecg.modules.xslmes.entity.MesXslEquipInspectRecord;
import org.jeecg.modules.xslmes.entity.MesXslEquipInspectRecordLine;
import org.jeecg.modules.xslmes.entity.MesXslEquipmentLedger;
import org.jeecg.modules.xslmes.service.IMesXslEquipInspectConfigService;
import org.jeecg.modules.xslmes.service.IMesXslEquipInspectRecordService;
import org.jeecg.modules.xslmes.service.IMesXslEquipmentLedgerService;
import org.jeecg.modules.xslmes.util.MesXslEquipInspectBizMsg;
import org.jeecg.modules.xslmes.vo.MesXslEquipInspectRecordBatchCreateDTO;
import org.jeecg.modules.xslmes.vo.MesXslEquipInspectRecordBatchCreateResult;
import org.jeecg.modules.xslmes.vo.MesXslEquipInspectRecordHandleDTO;
import org.jeecg.modules.xslmes.vo.MesXslEquipInspectRecordPage;
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
/**
* MES 点检/保养记录(主子表)
*/
@Tag(name = "MES点检保养记录")
@RestController
@RequestMapping("/xslmes/mesXslEquipInspectRecord")
@Slf4j
public class MesXslEquipInspectRecordController
extends JeecgController<MesXslEquipInspectRecord, IMesXslEquipInspectRecordService> {
private static final Set<String> RECORD_TYPE = Set.of("inspect", "maintain");
private static final Set<String> INSPECT_RESULT = Set.of("pass", "fail");
private static final Set<String> RECORD_STATUS = Set.of("pending", "done");
@Autowired
private IMesXslEquipInspectRecordService mesXslEquipInspectRecordService;
@Autowired
private IMesXslEquipmentLedgerService mesXslEquipmentLedgerService;
@Autowired
private IMesXslEquipInspectConfigService mesXslEquipInspectConfigService;
@Operation(summary = "MES点检保养记录-分页列表查询")
@GetMapping(value = "/list")
public Result<IPage<MesXslEquipInspectRecord>> queryPageList(
MesXslEquipInspectRecord model,
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<MesXslEquipInspectRecord> queryWrapper = QueryGenerator.initQueryWrapper(model, req.getParameterMap());
queryWrapper.orderByDesc("create_time");
Page<MesXslEquipInspectRecord> page = new Page<>(pageNo, pageSize);
IPage<MesXslEquipInspectRecord> pageList = mesXslEquipInspectRecordService.page(page, queryWrapper);
return Result.OK(pageList);
}
@AutoLog(value = "MES点检保养记录-添加")
@Operation(summary = "MES点检保养记录-添加")
@RequiresPermissions("mes:mes_xsl_equip_inspect_record:add")
@PostMapping(value = "/add")
public Result<String> add(@RequestBody MesXslEquipInspectRecordPage page) {
MesXslEquipInspectRecord main = new MesXslEquipInspectRecord();
BeanUtils.copyProperties(page, main);
String err = validateForSave(main, page.getLineList(), null);
if (err != null) {
return Result.error(err);
}
fillRecordNoIfEmpty(main);
fillInspector(main);
mesXslEquipInspectRecordService.saveMain(main, page.getLineList());
return Result.OK("添加成功!");
}
@AutoLog(value = "MES点检保养记录-编辑")
@Operation(summary = "MES点检保养记录-编辑")
@RequiresPermissions("mes:mes_xsl_equip_inspect_record:edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
public Result<String> edit(@RequestBody MesXslEquipInspectRecordPage page) {
MesXslEquipInspectRecord main = new MesXslEquipInspectRecord();
BeanUtils.copyProperties(page, main);
//update-begin---author:jiangxh ---date:20260520 for【MES】仅待点检可录入保存后变已点检-----------
if (oConvertUtils.isEmpty(main.getId())) {
return Result.error("记录主键不能为空");
}
MesXslEquipInspectRecord existing = mesXslEquipInspectRecordService.getById(main.getId());
if (existing == null) {
return Result.error("未找到对应数据");
}
if ("done".equals(existing.getRecordStatus())) {
return Result.error("已点检记录不可修改,仅可查看");
}
main.setRecordStatus("done");
String err = validateForEntry(main, page.getLineList());
if (err != null) {
return Result.error(err);
}
fillInspector(main);
mesXslEquipInspectRecordService.updateMain(main, page.getLineList());
return Result.OK("录入成功!");
//update-end---author:jiangxh ---date:20260520 for【MES】仅待点检可录入保存后变已点检-----------
}
@AutoLog(value = "MES点检保养记录-删除")
@Operation(summary = "MES点检保养记录-通过id删除")
@RequiresPermissions("mes:mes_xsl_equip_inspect_record:delete")
@DeleteMapping(value = "/delete")
public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
mesXslEquipInspectRecordService.delMain(id);
return Result.OK("删除成功!");
}
@AutoLog(value = "MES点检保养记录-批量删除")
@Operation(summary = "MES点检保养记录-批量删除")
@RequiresPermissions("mes:mes_xsl_equip_inspect_record:deleteBatch")
@DeleteMapping(value = "/deleteBatch")
public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
mesXslEquipInspectRecordService.delBatchMain(Arrays.asList(ids.split(",")));
return Result.OK("批量删除成功!");
}
@Operation(summary = "MES点检保养记录-通过id查询")
@GetMapping(value = "/queryById")
public Result<MesXslEquipInspectRecord> queryById(@RequestParam(name = "id", required = true) String id) {
MesXslEquipInspectRecord entity = mesXslEquipInspectRecordService.getById(id);
if (entity == null) {
return Result.error("未找到对应数据");
}
return Result.OK(entity);
}
@Operation(summary = "MES点检保养记录-查询明细")
@GetMapping(value = "/queryLineListByRecordId")
public Result<List<MesXslEquipInspectRecordLine>> queryLineListByRecordId(
@RequestParam(name = "id", required = true) String id) {
return Result.OK(mesXslEquipInspectRecordService.selectLinesByRecordId(id));
}
//update-begin---author:jiangxh ---date:20260521 for【MES】不合格点检记录登记处理人及处理时间-----------
@AutoLog(value = "MES点检保养记录-不合格处理")
@Operation(summary = "MES点检保养记录-不合格处理")
@RequiresPermissions("mes:mes_xsl_equip_inspect_record:edit")
@PostMapping(value = "/handleFail")
public Result<String> handleFail(@RequestBody MesXslEquipInspectRecordHandleDTO dto) {
try {
mesXslEquipInspectRecordService.handleFailRecord(dto);
return Result.OK("处理成功!");
} catch (IllegalArgumentException ex) {
return Result.error(ex.getMessage());
}
}
//update-end---author:jiangxh ---date:20260521 for【MES】不合格点检记录登记处理人及处理时间-----------
@Operation(summary = "MES点检保养记录-生成记录编号")
@GetMapping(value = "/generateRecordNo")
public Result<String> generateRecordNo() {
MesXslEquipInspectRecord ctx = new MesXslEquipInspectRecord();
return Result.OK(mesXslEquipInspectRecordService.generateRecordNo(ctx));
}
@AutoLog(value = "MES点检保养记录-从设备台账批量生成")
@Operation(summary = "MES点检保养记录-从设备台账批量生成")
@RequiresPermissions("mes:mes_xsl_equip_inspect_record:add")
@PostMapping(value = "/batchCreateFromEquipment")
public Result<MesXslEquipInspectRecordBatchCreateResult> batchCreateFromEquipment(
@RequestBody MesXslEquipInspectRecordBatchCreateDTO dto) {
if (dto == null || CollectionUtils.isEmpty(dto.getEquipmentLedgerIds())) {
return Result.error("请先选择设备");
}
String recordType = dto.getRecordType();
if (recordType != null) {
recordType = recordType.trim();
}
if (oConvertUtils.isEmpty(recordType) || !RECORD_TYPE.contains(recordType)) {
return Result.error("类型无效,请使用点检或保养");
}
MesXslEquipInspectRecord inspectorCtx = new MesXslEquipInspectRecord();
fillInspector(inspectorCtx);
MesXslEquipInspectRecordBatchCreateResult result =
mesXslEquipInspectRecordService.batchCreateFromEquipment(
dto.getEquipmentLedgerIds(), recordType, inspectorCtx);
if (result.getSuccessCount() <= 0 && !result.getFailMessages().isEmpty()) {
return Result.error(String.join("", result.getFailMessages()));
}
String msg = "成功生成 " + result.getSuccessCount() + " 条记录";
if (!result.getFailMessages().isEmpty()) {
msg = msg + "" + String.join("", result.getFailMessages());
}
return Result.OK(msg, result);
}
@Operation(summary = "MES点检保养记录-按设备与类型带出配置明细")
@GetMapping(value = "/loadLinesByEquipment")
public Result<List<MesXslEquipInspectRecordLine>> loadLinesByEquipment(
@RequestParam(name = "equipmentLedgerId") String equipmentLedgerId,
@RequestParam(name = "recordType") String recordType) {
String type = recordType != null ? recordType.trim() : "";
if (oConvertUtils.isEmpty(equipmentLedgerId) || !RECORD_TYPE.contains(type)) {
return Result.error("请选择设备与类型(点检/保养)");
}
List<MesXslEquipInspectRecordLine> lines =
mesXslEquipInspectRecordService.buildLinesFromEquipConfig(equipmentLedgerId, type);
if (lines.isEmpty()) {
MesXslEquipmentLedger ledger = mesXslEquipmentLedgerService.getById(equipmentLedgerId);
String equipName =
ledger != null && oConvertUtils.isNotEmpty(ledger.getEquipmentName())
? ledger.getEquipmentName()
: (ledger != null ? ledger.getEquipmentCode() : equipmentLedgerId);
return Result.error(MesXslEquipInspectBizMsg.noConfigMessage(equipName, type));
}
return Result.OK(lines);
}
@RequiresPermissions("mes:mes_xsl_equip_inspect_record:exportXls")
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, MesXslEquipInspectRecord model) {
return super.exportXls(request, model, MesXslEquipInspectRecord.class, "MES点检保养记录");
}
@RequiresPermissions("mes:mes_xsl_equip_inspect_record:importExcel")
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
return super.importExcel(request, response, MesXslEquipInspectRecord.class);
}
private void fillRecordNoIfEmpty(MesXslEquipInspectRecord main) {
if (oConvertUtils.isEmpty(main.getRecordNo())) {
main.setRecordNo(mesXslEquipInspectRecordService.generateRecordNo(main));
}
}
private void fillInspector(MesXslEquipInspectRecord main) {
if (SecurityUtils.getSubject() == null || SecurityUtils.getSubject().getPrincipal() == null) {
return;
}
if (!(SecurityUtils.getSubject().getPrincipal() instanceof LoginUser user)) {
return;
}
main.setInspectorUserId(user.getId());
main.setInspectorUsername(user.getUsername());
main.setInspectorRealname(user.getRealname());
}
//update-begin---author:jiangxh ---date:20260520 for【MES】录入点检结果必填项校验保存为已点检-----------
private String validateForEntry(MesXslEquipInspectRecord main, List<MesXslEquipInspectRecordLine> lineList) {
String err = validateForSave(main, lineList, main.getId());
if (err != null) {
return err;
}
if (main.getInspectDate() == null) {
return "请选择点检日期";
}
if (oConvertUtils.isEmpty(main.getInspectorUserId()) && oConvertUtils.isEmpty(main.getInspectorRealname())) {
return "点检人不能为空";
}
String inspectResult = main.getInspectResult();
if (inspectResult != null) {
inspectResult = inspectResult.trim();
}
if (oConvertUtils.isEmpty(inspectResult) || !INSPECT_RESULT.contains(inspectResult)) {
return "请选择点检结果(合格/不合格)";
}
main.setInspectResult(inspectResult);
main.setRecordStatus("done");
//update-begin---author:jiangxh ---date:20260521 for【MES】不合格记录默认未处理-----------
if ("fail".equals(inspectResult)) {
main.setHandledFlag("0");
} else {
main.setHandledFlag(null);
main.setHandlerUserId(null);
main.setHandlerUsername(null);
main.setHandlerRealname(null);
main.setHandleTime(null);
}
//update-end---author:jiangxh ---date:20260521 for【MES】不合格记录默认未处理-----------
return null;
}
//update-end---author:jiangxh ---date:20260520 for【MES】录入点检结果必填项校验保存为已点检-----------
//update-begin---author:jiangxh ---date:20260520 for【MES】点检保养记录保存校验与配置明细关联-----------
private String validateForSave(
MesXslEquipInspectRecord main, List<MesXslEquipInspectRecordLine> lineList, String excludeId) {
if (main == null) {
return "参数不能为空";
}
if (oConvertUtils.isEmpty(main.getEquipmentLedgerId())) {
return "请选择设备";
}
MesXslEquipmentLedger ledger = mesXslEquipmentLedgerService.getById(main.getEquipmentLedgerId());
if (ledger == null || isDeleted(ledger.getDelFlag())) {
return "设备台账不存在或已删除";
}
main.setEquipmentName(ledger.getEquipmentName());
main.setEquipmentCode(ledger.getEquipmentCode());
String recordType = main.getRecordType();
if (recordType != null) {
recordType = recordType.trim();
}
if (oConvertUtils.isEmpty(recordType) || !RECORD_TYPE.contains(recordType)) {
return "类型无效,请选择点检或保养";
}
main.setRecordType(recordType);
if (main.getInspectDate() == null) {
main.setInspectDate(new Date());
}
String recordStatus = main.getRecordStatus();
if (recordStatus != null) {
recordStatus = recordStatus.trim();
}
if (oConvertUtils.isEmpty(recordStatus) || !RECORD_STATUS.contains(recordStatus)) {
return "请选择状态(待点检/已点检)";
}
main.setRecordStatus(recordStatus);
String inspectResult = main.getInspectResult();
if (inspectResult != null) {
inspectResult = inspectResult.trim();
}
if ("done".equals(recordStatus)) {
if (oConvertUtils.isEmpty(inspectResult) || !INSPECT_RESULT.contains(inspectResult)) {
return "已点检时请选择点检结果(合格/不合格)";
}
main.setInspectResult(inspectResult);
} else {
if (oConvertUtils.isNotEmpty(inspectResult) && !INSPECT_RESULT.contains(inspectResult)) {
return "点检结果无效";
}
main.setInspectResult(oConvertUtils.isEmpty(inspectResult) ? null : inspectResult);
}
if (oConvertUtils.isEmpty(main.getRecordNo())) {
return "记录编号不能为空";
}
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<MesXslEquipInspectConfig> cw =
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<>();
cw.eq(MesXslEquipInspectConfig::getEquipmentLedgerId, main.getEquipmentLedgerId());
cw.eq(MesXslEquipInspectConfig::getConfigType, recordType);
cw.and(
q ->
q.eq(MesXslEquipInspectConfig::getDelFlag, CommonConstant.DEL_FLAG_0)
.or()
.isNull(MesXslEquipInspectConfig::getDelFlag));
MesXslEquipInspectConfig config = mesXslEquipInspectConfigService.getOne(cw, false);
if (config == null) {
String equipName =
oConvertUtils.isNotEmpty(ledger.getEquipmentName())
? ledger.getEquipmentName()
: ledger.getEquipmentCode();
return MesXslEquipInspectBizMsg.noConfigMessage(equipName, recordType);
}
main.setEquipInspectConfigId(config.getId());
if (lineList == null || lineList.isEmpty()) {
return "明细不能为空,请选择设备后自动带出点检项目";
}
Set<String> configLineIds = new HashSet<>();
int sort = 0;
for (int i = 0; i < lineList.size(); i++) {
MesXslEquipInspectRecordLine line = lineList.get(i);
if (line == null) {
continue;
}
int rowNo = i + 1;
if (oConvertUtils.isEmpty(line.getEquipInspectConfigLineId())) {
return "" + rowNo + " 行未关联点检配置明细";
}
String lineId = line.getEquipInspectConfigLineId().trim();
if (!configLineIds.add(lineId)) {
return "" + rowNo + " 行点检配置明细重复";
}
line.setEquipInspectConfigLineId(lineId);
line.setSortNo(sort++);
}
if (configLineIds.isEmpty()) {
return "明细不能为空";
}
return null;
}
private static boolean isDeleted(Integer delFlag) {
return delFlag != null && delFlag.equals(CommonConstant.DEL_FLAG_1);
}
//update-end---author:jiangxh ---date:20260520 for【MES】点检保养记录保存校验与配置明细关联-----------
}

View File

@@ -0,0 +1,126 @@
package org.jeecg.modules.xslmes.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.jeecg.common.aspect.annotation.Dict;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.springframework.format.annotation.DateTimeFormat;
/**
* MES 点检/保养记录主表(表 mes_xsl_equip_inspect_record
*/
@Data
@TableName("mes_xsl_equip_inspect_record")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@Schema(description = "MES点检保养记录")
public class MesXslEquipInspectRecord implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.ASSIGN_ID)
private String id;
@Excel(name = "记录编号", width = 20)
@Schema(description = "记录编号 EC+yyyyMMdd+4位流水")
private String recordNo;
@Excel(name = "计划单号", width = 18)
@Schema(description = "计划单号")
private String planNo;
@Schema(description = "计划主键")
private String planId;
@Schema(description = "设备台账主键")
private String equipmentLedgerId;
@Excel(name = "设备编码", width = 16)
@Schema(description = "设备编码冗余")
private String equipmentCode;
@Excel(name = "设备名称", width = 20)
@Schema(description = "设备名称冗余")
private String equipmentName;
@Schema(description = "设备点检配置主键")
private String equipInspectConfigId;
@Excel(name = "类型", width = 10, dicCode = "xslmes_im_item_category")
@Dict(dicCode = "xslmes_im_item_category")
@Schema(description = "点检/保养类型")
private String recordType;
@Excel(name = "点检日期", width = 12, format = "yyyy-MM-dd")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern = "yyyy-MM-dd")
@Schema(description = "点检日期")
private Date inspectDate;
@Schema(description = "点检人用户ID")
private String inspectorUserId;
@Schema(description = "点检人账号")
private String inspectorUsername;
@Excel(name = "点检人", width = 12)
@Schema(description = "点检人姓名")
private String inspectorRealname;
@Excel(name = "点检结果", width = 10, dicCode = "xslmes_im_inspect_result")
@Dict(dicCode = "xslmes_im_inspect_result")
@Schema(description = "点检结果 pass/fail")
private String inspectResult;
@Excel(name = "状态", width = 10, dicCode = "xslmes_im_record_status")
@Dict(dicCode = "xslmes_im_record_status")
@Schema(description = "记录状态 pending/done")
private String recordStatus;
@Excel(name = "是否已处理", width = 10, dicCode = "yn")
@Dict(dicCode = "yn")
@Schema(description = "是否已处理字典yn1是0否不合格记录使用")
private String handledFlag;
@Schema(description = "处理人用户ID")
private String handlerUserId;
@Schema(description = "处理人账号")
private String handlerUsername;
@Excel(name = "处理人", width = 12)
@Schema(description = "处理人姓名")
private String handlerRealname;
@Excel(name = "处理时间", width = 18, format = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Schema(description = "处理时间")
private Date handleTime;
private Integer tenantId;
private String sysOrgCode;
private String createBy;
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
private String updateBy;
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
private Integer delFlag;
@TableField(exist = false)
@Schema(description = "点检明细")
private List<MesXslEquipInspectRecordLine> lineList;
}

View File

@@ -0,0 +1,82 @@
package org.jeecg.modules.xslmes.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import java.io.Serializable;
import java.util.Date;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.jeecg.common.aspect.annotation.Dict;
import org.springframework.format.annotation.DateTimeFormat;
/**
* MES 点检/保养记录明细(表 mes_xsl_equip_inspect_record_line
*/
@Data
@TableName("mes_xsl_equip_inspect_record_line")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@Schema(description = "MES点检保养记录明细")
public class MesXslEquipInspectRecordLine implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.ASSIGN_ID)
private String id;
@Schema(description = "主表主键")
private String recordId;
@Schema(description = "设备点检配置明细主键")
private String equipInspectConfigLineId;
@Schema(description = "点检及保养项目主键冗余")
private String inspectMaintainItemId;
@Schema(description = "点检项目编号")
private String itemCode;
@Schema(description = "项目名称")
private String itemName;
@Dict(dicCode = "xslmes_im_item_category")
@Schema(description = "项目类别")
private String itemCategory;
@Dict(dicCode = "xslmes_im_item_type")
@Schema(description = "项目类型")
private String itemType;
@Schema(description = "设备部位")
private String equipmentPartName;
@Schema(description = "设备小部位")
private String equipmentSubPartName;
@Dict(dicCode = "xslmes_im_inspect_method")
@Schema(description = "点检方式")
private String inspectMethod;
@Schema(description = "判断基准")
private String judgmentCriteria;
@Schema(description = "明细点检结果文本")
private String lineInspectResult;
@Schema(description = "图片路径,逗号分隔")
private String pictureFiles;
private Integer sortNo;
private String createBy;
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
private String updateBy;
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}

View File

@@ -0,0 +1,6 @@
package org.jeecg.modules.xslmes.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.jeecg.modules.xslmes.entity.MesXslEquipInspectRecordLine;
public interface MesXslEquipInspectRecordLineMapper extends BaseMapper<MesXslEquipInspectRecordLine> {}

View File

@@ -0,0 +1,6 @@
package org.jeecg.modules.xslmes.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.jeecg.modules.xslmes.entity.MesXslEquipInspectRecord;
public interface MesXslEquipInspectRecordMapper extends BaseMapper<MesXslEquipInspectRecord> {}

View File

@@ -0,0 +1,34 @@
package org.jeecg.modules.xslmes.service;
import com.baomidou.mybatisplus.extension.service.IService;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import org.jeecg.modules.xslmes.entity.MesXslEquipInspectRecord;
import org.jeecg.modules.xslmes.entity.MesXslEquipInspectRecordLine;
import org.jeecg.modules.xslmes.vo.MesXslEquipInspectRecordBatchCreateResult;
import org.jeecg.modules.xslmes.vo.MesXslEquipInspectRecordHandleDTO;
public interface IMesXslEquipInspectRecordService extends IService<MesXslEquipInspectRecord> {
void saveMain(MesXslEquipInspectRecord main, List<MesXslEquipInspectRecordLine> lineList);
void updateMain(MesXslEquipInspectRecord main, List<MesXslEquipInspectRecordLine> lineList);
void delMain(String id);
void delBatchMain(Collection<? extends Serializable> idList);
List<MesXslEquipInspectRecordLine> selectLinesByRecordId(String recordId);
String generateRecordNo(MesXslEquipInspectRecord context);
List<MesXslEquipInspectRecordLine> buildLinesFromEquipConfig(String equipmentLedgerId, String recordType);
MesXslEquipInspectRecordBatchCreateResult batchCreateFromEquipment(
List<String> equipmentLedgerIds, String recordType, MesXslEquipInspectRecord inspectorContext);
//update-begin---author:jiangxh ---date:20260521 for【MES】不合格点检记录登记处理人及处理时间-----------
void handleFailRecord(MesXslEquipInspectRecordHandleDTO dto);
//update-end---author:jiangxh ---date:20260521 for【MES】不合格点检记录登记处理人及处理时间-----------
}

View File

@@ -0,0 +1,312 @@
package org.jeecg.modules.xslmes.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import org.jeecg.common.config.TenantContext;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.util.SpringContextUtils;
import org.jeecg.common.util.TokenUtils;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.xslmes.entity.MesXslEquipInspectConfig;
import org.jeecg.modules.xslmes.entity.MesXslEquipInspectConfigLine;
import org.jeecg.modules.xslmes.entity.MesXslEquipInspectRecord;
import org.jeecg.modules.xslmes.entity.MesXslEquipInspectRecordLine;
import org.jeecg.modules.xslmes.mapper.MesXslEquipInspectRecordLineMapper;
import org.jeecg.modules.xslmes.mapper.MesXslEquipInspectRecordMapper;
import org.jeecg.modules.xslmes.service.IMesXslEquipInspectConfigService;
import org.jeecg.modules.xslmes.service.IMesXslEquipInspectRecordService;
import org.jeecg.modules.xslmes.service.IMesXslEquipmentLedgerService;
import org.jeecg.modules.xslmes.entity.MesXslEquipmentLedger;
import org.jeecg.modules.xslmes.util.MesXslEquipInspectBizMsg;
import org.jeecg.modules.xslmes.vo.MesXslEquipInspectRecordBatchCreateResult;
import org.jeecg.modules.xslmes.vo.MesXslEquipInspectRecordHandleDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
@Service
public class MesXslEquipInspectRecordServiceImpl
extends ServiceImpl<MesXslEquipInspectRecordMapper, MesXslEquipInspectRecord>
implements IMesXslEquipInspectRecordService {
@Autowired
private MesXslEquipInspectRecordLineMapper mesXslEquipInspectRecordLineMapper;
@Autowired
private IMesXslEquipInspectConfigService mesXslEquipInspectConfigService;
@Autowired
private IMesXslEquipmentLedgerService mesXslEquipmentLedgerService;
@Override
@Transactional(rollbackFor = Exception.class)
public void saveMain(MesXslEquipInspectRecord main, List<MesXslEquipInspectRecordLine> lineList) {
this.save(main);
insertLines(main.getId(), lineList);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateMain(MesXslEquipInspectRecord main, List<MesXslEquipInspectRecordLine> lineList) {
this.updateById(main);
mesXslEquipInspectRecordLineMapper.delete(
new LambdaQueryWrapper<MesXslEquipInspectRecordLine>()
.eq(MesXslEquipInspectRecordLine::getRecordId, main.getId()));
insertLines(main.getId(), lineList);
}
private void insertLines(String recordId, List<MesXslEquipInspectRecordLine> lineList) {
if (CollectionUtils.isEmpty(lineList)) {
return;
}
int sort = 0;
for (MesXslEquipInspectRecordLine line : lineList) {
line.setId(null);
line.setRecordId(recordId);
line.setSortNo(sort++);
mesXslEquipInspectRecordLineMapper.insert(line);
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void delMain(String id) {
mesXslEquipInspectRecordLineMapper.delete(
new LambdaQueryWrapper<MesXslEquipInspectRecordLine>().eq(MesXslEquipInspectRecordLine::getRecordId, id));
this.removeById(id);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void delBatchMain(Collection<? extends Serializable> idList) {
for (Serializable id : idList) {
delMain(id.toString());
}
}
@Override
public List<MesXslEquipInspectRecordLine> selectLinesByRecordId(String recordId) {
return mesXslEquipInspectRecordLineMapper.selectList(
new LambdaQueryWrapper<MesXslEquipInspectRecordLine>()
.eq(MesXslEquipInspectRecordLine::getRecordId, recordId)
.orderByAsc(MesXslEquipInspectRecordLine::getSortNo));
}
//update-begin---author:jiangxh ---date:20260520 for【MES】点检保养记录编号 EC+日期+4位流水-----------
@Override
public String generateRecordNo(MesXslEquipInspectRecord context) {
String dateStr = new SimpleDateFormat("yyyyMMdd").format(new Date());
String prefix = "EC" + dateStr;
Integer tenantId = resolveTenantId(context);
LambdaQueryWrapper<MesXslEquipInspectRecord> qw = new LambdaQueryWrapper<>();
qw.likeRight(MesXslEquipInspectRecord::getRecordNo, prefix);
qw.and(
q ->
q.eq(MesXslEquipInspectRecord::getDelFlag, CommonConstant.DEL_FLAG_0)
.or()
.isNull(MesXslEquipInspectRecord::getDelFlag));
if (tenantId != null) {
qw.eq(MesXslEquipInspectRecord::getTenantId, tenantId);
}
qw.select(MesXslEquipInspectRecord::getRecordNo);
qw.orderByDesc(MesXslEquipInspectRecord::getRecordNo);
qw.last("LIMIT 1");
MesXslEquipInspectRecord last = this.getOne(qw, false);
int nextSeq = 1;
if (last != null && oConvertUtils.isNotEmpty(last.getRecordNo()) && last.getRecordNo().length() >= prefix.length() + 4) {
String suffix = last.getRecordNo().substring(prefix.length());
try {
nextSeq = Integer.parseInt(suffix) + 1;
} catch (NumberFormatException ignored) {
nextSeq = (int) this.count(qw) + 1;
}
}
return prefix + String.format("%04d", nextSeq);
}
//update-end---author:jiangxh ---date:20260520 for【MES】点检保养记录编号 EC+日期+4位流水-----------
//update-begin---author:jiangxh ---date:20260520 for【MES】点检保养记录从设备点检配置带出明细-----------
@Override
public List<MesXslEquipInspectRecordLine> buildLinesFromEquipConfig(String equipmentLedgerId, String recordType) {
if (oConvertUtils.isEmpty(equipmentLedgerId) || oConvertUtils.isEmpty(recordType)) {
return List.of();
}
String type = recordType.trim();
MesXslEquipInspectConfig config = findEquipInspectConfig(equipmentLedgerId.trim(), type);
if (config == null) {
return List.of();
}
List<MesXslEquipInspectConfigLine> configLines =
mesXslEquipInspectConfigService.selectLinesByConfigId(config.getId());
if (CollectionUtils.isEmpty(configLines)) {
return List.of();
}
return buildRecordLinesFromConfigLines(configLines);
}
private MesXslEquipInspectConfig findEquipInspectConfig(String equipmentLedgerId, String configType) {
LambdaQueryWrapper<MesXslEquipInspectConfig> cw = new LambdaQueryWrapper<>();
cw.eq(MesXslEquipInspectConfig::getEquipmentLedgerId, equipmentLedgerId);
cw.eq(MesXslEquipInspectConfig::getConfigType, configType);
cw.and(
q ->
q.eq(MesXslEquipInspectConfig::getDelFlag, CommonConstant.DEL_FLAG_0)
.or()
.isNull(MesXslEquipInspectConfig::getDelFlag));
return mesXslEquipInspectConfigService.getOne(cw, false);
}
private List<MesXslEquipInspectRecordLine> buildRecordLinesFromConfigLines(
List<MesXslEquipInspectConfigLine> configLines) {
List<MesXslEquipInspectRecordLine> result = new ArrayList<>(configLines.size());
for (MesXslEquipInspectConfigLine cl : configLines) {
MesXslEquipInspectRecordLine line = new MesXslEquipInspectRecordLine();
line.setEquipInspectConfigLineId(cl.getId());
line.setInspectMaintainItemId(cl.getInspectMaintainItemId());
line.setItemCode(cl.getItemCode());
line.setItemName(cl.getItemName());
line.setItemCategory(cl.getItemCategory());
line.setItemType(cl.getItemType());
line.setEquipmentPartName(cl.getEquipmentPartName());
line.setEquipmentSubPartName(cl.getEquipmentSubPartName());
line.setInspectMethod(cl.getInspectMethod());
line.setJudgmentCriteria(cl.getJudgmentCriteria());
result.add(line);
}
return result;
}
//update-end---author:jiangxh ---date:20260520 for【MES】点检保养记录从设备点检配置带出明细-----------
//update-begin---author:jiangxh ---date:20260520 for【MES】设备台账多选批量生成点检保养记录待点检-----------
@Override
@Transactional(rollbackFor = Exception.class)
public MesXslEquipInspectRecordBatchCreateResult batchCreateFromEquipment(
List<String> equipmentLedgerIds, String recordType, MesXslEquipInspectRecord inspectorContext) {
MesXslEquipInspectRecordBatchCreateResult result = new MesXslEquipInspectRecordBatchCreateResult();
if (CollectionUtils.isEmpty(equipmentLedgerIds) || oConvertUtils.isEmpty(recordType)) {
result.getFailMessages().add("请选择设备并指定点检或保养类型");
return result;
}
String type = recordType.trim();
for (String equipmentLedgerId : equipmentLedgerIds) {
if (oConvertUtils.isEmpty(equipmentLedgerId)) {
continue;
}
String equipId = equipmentLedgerId.trim();
MesXslEquipmentLedger ledger = mesXslEquipmentLedgerService.getById(equipId);
String equipName =
ledger != null
? (oConvertUtils.isNotEmpty(ledger.getEquipmentName())
? ledger.getEquipmentName()
: ledger.getEquipmentCode())
: equipId;
if (ledger == null
|| (ledger.getDelFlag() != null && ledger.getDelFlag().equals(CommonConstant.DEL_FLAG_1))) {
result.getFailMessages().add("设备【" + equipName + "】不存在或已删除");
continue;
}
//update-begin---author:jiangxh ---date:20260520 for【MES】未维护对应类型设备点检配置则不生成记录并提示设备名称-----------
MesXslEquipInspectConfig config = findEquipInspectConfig(equipId, type);
if (config == null) {
result.getFailMessages().add(MesXslEquipInspectBizMsg.noConfigMessage(equipName, type));
continue;
}
List<MesXslEquipInspectConfigLine> configLines =
mesXslEquipInspectConfigService.selectLinesByConfigId(config.getId());
if (CollectionUtils.isEmpty(configLines)) {
result.getFailMessages().add(MesXslEquipInspectBizMsg.noConfigLineMessage(equipName, type));
continue;
}
List<MesXslEquipInspectRecordLine> lines = buildRecordLinesFromConfigLines(configLines);
//update-end---author:jiangxh ---date:20260520 for【MES】未维护对应类型设备点检配置则不生成记录并提示设备名称-----------
MesXslEquipInspectRecord main = new MesXslEquipInspectRecord();
main.setEquipmentLedgerId(equipId);
main.setEquipmentCode(ledger.getEquipmentCode());
main.setEquipmentName(ledger.getEquipmentName());
main.setEquipInspectConfigId(config.getId());
main.setRecordType(type);
main.setRecordNo(generateRecordNo(main));
main.setRecordStatus("pending");
main.setInspectResult("");
main.setInspectDate(new Date());
if (inspectorContext != null) {
main.setInspectorUserId(inspectorContext.getInspectorUserId());
main.setInspectorUsername(inspectorContext.getInspectorUsername());
main.setInspectorRealname(inspectorContext.getInspectorRealname());
}
saveMain(main, lines);
result.setSuccessCount(result.getSuccessCount() + 1);
}
return result;
}
//update-end---author:jiangxh ---date:20260520 for【MES】设备台账多选批量生成点检保养记录待点检-----------
//update-begin---author:jiangxh ---date:20260521 for【MES】不合格点检记录登记处理人及处理时间-----------
@Override
@Transactional(rollbackFor = Exception.class)
public void handleFailRecord(MesXslEquipInspectRecordHandleDTO dto) {
if (dto == null || oConvertUtils.isEmpty(dto.getId())) {
throw new IllegalArgumentException("记录主键不能为空");
}
MesXslEquipInspectRecord existing = this.getById(dto.getId().trim());
if (existing == null) {
throw new IllegalArgumentException("未找到对应数据");
}
if (!"fail".equals(existing.getInspectResult())) {
throw new IllegalArgumentException("仅不合格记录可处理");
}
if (!"done".equals(existing.getRecordStatus())) {
throw new IllegalArgumentException("请先完成点检录入");
}
if ("1".equals(existing.getHandledFlag())) {
throw new IllegalArgumentException("该记录已处理");
}
if (oConvertUtils.isEmpty(dto.getHandlerUserId())
&& oConvertUtils.isEmpty(dto.getHandlerUsername())
&& oConvertUtils.isEmpty(dto.getHandlerRealname())) {
throw new IllegalArgumentException("请选择处理人");
}
Date handleTime = dto.getHandleTime() != null ? dto.getHandleTime() : new Date();
MesXslEquipInspectRecord patch = new MesXslEquipInspectRecord();
patch.setId(existing.getId());
patch.setHandledFlag("1");
patch.setHandlerUserId(dto.getHandlerUserId());
patch.setHandlerUsername(dto.getHandlerUsername());
patch.setHandlerRealname(dto.getHandlerRealname());
patch.setHandleTime(handleTime);
this.updateById(patch);
}
//update-end---author:jiangxh ---date:20260521 for【MES】不合格点检记录登记处理人及处理时间-----------
private static Integer resolveTenantId(MesXslEquipInspectRecord context) {
if (context != null && context.getTenantId() != null) {
return context.getTenantId();
}
String ts = TenantContext.getTenant();
if (oConvertUtils.isEmpty(ts)) {
try {
ts = TokenUtils.getTenantIdByRequest(SpringContextUtils.getHttpServletRequest());
} catch (Exception ignored) {
// ignore
}
}
if (oConvertUtils.isEmpty(ts)) {
return null;
}
try {
return Integer.parseInt(ts);
} catch (NumberFormatException e) {
return null;
}
}
}

View File

@@ -0,0 +1,27 @@
package org.jeecg.modules.xslmes.util;
import org.jeecg.common.util.oConvertUtils;
/**
* 设备点检/保养业务提示文案
*/
public final class MesXslEquipInspectBizMsg {
private MesXslEquipInspectBizMsg() {}
public static String recordTypeLabel(String recordType) {
return "inspect".equals(recordType) ? "点检" : "保养";
}
/** 未维护该类型设备点检配置(不生成记录) */
public static String noConfigMessage(String equipmentName, String recordType) {
String name = oConvertUtils.isNotEmpty(equipmentName) ? equipmentName.trim() : "该设备";
return name + " 未维护" + recordTypeLabel(recordType) + "类型的设备点检配置";
}
/** 已有点检配置主表但无明细行 */
public static String noConfigLineMessage(String equipmentName, String recordType) {
String name = oConvertUtils.isNotEmpty(equipmentName) ? equipmentName.trim() : "该设备";
return name + "" + recordTypeLabel(recordType) + "类型设备点检配置未维护明细项";
}
}

View File

@@ -0,0 +1,19 @@
package org.jeecg.modules.xslmes.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.List;
import lombok.Data;
/**
* 从设备台账批量生成点检/保养记录
*/
@Data
@Schema(description = "批量生成点检保养记录请求")
public class MesXslEquipInspectRecordBatchCreateDTO {
@Schema(description = "设备台账主键列表")
private List<String> equipmentLedgerIds;
@Schema(description = "记录类型 inspect点检/maintain保养")
private String recordType;
}

View File

@@ -0,0 +1,20 @@
package org.jeecg.modules.xslmes.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.ArrayList;
import java.util.List;
import lombok.Data;
/**
* 批量生成点检/保养记录结果
*/
@Data
@Schema(description = "批量生成点检保养记录结果")
public class MesXslEquipInspectRecordBatchCreateResult {
@Schema(description = "成功条数")
private int successCount;
@Schema(description = "失败说明(按设备)")
private List<String> failMessages = new ArrayList<>();
}

View File

@@ -0,0 +1,32 @@
package org.jeecg.modules.xslmes.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.Date;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
/**
* 不合格点检记录处理入参
*/
@Data
@Schema(description = "点检保养记录-不合格处理")
public class MesXslEquipInspectRecordHandleDTO {
@Schema(description = "记录主键", requiredMode = Schema.RequiredMode.REQUIRED)
private String id;
@Schema(description = "处理人用户ID")
private String handlerUserId;
@Schema(description = "处理人账号")
private String handlerUsername;
@Schema(description = "处理人姓名")
private String handlerRealname;
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Schema(description = "处理时间")
private Date handleTime;
}

View File

@@ -0,0 +1,12 @@
package org.jeecg.modules.xslmes.vo;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.jeecg.modules.xslmes.entity.MesXslEquipInspectRecord;
/**
* 点检/保养记录主子保存 VO
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class MesXslEquipInspectRecordPage extends MesXslEquipInspectRecord {}