kkk-ops 2 months ago
commit fcf8277bcb

@ -118,6 +118,14 @@ public class MoldBrandController {
return success(moldBrandService.getMoldPage(pageReqVO, brandId));
}
@GetMapping("/mold/list")
@Operation(summary = "获得模具列表")
@PreAuthorize("@ss.hasPermission('erp:mold-brand:query')")
public CommonResult<List<MoldDO>> getMoldList() {
List<MoldDO> moldDOList = moldBrandService.getMoldList();
return success(moldDOList);
}
@PostMapping("/mold/create")
@Operation(summary = "创建模具")
@PreAuthorize("@ss.hasPermission('erp:mold-brand:create')")

@ -0,0 +1,36 @@
package cn.iocoder.yudao.module.erp.controller.admin.moldrepair.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
*
*/
@Getter
@AllArgsConstructor
public enum MoldRecordStatusEnum {
PENDING(0, "待完成"),
COMPLETED(1, "已完成"),
// 可以根据需要添加其他状态
CANCELED(2, "已取消");
@JsonValue
private final Integer code;
private final String name;
@JsonCreator
public static MoldRecordStatusEnum getByCode(Integer code) {
if (code == null) {
return null;
}
for (MoldRecordStatusEnum status : MoldRecordStatusEnum.values()) {
if (status.getCode().equals(code)) {
return status;
}
}
return null;
}
}

@ -0,0 +1,78 @@
package cn.iocoder.yudao.module.erp.controller.admin.moldrepair.vo;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 模具维修记录分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class MoldRepairPageReqVO extends PageParam {
@Schema(description = "维修单编号")
private String repairCode;
@Schema(description = "维修单名称", example = "王五")
private String repairName;
@Schema(description = "模具ID", example = "6979")
private Long moldId;
@Schema(description = "模具编码")
private String moldCode;
@Schema(description = "模具名称", example = "张三")
private String moldName;
@Schema(description = "品牌")
private String moldBrand;
@Schema(description = "规格型号")
private String moldSpec;
@Schema(description = "模具类型", example = "1622")
private Long moldTypeId;
@Schema(description = "报修日期")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] requireDate;
@Schema(description = "完成日期")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] finishDate;
@Schema(description = "验收日期")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] confirmDate;
@Schema(description = "维修结果")
private String repairResult;
@Schema(description = "维修人员")
private String acceptedBy;
@Schema(description = "验收人员")
private String confirmBy;
@Schema(description = "单据状态0-待完成 1-已完成", example = "1")
private Integer status;
@Schema(description = "备注")
private String remark;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
@Schema(description = "ids集合导出用")
private String ids;
}

@ -0,0 +1,110 @@
package cn.iocoder.yudao.module.erp.controller.admin.moldrepair.vo;
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 模具维修记录 Response VO")
@Data
@ExcelIgnoreUnannotated
public class MoldRepairRespVO {
@Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "27809")
// @ExcelProperty("ID")
private Long id;
@Schema(description = "维修单编号", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("维修单编号")
private String repairCode;
@Schema(description = "维修单名称", example = "王五")
@ExcelProperty("维修单名称")
private String repairName;
@Schema(description = "模具ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "6979")
// @ExcelProperty("模具ID")
private Long moldId;
@Schema(description = "模具编码", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("模具编码")
private String moldCode;
@Schema(description = "模具名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三")
@ExcelProperty("模具名称")
private String moldName;
@Schema(description = "品牌")
// @ExcelProperty("品牌")
private String moldBrand;
@Schema(description = "规格型号")
// @ExcelProperty("规格型号")
private String moldSpec;
@Schema(description = "模具类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1622")
// @ExcelProperty(value = "模具类型", converter = DictConvert.class)
// @DictFormat("mes_machine_type") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
private Long moldTypeId;
@Schema(description = "报修日期")
@ExcelProperty("报修日期")
@ColumnWidth(20)
private LocalDateTime requireDate;
@Schema(description = "完成日期")
@ExcelProperty("完成日期")
@ColumnWidth(20)
private LocalDateTime finishDate;
@Schema(description = "验收日期")
@ExcelProperty("验收日期")
@ColumnWidth(20)
private LocalDateTime confirmDate;
@Schema(description = "维修结果")
@ExcelProperty("维修结果")
private String repairResult;
@Schema(description = "维修人员")
@ExcelProperty("维修人员")
private String acceptedBy;
@Schema(description = "验收人员")
@ExcelProperty("验收人员")
private String confirmBy;
@Schema(description = "单据状态", example = "1")
@ExcelProperty(value = "单据状态 0-待完成 1-已完成")
@DictFormat("mes_mold_record_status") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
private Integer status;
@Schema(description = "单据状态", example = "1")
@ExcelProperty(value = "单据状态 0-待完成 1-已完成")
@DictFormat("mes_mold_record_status") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
private String statusName;
@Schema(description = "备注", example = "你猜")
@ExcelProperty("备注")
private String remark;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
@ColumnWidth(20)
private LocalDateTime createTime;
@Schema(description = "模具类型 1-模具 2-关键件", example = "你猜")
private Integer deviceType;
@Schema(description = "模具Id", example = "你猜")
private Long deviceId;
@Schema(description = "关键件Id", example = "你猜")
private Long componentId;
}

@ -0,0 +1,83 @@
package cn.iocoder.yudao.module.erp.controller.admin.moldrepair.vo;
import cn.iocoder.yudao.module.erp.dal.dataobject.moldrepair.MoldRepairLineDO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import java.time.LocalDateTime;
import java.util.List;
@Schema(description = "管理后台 - 模具维修记录新增/修改 Request VO")
@Data
public class MoldRepairSaveReqVO {
@Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "27809")
private Long id;
@Schema(description = "维修单编号", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "维修单编号不能为空")
private String repairCode;
@Schema(description = "维修单名称", example = "王五")
private String repairName;
@Schema(description = "模具ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "6979")
// @NotNull(message = "模具ID不能为空")
private Long moldId;
@Schema(description = "模具编码", requiredMode = Schema.RequiredMode.REQUIRED)
// @NotEmpty(message = "模具编码不能为空")
private String moldCode;
@Schema(description = "模具名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三")
// @NotEmpty(message = "模具名称不能为空")
private String moldName;
@Schema(description = "品牌")
private String moldBrand;
@Schema(description = "规格型号")
private String moldSpec;
@Schema(description = "模具类型-待用", requiredMode = Schema.RequiredMode.REQUIRED, example = "1622")
// @NotNull(message = "模具类型不能为空")
private Long moldTypeId;
@Schema(description = "报修日期")
private LocalDateTime requireDate;
@Schema(description = "完成日期")
private LocalDateTime finishDate;
@Schema(description = "验收日期")
private LocalDateTime confirmDate;
@Schema(description = "维修结果")
private String repairResult;
@Schema(description = "维修人员")
private String acceptedBy;
@Schema(description = "验收人员")
private String confirmBy;
@Schema(description = "单据状态", example = "1")
private String status;
@Schema(description = "备注", example = "你猜")
private String remark;
@Schema(description = "模具维修记录行列表")
private List<MoldRepairLineDO> moldRepairLines;
@Schema(description = "模具类型 1-模具 2-关键件")
private Integer deviceType;
@Schema(description = "模具Id")
private Long deviceId;
@Schema(description = "关键件Id")
private Long componentId;
}

@ -0,0 +1,87 @@
package cn.iocoder.yudao.module.erp.controller.admin.moldticketmanagement.enums;
import lombok.Getter;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
*
* 1- 2-
*/
@Getter
public enum MoldPlanTypeEnum {
INSPECTION(1, "点检"),
MAINTENANCE(2, "保养");
private final Integer code;
private final String description;
MoldPlanTypeEnum(Integer code, String description) {
this.code = code;
this.description = description;
}
/**
* code
*/
public static MoldPlanTypeEnum getByCode(Integer code) {
if (code == null) {
return null;
}
for (MoldPlanTypeEnum type : values()) {
if (type.getCode().equals(code)) {
return type;
}
}
return null;
}
/**
* code
*/
public static String getDescriptionByCode(Integer code) {
MoldPlanTypeEnum type = getByCode(code);
return type != null ? type.getDescription() : "未知";
}
/**
* code
*/
public static boolean isValidCode(Integer code) {
return getByCode(code) != null;
}
/**
* code
*/
public static List<Integer> getAllCodes() {
return Arrays.stream(values())
.map(MoldPlanTypeEnum::getCode)
.collect(Collectors.toList());
}
/**
*
*/
public static List<String> getAllDescriptions() {
return Arrays.stream(values())
.map(MoldPlanTypeEnum::getDescription)
.collect(Collectors.toList());
}
/**
* code
*/
public static Map<Integer, String> getCodeDescriptionMap() {
Map<Integer, String> map = new LinkedHashMap<>();
for (MoldPlanTypeEnum type : values()) {
map.put(type.getCode(), type.getDescription());
}
return map;
}
}

@ -0,0 +1,20 @@
package cn.iocoder.yudao.module.erp.controller.admin.moldticketmanagement.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
// 1. 新增请求VO
@Data
public class MoldTicketManagementBatchUpdateReqVO {
@Schema(description = "工单ID列表用逗号分隔", example = "1,2,3")
@NotBlank(message = "工单ID不能为空")
private String ids;
@Schema(description = "作业状态", example = "2")
@NotNull(message = "作业状态不能为空")
private Integer jobStatus ; // 默认值为2
}

@ -0,0 +1,63 @@
package cn.iocoder.yudao.module.erp.controller.admin.moldticketmanagement.vo;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 项目方案关联分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class MoldTicketManagementPageReqVO extends PageParam {
@Schema(description = "项目ID", example = "21368")
private Long taskId;
@Schema(description = "方案ID", example = "20459")
private Long planId;
@Schema(description = "单号")
private String planNo;
@Schema(description = "设备名称", example = "张三")
private String moldName;
@Schema(description = "类型(1-点检 2-保养)", example = "2")
private String planType;
@Schema(description = "计划配置名称", example = "赵六")
private String configName;
@Schema(description = "作业状态", example = "1")
private Integer jobStatus;
@Schema(description = "作业结果")
private String jobResult;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
@Schema(description = "id集合导出用")
private String ids;
/**
*
*/
private String taskTime;
/**
*
*/
private String taskEndTime;
}

@ -0,0 +1,91 @@
package cn.iocoder.yudao.module.erp.controller.admin.moldticketmanagement.vo;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 项目方案关联 Response VO")
@Data
@ExcelIgnoreUnannotated
public class MoldTicketManagementRespVO extends BaseDO {
@Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED, example = "6566")
@ExcelProperty("id")
private Long id;
@Schema(description = "任务Id", example = "21368")
// @ExcelProperty("项目ID")
private Long taskId;
@Schema(description = "方案ID", example = "20459")
// @ExcelProperty("方案ID")
private Long planId;
@Schema(description = "单号")
@ExcelProperty("单号")
private String planNo;
@Schema(description = "设备名称", example = "张三")
@ExcelProperty("设备名称")
private String moldName;
@Schema(description = "类型", example = "2")
@ExcelProperty("类型")
private String planType;
@Schema(description = "计划配置名称", example = "赵六")
@ExcelProperty("计划配置名称")
private String configName;
@Schema(description = "作业状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@ExcelProperty("作业状态")
private Integer jobStatus;
@Schema(description = "作业结果")
@ExcelProperty("作业结果")
private Integer jobResult;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
/**
*
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
private LocalDateTime taskTime;
/**
*
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
private LocalDateTime taskEndTime;
@Schema(description = "创建人名字")
@ExcelProperty("创建人名字")
private String creatorName;
@Schema(description = "作业人")
private String operator;
@Schema(description = "作业人名称")
@ExcelProperty("作业人名称")
private String operatorName;
}

@ -0,0 +1,42 @@
package cn.iocoder.yudao.module.erp.controller.admin.moldticketmanagement.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
@Schema(description = "管理后台 - 项目方案关联新增/修改 Request VO")
@Data
public class MoldTicketManagementSaveReqVO {
@Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED, example = "6566")
private Long id;
@Schema(description = "项目ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "21368")
@NotNull(message = "项目ID不能为空")
private Long subjectId;
@Schema(description = "方案ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "20459")
@NotNull(message = "方案ID不能为空")
private Long planId;
@Schema(description = "单号")
private String planNo;
@Schema(description = "设备名称", example = "张三")
private String moldName;
@Schema(description = "类型", example = "2")
private String planType;
@Schema(description = "计划配置名称", example = "赵六")
private String configName;
@Schema(description = "作业状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "作业状态不能为空")
private Integer jobStatus;
@Schema(description = "作业结果")
private Integer jobResult;
}

@ -0,0 +1,109 @@
package cn.iocoder.yudao.module.erp.controller.admin.moldticketresults.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
*
*/
@Getter
@AllArgsConstructor
public enum MoldJobResultEnum {
/**
*
*/
PENDING(0, "待完成"),
/**
*
*/
PASS(1, "通过"),
/**
*
*/
FAIL(2, "不通过");
/**
*
*/
private final Integer code;
/**
*
*/
private final String description;
/**
*
*/
public static MoldJobResultEnum getByCode(Integer code) {
if (code == null) {
return null;
}
for (MoldJobResultEnum status : values()) {
if (status.getCode().equals(code)) {
return status;
}
}
return null;
}
/**
*
*/
public static boolean isValidCode(Integer code) {
return getByCode(code) != null;
}
/**
*
*/
public static List<Integer> getAllCodes() {
return Arrays.stream(values())
.map(MoldJobResultEnum::getCode)
.collect(Collectors.toList());
}
/**
*
*/
public static List<String> getAllDescriptions() {
return Arrays.stream(values())
.map(MoldJobResultEnum::getDescription)
.collect(Collectors.toList());
}
/**
*
*/
public boolean isPending() {
return this == PENDING;
}
/**
*
*/
public boolean isPass() {
return this == PASS;
}
/**
*
*/
public boolean isFail() {
return this == FAIL;
}
/**
*
*/
public boolean isCompleted() {
return this == PASS || this == FAIL;
}
}

@ -0,0 +1,49 @@
package cn.iocoder.yudao.module.erp.controller.admin.moldticketresults.vo;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 工单检验结果分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class MoldTicketResultsPageReqVO extends PageParam {
@Schema(description = "检验项名称", example = "赵六")
private String inspectionItemName;
@Schema(description = "检验方式")
private String inspectionMethod;
@Schema(description = "判定基准")
private String judgmentCriteria;
@Schema(description = "检验结果 0-待检测 1-检测通过 2-检测不通过")
private Integer inspectionResult;
@Schema(description = "图片路径")
private String images;
@Schema(description = "备注", example = "你说的对")
private String remark;
@Schema(description = "检验时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] inspectionTime;
@Schema(description = "工单管理Id")
private Long managementId;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

@ -0,0 +1,56 @@
package cn.iocoder.yudao.module.erp.controller.admin.moldticketresults.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 工单检验结果 Response VO")
@Data
@ExcelIgnoreUnannotated
public class MoldTicketResultsRespVO {
@Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED, example = "30557")
@ExcelProperty("id")
private Long id;
@Schema(description = "检验项名称", example = "赵六")
@ExcelProperty("检验项名称")
private String inspectionItemName;
@Schema(description = "检验方式")
@ExcelProperty("检验方式")
private String inspectionMethod;
@Schema(description = "判定基准")
@ExcelProperty("判定基准")
private String judgmentCriteria;
@Schema(description = "检验结果 0-待检测 1-检测通过 2-检测不通过")
@ExcelProperty("检验结果 0-待检测 1-检测通过 2-检测不通过")
private Integer inspectionResult;
@Schema(description = "图片路径")
@ExcelProperty("图片路径")
private String images;
@Schema(description = "备注", example = "你说的对")
@ExcelProperty("备注")
private String remark;
@Schema(description = "检验时间")
@ExcelProperty("检验时间")
private LocalDateTime inspectionTime;
@Schema(description = "工单管理Id")
private Long managementId;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
@Schema(description = "模具Id")
private Long moldId;
}

@ -0,0 +1,42 @@
package cn.iocoder.yudao.module.erp.controller.admin.moldticketresults.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 工单检验结果新增/修改 Request VO")
@Data
public class MoldTicketResultsSaveReqVO {
@Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED, example = "30557")
private Long id;
@Schema(description = "检验项名称", example = "赵六")
private String inspectionItemName;
@Schema(description = "工单管理Id")
private Long managementId;
@Schema(description = "检验方式")
private String inspectionMethod;
@Schema(description = "判定基准")
private String judgmentCriteria;
@Schema(description = "检验结果 0-待检测 1-检测通过 2-检测不通过")
private Integer inspectionResult;
@Schema(description = "图片路径")
private String images;
@Schema(description = "备注", example = "你说的对")
private String remark;
@Schema(description = "检验时间")
private LocalDateTime inspectionTime;
@Schema(description = "检验人")
private String inspector;
}

@ -9,6 +9,9 @@ import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.moldrepair.MoldRepairLineDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.moldticketresults.MoldTicketResultsDO;
/**
* DO
*
@ -83,4 +86,31 @@ public class MoldDO extends BaseDO {
private String fileUrl;
/**
*
*/
@TableField(exist = false)
private List<MoldTicketResultsDO> inspectionList;
/**
*
*/
@TableField(exist = false)
private List<MoldTicketResultsDO> maintainList;
/**
*
*/
@TableField(exist = false)
private Map<String,List<MoldRepairLineDO>> repairList;
@TableField(exist = false)
private String orgType;
@TableField(exist = false)
private Long moldSize;
@TableField(exist = false)
private String brandName;
@TableField(exist = false)
private String moldType;
}

@ -0,0 +1,117 @@
package cn.iocoder.yudao.module.erp.dal.dataobject.moldrepair;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import org.apache.ibatis.type.Alias;
import java.time.LocalDateTime;
/**
* DO
*
* @author
*/
@TableName("mes_mold_repair")
@KeySequence("mes_mold_repair_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Alias("ErpMoldRepairDO")
public class MoldRepairDO extends BaseDO {
/**
* ID
*/
@TableId
private Long id;
/**
*
*/
private String repairCode;
/**
*
*/
private String repairName;
/**
* ID
*/
private Long moldId;
/**
*
*/
private String moldCode;
/**
*
*/
private String moldName;
/**
*
*/
private String moldBrand;
/**
*
*/
private String moldSpec;
/**
*
*
* {@link TODO mes_machine_type }
*/
private Long moldTypeId;
/**
*
*/
private LocalDateTime requireDate;
/**
*
*/
private LocalDateTime finishDate;
/**
*
*/
private LocalDateTime confirmDate;
/**
*
*/
private String repairResult;
/**
*
*/
private String acceptedBy;
/**
*
*/
private String confirmBy;
/**
* 0- 1-
*
* {@link TODO mes_mold_record_status }
*/
private Integer status;
/**
*
*/
private String remark;
/**
* 1- 2-
*/
private Integer moldType;
/**
* Id
*/
private Long deviceId;
/**
* Id
*/
private Long componentId;
}

@ -0,0 +1,76 @@
package cn.iocoder.yudao.module.erp.dal.dataobject.moldrepair;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import org.apache.ibatis.type.Alias;
/**
* DO
*
* @author
*/
@TableName("mes_mold_repair_line")
@KeySequence("mes_mold_repair_line_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Alias("ErpMoldRepairLineDO")
public class MoldRepairLineDO extends BaseDO {
/**
* ID
*/
@TableId
private Long id;
/**
* ID
*/
private Long repairId;
/**
* ID
*/
private Long subjectId;
/**
*
*/
private String subjectCode;
/**
*
*/
private String subjectName;
/**
*
*/
private String subjectType;
/**
*
*/
private String subjectContent;
/**
*
*/
private String subjectStandard;
/**
*
*/
private String malfunction;
/**
*
*/
private String malfunctionUrl;
/**
*
*/
private String repairDes;
/**
*
*/
private String remark;
}

@ -0,0 +1,70 @@
package cn.iocoder.yudao.module.erp.dal.dataobject.moldticketresults;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import org.apache.ibatis.type.Alias;
import java.time.LocalDateTime;
/**
* DO
*
* @author
*/
@TableName("mes_mold_ticket_results")
@KeySequence("mes_mold_ticket_results_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Alias("ErpMoldTicketResultsDO")
public class MoldTicketResultsDO extends BaseDO {
/**
* id
*/
@TableId
private Long id;
/**
*
*/
private String inspectionItemName;
/**
*
*/
private String inspectionMethod;
/**
*
*/
private String judgmentCriteria;
/**
* 0- 1- 2-
*/
private Integer inspectionResult;
/**
*
*/
private String images;
/**
*
*/
private String remark;
/**
*
*/
private LocalDateTime inspectionTime;
/**
*
*/
private Long managementId;
/**
* id
*/
private Long moldId;
}

@ -0,0 +1,27 @@
package cn.iocoder.yudao.module.erp.dal.mysql.moldrepair;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.erp.dal.dataobject.moldrepair.MoldRepairLineDO;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* Mapper
*
* @author
*/
@Mapper
@Repository("erpMoldRepairLineMapper")
public interface MoldRepairLineMapper extends BaseMapperX<MoldRepairLineDO> {
default List<MoldRepairLineDO> selectListByRepairId(Long repairId) {
return selectList(MoldRepairLineDO::getRepairId, repairId);
}
default int deleteByRepairId(Long repairId) {
return delete(MoldRepairLineDO::getRepairId, repairId);
}
}

@ -0,0 +1,61 @@
package cn.iocoder.yudao.module.erp.dal.mysql.moldrepair;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.erp.controller.admin.moldrepair.vo.MoldRepairPageReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.moldrepair.MoldRepairDO;
import com.alibaba.excel.util.StringUtils;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* Mapper
*
* @author
*/
@Mapper
@Repository("erpMoldRepairMapper")
public interface MoldRepairMapper extends BaseMapperX<MoldRepairDO> {
default PageResult<MoldRepairDO> selectPage(MoldRepairPageReqVO reqVO) {
LambdaQueryWrapperX<MoldRepairDO> moldRepairDOLambdaQueryWrapperX = new LambdaQueryWrapperX<>();
moldRepairDOLambdaQueryWrapperX
.eqIfPresent(MoldRepairDO::getRepairCode, reqVO.getRepairCode())
.likeIfPresent(MoldRepairDO::getRepairName, reqVO.getRepairName())
.eqIfPresent(MoldRepairDO::getMoldId, reqVO.getMoldId())
.eqIfPresent(MoldRepairDO::getMoldCode, reqVO.getMoldCode())
.likeIfPresent(MoldRepairDO::getMoldName, reqVO.getMoldName())
.eqIfPresent(MoldRepairDO::getMoldBrand, reqVO.getMoldBrand())
.eqIfPresent(MoldRepairDO::getMoldSpec, reqVO.getMoldSpec())
.eqIfPresent(MoldRepairDO::getMoldTypeId, reqVO.getMoldTypeId())
.betweenIfPresent(MoldRepairDO::getRequireDate, reqVO.getRequireDate())
.betweenIfPresent(MoldRepairDO::getFinishDate, reqVO.getFinishDate())
.betweenIfPresent(MoldRepairDO::getConfirmDate, reqVO.getConfirmDate())
.eqIfPresent(MoldRepairDO::getRepairResult, reqVO.getRepairResult())
.eqIfPresent(MoldRepairDO::getAcceptedBy, reqVO.getAcceptedBy())
.eqIfPresent(MoldRepairDO::getConfirmBy, reqVO.getConfirmBy())
.eqIfPresent(MoldRepairDO::getStatus, reqVO.getStatus())
.eqIfPresent(MoldRepairDO::getRemark, reqVO.getRemark())
.betweenIfPresent(MoldRepairDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(MoldRepairDO::getCreateTime);
// 单独处理 ids 条件
if (StringUtils.isNotBlank(reqVO.getIds())) {
List<Long> idList = Arrays.stream(reqVO.getIds().split(","))
.map(String::trim)
.map(Long::valueOf)
.collect(Collectors.toList());
moldRepairDOLambdaQueryWrapperX.in(MoldRepairDO::getId, idList);
}
return selectPage(reqVO,moldRepairDOLambdaQueryWrapperX );
}
}

@ -0,0 +1,38 @@
package cn.iocoder.yudao.module.erp.dal.mysql.moldticketresults;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.erp.controller.admin.moldticketresults.vo.MoldTicketResultsPageReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.moldticketresults.MoldTicketResultsDO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* Mapper
*
* @author
*/
@Mapper
@Repository("erpMoldTicketResultsMapper")
public interface MoldTicketResultsMapper extends BaseMapperX<MoldTicketResultsDO> {
default PageResult<MoldTicketResultsDO> selectPage(MoldTicketResultsPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<MoldTicketResultsDO>()
.likeIfPresent(MoldTicketResultsDO::getInspectionItemName, reqVO.getInspectionItemName())
.eqIfPresent(MoldTicketResultsDO::getInspectionMethod, reqVO.getInspectionMethod())
.eqIfPresent(MoldTicketResultsDO::getJudgmentCriteria, reqVO.getJudgmentCriteria())
.eqIfPresent(MoldTicketResultsDO::getInspectionResult, reqVO.getInspectionResult())
.eqIfPresent(MoldTicketResultsDO::getImages, reqVO.getImages())
.eqIfPresent(MoldTicketResultsDO::getRemark, reqVO.getRemark())
.betweenIfPresent(MoldTicketResultsDO::getInspectionTime, reqVO.getInspectionTime())
.eqIfPresent(MoldTicketResultsDO::getManagementId, reqVO.getManagementId())
.betweenIfPresent(MoldTicketResultsDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(MoldTicketResultsDO::getId));
}
List<MoldTicketResultsDO> findByMoldIdAndPlanType(@Param("moldId") Long moldId,@Param("planType") Integer planType);
}

@ -80,6 +80,8 @@ public interface MoldBrandService {
*/
PageResult<MoldRespVO> getMoldPage(PageParam pageReqVO, Long brandId);
List<MoldDO> getMoldList();
/**
*
*

@ -9,23 +9,30 @@ import cn.iocoder.yudao.module.erp.controller.admin.mold.vo.*;
import cn.iocoder.yudao.module.erp.dal.dataobject.mold.MoldBrandDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.mold.MoldBrandProductDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.mold.MoldDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductCategoryDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.moldrepair.MoldRepairDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.moldrepair.MoldRepairLineDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.moldticketresults.MoldTicketResultsDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductUnitDO;
import cn.iocoder.yudao.module.erp.dal.mysql.mold.MoldBrandMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.mold.MoldBrandProductMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.mold.MoldMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.moldrepair.MoldRepairLineMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.moldrepair.MoldRepairMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.moldticketresults.MoldTicketResultsMapper;
import cn.iocoder.yudao.module.erp.controller.admin.moldticketmanagement.enums.MoldPlanTypeEnum;
import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
import cn.iocoder.yudao.module.erp.service.product.ErpProductUnitService;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@ -45,6 +52,12 @@ public class MoldBrandServiceImpl implements MoldBrandService {
@Resource
private MoldMapper moldMapper;
@Resource
private MoldRepairMapper moldRepairMapperRepair;
@Resource
private MoldRepairLineMapper moldRepairLineMapper;
@Resource
private MoldTicketResultsMapper moldticketResultsMapper;
@Resource
private ErpProductUnitService productUnitService;
@Resource
private ErpProductService productService;
@ -122,6 +135,11 @@ public class MoldBrandServiceImpl implements MoldBrandService {
return new PageResult<>(buildMoldVOList(pageResult.getList()), pageResult.getTotal());
}
@Override
public List<MoldDO> getMoldList() {
return moldMapper.selectList();
}
private List<MoldRespVO> buildMoldVOList(List<MoldDO> list) {
if (CollUtil.isEmpty(list)) {
return Collections.emptyList();
@ -157,7 +175,56 @@ public class MoldBrandServiceImpl implements MoldBrandService {
@Override
public MoldDO getMold(Long id) {
return moldMapper.selectById(id);
MoldDO moldDO = moldMapper.selectById(id);
Map<String,List<MoldRepairLineDO>> moldRepairDOMap=new HashMap<>();
// 关联查询品牌表并补充字段
if (moldDO != null && moldDO.getBrandId() != null) {
MoldBrandDO moldBrandDO = moldBrandMapper.selectById(moldDO.getBrandId());
if (moldBrandDO != null) {
moldDO.setBrandName(moldBrandDO.getName()); // 品牌名称
moldDO.setMoldType(moldBrandDO.getMoldType()); // 模具类型
moldDO.setMoldSize(moldBrandDO.getMoldSize()); // 模具尺寸
moldDO.setOrgType(moldBrandDO.getOrgType()); // 组织类型
}
}
//点检列表
List<MoldTicketResultsDO> inspectionList = moldticketResultsMapper.findByMoldIdAndPlanType(id, MoldPlanTypeEnum.INSPECTION.getCode());
if(CollectionUtils.isNotEmpty(inspectionList)){
moldDO.setInspectionList(inspectionList);
}
//保养列表
List<MoldTicketResultsDO> maintainList = moldticketResultsMapper.findByMoldIdAndPlanType(id, MoldPlanTypeEnum.MAINTENANCE.getCode());
if(CollectionUtils.isNotEmpty(maintainList)){
moldDO.setMaintainList(maintainList);
}
//维修列表
List<MoldRepairDO> moldRepairDOS = moldRepairMapperRepair.selectList(
Wrappers.<MoldRepairDO>lambdaQuery()
.eq(MoldRepairDO::getMoldId, id));
for (MoldRepairDO moldRepairDO : moldRepairDOS) {
List<MoldRepairLineDO> moldRepairLineDOS = moldRepairLineMapper.selectList(Wrappers.<MoldRepairLineDO>lambdaQuery()
.eq(MoldRepairLineDO::getRepairId, moldRepairDO.getId())
.orderByDesc(MoldRepairLineDO::getCreateTime));
if (!moldRepairLineDOS.isEmpty()) {
// 修复JSON序列化null Key问题保持原有风格的极简处理
String repairName = moldRepairDO.getRepairName();
if (repairName == null || repairName.trim().isEmpty()) {
repairName = "维修单-" + moldRepairDO.getId();
}
moldRepairDOMap.put(repairName, moldRepairLineDOS);
}
}
if(CollectionUtils.isNotEmpty(moldRepairDOMap)){
moldDO.setRepairList(moldRepairDOMap);
}
return moldDO;
}
@Override
public List<MoldDO> selectBy(MoldDO reqVO){
@ -225,6 +292,16 @@ public class MoldBrandServiceImpl implements MoldBrandService {
return moldBrandProductMapper.selectById(id);
}
@Override
public List<MoldDO> getAllList() {
return Collections.emptyList();
}
@Override
public List<MoldBrandDO> getMoldBrandList(Collection<Long> ids) {
return Collections.emptyList();
}
private void validateMoldBrandProductExists(Long id) {
if (moldBrandProductMapper.selectById(id) == null) {
throw exception(MOLD_BRAND_PRODUCT_NOT_EXISTS);
@ -234,14 +311,4 @@ public class MoldBrandServiceImpl implements MoldBrandService {
private void deleteMoldBrandProductByBrandId(Long brandId) {
moldBrandProductMapper.deleteByBrandId(brandId);
}
@Override
public List<MoldDO> getAllList() {
return moldMapper.selectList();
}
@Override
public List<MoldBrandDO> getMoldBrandList(Collection<Long> ids) {
return moldBrandMapper.selectBatchIds(ids);
}
}

@ -1,14 +1,6 @@
package cn.iocoder.yudao.module.erp.service.mold;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.mold.MoldBrandDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductCategoryDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductUnitDO;
import cn.iocoder.yudao.module.erp.service.product.ErpProductUnitService;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
@ -25,8 +17,6 @@ import cn.iocoder.yudao.module.erp.dal.mysql.mold.MoldMapper;
import javax.annotation.Resource;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
/**
@ -41,12 +31,6 @@ public class MoldServiceImpl implements MoldService {
@Resource
private MoldMapper moldMapper;
@Resource
private MoldBrandService moldBrandService;
@Resource
private ErpProductUnitService productUnitService;
@Override
public Long createMold(MoldSaveReqVO createReqVO) {
// 插入
@ -95,46 +79,16 @@ public class MoldServiceImpl implements MoldService {
@Override
public List<MoldDO> validMoldList(Collection<Long> ids) {
if (CollUtil.isEmpty(ids)) {
return Collections.emptyList();
}
List<MoldDO> list = moldMapper.selectBatchIds(ids);
Map<Long, MoldDO> moldMap = convertMap(list, MoldDO::getId);
for (Long id : ids) {
MoldDO mold = moldMap.get(id);
if (moldMap.get(id) == null) {
throw exception(PRODUCT_NOT_EXISTS);
}
if (CommonStatusEnum.isDisable(mold.getStatus())) {
throw exception(PRODUCT_NOT_ENABLE, mold.getName());
}
}
return list;
return Collections.emptyList();
}
@Override
public List<MoldRespVO> getMoldVOList(Collection<Long> ids) {
if (CollUtil.isEmpty(ids)) {
return Collections.emptyList();
}
List<MoldDO> list = moldMapper.selectBatchIds(ids);
return buildMoldVOList(list);
return Collections.emptyList();
}
@Override
public List<MoldRespVO> buildMoldVOList(List<MoldDO> list) {
if (CollUtil.isEmpty(list)) {
return Collections.emptyList();
}
Map<Long, MoldBrandDO> brandMap = moldBrandService.getMoldBrandMap(
convertSet(list, MoldDO::getBrandId));
Map<Long, ErpProductUnitDO> unitMap = productUnitService.getProductUnitMap(
convertSet(list, MoldDO::getUnitId));
return BeanUtils.toBean(list, MoldRespVO.class, product -> {
MapUtils.findAndThen(brandMap, product.getBrandId(),
category -> product.setBrandName(category.getName()));
MapUtils.findAndThen(unitMap, product.getUnitId(),
unit -> product.setUnitName(unit.getName()));
});
return Collections.emptyList();
}
}

@ -0,0 +1,30 @@
<?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="cn.iocoder.yudao.module.erp.dal.mysql.moldticketresults.MoldTicketResultsMapper">
<!--
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
文档可见https://www.iocoder.cn/MyBatis/x-plugins/
-->
<select id="findByMoldIdAndPlanType"
resultType="cn.iocoder.yudao.module.mes.dal.dataobject.moldticketresults.MoldTicketResultsDO">
SELECT
mtr.*
from
besure.mes_mold_ticket_results mtr
left join besure.mes_mold_ticket_management mtm on mtm.id = mtr.management_id
WHERE 1=1
<!-- 必填条件 -->
<if test="moldId != null and moldId != ''">
and mtr.mold_id = #{moldId}
</if>
<if test="planType != null and planType != ''">
and mtm.plan_type= #{planType}
</if>
order by mtr.create_time desc
</select>
</mapper>

@ -0,0 +1,60 @@
// TaskTypeEnum.java
package cn.iocoder.yudao.module.iot.controller.admin.device.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum TaskTypeEnum {
DEVICE("DEVICE", "设备数据采集"),
WORK_ORDER("WORK_ORDER", "工单生成");
/**
*
*/
private final String code;
/**
*
*/
private final String name;
/**
*
*/
public static TaskTypeEnum getByCode(String code) {
for (TaskTypeEnum type : values()) {
if (type.getCode().equals(code)) {
return type;
}
}
return null;
}
/**
*
*/
public static boolean contains(String code) {
return getByCode(code) != null;
}
/**
* ID
*/
public Long generateTaskId(Long baseId) {
if (baseId == null) {
baseId = 0L;
}
switch (this) {
case DEVICE:
return 1000000L + baseId;
case WORK_ORDER:
return 2000000L + baseId;
default:
return 9000000L + baseId;
}
}
}

@ -13,11 +13,16 @@ public class SchedulerConfig {
@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setPoolSize(20); // 设置线程池大小
scheduler.setThreadNamePrefix("scheduled-task-"); // 线程名前缀
scheduler.setAwaitTerminationSeconds(60); // 等待任务完成的秒数
scheduler.setWaitForTasksToCompleteOnShutdown(true); // 关闭时等待任务完成
scheduler.initialize(); // 初始化
scheduler.setPoolSize(50); // 增加线程数
scheduler.setThreadNamePrefix("scheduled-task-");
scheduler.setAwaitTerminationSeconds(60);
scheduler.setWaitForTasksToCompleteOnShutdown(true);
// 设置队列容量
scheduler.setPoolSize(50);
scheduler.setThreadPriority(Thread.NORM_PRIORITY);
scheduler.setDaemon(false);
scheduler.initialize();
return scheduler;
}
}

@ -0,0 +1,14 @@
package cn.iocoder.yudao.module.iot.controller.admin.device.scheduled.core;
public interface Task {
/**
*
*/
void execute(Long taskId, String taskParam);
/**
*
*/
String getTaskType();
}

@ -1,39 +1,196 @@
// DeviceTask.java - 原有设备任务
package cn.iocoder.yudao.module.iot.controller.admin.device.scheduled.coretask;
import cn.iocoder.yudao.framework.common.util.opc.OpcUtils;
import cn.iocoder.yudao.module.iot.controller.admin.device.enums.TaskTypeEnum;
import cn.iocoder.yudao.module.iot.controller.admin.device.scheduled.core.Task;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO;
import cn.iocoder.yudao.module.iot.dal.devicecontactmodel.DeviceContactModelDO;
import cn.iocoder.yudao.module.iot.dal.mysql.device.DeviceMapper;
import cn.iocoder.yudao.module.iot.dal.mysql.devicecontactmodel.DeviceContactModelMapper;
import cn.iocoder.yudao.module.iot.service.device.TDengineService;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Component
public class DeviceTask {
@Slf4j
public class DeviceTask implements Task {
private static final Logger logger = LoggerFactory.getLogger(DeviceTask.class);
/**
*
* @param deviceId ID
* @param deviceCode
*/
public void executeDeviceLogic(Long deviceId, String deviceCode) {
@Resource
private DeviceContactModelMapper deviceContactModelMapper;
@Resource
private DeviceMapper deviceMapper;
@Resource
private TDengineService tDengineService;
@Override
public String getTaskType() {
return TaskTypeEnum.DEVICE.getCode();
}
@Override
public void execute(Long taskId, String taskParam) {
try {
// 创建时间格式化对象
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String currentTime = sdf.format(new Date());
logger.info("执行设备任务设备ID: {}, 设备编码: {}, 时间: {}",
deviceId, deviceCode, currentTime);
logger.info("执行设备任务任务ID: {}, 参数: {}, 时间: {}",
taskId, taskParam, currentTime);
// 解析参数,假设格式为 deviceId:deviceCode
// String[] params = taskParam.split(":");
// if (params.length >= 2) {
// Long deviceId = Long.parseLong(params[0]);
// String deviceCode = params[1];
// executeDeviceLogic(deviceId, deviceCode);
// }
executeDeviceLogic(taskId,taskParam);
// TODO: 这里编写具体的设备执行逻辑
// 比如:读取设备数据、发送指令、处理响应等
} catch (Exception e) {
// 异常信息中也加入时间戳
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String errorTime = sdf.format(new Date());
logger.error("执行设备任务异常任务ID: {}", taskId, e);
}
}
/**
*
*/
private void executeDeviceLogic(Long sourceDeviceId, String param) {
logger.info("执行设备 {} 的具体逻辑,参数: {}", sourceDeviceId, param);
Long deviceId = sourceDeviceId - 1000000L;
logger.info("处理后id{} ", deviceId );
// 1. 参数校验
if (deviceId == null){
logger.error("设备ID不能为空");
throw new RuntimeException("设备ID不能为空");
}
// 2. 查询设备信息
DeviceDO deviceDO = deviceMapper.selectById(deviceId);
if (deviceDO == null) {
logger.error("设备不存在设备ID: {}", deviceId);
throw new RuntimeException("设备不存在设备ID: " + deviceId);
}
if (deviceDO.getUrl() == null || deviceDO.getUrl().trim().isEmpty()) {
logger.error("设备URL不能为空设备ID: {}", deviceId);
throw new RuntimeException("设备URL不能为空");
}
// 3. 连接OPC服务器
String username = deviceDO.getUsername() != null ? deviceDO.getUsername() : "";
String password = deviceDO.getPassword() != null ? deviceDO.getPassword() : "";
logger.error("执行设备任务异常设备ID: {}, 异常时间: {}",
deviceId, errorTime, e);
boolean connected = OpcUtils.connect(deviceDO.getUrl(), username, password, 10);
if (!connected) {
logger.error("连接OPC服务器失败设备ID: {}URL: {}", deviceId, deviceDO.getUrl());
throw new RuntimeException("连接OPC服务器失败");
}
// 4. 查询设备点位配置
LambdaQueryWrapper<DeviceContactModelDO> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(DeviceContactModelDO::getDeviceId, deviceId);
List<DeviceContactModelDO> deviceContactModelDOS = deviceContactModelMapper.selectList(queryWrapper);
// 5. 判断是否有点位数据
if (deviceContactModelDOS == null || deviceContactModelDOS.isEmpty()) {
logger.warn("设备 {} 没有配置数据点位,跳过数据读取", deviceId);
return;
}
logger.info("设备 {} 共有 {} 个点位需要读取", deviceId, deviceContactModelDOS.size());
// 6. 读取OPC数据
int successCount = 0;
List<DeviceContactModelDO> validDataList = new ArrayList<>();
for (DeviceContactModelDO deviceContactModelDO : deviceContactModelDOS) {
try {
// 判断点位地址是否有效
String address = deviceContactModelDO.getAddress();
if (address == null || address.trim().isEmpty()) {
logger.warn("点位ID {} 的地址为空,跳过", deviceContactModelDO.getId());
continue;
}
// 读取OPC值
Object addressValue = OpcUtils.readValue(address);
if (addressValue == null) {
logger.warn("读取点位 {} 的值返回null地址: {}",
deviceContactModelDO.getId(), address);
} else {
// 值验证
if (addressValue instanceof String) {
String strValue = (String) addressValue;
if (strValue.trim().isEmpty()) {
logger.warn("读取点位 {} 的值为空字符串", deviceContactModelDO.getId());
deviceContactModelDO.setAddressValue("");
} else {
deviceContactModelDO.setAddressValue(addressValue);
successCount++;
}
} else {
deviceContactModelDO.setAddressValue(addressValue);
successCount++;
}
}
validDataList.add(deviceContactModelDO);
} catch (Exception e) {
logger.error("读取点位 {} 异常,地址: {}",
deviceContactModelDO.getId(),
deviceContactModelDO.getAddress(), e);
}
}
// 7. 判断是否有有效数据
if (validDataList.isEmpty()) {
logger.warn("设备 {} 没有读取到任何有效数据,跳过入库", deviceId);
return;
}
logger.info("设备 {} 成功读取 {} 个点位数据,总计 {} 个点位",
deviceId, successCount, validDataList.size());
try {
// 8. 数据入库
String json = JSON.toJSONString(validDataList);
boolean insertSuccess = tDengineService.insertDeviceData(deviceId, json);
if (insertSuccess) {
logger.info("设备 {} 数据成功插入TDengine数据量: {}", deviceId, validDataList.size());
} else {
logger.error("设备 {} 数据插入TDengine失败", deviceId);
}
} catch (Exception e) {
logger.error("设备 {} 数据入库异常", deviceId, e);
} finally {
// 9. 确保断开连接
try {
OpcUtils.disconnect();
} catch (Exception e) {
logger.error("断开OPC连接异常设备ID: {}", deviceId, e);
}
}
}
}

@ -1,142 +1,283 @@
// TaskSchedulerManager.java
package cn.iocoder.yudao.module.iot.controller.admin.device.scheduled.scheduler;
import cn.iocoder.yudao.module.iot.controller.admin.device.scheduled.coretask.DeviceTask;
import cn.iocoder.yudao.module.iot.controller.admin.device.enums.TaskTypeEnum;
import cn.iocoder.yudao.module.iot.controller.admin.device.scheduled.core.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.scheduling.support.PeriodicTrigger;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.time.Duration;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
@Component
public class TaskSchedulerManager {
private static final Logger logger = LoggerFactory.getLogger(TaskSchedulerManager.class);
private TaskScheduler taskScheduler; // 移除 static
private DeviceTask deviceTask; // 移除 static
private final Map<Long, ScheduledFuture<?>> taskMap = new ConcurrentHashMap<>();
private final TaskScheduler taskScheduler;
// 存储所有任务
private final Map<String, Task> taskBeans = new ConcurrentHashMap<>();
// 存储正在运行的任务
private final Map<Long, ScheduledFuture<?>> runningTasks = new ConcurrentHashMap<>();
private final Map<Long, TaskInfo> taskInfos = new ConcurrentHashMap<>();
// 任务信息类
private static class TaskInfo {
private Long taskId;
private String taskType;
private String taskParam;
private String cronExpression;
private String scheduleType; // "CRON" 或 "FIXED_RATE" 或 "FIXED_DELAY"
private Long initialDelay;
private Long period;
private TimeUnit timeUnit;
// 构造器
public TaskInfo(Long taskId, String taskType, String taskParam) {
this.taskId = taskId;
this.taskType = taskType;
this.taskParam = taskParam;
}
// getters and setters...
}
// 通过构造器注入
public TaskSchedulerManager(TaskScheduler taskScheduler,
@Autowired(required = false) java.util.List<Task> tasks) {
this.taskScheduler = taskScheduler;
// 注册所有任务
if (tasks != null) {
for (Task task : tasks) {
taskBeans.put(task.getTaskType(), task);
logger.info("注册任务类型: {}", task.getTaskType());
}
}
}
/**
* TaskScheduler
* Spring TaskScheduler Bean
* Cron
*/
@Autowired
public TaskSchedulerManager(TaskScheduler taskScheduler) {
this.taskScheduler = taskScheduler;
public boolean startCronTask(Long taskId, String taskType, String taskParam, String cronExpression) {
return startTask(taskId, taskType, taskParam, "CRON", cronExpression, null, null, null);
}
/**
* DeviceTask
*
*/
@Autowired
public void setDeviceTask(DeviceTask deviceTask) {
this.deviceTask = deviceTask;
public boolean startFixedRateTask(Long taskId, String taskType, String taskParam,
long initialDelay, long period, TimeUnit timeUnit) {
return startTask(taskId, taskType, taskParam, "FIXED_RATE", null,
initialDelay, period, timeUnit);
}
/**
* Spring TaskScheduler Bean
*
*
*/
@PostConstruct
public void init() {
if (taskScheduler == null) {
logger.warn("TaskScheduler not found in context, creating default one");
ThreadPoolTaskScheduler defaultScheduler = new ThreadPoolTaskScheduler();
defaultScheduler.setPoolSize(10);
defaultScheduler.setThreadNamePrefix("device-task-");
defaultScheduler.initialize();
this.taskScheduler = defaultScheduler;
}
public boolean startFixedDelayTask(Long taskId, String taskType, String taskParam,
long initialDelay, long period, TimeUnit timeUnit) {
return startTask(taskId, taskType, taskParam, "FIXED_DELAY", null,
initialDelay, period, timeUnit);
}
/**
*
* static
*
*/
public boolean startDeviceTask(Long deviceId, String deviceCode, String cronExpression) {
private boolean startTask(Long taskId, String taskType, String taskParam,
String scheduleType, String cronExpression,
Long initialDelay, Long period, TimeUnit timeUnit) {
try {
// 先停止已存在的任务
stopDeviceTask(deviceId);
// 停止已存在的任务
stopTask(taskId);
// 验证 DeviceTask
if (deviceTask == null) {
logger.error("DeviceTask is not initialized");
// 获取任务实例
Task task = taskBeans.get(taskType);
if (task == null) {
logger.error("任务类型不存在: {}", taskType);
return false;
}
// 创建新的定时任务
ScheduledFuture<?> future = taskScheduler.schedule(
() -> {
try {
deviceTask.executeDeviceLogic(deviceId, deviceCode);
} catch (Exception e) {
logger.error("Device task execution failed for deviceId: {}", deviceId, e);
}
},
new CronTrigger(cronExpression)
);
taskMap.put(deviceId, future);
logger.info("启动设备定时任务成功设备ID: {}, cron表达式: {}", deviceId, cronExpression);
return true;
// 创建任务信息
TaskInfo taskInfo = new TaskInfo(taskId, taskType, taskParam);
taskInfo.scheduleType = scheduleType;
taskInfo.cronExpression = cronExpression;
taskInfo.initialDelay = initialDelay;
taskInfo.period = period;
taskInfo.timeUnit = timeUnit;
taskInfos.put(taskId, taskInfo);
// 根据调度类型创建任务
ScheduledFuture<?> future = null;
switch (scheduleType) {
case "CRON":
future = taskScheduler.schedule(
() -> task.execute(taskId, taskParam),
new CronTrigger(cronExpression)
);
break;
case "FIXED_RATE":
if (initialDelay != null && period != null && timeUnit != null) {
future = taskScheduler.scheduleAtFixedRate(
() -> task.execute(taskId, taskParam),
initialDelay
);
}
break;
case "FIXED_DELAY":
if (initialDelay != null && period != null && timeUnit != null) {
future = taskScheduler.scheduleWithFixedDelay(
() -> task.execute(taskId, taskParam),
initialDelay
);
}
break;
}
if (future != null) {
runningTasks.put(taskId, future);
logger.info("启动{}任务成功任务ID: {}, 类型: {}, 参数: {}",
scheduleType, taskId, taskType, taskParam);
return true;
}
return false;
} catch (Exception e) {
logger.error("启动设备定时任务失败设备ID: {}", deviceId, e);
logger.error("启动任务失败任务ID: {}", taskId, e);
return false;
}
}
/**
*
* static
*
*/
public boolean stopDeviceTask(Long deviceId) {
public boolean stopTask(Long taskId) {
try {
ScheduledFuture<?> future = taskMap.get(deviceId);
ScheduledFuture<?> future = runningTasks.get(taskId);
if (future != null) {
future.cancel(true);
taskMap.remove(deviceId);
logger.info("停止设备定时任务成功设备ID: {}", deviceId);
runningTasks.remove(taskId);
taskInfos.remove(taskId);
logger.info("停止任务成功任务ID: {}", taskId);
return true;
} else {
logger.info("设备定时任务不存在设备ID: {}", deviceId);
return false;
}
return false;
} catch (Exception e) {
logger.error("停止设备定时任务失败设备ID: {}", deviceId, e);
logger.error("停止任务失败任务ID: {}", taskId, e);
return false;
}
}
/**
*
*
*/
public TaskInfo getTaskInfo(Long taskId) {
return taskInfos.get(taskId);
}
/**
*
*/
public boolean isTaskRunning(Long deviceId) {
ScheduledFuture<?> future = taskMap.get(deviceId);
public boolean isTaskRunning(Long taskId) {
ScheduledFuture<?> future = runningTasks.get(taskId);
return future != null && !future.isCancelled() && !future.isDone();
}
/**
*
*
*/
public int getTaskCount() {
return taskMap.size();
public Map<String, Task> getAllTaskTypes() {
return new ConcurrentHashMap<>(taskBeans);
}
/**
*
*/
public int getRunningTaskCount() {
return runningTasks.size();
}
/**
*
*/
public void stopAllTasks() {
logger.info("停止所有定时任务,共 {} 个", taskMap.size());
for (Long deviceId : taskMap.keySet()) {
stopDeviceTask(deviceId);
logger.info("停止所有定时任务,共 {} 个", runningTasks.size());
for (Long taskId : runningTasks.keySet()) {
stopTask(taskId);
}
}
// /**
// * 原设备任务方法(保持兼容性)
// */
// public boolean startDeviceTask(Long deviceId, String deviceCode, String cronExpression) {
// String taskParam = deviceId + ":" + deviceCode;
// return startCronTask(deviceId, TaskTypeEnum.DEVICE.getCode(), taskParam, cronExpression);
// }
/**
*
*/
public boolean startDeviceTask(Long deviceId, String cronExpression) {
Long taskId = TaskTypeEnum.DEVICE.generateTaskId(deviceId);
return startCronTask(taskId, TaskTypeEnum.DEVICE.getCode(),
"device:" + deviceId, cronExpression);
}
/**
*
*/
public boolean stopDeviceTask(Long deviceId) {
if (deviceId == null) {
logger.warn("设备ID不能为空");
return false;
}
// 生成与启动时相同的任务ID
Long taskId = TaskTypeEnum.DEVICE.generateTaskId(deviceId);
logger.info("停止设备任务设备ID: {}, 生成的任务ID: {}", deviceId, taskId);
return stopTask(taskId);
}
/**
*
*/
public boolean startWorkOrderTask(Long configId, String cronExpression) {
Long taskId = TaskTypeEnum.WORK_ORDER.generateTaskId(configId);
return startCronTask(taskId, TaskTypeEnum.WORK_ORDER.getCode(),
"workOrder:" + configId, cronExpression);
}
/**
*
*/
public boolean stopWorkOrderTask(Long configId) {
if (configId == null) {
logger.warn("工单配置ID不能为空");
return false;
}
// 生成与启动时相同的任务ID
Long taskId = TaskTypeEnum.WORK_ORDER.generateTaskId(configId);
logger.info("停止工单任务配置ID: {}, 生成的任务ID: {}", configId, taskId);
return stopTask(taskId);
}
}

@ -95,6 +95,7 @@ public CommonResult<PageResult<RecipeRespVO>> getRecipePage(@Valid RecipePageReq
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<RecipeDO> list = recipeService.getRecipePage(pageReqVO).getList();
PageResult<RecipeDO> pageResult = recipeService.getRecipePage(pageReqVO);
// 导出 Excel
ExcelUtils.write(response, "配方管理主.xls", "数据", RecipeRespVO.class,
BeanUtils.toBean(list, RecipeRespVO.class));

@ -15,19 +15,25 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
@ToString(callSuper = true)
public class RecipePageReqVO extends PageParam {
@Schema(description = "配方名称", example = "李四")
@Schema(description = "配方名称", example = "赵六")
private String name;
@Schema(description = "配方编码")
private String recipeCode;
@Schema(description = "关联配方类型", example = "2")
@Schema(description = "配方类型(关联配方类型表code", example = "2")
private String recipeType;
@Schema(description = "关联产品名字", example = "赵六")
@Schema(description = "关联产品名称", example = "李四")
private String productName;
@Schema(description = "关联设备名字", example = "赵六")
@Schema(description = "关联设备ID关联iot_device.id", example = "14725")
private Long machineId;
@Schema(description = "关联设备编码(冗余字段)")
private String machineCode;
@Schema(description = "关联设备名称(冗余字段)", example = "芋艿")
private String machineName;
@Schema(description = "配方描述")
@ -43,8 +49,4 @@ public class RecipePageReqVO extends PageParam {
@Schema(description = "数据单位")
private String dataUnit;
// 新增多选导出的ids字段逗号分隔的id字符串如"1,2,3"
@Schema(description = "多选导出ID集合逗号分隔", example = "1,2,3")
private String ids;
}

@ -12,11 +12,11 @@ import com.alibaba.excel.annotation.*;
@ExcelIgnoreUnannotated
public class RecipeRespVO {
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "631")
// @ExcelProperty("主键ID")
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "6587")
@ExcelProperty("主键ID")
private Long id;
@Schema(description = "配方名称", example = "李四")
@Schema(description = "配方名称", example = "赵六")
@ExcelProperty("配方名称")
private String name;
@ -24,36 +24,40 @@ public class RecipeRespVO {
@ExcelProperty("配方编码")
private String recipeCode;
@Schema(description = "关联配方类型", example = "2")
@ExcelProperty("配方类型")
@Schema(description = "配方类型(关联配方类型表code", example = "2")
@ExcelProperty("配方类型关联配方类型表code")
private String recipeType;
@Schema(description = "关联产品名字", example = "赵六")
@ExcelProperty("关联产品")
@Schema(description = "关联产品名称", example = "李四")
@ExcelProperty("关联产品名称")
private String productName;
@Schema(description = "关联设备名字", example = "赵六")
@ExcelProperty("关联设备")
@Schema(description = "关联设备ID关联iot_device.id", example = "14725")
@ExcelProperty("关联设备ID关联iot_device.id")
private Long machineId;
@Schema(description = "关联设备编码(冗余字段)")
@ExcelProperty("关联设备编码(冗余字段)")
private String machineCode;
@Schema(description = "关联设备名称(冗余字段)", example = "芋艿")
@ExcelProperty("关联设备名称(冗余字段)")
private String machineName;
@Schema(description = "配方描述")
@ExcelProperty("备注")
@ExcelProperty("配方描述")
private String recipeDesc;
@Schema(description = "是否启用0-禁用1-启用)", requiredMode = Schema.RequiredMode.REQUIRED)
// @ExcelProperty("是否启用0-禁用1-启用)")
@ExcelProperty("是否启用0-禁用1-启用)")
private Boolean isEnable;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
// @ExcelProperty("创建时间")
@ExcelProperty("创建时间")
private LocalDateTime createTime;
@Schema(description = "数据单位")
// @ExcelProperty("数据单位")
@ExcelProperty("数据单位")
private String dataUnit;
@Schema(description = "关联设备ID", example = "1001")
// @ExcelProperty("关联设备ID")
private Long deviceId;
}

@ -1,16 +1,13 @@
package cn.iocoder.yudao.module.iot.dal.mysql.recipe;
import java.util.*;
import java.util.stream.Collectors;
import com.alibaba.excel.util.StringUtils;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
//import cn.iocoder.yudao.framework.common.util.StringUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.iot.dal.dataobject.recipe.RecipeDO;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.iot.controller.admin.recipe.vo.RecipePageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.recipe.vo.*;
/**
* Mapper
@ -21,33 +18,19 @@ import cn.iocoder.yudao.module.iot.controller.admin.recipe.vo.RecipePageReqVO;
public interface RecipeMapper extends BaseMapperX<RecipeDO> {
default PageResult<RecipeDO> selectPage(RecipePageReqVO reqVO) {
// 1. 先创建查询条件对象
LambdaQueryWrapperX<RecipeDO> queryWrapper = new LambdaQueryWrapperX<RecipeDO>()
// 原有所有查询条件(保留不变)
return selectPage(reqVO, new LambdaQueryWrapperX<RecipeDO>()
.likeIfPresent(RecipeDO::getName, reqVO.getName())
.likeIfPresent(RecipeDO::getRecipeCode, reqVO.getRecipeCode())
.eqIfPresent(RecipeDO::getRecipeCode, reqVO.getRecipeCode())
.eqIfPresent(RecipeDO::getRecipeType, reqVO.getRecipeType())
.likeIfPresent(RecipeDO::getProductName, reqVO.getProductName())
.eqIfPresent(RecipeDO::getMachineId, reqVO.getMachineId())
.eqIfPresent(RecipeDO::getMachineCode, reqVO.getMachineCode())
.likeIfPresent(RecipeDO::getMachineName, reqVO.getMachineName())
.eqIfPresent(RecipeDO::getRecipeDesc, reqVO.getRecipeDesc())
.eqIfPresent(RecipeDO::getIsEnable, reqVO.getIsEnable())
.betweenIfPresent(RecipeDO::getCreateTime, reqVO.getCreateTime())
.eqIfPresent(RecipeDO::getDataUnit, reqVO.getDataUnit())
.orderByDesc(RecipeDO::getId);
// 2. 新增处理ids多选导出条件和参考代码逻辑一致
if (StringUtils.isNotBlank(reqVO.getIds())) {
// 将逗号分隔的ids字符串转为Long类型的List
List<Long> idList = Arrays.stream(reqVO.getIds().split(","))
.map(String::trim) // 去除空格,避免空字符导致转换失败
.map(Long::valueOf) // 转为Long类型
.collect(Collectors.toList());
// 添加idIn条件只查询指定ids的记录
queryWrapper.in(RecipeDO::getId, idList);
}
// 3. 执行分页查询
return selectPage(reqVO, queryWrapper);
.orderByDesc(RecipeDO::getId));
}
}

@ -1,16 +1,11 @@
package cn.iocoder.yudao.module.iot.dal.mysql.recipetype;
import java.util.*;
import java.util.stream.Collectors;
import cn.iocoder.yudao.module.iot.controller.admin.recipe.vo.RecipePageReqVO;
import com.alibaba.excel.util.StringUtils;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.iot.dal.dataobject.recipe.RecipeDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.recipetype.RecipeTypeDO;
import com.alibaba.excel.util.StringUtils;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.iot.controller.admin.recipetype.vo.*;
@ -19,71 +14,18 @@ import cn.iocoder.yudao.module.iot.controller.admin.recipetype.vo.*;
*
* @author
*/
//@Mapper
//public interface RecipeTypeMapper extends BaseMapperX<RecipeTypeDO> {
//
// default PageResult<RecipeTypeDO> selectPage(RecipeTypePageReqVO reqVO) {
// LambdaQueryWrapperX<RecipeTypeDO> queryWrapper = new LambdaQueryWrapperX<RecipeTypeDO>()
//// return selectPage(reqVO, new LambdaQueryWrapperX<RecipeTypeDO>()
// .eqIfPresent(RecipeTypeDO::getCode, reqVO.getCode())
// .likeIfPresent(RecipeTypeDO::getName, reqVO.getName())
// .eqIfPresent(RecipeTypeDO::getProcess, reqVO.getProcess())
// .eqIfPresent(RecipeTypeDO::getRemark, reqVO.getRemark())
// .eqIfPresent(RecipeTypeDO::getSort, reqVO.getSort())
// .betweenIfPresent(RecipeTypeDO::getCreateTime, reqVO.getCreateTime())
// .orderByDesc(RecipeTypeDO::getId);
//
// // 新增处理ids多选导出条件
// if (StringUtils.isNotBlank(reqVO.getIds())) {
// List<Long> idList = Arrays.stream(reqVO.getIds().split(","))
// .map(String::trim)
// .map(Long::valueOf)
// .collect(Collectors.toList());
// queryWrapper.in(RecipeTypeDO::getId, idList);
// }
//
// return selectPage(reqVO, queryWrapper);
//
//
// }
//
//}
@Mapper
public interface RecipeTypeMapper extends BaseMapperX<RecipeTypeDO> {
// 原有selectPage方法保留不动
default PageResult<RecipeTypeDO> selectPage(RecipeTypePageReqVO reqVO) {
LambdaQueryWrapperX<RecipeTypeDO> queryWrapper = buildQueryWrapper(reqVO);
return selectPage(reqVO, queryWrapper);
}
// 新增selectList方法复用查询条件仅查全部列表解决Service报错
default List<RecipeTypeDO> selectList(RecipeTypePageReqVO reqVO) {
LambdaQueryWrapperX<RecipeTypeDO> queryWrapper = buildQueryWrapper(reqVO);
return selectList(queryWrapper); // 调用BaseMapperX的selectList方法
}
// 抽取通用查询条件构造方法(复用,避免代码重复)
default LambdaQueryWrapperX<RecipeTypeDO> buildQueryWrapper(RecipeTypePageReqVO reqVO) {
LambdaQueryWrapperX<RecipeTypeDO> queryWrapper = new LambdaQueryWrapperX<RecipeTypeDO>()
return selectPage(reqVO, new LambdaQueryWrapperX<RecipeTypeDO>()
.eqIfPresent(RecipeTypeDO::getCode, reqVO.getCode())
.likeIfPresent(RecipeTypeDO::getName, reqVO.getName())
.eqIfPresent(RecipeTypeDO::getProcess, reqVO.getProcess())
.eqIfPresent(RecipeTypeDO::getRemark, reqVO.getRemark())
.eqIfPresent(RecipeTypeDO::getSort, reqVO.getSort())
.betweenIfPresent(RecipeTypeDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(RecipeTypeDO::getId);
// 处理ids多选导出条件复用原有逻辑
if (StringUtils.isNotBlank(reqVO.getIds())) {
List<Long> idList = Arrays.stream(reqVO.getIds().split(","))
.map(String::trim)
.map(Long::valueOf)
.collect(Collectors.toList());
queryWrapper.in(RecipeTypeDO::getId, idList);
}
return queryWrapper;
.orderByDesc(RecipeTypeDO::getId));
}
}
}

@ -406,23 +406,12 @@ public class DeviceServiceImpl implements DeviceService {
deviceDO.setStatus(String.valueOf(DeviceConnectionStatusEnum.CONNECTED.getStatus()));
deviceMapper.updateById(deviceDO);
String cronExpression = CronExpressionUtils.secondsToCron(deviceDO.getSampleCycle());
//查询存储
LambdaQueryWrapper<DeviceContactModelDO> deviceModelAttributeLambdaQueryWrapper = new LambdaQueryWrapper<>();
deviceModelAttributeLambdaQueryWrapper.eq(DeviceContactModelDO::getDeviceId,createReqVO.getId());
List<DeviceContactModelDO> deviceContactModelDOS = deviceContactModelMapper.selectList(deviceModelAttributeLambdaQueryWrapper);
if (deviceContactModelDOS != null && deviceContactModelDOS.size() > 0){
for (DeviceContactModelDO deviceContactModelDO : deviceContactModelDOS) {
Object addressValue = OpcUtils.readValue(deviceContactModelDO.getAddress() != null ? deviceContactModelDO.getAddress() : "");
deviceContactModelDO.setAddressValue(addressValue);
}
String json = JSON.toJSONString(deviceContactModelDOS);
tdengineService.insertDeviceData(createReqVO.getId(),json);
}
taskSchedulerManager.startDeviceTask(
deviceDO.getId(),
cronExpression
);
}else {
@ -433,6 +422,7 @@ public class DeviceServiceImpl implements DeviceService {
if (disconnect){
deviceDO.setStatus(String.valueOf(DeviceConnectionStatusEnum.DISCONNECTED.getStatus()));
deviceMapper.updateById(deviceDO);
taskSchedulerManager.stopDeviceTask(deviceDO.getId());
}else {
throw exception(OPC_CLOSE_CONNECT_FAILURE);
}
@ -440,15 +430,6 @@ public class DeviceServiceImpl implements DeviceService {
throw exception(OPC_PARAMETER_DOES_NOT_EXIST);
}
return Boolean.TRUE;
}
@ -704,7 +685,6 @@ public class DeviceServiceImpl implements DeviceService {
// 2. 启动定时任务
boolean success = taskSchedulerManager.startDeviceTask(
deviceDO.getId(),
deviceDO.getDeviceCode(),
cronExpression
);

@ -1,129 +1,21 @@
//package cn.iocoder.yudao.module.iot.service.recipe;
//
//import cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants;
//import org.springframework.stereotype.Service;
//import javax.annotation.Resource;
//import org.springframework.validation.annotation.Validated;
//import org.springframework.transaction.annotation.Transactional;
//
//import java.util.*;
//import cn.iocoder.yudao.module.iot.controller.admin.recipe.vo.*;
//import cn.iocoder.yudao.module.iot.dal.dataobject.recipe.RecipeDO;
//import cn.iocoder.yudao.framework.common.pojo.PageResult;
//import cn.iocoder.yudao.framework.common.pojo.PageParam;
//import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
//
//import cn.iocoder.yudao.module.iot.dal.mysql.recipe.RecipeMapper;
//import cn.iocoder.yudao.module.iot.dal.mysql.device.DeviceMapper;
//
//import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
//import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*;
//
//import cn.iocoder.yudao.framework.common.exception.ServiceException;
//import cn.hutool.core.util.StrUtil;
//import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
//import cn.iocoder.yudao.framework.common.exception.ServiceException;
//
//import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO; // 引入现有DeviceDO
//import cn.iocoder.yudao.module.iot.dal.mysql.device.DeviceMapper; // 引入现有DeviceMapper
//
///**
// * 配方管理主 Service 实现类
// *
// * @author 内蒙必硕
// */
//@Service
//@Validated
//public class RecipeServiceImpl implements RecipeService {
//
// @Resource
// private RecipeMapper recipeMapper;
//
//// @Override
//// public Long createRecipe(RecipeSaveReqVO createReqVO) {
//// // 插入
//// RecipeDO recipe = BeanUtils.toBean(createReqVO, RecipeDO.class);
//// recipeMapper.insert(recipe);
//// // 返回
//// return recipe.getId();
//// }
//@Override
//public Long createRecipe(RecipeSaveReqVO createReqVO) {
// String recipeCode = createReqVO.getRecipeCode();
//
// // 1. 校验recipeCode不为空使用新增的RECIPE_CODE_EMPTY错误码
// if (StrUtil.isBlank(recipeCode)) {
// throw new ServiceException(ErrorCodeConstants.RECIPE_CODE_EMPTY);
// }
//
// // 2. 校验recipeCode是否重复使用新增的RECIPE_CODE_DUPLICATE错误码
// boolean exists = recipeMapper.exists(
// new LambdaQueryWrapperX<RecipeDO>().eq(RecipeDO::getRecipeCode, recipeCode)
// );
// if (exists) {
// throw new ServiceException(ErrorCodeConstants.RECIPE_CODE_DUPLICATE);
// }
//
// // ========== 原有逻辑保持不变 ==========
// RecipeDO recipe = BeanUtils.toBean(createReqVO, RecipeDO.class);
// recipeMapper.insert(recipe);
// return recipe.getId();
//}
//
// @Override
// public void updateRecipe(RecipeSaveReqVO updateReqVO) {
// // 校验存在
// validateRecipeExists(updateReqVO.getId());
// // 更新
// RecipeDO updateObj = BeanUtils.toBean(updateReqVO, RecipeDO.class);
// recipeMapper.updateById(updateObj);
// }
//
// @Override
// public void deleteRecipe(Long id) {
// // 校验存在
// validateRecipeExists(id);
// // 删除
// recipeMapper.deleteById(id);
// }
//
// private void validateRecipeExists(Long id) {
// if (recipeMapper.selectById(id) == null) {
// throw exception(RECIPE_NOT_EXISTS);
// }
// }
//
// @Override
// public RecipeDO getRecipe(Long id) {
// return recipeMapper.selectById(id);
// }
//
//}
package cn.iocoder.yudao.module.iot.service.recipe;
import cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.iot.controller.admin.recipe.vo.RecipePageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.recipe.vo.RecipeRespVO;
import cn.iocoder.yudao.module.iot.controller.admin.recipe.vo.RecipeSaveReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.recipe.RecipeDO;
import cn.iocoder.yudao.module.iot.dal.mysql.device.DeviceMapper;
import cn.iocoder.yudao.module.iot.dal.mysql.recipe.RecipeMapper;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.hutool.core.util.StrUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
import cn.iocoder.yudao.module.iot.controller.admin.recipe.vo.*;
import cn.iocoder.yudao.module.iot.dal.dataobject.recipe.RecipeDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.iot.dal.mysql.recipe.RecipeMapper;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.RECIPE_NOT_EXISTS;
import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*;
/**
* Service
@ -136,37 +28,30 @@ public class RecipeServiceImpl implements RecipeService {
@Resource
private RecipeMapper recipeMapper;
@Resource
private DeviceMapper deviceMapper; // 注入现有DeviceMapper
// ========== 原有方法保持不变 ==========
@Override
public Long createRecipe(RecipeSaveReqVO createReqVO) {
String recipeCode = createReqVO.getRecipeCode();
if (StrUtil.isBlank(recipeCode)) {
throw new ServiceException(ErrorCodeConstants.RECIPE_CODE_EMPTY);
}
boolean exists = recipeMapper.exists(
new LambdaQueryWrapperX<RecipeDO>().eq(RecipeDO::getRecipeCode, recipeCode)
);
if (exists) {
throw new ServiceException(ErrorCodeConstants.RECIPE_CODE_DUPLICATE);
}
// 插入
RecipeDO recipe = BeanUtils.toBean(createReqVO, RecipeDO.class);
recipeMapper.insert(recipe);
// 返回
return recipe.getId();
}
@Override
public void updateRecipe(RecipeSaveReqVO updateReqVO) {
// 校验存在
validateRecipeExists(updateReqVO.getId());
// 更新
RecipeDO updateObj = BeanUtils.toBean(updateReqVO, RecipeDO.class);
recipeMapper.updateById(updateObj);
}
@Override
public void deleteRecipe(Long id) {
// 校验存在
validateRecipeExists(id);
// 删除
recipeMapper.deleteById(id);
}
@ -186,65 +71,4 @@ public class RecipeServiceImpl implements RecipeService {
return recipeMapper.selectPage(pageReqVO);
}
// ========== 新增带deviceId的方法改为public供Controller直接调用 ==========
/**
* deviceId
*/
public PageResult<RecipeRespVO> getRecipePageWithDeviceId(RecipePageReqVO pageReqVO) {
// 1. 查询配方分页数据
PageResult<RecipeDO> recipePage = recipeMapper.selectPage(pageReqVO);
List<RecipeDO> recipeList = recipePage.getList();
if (recipeList.isEmpty()) {
return PageResult.empty(recipePage.getTotal());
}
// 2. 提取所有machineName批量查询deviceId避免N+1查询
List<String> machineNames = recipeList.stream()
.map(RecipeDO::getMachineName)
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList());
// 调用现有DeviceMapper查询设备名称->ID映射
List<DeviceDO> deviceList = deviceMapper.selectList(
new LambdaQueryWrapperX<DeviceDO>().in(DeviceDO::getDeviceName, machineNames)
);
// 构建设备名称到ID的映射处理重复名称取第一个
Map<String, Long> deviceName2IdMap = new HashMap<>();
for (DeviceDO device : deviceList) {
deviceName2IdMap.putIfAbsent(device.getDeviceName(), device.getId());
}
// 3. 转换为VO并设置deviceId
List<RecipeRespVO> respVOList = new ArrayList<>();
for (RecipeDO recipe : recipeList) {
RecipeRespVO respVO = BeanUtils.toBean(recipe, RecipeRespVO.class);
// 根据machineName关联设置deviceId
respVO.setDeviceId(deviceName2IdMap.get(recipe.getMachineName()));
respVOList.add(respVO);
}
return new PageResult<>(respVOList, recipePage.getTotal());
}
/**
* deviceId
*/
public RecipeRespVO getRecipeWithDeviceId(Long id) {
RecipeDO recipe = getRecipe(id);
if (recipe == null) {
return null;
}
RecipeRespVO respVO = BeanUtils.toBean(recipe, RecipeRespVO.class);
// 关联查询deviceId
if (recipe.getMachineName() != null) {
DeviceDO device = deviceMapper.selectOne(
new LambdaQueryWrapperX<DeviceDO>().eq(DeviceDO::getDeviceName, recipe.getMachineName())
);
if (device != null) {
respVO.setDeviceId(device.getId());
}
}
return respVO;
}
}

@ -121,15 +121,23 @@ public class TaskManagementController {
return success(true);
}
@PutMapping("/update-enabled")
@Operation(summary = "更新任务管理启用状态")
@PreAuthorize("@ss.hasPermission('mes:task-management:update')")
public CommonResult<Boolean> updateTaskManagementEnabled(@Valid @RequestBody TaskManagementUpdateEnabledReqVO updateEnabledReqVO) {
taskManagementService.updateTaskManagementEnabled(updateEnabledReqVO);
return success(true);
}
private PageResult<TaskManagementRespVO> buildPageCreatorName(PageResult<TaskManagementRespVO> planMaintenanceRespVOPageResult) {
for (TaskManagementRespVO planMaintenanceRespVO : planMaintenanceRespVOPageResult.getList()) {
AdminUserRespDTO user = adminUserApi.getUser(Long.valueOf(planMaintenanceRespVO.getCreator()));
planMaintenanceRespVO.setCreatorName( "(" + user.getUsername()+ ")" + user.getNickname());
if (user!=null){
planMaintenanceRespVO.setCreatorName( "(" + user.getUsername()+ ")" + user.getNickname());
}
}
return planMaintenanceRespVOPageResult;
}

@ -0,0 +1,143 @@
// DataSyncTask.java - 数据同步任务
package cn.iocoder.yudao.module.mes.controller.admin.taskmanagement.scheduled.coretask;
import cn.iocoder.yudao.module.iot.controller.admin.device.enums.TaskTypeEnum;
import cn.iocoder.yudao.module.iot.controller.admin.device.scheduled.core.Task;
import cn.iocoder.yudao.module.iot.service.device.TDengineService;
import cn.iocoder.yudao.module.mes.dal.dataobject.deviceledger.DeviceLedgerDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.dvsubject.DvSubjectDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.subjectplan.SubjectPlanDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.taskmanagement.TaskManagementDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.ticketmanagement.TicketManagementDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.ticketresults.TicketResultsDO;
import cn.iocoder.yudao.module.mes.dal.mysql.deviceledger.DeviceLedgerMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.dvsubject.DvSubjectMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.subjectplan.SubjectPlanMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.taskmanagement.TaskManagementMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.ticketmanagement.TicketManagementMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.ticketresults.TicketResultsMapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@Component
public class GenerateWorkOrderTask implements Task {
private static final Logger logger = LoggerFactory.getLogger(GenerateWorkOrderTask.class);
@Resource
private TaskManagementMapper taskManagementMapper;
@Resource
private DeviceLedgerMapper deviceLedgerMapper;
@Resource
private TicketManagementMapper ticketManagementMapper;
@Resource
private SubjectPlanMapper subjectPlanMapper;
@Resource
private DvSubjectMapper dvSubjectMapper;
@Resource
private TicketResultsMapper ticketResultsMapper;
@Override
public String getTaskType() {
return TaskTypeEnum.WORK_ORDER.getCode();
}
@Override
public void execute(Long taskId, String taskParam) {
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String currentTime = sdf.format(new Date());
logger.info("执行数据同步任务任务ID: {}, 参数: {}, 时间: {}",
taskId, taskParam, currentTime);
// 解析同步参数
// 格式示例: "source:target" 或 "table:condition"
generateWorkOrder(taskId);
} catch (Exception e) {
logger.error("执行数据同步任务异常任务ID: {}", taskId, e);
}
}
private void generateWorkOrder(Long taskId) {
logger.info("开始同步数据id: {}", taskId);
Long id = taskId -2000000L;
logger.info("处理后id{} ", id );
//检验数据是否存在
taskManagementMapper.selectById(id);
TaskManagementDO taskManagementDO = taskManagementMapper.selectById(id);
if (taskManagementDO == null){
return;
}
// 将逗号分隔的字符串转换为Long类型的List
List<Long> idList = Arrays.stream(taskManagementDO.getDeviceList().split(","))
.map(String::trim) // 去除可能存在的空格
.map(Long::valueOf)
.collect(Collectors.toList());
for (Long deviceId : idList) {
TicketManagementDO ticketManagementDO = new TicketManagementDO();
DeviceLedgerDO deviceLedgerDO = deviceLedgerMapper.selectById(deviceId);
ticketManagementDO.setTaskId(taskManagementDO.getId());
ticketManagementDO.setPlanNo(generatePrefixedOrderNo());
ticketManagementDO.setPlanId(taskManagementDO.getProjectForm());
ticketManagementDO.setDeviceName(deviceLedgerDO.getDeviceName());
ticketManagementDO.setPlanType(taskManagementDO.getTaskType());
ticketManagementDO.setConfigName(taskManagementDO.getName());
ticketManagementDO.setTaskEndTime(taskManagementDO.getEndDate().atStartOfDay());
// TODO 默认为内置管理员Id
ticketManagementDO.setCreator("1");
ticketManagementDO.setUpdater("1");
ticketManagementMapper.insert(ticketManagementDO);
List<SubjectPlanDO> subjectPlanDOList = subjectPlanMapper.selectList(Wrappers.<SubjectPlanDO>lambdaQuery().eq(SubjectPlanDO::getPlanId, ticketManagementDO.getPlanId()));
for (SubjectPlanDO subjectPlanDO : subjectPlanDOList) {
DvSubjectDO dvSubjectDO = dvSubjectMapper.selectById(subjectPlanDO.getSubjectId());
TicketResultsDO ticketResultsDO = new TicketResultsDO();
ticketResultsDO.setInspectionItemName(dvSubjectDO.getSubjectName());
ticketResultsDO.setInspectionMethod(dvSubjectDO.getInspectionMethod());
ticketResultsDO.setJudgmentCriteria(dvSubjectDO.getJudgmentCriteria());
ticketResultsDO.setManagementId(ticketManagementDO.getId());
ticketResultsDO.setDeviceId(deviceId);
// TODO 默认为内置管理员Id
ticketResultsDO.setCreator("1");
ticketResultsDO.setUpdater("1");
ticketResultsMapper.insert(ticketResultsDO);
}
}
}
/**
*
*/
public static String generatePrefixedOrderNo() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
String date = sdf.format(new Date());
String randomNum = String.format("%06d", new Random().nextInt(1000000));
return "E" + date + randomNum;
}
}

@ -0,0 +1,19 @@
package cn.iocoder.yudao.module.mes.controller.admin.taskmanagement.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
@Schema(description = "任务管理 - 更新启用状态 Request VO")
@Data
public class TaskManagementUpdateEnabledReqVO {
@Schema(description = "任务ID", required = true, example = "1024")
@NotNull(message = "任务ID不能为空")
private Long id;
@Schema(description = "是否启用", required = true, example = "true")
@NotNull(message = "启用状态不能为空")
private Boolean enabled;
}

@ -115,8 +115,10 @@ public class TicketManagementController {
private PageResult<TicketManagementRespVO> buildPageCreatorName(PageResult<TicketManagementRespVO> ticketManagementRespVOPageResult) {
for (TicketManagementRespVO ticketManagementRespVO : ticketManagementRespVOPageResult.getList()) {
AdminUserRespDTO user = adminUserApi.getUser(Long.valueOf(ticketManagementRespVO.getCreator()));
ticketManagementRespVO.setCreatorName( "(" + user.getUsername()+ ")" + user.getNickname());
if (ticketManagementRespVO.getCreator()!=null){
AdminUserRespDTO user = adminUserApi.getUser(Long.valueOf(ticketManagementRespVO.getCreator()));
ticketManagementRespVO.setCreatorName( "(" + user.getUsername()+ ")" + user.getNickname());
}
if (ticketManagementRespVO.getOperator()!=null){
AdminUserRespDTO operator = adminUserApi.getUser(Long.valueOf(ticketManagementRespVO.getOperator()));
ticketManagementRespVO.setOperatorName("(" + operator.getUsername()+ ")" + operator.getNickname());

@ -8,6 +8,7 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.mes.dal.dataobject.moldrepair.MoldRepairLineDO;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
/**
* Mapper
@ -15,6 +16,7 @@ import org.apache.ibatis.annotations.Mapper;
* @author
*/
@Mapper
@Repository("mesMoldRepairLineMapper")
public interface MoldRepairLineMapper extends BaseMapperX<MoldRepairLineDO> {
default List<MoldRepairLineDO> selectListByRepairId(Long repairId) {

@ -11,6 +11,7 @@ import cn.iocoder.yudao.module.mes.dal.dataobject.moldsubject.MoldSubjectDO;
import com.alibaba.excel.util.StringUtils;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.mes.controller.admin.moldrepair.vo.*;
import org.springframework.stereotype.Repository;
/**
* Mapper
@ -18,6 +19,7 @@ import cn.iocoder.yudao.module.mes.controller.admin.moldrepair.vo.*;
* @author
*/
@Mapper
@Repository("mesMoldRepairMapper")
public interface MoldRepairMapper extends BaseMapperX<MoldRepairDO> {
default PageResult<MoldRepairDO> selectPage(MoldRepairPageReqVO reqVO) {

@ -9,6 +9,7 @@ import cn.iocoder.yudao.module.mes.dal.dataobject.moldticketresults.MoldTicketRe
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.mes.controller.admin.moldticketresults.vo.*;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
/**
* Mapper
@ -16,6 +17,7 @@ import org.apache.ibatis.annotations.Param;
* @author
*/
@Mapper
@Repository("mesMoldTicketResultsMapper")
public interface MoldTicketResultsMapper extends BaseMapperX<MoldTicketResultsDO> {
default PageResult<MoldTicketResultsDO> selectPage(MoldTicketResultsPageReqVO reqVO) {

@ -33,7 +33,7 @@ public interface TicketManagementMapper extends BaseMapperX<TicketManagementDO>
.likeIfPresent(TicketManagementDO::getConfigName, reqVO.getConfigName())
.eqIfPresent(TicketManagementDO::getJobStatus, reqVO.getJobStatus())
.eqIfPresent(TicketManagementDO::getJobResult, reqVO.getJobResult())
.orderByDesc(TicketManagementDO::getCreateTime);
.orderByDesc(TicketManagementDO::getId);
// 单独处理 ids 条件

@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.mes.controller.admin.moldrepair.vo.MoldRepairPage
import cn.iocoder.yudao.module.mes.controller.admin.moldrepair.vo.MoldRepairSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.moldrepair.MoldRepairDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.moldrepair.MoldRepairLineDO;
import cn.iocoder.yudao.module.mes.dal.mysql.moldrepair.MoldRepairLineMapper;
import javax.validation.Valid;
import java.util.List;

@ -36,11 +36,11 @@ import cn.iocoder.yudao.framework.common.exception.ServiceException;
@Slf4j
@Service
@Validated
public class MoldRepairServiceImpl implements MoldRepairService {
public class MoldRepairServiceImpl implements MoldRepairService {
@Resource
@Resource(name = "mesMoldRepairMapper")
private MoldRepairMapper moldRepairMapper;
@Resource
@Resource(name = "mesMoldRepairLineMapper")
private MoldRepairLineMapper moldRepairLineMapper;
@Override

@ -35,7 +35,7 @@ import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
@Validated
public class MoldTicketResultsServiceImpl implements MoldTicketResultsService {
@Resource
@Resource(name = "mesMoldTicketResultsMapper")
private MoldTicketResultsMapper moldticketResultsMapper;
@Resource

@ -53,4 +53,6 @@ public interface TaskManagementService {
PageResult<TaskManagementDO> getTaskManagementPage(TaskManagementPageReqVO pageReqVO);
void createTicket(Long id);
void updateTaskManagementEnabled(TaskManagementUpdateEnabledReqVO updateEnabledReqVO);
}

@ -1,5 +1,7 @@
package cn.iocoder.yudao.module.mes.service.taskmanagement;
import cn.iocoder.yudao.module.iot.controller.admin.device.enums.TaskTypeEnum;
import cn.iocoder.yudao.module.iot.controller.admin.device.scheduled.scheduler.TaskSchedulerManager;
import cn.iocoder.yudao.module.mes.dal.dataobject.deviceledger.DeviceLedgerDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.dvsubject.DvSubjectDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.planmaintenance.PlanMaintenanceDO;
@ -12,7 +14,9 @@ import cn.iocoder.yudao.module.mes.dal.mysql.planmaintenance.PlanMaintenanceMapp
import cn.iocoder.yudao.module.mes.dal.mysql.subjectplan.SubjectPlanMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.ticketmanagement.TicketManagementMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.ticketresults.TicketResultsMapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
@ -40,6 +44,7 @@ import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
*/
@Service
@Validated
@Slf4j
public class TaskManagementServiceImpl implements TaskManagementService {
@Resource
@ -60,10 +65,12 @@ public class TaskManagementServiceImpl implements TaskManagementService {
@Resource
private SubjectPlanMapper subjectPlanMapper;
@Resource
private DvSubjectMapper dvSubjectMapper;
@Resource
private TaskSchedulerManager taskSchedulerManager;
@Override
public Long createTaskManagement(TaskManagementSaveReqVO createReqVO) {
// 插入
@ -121,8 +128,6 @@ public class TaskManagementServiceImpl implements TaskManagementService {
@Override
public void createTicket(Long id) {
List<TicketManagementDO> ticketManagementDOS = new ArrayList<>();
//检验数据是否存在
validateTaskManagementExists(id);
TaskManagementDO taskManagementDO = taskManagementMapper.selectById(id);
@ -136,7 +141,6 @@ public class TaskManagementServiceImpl implements TaskManagementService {
.map(Long::valueOf)
.collect(Collectors.toList());
for (Long deviceId : idList) {
TicketManagementDO ticketManagementDO = new TicketManagementDO();
DeviceLedgerDO deviceLedgerDO = deviceLedgerMapper.selectById(deviceId);
@ -149,7 +153,6 @@ public class TaskManagementServiceImpl implements TaskManagementService {
ticketManagementDO.setTaskEndTime(taskManagementDO.getEndDate().atStartOfDay());
ticketManagementMapper.insert(ticketManagementDO);
List<DvSubjectDO> dvSubjectDOList = new ArrayList<>();
List<SubjectPlanDO> subjectPlanDOList = subjectPlanMapper.selectList(Wrappers.<SubjectPlanDO>lambdaQuery().eq(SubjectPlanDO::getPlanId, ticketManagementDO.getPlanId()));
for (SubjectPlanDO subjectPlanDO : subjectPlanDOList) {
DvSubjectDO dvSubjectDO = dvSubjectMapper.selectById(subjectPlanDO.getSubjectId());
@ -167,6 +170,95 @@ public class TaskManagementServiceImpl implements TaskManagementService {
}
@Override
public void updateTaskManagementEnabled(TaskManagementUpdateEnabledReqVO updateEnabledReqVO) {
// 1. 校验任务是否存在
TaskManagementDO task = taskManagementMapper.selectById(updateEnabledReqVO.getId());
if (task == null) {
throw exception(TASK_MANAGEMENT_NOT_EXISTS);
}
// 2. 如果状态没有变化,直接返回
if (Objects.equals(task.getEnabled(), updateEnabledReqVO.getEnabled())) {
return;
}
// 3. 执行状态更新操作
executeEnableUpdate(task, updateEnabledReqVO.getEnabled());
}
/**
* /
*/
private void executeEnableUpdate(TaskManagementDO task, Boolean enabled) {
// 更新数据库状态
updateTaskStatusInDB(task.getId(), enabled);
// 处理定时任务
if (enabled) {
enableTaskSchedule(task);
} else {
disableTaskSchedule(task);
}
}
/**
*
*/
private void enableTaskSchedule(TaskManagementDO task) {
// 验证Cron表达式
if (StringUtils.isBlank(task.getCronExpression())) {
log.warn("任务{}没有配置Cron表达式无法启用调度", task.getId());
return;
}
// 启动定时任务
try {
boolean success = taskSchedulerManager.startWorkOrderTask(
task.getId(),
task.getCronExpression()
);
if (success) {
log.info("任务{}调度启动成功", task.getId());
} else {
log.error("任务{}调度启动失败", task.getId());
// 可以记录失败日志或发送通知
}
} catch (Exception e) {
log.error("任务{}调度启动异常", task.getId(), e);
// 可以考虑回滚数据库状态
}
}
/**
*
*/
private void disableTaskSchedule(TaskManagementDO task) {
try {
boolean success = taskSchedulerManager.stopWorkOrderTask(task.getId());
if (success) {
log.info("任务{}调度停止成功", task.getId());
} else {
log.warn("任务{}调度停止失败,可能任务不存在或已停止", task.getId());
}
} catch (Exception e) {
log.error("任务{}调度停止异常", task.getId(), e);
}
}
/**
*
*/
private void updateTaskStatusInDB(Long taskId, Boolean enabled) {
TaskManagementDO updateObj = new TaskManagementDO();
updateObj.setId(taskId);
updateObj.setEnabled(enabled);
taskManagementMapper.updateById(updateObj);
}
/**
*

Loading…
Cancel
Save