()
.eq(CrmCustomerLimitConfigDO::getType, type);
- query.apply("FIND_IN_SET({0}, user_ids) > 0", userId);
- if (deptId != null) {
- query.apply("FIND_IN_SET({0}, dept_ids) > 0", deptId);
- }
+ query.and(w -> {
+ w.apply("FIND_IN_SET({0}, user_ids) > 0", userId);
+ if (deptId != null) {
+ w.or().apply("FIND_IN_SET({0}, dept_ids) > 0", deptId);
+ }
+ });
return selectList(query);
}
diff --git a/yudao-module-mes/pom.xml b/yudao-module-mes/pom.xml
new file mode 100644
index 000000000..e51f660ab
--- /dev/null
+++ b/yudao-module-mes/pom.xml
@@ -0,0 +1,24 @@
+
+
+
+ cn.iocoder.cloud
+ yudao
+ ${revision}
+
+
+ yudao-module-mes-api
+ yudao-module-mes-server
+
+ 4.0.0
+ yudao-module-mes
+ pom
+
+ ${project.artifactId}
+
+ mes 包下,制造执行系统(Manufacturing Execution System)。
+ 例如说:基础数据、排班日历、设备管理、工具管理、生产管理、质量管理、仓库管理等等
+
+
+
diff --git a/yudao-module-mes/yudao-module-mes-api/pom.xml b/yudao-module-mes/yudao-module-mes-api/pom.xml
new file mode 100644
index 000000000..29a6d9bf2
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/pom.xml
@@ -0,0 +1,33 @@
+
+
+
+ cn.iocoder.cloud
+ yudao-module-mes
+ ${revision}
+
+ 4.0.0
+ yudao-module-mes-api
+ jar
+
+ ${project.artifactId}
+
+ mes 模块 API,暴露给其它模块调用
+
+
+
+
+ cn.iocoder.cloud
+ yudao-common
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+ true
+
+
+
+
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/ApiConstants.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/ApiConstants.java
new file mode 100644
index 000000000..fa678c6ee
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/ApiConstants.java
@@ -0,0 +1,23 @@
+package cn.iocoder.yudao.module.mes.enums;
+
+import cn.iocoder.yudao.framework.common.enums.RpcConstants;
+
+/**
+ * API 相关的枚举
+ *
+ * @author 芋道源码
+ */
+public class ApiConstants {
+
+ /**
+ * 服务名
+ *
+ * 注意,需要保证和 spring.application.name 保持一致
+ */
+ public static final String NAME = "mes-server";
+
+ public static final String PREFIX = RpcConstants.RPC_API_PREFIX + "/mes";
+
+ public static final String VERSION = "1.0.0";
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/DictTypeConstants.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/DictTypeConstants.java
new file mode 100644
index 000000000..ea234136e
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/DictTypeConstants.java
@@ -0,0 +1,63 @@
+package cn.iocoder.yudao.module.mes.enums;
+
+/**
+ * MES 字典类型的枚举类
+ *
+ * @author 芋道源码
+ */
+public interface DictTypeConstants {
+
+ String MES_MD_ITEM_OR_PRODUCT = "mes_md_item_or_product"; // MES 物料产品标识
+ String MES_CLIENT_TYPE = "mes_client_type"; // MES 客户类型
+ String MES_VENDOR_LEVEL = "mes_vendor_level"; // MES 供应商级别
+ String MES_CAL_HOLIDAY_TYPE = "mes_cal_holiday_type"; // MES 假期类型
+ String MES_TM_TOOL_STATUS = "mes_tm_tool_status"; // MES 工具状态
+ String MES_TM_MAINTEN_TYPE = "mes_tm_mainten_type"; // MES 保养维护类型
+ String MES_CAL_SHIFT_TYPE = "mes_cal_shift_type"; // MES 轮班方式
+ String MES_CAL_SHIFT_METHOD = "mes_cal_shift_method"; // MES 倒班方式
+ String MES_CAL_CALENDAR_TYPE = "mes_cal_calendar_type"; // MES 班组类型
+ String MES_CAL_PLAN_STATUS = "mes_cal_plan_status"; // MES 排班计划状态
+ String MES_DV_MACHINERY_STATUS = "mes_dv_machinery_status"; // MES 设备状态
+ String MES_DV_SUBJECT_TYPE = "mes_dv_subject_type"; // MES 点检保养项目类型
+ String MES_INDICATOR_TYPE = "mes_indicator_type"; // MES 检测项类型
+ String MES_QC_RESULT_TYPE = "mes_qc_result_type"; // MES 质检结果值类型
+ String MES_DEFECT_TYPE = "mes_defect_type"; // MES 缺陷检测项类型
+ String MES_DEFECT_LEVEL = "mes_defect_level"; // MES 缺陷等级
+ String MES_PRO_WORK_ORDER_STATUS = "mes_pro_work_order_status"; // MES 生产工单状态
+ String MES_PRO_WORK_ORDER_SOURCE_TYPE = "mes_pro_work_order_source_type"; // MES 工单来源类型
+ String MES_PRO_WORK_ORDER_TYPE = "mes_pro_work_order_type"; // MES 工单类型
+ String MES_QC_TYPE = "mes_qc_type"; // MES 检测种类(IQC/IPQC/OQC/RQC)
+ String MES_PRO_LINK_TYPE = "mes_pro_link_type"; // MES 工序关系类型
+ String MES_TIME_UNIT_TYPE = "mes_time_unit_type"; // MES 时间单位
+ String MES_IPQC_TYPE = "mes_ipqc_type"; // MES IPQC 检验类型
+ String MES_ORDER_STATUS = "mes_order_status"; // MES 单据状态(IQC/IPQC/OQC/RQC 通用)
+ String MES_QC_CHECK_RESULT = "mes_qc_check_result"; // MES 检测结果
+ String MES_QC_SOURCE_DOC_TYPE = "mes_qc_source_doc_type"; // MES 来源单据类型
+ String MES_DV_CYCLE_TYPE = "mes_dv_cycle_type"; // MES 点检保养周期类型
+ String MES_DV_CHECK_PLAN_STATUS = "mes_dv_check_plan_status"; // MES 点检保养方案状态
+ String MES_MAINTEN_RECORD_STATUS = "mes_mainten_record_status"; // MES 保养记录状态
+ String MES_MAINTEN_STATUS = "mes_mainten_status"; // MES 保养结果
+ String MES_DV_CHECK_RECORD_STATUS = "mes_dv_check_record_status"; // MES 点检记录状态
+ String MES_DV_CHECK_RESULT = "mes_dv_check_result"; // MES 点检结果
+ String MES_DV_REPAIR_STATUS = "mes_dv_repair_status"; // MES 维修工单状态
+ String MES_DV_REPAIR_RESULT = "mes_dv_repair_result"; // MES 维修结果
+ String MES_PRO_ANDON_STATUS = "mes_pro_andon_status"; // MES 安灯处置状态
+ String MES_PRO_ANDON_LEVEL = "mes_pro_andon_level"; // MES 安灯级别
+ String MES_PRO_WORK_RECORD_TYPE = "mes_pro_work_record_type"; // MES 上下工状态类型
+ String MES_PRO_FEEDBACK_STATUS = "mes_pro_feedback_status"; // MES 生产报工状态
+ String MES_PRO_FEEDBACK_TYPE = "mes_pro_feedback_type"; // MES 生产报工类型
+ String MES_PRO_FEEDBACK_CHANNEL = "mes_pro_feedback_channel"; // MES 生产报工途径
+ String MES_WM_ARRIVAL_NOTICE_STATUS = "mes_wm_arrival_notice_status"; // MES 到货通知单状态
+ String MES_WM_ITEM_RECEIPT_STATUS = "mes_wm_item_receipt_status"; // MES 采购入库单状态
+ String MES_WM_PRODUCT_PRODUCE_STATUS = "mes_wm_product_produce_status"; // MES 生产入库单状态
+ String MES_WM_RETURN_VENDOR_STATUS = "mes_wm_return_vendor_status"; // MES 供应商退货单状态
+ String MES_WM_QUALITY_STATUS = "mes_wm_quality_status"; // MES 质量状态(待检/合格/不合格)
+ String MES_WM_RETURN_ISSUE_STATUS = "mes_wm_return_issue_status"; // MES 生产退料单状态
+ String MES_WM_RETURN_ISSUE_TYPE = "mes_wm_return_issue_type"; // MES 生产退料类型
+ String MES_WM_MISC_ISSUE_TYPE = "mes_wm_misc_issue_type"; // MES 杂项出库类型
+ String MES_WM_MISC_ISSUE_STATUS = "mes_wm_misc_issue_status"; // MES 杂项出库单状态
+ String MES_WM_SALES_NOTICE_STATUS = "mes_wm_sales_notice_status"; // MES 发货通知单状态
+ String MES_WM_TRANSFER_STATUS = "mes_wm_transfer_status"; // MES 转移单状态
+ String MES_WM_TRANSFER_TYPE = "mes_wm_transfer_type"; // MES 转移单类型
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
new file mode 100644
index 000000000..aaee1b8f6
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
@@ -0,0 +1,647 @@
+package cn.iocoder.yudao.module.mes.enums;
+
+import cn.iocoder.yudao.framework.common.exception.ErrorCode;
+
+/**
+ * MES 错误码枚举类
+ *
+ * mes 系统,使用 1-040-000-000 段
+ */
+public interface ErrorCodeConstants {
+
+ // ========== MES 基础数据-物料分类(1-040-100-000) ==========
+ ErrorCode MD_ITEM_TYPE_NOT_EXISTS = new ErrorCode(1_040_100_000, "物料分类不存在");
+ ErrorCode MD_ITEM_TYPE_EXITS_CHILDREN = new ErrorCode(1_040_100_001, "存在子分类,无法删除");
+ ErrorCode MD_ITEM_TYPE_PARENT_NOT_EXITS = new ErrorCode(1_040_100_002, "父级分类不存在");
+ ErrorCode MD_ITEM_TYPE_PARENT_ERROR = new ErrorCode(1_040_100_003, "不能设置自己为父分类");
+ ErrorCode MD_ITEM_TYPE_NAME_DUPLICATE = new ErrorCode(1_040_100_004, "同一父分类下已存在该名称的分类");
+ ErrorCode MD_ITEM_TYPE_CODE_DUPLICATE = new ErrorCode(1_040_100_005, "同一父分类下已存在该编码的分类");
+ ErrorCode MD_ITEM_TYPE_PARENT_IS_CHILD = new ErrorCode(1_040_100_006, "不能设置自己的子分类为父分类");
+ ErrorCode MD_ITEM_TYPE_EXITS_ITEM = new ErrorCode(1_040_100_007, "该分类下存在物料,无法删除");
+
+ // ========== MES 基础数据-计量单位(1-040-101-000) ==========
+ ErrorCode MD_UNIT_MEASURE_NOT_EXISTS = new ErrorCode(1_040_101_000, "计量单位不存在");
+ ErrorCode MD_UNIT_MEASURE_CODE_DUPLICATE = new ErrorCode(1_040_101_001, "计量单位编码已存在");
+ ErrorCode MD_UNIT_MEASURE_HAS_ITEM = new ErrorCode(1_040_101_002, "该计量单位下存在物料,无法删除");
+
+ // ========== MES 基础数据-物料(1-040-102-000) ==========
+ ErrorCode MD_ITEM_NOT_EXISTS = new ErrorCode(1_040_102_000, "物料不存在");
+ ErrorCode MD_ITEM_CODE_DUPLICATE = new ErrorCode(1_040_102_001, "物料编码已存在");
+ ErrorCode MD_ITEM_NAME_DUPLICATE = new ErrorCode(1_040_102_002, "物料名称已存在");
+ ErrorCode MD_ITEM_IMPORT_LIST_IS_EMPTY = new ErrorCode(1_040_102_003, "导入物料数据不能为空");
+ ErrorCode MD_ITEM_BATCH_REQUIRED = new ErrorCode(1_040_102_004, "当前物料启用了批次管理,请选择批次");
+
+ // ========== MES 基础数据-物料批次属性配置(1-040-102-100) ==========
+ ErrorCode MD_ITEM_BATCH_CONFIG_NOT_EXISTS = new ErrorCode(1_040_102_100, "物料批次属性配置不存在");
+ ErrorCode MD_ITEM_BATCH_CONFIG_AT_LEAST_ONE_FLAG = new ErrorCode(1_040_102_101, "批次管理已启用,至少需要配置一个批次属性");
+ ErrorCode MD_ITEM_PRODUCT_BOM_REQUIRED = new ErrorCode(1_040_102_102, "产品类物料启用前,必须配置至少一个 BOM 组成");
+
+ // ========== MES 仓库管理-批次管理(1-040-717-000) ==========
+ ErrorCode WM_BATCH_PRODUCE_DATE_REQUIRED = new ErrorCode(1_040_717_000, "批次配置要求生产日期不能为空");
+ ErrorCode WM_BATCH_RECEIPT_DATE_REQUIRED = new ErrorCode(1_040_717_001, "批次配置要求入库日期不能为空");
+ ErrorCode WM_BATCH_EXPIRE_DATE_REQUIRED = new ErrorCode(1_040_717_002, "批次配置要求有效期不能为空");
+ ErrorCode WM_BATCH_VENDOR_REQUIRED = new ErrorCode(1_040_717_003, "批次配置要求供应商不能为空");
+ ErrorCode WM_BATCH_CLIENT_REQUIRED = new ErrorCode(1_040_717_004, "批次配置要求客户不能为空");
+ ErrorCode WM_BATCH_PURCHASE_ORDER_CODE_REQUIRED = new ErrorCode(1_040_717_005, "批次配置要求采购订单编号不能为空");
+ ErrorCode WM_BATCH_CUSTOMER_ORDER_CODE_REQUIRED = new ErrorCode(1_040_717_006, "批次配置要求销售订单编号不能为空");
+ ErrorCode WM_BATCH_WORK_ORDER_REQUIRED = new ErrorCode(1_040_717_007, "批次配置要求生产工单不能为空");
+ ErrorCode WM_BATCH_TASK_REQUIRED = new ErrorCode(1_040_717_008, "批次配置要求生产任务不能为空");
+ ErrorCode WM_BATCH_WORKSTATION_REQUIRED = new ErrorCode(1_040_717_009, "批次配置要求工作站不能为空");
+ ErrorCode WM_BATCH_TOOL_REQUIRED = new ErrorCode(1_040_717_010, "批次配置要求工具不能为空");
+ ErrorCode WM_BATCH_MOLD_REQUIRED = new ErrorCode(1_040_717_011, "批次配置要求模具不能为空");
+ ErrorCode WM_BATCH_LOT_NUMBER_REQUIRED = new ErrorCode(1_040_717_012, "批次配置要求生产批号不能为空");
+ ErrorCode WM_BATCH_QUALITY_STATUS_REQUIRED = new ErrorCode(1_040_717_013, "批次配置要求质量状态不能为空");
+
+ // ========== MES 基础数据-客户(1-040-103-000) ==========
+ ErrorCode MD_CLIENT_NOT_EXISTS = new ErrorCode(1_040_103_000, "客户不存在");
+ ErrorCode MD_CLIENT_CODE_DUPLICATE = new ErrorCode(1_040_103_001, "客户编码已存在");
+ ErrorCode MD_CLIENT_NAME_DUPLICATE = new ErrorCode(1_040_103_002, "客户名称已存在");
+ ErrorCode MD_CLIENT_NICKNAME_DUPLICATE = new ErrorCode(1_040_103_003, "客户简称已存在");
+ ErrorCode MD_CLIENT_IMPORT_LIST_IS_EMPTY = new ErrorCode(1_040_103_004, "导入客户数据不能为空");
+
+ // ========== MES 基础数据-供应商(1-040-104-000) ==========
+ ErrorCode MD_VENDOR_NOT_EXISTS = new ErrorCode(1_040_104_000, "供应商不存在");
+ ErrorCode MD_VENDOR_CODE_DUPLICATE = new ErrorCode(1_040_104_001, "供应商编码已存在");
+ ErrorCode MD_VENDOR_NAME_DUPLICATE = new ErrorCode(1_040_104_002, "供应商名称已存在");
+ ErrorCode MD_VENDOR_NICKNAME_DUPLICATE = new ErrorCode(1_040_104_003, "供应商简称已存在");
+ ErrorCode MD_VENDOR_IMPORT_LIST_IS_EMPTY = new ErrorCode(1_040_104_004, "导入供应商数据不能为空");
+ ErrorCode MD_VENDOR_HAS_REFERENCE = new ErrorCode(1_040_104_005, "该供应商已被其他业务引用,无法删除");
+
+ // ========== MES 基础数据-车间(1-040-105-000) ==========
+ ErrorCode MD_WORKSHOP_NOT_EXISTS = new ErrorCode(1_040_105_000, "车间不存在");
+ ErrorCode MD_WORKSHOP_CODE_DUPLICATE = new ErrorCode(1_040_105_001, "车间编码已存在");
+ ErrorCode MD_WORKSHOP_NAME_DUPLICATE = new ErrorCode(1_040_105_002, "车间名称已存在");
+ ErrorCode MD_WORKSHOP_HAS_WORKSTATION = new ErrorCode(1_040_105_003, "车间下存在工作站,无法删除");
+
+ // ========== MES 基础数据-工作站(1-040-106-000) ==========
+ ErrorCode MD_WORKSTATION_NOT_EXISTS = new ErrorCode(1_040_106_000, "工作站不存在");
+ ErrorCode MD_WORKSTATION_CODE_DUPLICATE = new ErrorCode(1_040_106_001, "工作站编码已存在");
+ ErrorCode MD_WORKSTATION_NAME_DUPLICATE = new ErrorCode(1_040_106_002, "工作站名称已存在");
+ // ========== MES 基础数据-设备资源(1-040-106-100) ==========
+ ErrorCode MD_WORKSTATION_MACHINE_NOT_EXISTS = new ErrorCode(1_040_106_100, "设备资源记录不存在");
+ ErrorCode MD_WORKSTATION_MACHINE_EXISTS = new ErrorCode(1_040_106_101, "该设备已分配至工作站:{}");
+ // ========== MES 基础数据-工装夹具资源(1-040-106-200) ==========
+ ErrorCode MD_WORKSTATION_TOOL_NOT_EXISTS = new ErrorCode(1_040_106_200, "工装夹具资源记录不存在");
+ ErrorCode MD_WORKSTATION_TOOL_TYPE_EXISTS = new ErrorCode(1_040_106_201, "该工具类型已在此工作站中存在");
+ // ========== MES 基础数据-人力资源(1-040-106-300) ==========
+ ErrorCode MD_WORKSTATION_WORKER_NOT_EXISTS = new ErrorCode(1_040_106_300, "人力资源记录不存在");
+ ErrorCode MD_WORKSTATION_WORKER_POST_EXISTS = new ErrorCode(1_040_106_301, "该岗位已在此工作站中存在");
+
+ // ========== MES 基础数据-产品BOM(1-040-107-000) ==========
+ ErrorCode MD_PRODUCT_BOM_NOT_EXISTS = new ErrorCode(1_040_107_000, "产品BOM不存在");
+ ErrorCode MD_PRODUCT_BOM_SELF_REFERENCE = new ErrorCode(1_040_107_001, "产品不能作为自身的BOM物料");
+ ErrorCode MD_PRODUCT_BOM_CIRCULAR = new ErrorCode(1_040_107_002, "BOM物料存在闭环,无法新增");
+
+ // ========== MES 基础数据-产品SOP(1-040-108-000) ==========
+ ErrorCode MD_PRODUCT_SOP_NOT_EXISTS = new ErrorCode(1_040_108_000, "产品SOP不存在");
+ ErrorCode MD_PRODUCT_SOP_SORT_DUPLICATE = new ErrorCode(1_040_108_001, "该展示序号已存在");
+
+ // ========== MES 基础数据-产品SIP(1-040-109-000) ==========
+ ErrorCode MD_PRODUCT_SIP_NOT_EXISTS = new ErrorCode(1_040_109_000, "产品SIP不存在");
+ ErrorCode MD_PRODUCT_SIP_SORT_DUPLICATE = new ErrorCode(1_040_109_001, "该展示序号已存在");
+
+ // ========== MES 基础数据-编码规则(1-040-110-000) ==========
+ ErrorCode AUTO_CODE_RULE_NOT_EXISTS = new ErrorCode(1_040_110_000, "编码规则不存在");
+ ErrorCode AUTO_CODE_RULE_CODE_DUPLICATE = new ErrorCode(1_040_110_001, "规则编码已存在");
+ ErrorCode AUTO_CODE_PART_NOT_EXISTS = new ErrorCode(1_040_110_002, "规则组成不存在");
+ ErrorCode AUTO_CODE_REDIS_ERROR = new ErrorCode(1_040_110_003, "编码生成服务不可用,请稍后重试");
+ ErrorCode AUTO_CODE_GENERATE_FAILED = new ErrorCode(1_040_110_004, "编码生成失败");
+ ErrorCode AUTO_CODE_PART_SERIAL_NUMBER_DUPLICATE = new ErrorCode(1_040_110_005, "流水号分段只能存在一个");
+
+ // ========== MES 日历排班-计划班次(1-040-200-000) ==========
+ ErrorCode CAL_PLAN_SHIFT_NOT_EXISTS = new ErrorCode(1_040_200_000, "计划班次不存在");
+ ErrorCode CAL_PLAN_SHIFT_COUNT_EXCEED = new ErrorCode(1_040_200_001, "班次数量已达到轮班方式的上限");
+
+ // ========== MES 日历排班-班组(1-040-201-000) ==========
+ ErrorCode CAL_TEAM_NOT_EXISTS = new ErrorCode(1_040_201_000, "班组不存在");
+ ErrorCode CAL_TEAM_CODE_DUPLICATE = new ErrorCode(1_040_201_001, "班组编码已存在");
+ // ========== MES 日历排班-班组成员(1-040-201-100) ==========
+ ErrorCode CAL_TEAM_MEMBER_NOT_EXISTS = new ErrorCode(1_040_201_100, "班组成员不存在");
+ ErrorCode CAL_TEAM_MEMBER_USER_DUPLICATE = new ErrorCode(1_040_201_101, "该用户已分配到其他班组");
+ ErrorCode CAL_TEAM_MEMBER_USER_NOT_EXISTS = new ErrorCode(1_040_201_102, "用户不存在");
+ // ========== MES 日历排班-班组排班(1-040-201-200) ==========
+ ErrorCode CAL_TEAM_SHIFT_NOT_EXISTS = new ErrorCode(1_040_201_200, "班组排班记录不存在");
+ ErrorCode CAL_TEAM_SHIFT_GENERATE_TEAM_NOT_ENOUGH = new ErrorCode(1_040_201_201, "班组数量不满足轮班方式要求");
+ ErrorCode CAL_TEAM_SHIFT_GENERATE_SHIFT_NOT_ENOUGH = new ErrorCode(1_040_201_202, "班次数量不满足轮班方式要求");
+
+ // ========== MES 日历排班-排班计划(1-040-202-000) ==========
+ ErrorCode CAL_PLAN_NOT_EXISTS = new ErrorCode(1_040_202_000, "排班计划不存在");
+ ErrorCode CAL_PLAN_CODE_DUPLICATE = new ErrorCode(1_040_202_001, "排班计划编码已存在");
+ ErrorCode CAL_PLAN_NOT_PREPARE = new ErrorCode(1_040_202_002, "排班计划已确认,不允许修改或删除");
+ ErrorCode CAL_PLAN_TEAM_COUNT_NOT_MATCH = new ErrorCode(1_040_202_003, "确认排班计划时,分配的班组数量与轮班方式不匹配");
+ // ========== MES 日历排班-计划班组关联(1-040-202-100) ==========
+ ErrorCode CAL_PLAN_TEAM_NOT_EXISTS = new ErrorCode(1_040_202_100, "计划班组关联不存在");
+ ErrorCode CAL_PLAN_TEAM_DUPLICATE = new ErrorCode(1_040_202_101, "该班组已分配到此计划");
+
+ // ========== MES 日历排班-假期设置(1-040-203-000) ==========
+ ErrorCode CAL_HOLIDAY_NOT_EXISTS = new ErrorCode(1_040_203_000, "假期设置不存在");
+
+ // ========== MES 设备管理-设备类型(1-040-300-000) ==========
+ ErrorCode DV_MACHINERY_TYPE_NOT_EXISTS = new ErrorCode(1_040_300_000, "设备类型不存在");
+ ErrorCode DV_MACHINERY_TYPE_EXITS_CHILDREN = new ErrorCode(1_040_300_001, "存在子类型,无法删除");
+ ErrorCode DV_MACHINERY_TYPE_PARENT_NOT_EXITS = new ErrorCode(1_040_300_002, "父级类型不存在");
+ ErrorCode DV_MACHINERY_TYPE_PARENT_ERROR = new ErrorCode(1_040_300_003, "不能设置自己为父类型");
+ ErrorCode DV_MACHINERY_TYPE_NAME_DUPLICATE = new ErrorCode(1_040_300_004, "同一父类型下已存在该名称");
+ ErrorCode DV_MACHINERY_TYPE_CODE_DUPLICATE = new ErrorCode(1_040_300_005, "设备类型编码已存在");
+ ErrorCode DV_MACHINERY_TYPE_PARENT_IS_CHILD = new ErrorCode(1_040_300_006, "不能设置自己的子类型为父类型");
+ ErrorCode DV_MACHINERY_TYPE_HAS_MACHINERY = new ErrorCode(1_040_300_007, "该类型下存在设备,无法删除");
+
+ // ========== MES 设备管理-设备台账(1-040-301-000) ==========
+ ErrorCode DV_MACHINERY_NOT_EXISTS = new ErrorCode(1_040_301_000, "设备不存在");
+ ErrorCode DV_MACHINERY_CODE_DUPLICATE = new ErrorCode(1_040_301_001, "设备编码已存在");
+ ErrorCode DV_MACHINERY_IMPORT_LIST_IS_EMPTY = new ErrorCode(1_040_301_002, "导入设备数据不能为空");
+ ErrorCode DV_MACHINERY_HAS_CHECK_PLAN = new ErrorCode(1_040_301_003, "设备已关联点检计划,无法删除");
+ ErrorCode DV_MACHINERY_HAS_CHECK_RECORD = new ErrorCode(1_040_301_004, "设备已关联点检记录,无法删除");
+ ErrorCode DV_MACHINERY_HAS_MAINTEN_RECORD = new ErrorCode(1_040_301_005, "设备已关联保养记录,无法删除");
+ ErrorCode DV_MACHINERY_HAS_REPAIR = new ErrorCode(1_040_301_006, "设备已关联维修工单,无法删除");
+
+ // ========== MES 设备管理-点检保养项目(1-040-304-000) ==========
+ ErrorCode DV_SUBJECT_NOT_EXISTS = new ErrorCode(1_040_304_000, "点检保养项目不存在");
+ ErrorCode DV_SUBJECT_CODE_DUPLICATE = new ErrorCode(1_040_304_001, "项目编码已存在");
+ ErrorCode DV_SUBJECT_USED_BY_CHECK_PLAN = new ErrorCode(1_040_304_002, "点检保养项目已被点检保养方案使用,无法删除");
+
+ // ========== MES 设备管理-点检计划(1-040-302-000) ==========
+ ErrorCode DV_CHECK_PLAN_NOT_EXISTS = new ErrorCode(1_040_302_000, "点检计划不存在");
+ ErrorCode DV_CHECK_PLAN_CODE_DUPLICATE = new ErrorCode(1_040_302_001, "点检保养方案编码已存在");
+ ErrorCode DV_CHECK_PLAN_NOT_PREPARE = new ErrorCode(1_040_302_002, "点检保养方案已启用,不允许修改或删除");
+ ErrorCode DV_CHECK_PLAN_NO_MACHINERY = new ErrorCode(1_040_302_003, "启用方案时,至少需要关联一台设备");
+ ErrorCode DV_CHECK_PLAN_NO_SUBJECT = new ErrorCode(1_040_302_004, "启用方案时,至少需要关联一个点检保养项目");
+ ErrorCode DV_CHECK_PLAN_NOT_ENABLED = new ErrorCode(1_040_302_005, "点检保养方案未启用,不允许停用");
+ // ========== MES 设备管理-点检方案设备(1-040-302-100) ==========
+ ErrorCode DV_CHECK_PLAN_MACHINERY_NOT_EXISTS = new ErrorCode(1_040_302_100, "点检保养方案设备不存在");
+ ErrorCode DV_CHECK_PLAN_MACHINERY_DUPLICATE = new ErrorCode(1_040_302_101, "该设备已关联到当前方案,请勿重复添加");
+ ErrorCode DV_CHECK_PLAN_MACHINERY_EXISTS_IN_SAME_TYPE = new ErrorCode(1_040_302_102, "该设备已存在于同类型的其他启用的或草稿的方案中,不允许同一设备添加多个同类型的方案");
+ // ========== MES 设备管理-点检方案项目(1-040-302-200) ==========
+ ErrorCode DV_CHECK_PLAN_SUBJECT_NOT_EXISTS = new ErrorCode(1_040_302_200, "点检保养方案项目不存在");
+ ErrorCode DV_CHECK_PLAN_SUBJECT_DUPLICATE = new ErrorCode(1_040_302_201, "该项目已关联到当前方案,请勿重复添加");
+
+ // ========== MES 设备管理-维修工单(1-040-303-000) ==========
+ ErrorCode DV_REPAIR_NOT_EXISTS = new ErrorCode(1_040_303_000, "维修工单不存在");
+ ErrorCode DV_REPAIR_NOT_PREPARE = new ErrorCode(1_040_303_001, "维修工单不是草稿状态,不允许修改或删除");
+ ErrorCode DV_REPAIR_CODE_DUPLICATE = new ErrorCode(1_040_303_002, "维修工单编码已存在");
+ ErrorCode DV_REPAIR_NOT_CONFIRMED = new ErrorCode(1_040_303_003, "只有维修中状态的维修工单才能完成维修");
+ ErrorCode DV_REPAIR_NOT_APPROVING = new ErrorCode(1_040_303_004, "只有待验收状态的维修工单才能验收");
+ // ========== MES 设备管理-维修工单行(1-040-303-100) ==========
+ ErrorCode DV_REPAIR_LINE_NOT_EXISTS = new ErrorCode(1_040_303_100, "维修工单行不存在");
+
+ // ========== MES 设备管理-保养记录(1-040-305-000) ==========
+ ErrorCode MAINTEN_RECORD_NOT_EXISTS = new ErrorCode(1_040_305_000, "设备保养记录不存在");
+ ErrorCode MAINTEN_RECORD_NOT_DRAFT = new ErrorCode(1_040_305_001, "设备保养记录已提交,不允许修改或删除");
+ ErrorCode MAINTEN_RECORD_NO_LINE = new ErrorCode(1_040_305_002, "提交保养记录时,至少需要一条保养项目");
+ // ========== MES 设备管理-保养记录明细(1-040-305-100) ==========
+ ErrorCode MAINTEN_RECORD_LINE_NOT_EXISTS = new ErrorCode(1_040_305_100, "设备保养记录明细不存在");
+
+ // ========== MES 设备管理-点检记录(1-040-306-000) ==========
+ ErrorCode DV_CHECK_RECORD_NOT_EXISTS = new ErrorCode(1_040_306_000, "设备点检记录不存在");
+ ErrorCode DV_CHECK_RECORD_NOT_DRAFT = new ErrorCode(1_040_306_001, "设备点检记录已完成,不允许修改或删除");
+ ErrorCode DV_CHECK_RECORD_NO_LINE = new ErrorCode(1_040_306_002, "提交点检记录时,至少需要一条点检项目");
+ // ========== MES 设备管理-点检记录明细(1-040-306-100) ==========
+ ErrorCode DV_CHECK_RECORD_LINE_NOT_EXISTS = new ErrorCode(1_040_306_100, "设备点检记录明细不存在");
+
+ // ========== MES 工具管理-工具类型(1-040-400-000) ==========
+ ErrorCode TM_TOOL_TYPE_NOT_EXISTS = new ErrorCode(1_040_400_000, "工具类型不存在");
+ ErrorCode TM_TOOL_TYPE_CODE_DUPLICATE = new ErrorCode(1_040_400_001, "工具类型编码已存在");
+ ErrorCode TM_TOOL_TYPE_NAME_DUPLICATE = new ErrorCode(1_040_400_002, "工具类型名称已存在");
+ ErrorCode TM_TOOL_TYPE_HAS_TOOL = new ErrorCode(1_040_400_003, "该工具类型下存在工具,无法删除");
+
+ // ========== MES 工具管理-工具台账(1-040-401-000) ==========
+ ErrorCode TM_TOOL_NOT_EXISTS = new ErrorCode(1_040_401_000, "工具不存在");
+ ErrorCode TM_TOOL_CODE_DUPLICATE = new ErrorCode(1_040_401_001, "工具编码已存在");
+
+ // ========== MES 生产管理-工序(1-040-500-000) ==========
+ ErrorCode PRO_PROCESS_NOT_EXISTS = new ErrorCode(1_040_500_000, "工序不存在");
+ ErrorCode PRO_PROCESS_CODE_EXISTS = new ErrorCode(1_040_500_001, "工序编码已存在");
+ ErrorCode PRO_PROCESS_NAME_EXISTS = new ErrorCode(1_040_500_002, "工序名称已存在");
+ ErrorCode PRO_PROCESS_USED_BY_ROUTE = new ErrorCode(1_040_500_003, "工序已被工艺路线引用,无法删除");
+ // ========== MES 生产管理-工序内容(1-040-500-100) ==========
+ ErrorCode PRO_PROCESS_CONTENT_NOT_EXISTS = new ErrorCode(1_040_500_100, "工序内容不存在");
+
+ // ========== MES 生产管理-工艺路线(1-040-501-000) ==========
+ ErrorCode PRO_ROUTE_NOT_EXISTS = new ErrorCode(1_040_501_000, "工艺路线不存在");
+ ErrorCode PRO_ROUTE_CODE_DUPLICATE = new ErrorCode(1_040_501_001, "工艺路线编码已存在");
+ ErrorCode PRO_ROUTE_ENABLE_NO_PROCESS = new ErrorCode(1_040_501_002, "请先添加组成工序");
+ ErrorCode PRO_ROUTE_ENABLE_NO_KEY_PROCESS = new ErrorCode(1_040_501_003, "工艺路线必须要有关键工序");
+ ErrorCode PRO_ROUTE_ENABLE_PRODUCT_NO_BOM = new ErrorCode(1_040_501_004, "产品 {} 未配置工序的 BOM 消耗");
+ ErrorCode PRO_ROUTE_IS_ENABLE = new ErrorCode(1_040_501_005, "工艺路线已启用,不允许操作");
+ // ========== MES 生产管理-工艺路线工序(1-040-501-100) ==========
+ ErrorCode PRO_ROUTE_PROCESS_NOT_EXISTS = new ErrorCode(1_040_501_100, "工艺路线工序不存在");
+ ErrorCode PRO_ROUTE_PROCESS_SORT_DUPLICATE = new ErrorCode(1_040_501_101, "序号已存在");
+ ErrorCode PRO_ROUTE_PROCESS_DUPLICATE = new ErrorCode(1_040_501_102, "不能重复添加工序");
+ ErrorCode PRO_ROUTE_PROCESS_KEY_DUPLICATE = new ErrorCode(1_040_501_103, "当前工艺路线已经指定过关键工序");
+ // ========== MES 生产管理-工艺路线产品(1-040-501-200) ==========
+ ErrorCode PRO_ROUTE_PRODUCT_NOT_EXISTS = new ErrorCode(1_040_501_200, "工艺路线产品不存在");
+ ErrorCode PRO_ROUTE_PRODUCT_ITEM_DUPLICATE = new ErrorCode(1_040_501_201, "此产品已配置了工艺路线");
+ // ========== MES 生产管理-工艺路线产品BOM(1-040-501-300) ==========
+ ErrorCode PRO_ROUTE_PRODUCT_BOM_NOT_EXISTS = new ErrorCode(1_040_501_300, "工艺路线产品 BOM 不存在");
+ ErrorCode PRO_ROUTE_PRODUCT_BOM_DUPLICATE = new ErrorCode(1_040_501_301, "当前 BOM 物料在此工序已经配置过");
+
+ // ========== MES 生产管理-生产工单(1-040-502-000) ==========
+ ErrorCode PRO_WORK_ORDER_NOT_EXISTS = new ErrorCode(1_040_502_000, "生产工单不存在");
+ ErrorCode PRO_WORK_ORDER_CODE_DUPLICATE = new ErrorCode(1_040_502_001, "生产工单编码已存在");
+ ErrorCode PRO_WORK_ORDER_NOT_PREPARE = new ErrorCode(1_040_502_002, "只有草稿状态的工单才能执行此操作");
+ ErrorCode PRO_WORK_ORDER_NOT_CONFIRMED = new ErrorCode(1_040_502_003, "只有已确认状态的工单才能执行此操作");
+ ErrorCode PRO_WORK_ORDER_HAS_CHILDREN = new ErrorCode(1_040_502_004, "存在子工单,无法删除");
+ ErrorCode PRO_WORK_ORDER_BOM_NOT_EXISTS = new ErrorCode(1_040_502_100, "生产工单BOM不存在");
+
+ // ========== MES 生产管理-生产任务(1-040-503-000) ==========
+ ErrorCode PRO_TASK_NOT_EXISTS = new ErrorCode(1_040_503_000, "生产任务不存在");
+ ErrorCode PRO_TASK_ALREADY_FINISHED = new ErrorCode(1_040_503_001, "生产任务已完成或已取消,不能继续操作");
+ // ========== MES 生产管理-生产任务投料(1-040-503-100) ==========
+ ErrorCode PRO_TASK_ISSUE_NOT_EXISTS = new ErrorCode(1_040_503_100, "生产任务投料记录不存在");
+
+ // ========== MES 生产管理-安灯呼叫配置(1-040-504-000) ==========
+ ErrorCode PRO_ANDON_CONFIG_NOT_EXISTS = new ErrorCode(1_040_504_000, "安灯呼叫配置不存在");
+
+ // ========== MES 生产管理-安灯呼叫记录(1-040-505-000) ==========
+ ErrorCode PRO_ANDON_RECORD_NOT_EXISTS = new ErrorCode(1_040_505_000, "安灯呼叫记录不存在");
+ ErrorCode PRO_ANDON_RECORD_ALREADY_HANDLED = new ErrorCode(1_040_505_001, "安灯记录已处置,不允许重复处置");
+ ErrorCode PRO_ANDON_RECORD_HANDLE_TIME_REQUIRED = new ErrorCode(1_040_505_002, "标记已处置时,处置时间不能为空");
+ ErrorCode PRO_ANDON_RECORD_HANDLER_USER_REQUIRED = new ErrorCode(1_040_505_003, "标记已处置时,处置人不能为空");
+
+ // ========== MES 生产管理-生产报工(1-040-506-000) ==========
+ ErrorCode PRO_FEEDBACK_NOT_EXISTS = new ErrorCode(1_040_506_000, "生产报工不存在");
+ ErrorCode PRO_FEEDBACK_NOT_PREPARE = new ErrorCode(1_040_506_001, "只能修改或删除草稿状态的报工单");
+ ErrorCode PRO_FEEDBACK_NOT_APPROVING = new ErrorCode(1_040_506_002, "只有审批中状态的报工单才能执行此操作");
+ ErrorCode PRO_FEEDBACK_NOT_UNCHECK = new ErrorCode(1_040_506_003, "只有待检验状态的报工单才能完成检验");
+ ErrorCode PRO_FEEDBACK_QUANTITY_EXCEED = new ErrorCode(1_040_506_004, "报工数量不能超过排产数量");
+ ErrorCode PRO_FEEDBACK_STATUS_ERROR = new ErrorCode(1_040_506_005, "报工单状态不正确,无法执行此操作");
+ ErrorCode PRO_FEEDBACK_WORK_ORDER_NOT_CONFIRMED = new ErrorCode(1_040_506_006, "关联的工单未确认,无法创建报工");
+ ErrorCode PRO_FEEDBACK_QUALIFIED_UNQUALIFIED_MISMATCH = new ErrorCode(1_040_506_007, "合格品数量与不良品数量之和必须等于报工数量");
+ ErrorCode PRO_FEEDBACK_ROUTE_PROCESS_INVALID = new ErrorCode(1_040_506_008, "未找到对应的工艺工序配置,请检查工艺路线与工序");
+ ErrorCode PRO_FEEDBACK_TASK_OR_ORDER_FINISHED = new ErrorCode(1_040_506_009, "当前生产任务或工单已完成,不能继续报工");
+ ErrorCode PRO_FEEDBACK_QUANTITY_MUST_POSITIVE = new ErrorCode(1_040_506_010, "报工数量必须大于 0");
+ ErrorCode PRO_FEEDBACK_QUALIFIED_UNQUALIFIED_REQUIRED = new ErrorCode(1_040_506_011, "请输入合格品和不良品数量,且合计须大于 0");
+ ErrorCode PRO_FEEDBACK_UNCHECK_QUANTITY_EXISTS = new ErrorCode(1_040_506_012, "当前报工单未完成检验(待检数量:{}),无法执行报工");
+
+ // ========== MES 生产管理-生产流转卡(1-040-507-000) ==========
+ ErrorCode PRO_CARD_NOT_EXISTS = new ErrorCode(1_040_507_000, "生产流转卡不存在");
+ ErrorCode PRO_CARD_CODE_DUPLICATE = new ErrorCode(1_040_507_001, "流转卡编码已存在");
+ ErrorCode PRO_CARD_STATUS_ERROR = new ErrorCode(1_040_507_002, "流转卡状态不正确");
+ ErrorCode PRO_CARD_CANCEL_NOT_ALLOWED = new ErrorCode(1_040_507_003, "已完成或已取消的流转卡不允许取消");
+ // ========== MES 生产管理-流转卡工序(1-040-507-100) ==========
+ ErrorCode PRO_CARD_PROCESS_NOT_EXISTS = new ErrorCode(1_040_507_100, "流转卡工序记录不存在");
+
+ // ========== MES 生产管理-工作记录(1-040-508-000) ==========
+ ErrorCode WORK_RECORD_NOT_CLOCK_IN = new ErrorCode(1_040_508_001, "当前用户未上工,无法下工");
+ ErrorCode WORK_RECORD_ALREADY_CLOCK_IN = new ErrorCode(1_040_508_002, "当前用户已上工,请先下工再操作");
+
+ // ========== MES 质量管理-质检方案(1-040-600-000) ==========
+ ErrorCode QC_TEMPLATE_NOT_EXISTS = new ErrorCode(1_040_600_000, "质检方案不存在");
+ ErrorCode QC_TEMPLATE_CODE_DUPLICATE = new ErrorCode(1_040_600_001, "质检方案编号已存在");
+ // ========== MES 质量管理-质检方案检测指标项(1-040-600-100) ==========
+ ErrorCode QC_TEMPLATE_INDICATOR_NOT_EXISTS = new ErrorCode(1_040_600_100, "质检方案检测指标项不存在");
+ // ========== MES 质量管理-质检方案产品关联(1-040-600-200) ==========
+ ErrorCode QC_TEMPLATE_ITEM_NOT_EXISTS = new ErrorCode(1_040_600_200, "质检方案产品关联不存在");
+ ErrorCode QC_TEMPLATE_ITEM_DUPLICATE = new ErrorCode(1_040_600_201, "该产品已关联此质检方案");
+
+ // ========== MES 质量管理-质检指标(1-040-601-000) ==========
+ ErrorCode QC_INDICATOR_NOT_EXISTS = new ErrorCode(1_040_601_000, "质检指标不存在");
+ ErrorCode QC_INDICATOR_CODE_DUPLICATE = new ErrorCode(1_040_601_001, "质检指标编码已存在");
+ ErrorCode QC_INDICATOR_NAME_DUPLICATE = new ErrorCode(1_040_601_002, "质检指标名称已存在");
+ ErrorCode QC_INDICATOR_RESULT_SPECIFICATION_REQUIRED = new ErrorCode(1_040_601_003, "结果值属性不能为空");
+
+ // ========== MES 质量管理-缺陷类型(1-040-602-000) ==========
+ ErrorCode QC_DEFECT_NOT_EXISTS = new ErrorCode(1_040_602_000, "缺陷类型不存在");
+ ErrorCode QC_DEFECT_CODE_DUPLICATE = new ErrorCode(1_040_602_001, "缺陷类型编码已存在");
+ ErrorCode QC_DEFECT_NAME_DUPLICATE = new ErrorCode(1_040_602_002, "缺陷类型名称已存在");
+
+ // ========== MES 质量管理-来料检验 IQC(1-040-603-000) ==========
+ ErrorCode QC_IQC_NOT_EXISTS = new ErrorCode(1_040_603_000, "来料检验单不存在");
+ ErrorCode QC_IQC_CODE_DUPLICATE = new ErrorCode(1_040_603_001, "来料检验单编号已存在");
+ ErrorCode QC_IQC_NOT_PREPARE = new ErrorCode(1_040_603_002, "只有草稿状态的检验单才可操作");
+ ErrorCode QC_IQC_QUANTITY_MISMATCH = new ErrorCode(1_040_603_004, "合格品与不合格品数量之和须等于检测数量");
+ ErrorCode QC_NO_TEMPLATE = new ErrorCode(1_040_603_005, "当前产品未配置检测模板");
+ ErrorCode QC_IQC_SOURCE_DOC_PARAMS_MISSING = new ErrorCode(1_040_603_006, "来源单据类型非空时,来源单据 ID 和来源单据行 ID 不能为空");
+ ErrorCode QC_IQC_CHECK_RESULT_EMPTY = new ErrorCode(1_040_603_007, "完成检验单前,检测结果必须填写");
+ // ========== MES 质量管理-来料检验行(1-040-603-100) ==========
+ ErrorCode QC_IQC_LINE_NOT_EXISTS = new ErrorCode(1_040_603_100, "来料检验行不存在");
+
+ // ========== MES 质量管理-过程检验 IPQC(1-040-604-000) ==========
+ ErrorCode QC_IPQC_NOT_EXISTS = new ErrorCode(1_040_604_000, "过程检验单不存在");
+ ErrorCode QC_IPQC_CODE_DUPLICATE = new ErrorCode(1_040_604_001, "过程检验单编号已存在");
+ ErrorCode QC_IPQC_NOT_PREPARE = new ErrorCode(1_040_604_002, "只有草稿状态的检验单才可操作");
+ ErrorCode QC_IPQC_QUANTITY_MISMATCH = new ErrorCode(1_040_604_004, "合格品与不合格品数量之和须等于检测数量");
+ ErrorCode QC_IPQC_NO_TEMPLATE = new ErrorCode(1_040_604_005, "当前产品未配置 IPQC 检测模板");
+ ErrorCode QC_IPQC_CHECK_RESULT_EMPTY = new ErrorCode(1_040_604_006, "完成检验单前,检测结果必须填写");
+ // ========== MES 质量管理-过程检验行(1-040-604-100) ==========
+ ErrorCode QC_IPQC_LINE_NOT_EXISTS = new ErrorCode(1_040_604_100, "过程检验行不存在");
+
+ // ========== MES 质量管理-质检缺陷记录(通用)(1-040-605-000) ==========
+ ErrorCode QC_DEFECT_RECORD_NOT_EXISTS = new ErrorCode(1_040_605_000, "缺陷记录不存在");
+ ErrorCode QC_DEFECT_RECORD_LEVEL_UNKNOWN = new ErrorCode(1_040_605_001, "未知的缺陷等级");
+ ErrorCode QC_DEFECT_RECORD_QC_TYPE_UNSUPPORTED = new ErrorCode(1_040_605_002, "不支持的检验类型");
+
+ // ========== MES 质量管理-检验结果(1-040-606-000) ==========
+ ErrorCode QC_RESULT_NOT_EXISTS = new ErrorCode(1_040_606_000, "检验结果不存在");
+
+ // ========== MES 质量管理-出货检验(1-040-607-000) ==========
+ ErrorCode QC_OQC_NOT_EXISTS = new ErrorCode(1_040_607_000, "出货检验单不存在");
+ ErrorCode QC_OQC_CODE_DUPLICATE = new ErrorCode(1_040_607_001, "出货检验单编号已存在");
+ ErrorCode QC_OQC_NOT_PREPARE = new ErrorCode(1_040_607_002, "只有草稿状态的检验单才可操作");
+ ErrorCode QC_OQC_QUANTITY_MISMATCH = new ErrorCode(1_040_607_004, "合格品与不合格品数量之和须等于检测数量");
+ ErrorCode QC_OQC_NO_TEMPLATE = new ErrorCode(1_040_607_005, "当前产品未配置 OQC 检测模板");
+ ErrorCode QC_OQC_CHECK_RESULT_EMPTY = new ErrorCode(1_040_607_006, "完成检验单前,检测结果必须填写");
+ // ========== MES 质量管理-出货检验行(1-040-607-100) ==========
+ ErrorCode QC_OQC_LINE_NOT_EXISTS = new ErrorCode(1_040_607_100, "出货检验行不存在");
+
+ // ========== MES 质量管理-退货检验 RQC(1-040-608-000) ==========
+ ErrorCode QC_RQC_NOT_EXISTS = new ErrorCode(1_040_608_000, "退货检验单不存在");
+ ErrorCode QC_RQC_CODE_DUPLICATE = new ErrorCode(1_040_608_001, "退货检验单编号已存在");
+ ErrorCode QC_RQC_NOT_PREPARE = new ErrorCode(1_040_608_002, "只有草稿状态的检验单才可操作");
+ ErrorCode QC_RQC_QUANTITY_MISMATCH = new ErrorCode(1_040_608_004, "合格品与不合格品数量之和须等于检测数量");
+ ErrorCode QC_RQC_NO_TEMPLATE = new ErrorCode(1_040_608_005, "当前产品未配置 RQC 检测模板");
+ ErrorCode QC_RQC_CHECK_RESULT_EMPTY = new ErrorCode(1_040_608_006, "完成检验单前,检测结果必须填写");
+ // ========== MES 质量管理-退货检验行(1-040-608-100) ==========
+ ErrorCode QC_RQC_LINE_NOT_EXISTS = new ErrorCode(1_040_608_100, "退货检验行不存在");
+
+ // ========== MES 仓库管理-仓库(1-040-700-000) ==========
+ ErrorCode WM_WAREHOUSE_NOT_EXISTS = new ErrorCode(1_040_700_000, "仓库不存在");
+ ErrorCode WM_WAREHOUSE_CODE_DUPLICATE = new ErrorCode(1_040_700_001, "仓库编码已存在");
+ ErrorCode WM_WAREHOUSE_NAME_DUPLICATE = new ErrorCode(1_040_700_002, "仓库名称已存在");
+ ErrorCode WM_WAREHOUSE_HAS_LOCATION = new ErrorCode(1_040_700_003, "仓库下存在库区,无法删除");
+ ErrorCode WM_WAREHOUSE_HAS_WORKSTATION = new ErrorCode(1_040_700_004, "仓库已被工作站引用,无法删除");
+ ErrorCode WM_WAREHOUSE_HAS_MATERIAL_STOCK = new ErrorCode(1_040_700_005, "仓库下有库存记录,无法删除");
+ ErrorCode WM_WAREHOUSE_IS_VIRTUAL = new ErrorCode(1_040_700_006, "虚拟仓库不允许操作");
+
+ // ========== MES 仓库管理-库区(1-040-701-000) ==========
+ ErrorCode WM_WAREHOUSE_LOCATION_NOT_EXISTS = new ErrorCode(1_040_701_000, "库区不存在");
+ ErrorCode WM_WAREHOUSE_LOCATION_CODE_DUPLICATE = new ErrorCode(1_040_701_001, "同一仓库下库区编码已存在");
+ ErrorCode WM_WAREHOUSE_LOCATION_NAME_DUPLICATE = new ErrorCode(1_040_701_002, "同一仓库下库区名称已存在");
+ ErrorCode WM_WAREHOUSE_LOCATION_HAS_AREA = new ErrorCode(1_040_701_003, "库区下存在库位,无法删除");
+ ErrorCode WM_WAREHOUSE_LOCATION_HAS_WORKSTATION = new ErrorCode(1_040_701_004, "库区已被工作站引用,无法删除");
+ ErrorCode WM_WAREHOUSE_REQUIRED = new ErrorCode(1_040_701_005, "选择库区时,仓库不能为空");
+ ErrorCode WM_WAREHOUSE_LOCATION_RELATION_INVALID = new ErrorCode(1_040_701_006, "库区不属于所选仓库");
+ ErrorCode WM_WAREHOUSE_LOCATION_HAS_MATERIAL_STOCK = new ErrorCode(1_040_701_007, "库区下有库存记录,无法删除");
+ ErrorCode WM_WAREHOUSE_LOCATION_IS_VIRTUAL = new ErrorCode(1_040_701_008, "虚拟库区不允许操作");
+
+ // ========== MES 仓库管理-库位(1-040-702-000) ==========
+ ErrorCode WM_WAREHOUSE_AREA_NOT_EXISTS = new ErrorCode(1_040_702_000, "库位不存在");
+ ErrorCode WM_WAREHOUSE_AREA_CODE_DUPLICATE = new ErrorCode(1_040_702_001, "同一库区下库位编码已存在");
+ ErrorCode WM_WAREHOUSE_AREA_NAME_DUPLICATE = new ErrorCode(1_040_702_002, "同一库区下库位名称已存在");
+ ErrorCode WM_WAREHOUSE_AREA_HAS_WORKSTATION = new ErrorCode(1_040_702_003, "库位已被工作站引用,无法删除");
+ ErrorCode WM_WAREHOUSE_LOCATION_REQUIRED = new ErrorCode(1_040_702_004, "选择库位时,库区不能为空");
+ ErrorCode WM_WAREHOUSE_AREA_RELATION_INVALID = new ErrorCode(1_040_702_005, "库位不属于所选库区");
+ ErrorCode WM_WAREHOUSE_AREA_HAS_MATERIAL_STOCK = new ErrorCode(1_040_702_006, "库位下有库存记录,无法删除");
+ ErrorCode WM_WAREHOUSE_AREA_WAREHOUSE_MISMATCH = new ErrorCode(1_040_702_007, "库位不属于所选仓库");
+ ErrorCode WM_WAREHOUSE_AREA_IS_VIRTUAL = new ErrorCode(1_040_702_008, "虚拟库位不允许操作");
+
+ // ========== MES 仓库管理-库存(1-040-703-000) ==========
+ ErrorCode WM_MATERIAL_STOCK_NOT_EXISTS = new ErrorCode(1_040_703_000, "库存记录不存在");
+ ErrorCode WM_MATERIAL_STOCK_INSUFFICIENT = new ErrorCode(1_040_703_001, "库存数量不足");
+ ErrorCode WM_TRANSACTION_TYPE_NOT_EXISTS = new ErrorCode(1_040_703_002, "库存事务类型不存在");
+ ErrorCode WM_TRANSACTION_WAREHOUSE_FROZEN = new ErrorCode(1_040_703_003, "仓库({})已被冻结");
+ ErrorCode WM_TRANSACTION_LOCATION_FROZEN = new ErrorCode(1_040_703_004, "库区({})已被冻结");
+ ErrorCode WM_TRANSACTION_AREA_FROZEN = new ErrorCode(1_040_703_005, "库位({})已被冻结");
+ ErrorCode WM_TRANSACTION_STOCK_FROZEN = new ErrorCode(1_040_703_006, "存放于({}/{}/{})下的物料已被冻结");
+ ErrorCode WM_TRANSACTION_BATCH_REQUIRED = new ErrorCode(1_040_703_007, "当前物料启用了批次管理,批次号不能为空");
+ ErrorCode WM_MATERIAL_STOCK_AREA_ITEM_MIXING_NOT_ALLOWED = new ErrorCode(1_040_703_008, "库位({})不允许物料混放,请选择其他库位");
+ ErrorCode WM_MATERIAL_STOCK_AREA_BATCH_MIXING_NOT_ALLOWED = new ErrorCode(1_040_703_009, "库位({})不允许批次混放,请选择其他库位");
+ ErrorCode WM_TRANSACTION_RELATED_NOT_EXISTS = new ErrorCode(1_040_703_010, "关联的库存事务不存在");
+ ErrorCode WM_TRANSACTION_LIST_EMPTY = new ErrorCode(1_040_703_011, "库存事务列表不能为空");
+ ErrorCode WM_TRANSACTION_BATCH_NOT_EXISTS = new ErrorCode(1_040_703_012, "批次记录不存在");
+
+ // ========== MES 仓库管理-到货通知单(1-040-704-000) ==========
+ ErrorCode WM_ARRIVAL_NOTICE_NOT_EXISTS = new ErrorCode(1_040_704_000, "到货通知单不存在");
+ ErrorCode WM_ARRIVAL_NOTICE_CODE_DUPLICATE = new ErrorCode(1_040_704_001, "到货通知单编码已存在");
+ ErrorCode WM_ARRIVAL_NOTICE_STATUS_NOT_PREPARE = new ErrorCode(1_040_704_002, "只有草稿状态才允许此操作");
+ ErrorCode WM_ARRIVAL_NOTICE_STATUS_NOT_PENDING_QC = new ErrorCode(1_040_704_003, "只有待质检状态才允许审批");
+ ErrorCode WM_ARRIVAL_NOTICE_STATUS_NOT_PENDING_RECEIPT = new ErrorCode(1_040_704_004, "只有待入库状态才允许完成");
+ ErrorCode WM_ARRIVAL_NOTICE_IQC_PENDING = new ErrorCode(1_040_704_005, "存在待检验行,无法审批通过");
+ ErrorCode WM_ARRIVAL_NOTICE_NO_LINE = new ErrorCode(1_040_704_006, "至少需要一条行项目");
+ ErrorCode WM_ARRIVAL_NOTICE_LINE_NOT_EXISTS = new ErrorCode(1_040_704_100, "到货通知单行不存在");
+ ErrorCode WM_ARRIVAL_NOTICE_LINE_NOT_MATCH = new ErrorCode(1_040_704_101, "到货通知单行不属于指定的到货通知单");
+
+ // ========== MES 仓库管理-采购入库单(1-040-705-000) ==========
+ ErrorCode WM_ITEM_RECEIPT_NOT_EXISTS = new ErrorCode(1_040_705_000, "采购入库单不存在");
+ ErrorCode WM_ITEM_RECEIPT_CODE_DUPLICATE = new ErrorCode(1_040_705_001, "采购入库单编码已存在");
+ ErrorCode WM_ITEM_RECEIPT_STATUS_NOT_PREPARE = new ErrorCode(1_040_705_002, "只有草稿或待上架状态才允许此操作");
+ ErrorCode WM_ITEM_RECEIPT_NO_LINE = new ErrorCode(1_040_705_003, "至少需要一条行项目");
+ ErrorCode WM_ITEM_RECEIPT_DETAIL_QUANTITY_MISMATCH = new ErrorCode(1_040_705_004, "明细上架总数与行入库数量不匹配");
+ ErrorCode WM_ITEM_RECEIPT_STATUS_ERROR = new ErrorCode(1_040_705_005, "入库单状态不正确");
+ ErrorCode WM_ITEM_RECEIPT_CANCEL_NOT_ALLOWED = new ErrorCode(1_040_705_006, "已完成或已取消的入库单不允许取消");
+ ErrorCode WM_ITEM_RECEIPT_LINE_NOT_EXISTS = new ErrorCode(1_040_705_100, "采购入库单行不存在");
+ ErrorCode WM_ITEM_RECEIPT_LINE_ARRIVAL_NOTICE_LINE_REQUIRED = new ErrorCode(1_040_705_101,
+ "入库单关联了到货通知单,必须选择到货通知单行");
+ ErrorCode WM_ITEM_RECEIPT_LINE_ARRIVAL_NOTICE_LINE_NOT_ALLOWED = new ErrorCode(1_040_705_102,
+ "入库单未关联到货通知单,不能选择到货通知单行");
+ ErrorCode WM_ITEM_RECEIPT_DETAIL_NOT_EXISTS = new ErrorCode(1_040_705_200, "采购入库明细不存在");
+ ErrorCode WM_ITEM_RECEIPT_DETAIL_QUANTITY_EXCEED = new ErrorCode(1_040_705_202, "上架明细总数量不能超过行入库数量");
+
+ // ========== MES 仓库管理-领料申请单(1-040-706-000) ==========
+ ErrorCode WM_MATERIAL_REQUEST_NOT_EXISTS = new ErrorCode(1_040_706_000, "领料申请单不存在");
+ ErrorCode WM_MATERIAL_REQUEST_STATUS_INVALID = new ErrorCode(1_040_706_001, "领料申请单状态不正确,无法执行该操作");
+ ErrorCode WM_MATERIAL_REQUEST_LINE_NOT_EXISTS = new ErrorCode(1_040_706_100, "领料申请单行不存在");
+
+ // ========== MES 仓库管理-外协发料单(1-040-707-000) ==========
+ ErrorCode WM_OUTSOURCE_ISSUE_NOT_EXISTS = new ErrorCode(1_040_707_000, "外协发料单不存在");
+ ErrorCode WM_OUTSOURCE_ISSUE_CODE_DUPLICATE = new ErrorCode(1_040_707_001, "外协发料单编码已存在");
+ ErrorCode WM_OUTSOURCE_ISSUE_STATUS_NOT_PREPARE = new ErrorCode(1_040_707_002, "只有草稿状态才允许此操作");
+ ErrorCode WM_OUTSOURCE_ISSUE_NO_LINE = new ErrorCode(1_040_707_003, "至少需要一条发料行");
+ ErrorCode WM_OUTSOURCE_ISSUE_QUANTITY_MISMATCH = new ErrorCode(1_040_707_004, "发料单行数量与明细数量不一致");
+ ErrorCode WM_OUTSOURCE_ISSUE_STATUS_NOT_APPROVING = new ErrorCode(1_040_707_005, "只有待拣货状态才允许此操作");
+ ErrorCode WM_OUTSOURCE_ISSUE_STATUS_NOT_APPROVED = new ErrorCode(1_040_707_006, "只有待执行出库状态才允许此操作");
+ ErrorCode WM_OUTSOURCE_ISSUE_CANCEL_NOT_ALLOWED = new ErrorCode(1_040_707_007, "已完成或已取消的发料单不允许取消");
+ ErrorCode WM_OUTSOURCE_ISSUE_LINE_NOT_EXISTS = new ErrorCode(1_040_707_100, "外协发料单行不存在");
+ ErrorCode WM_OUTSOURCE_ISSUE_LINE_ITEM_NOT_IN_BOM = new ErrorCode(1_040_707_101, "发料单行对应的物料不在当前工单的 BOM 列表中");
+ ErrorCode WM_OUTSOURCE_ISSUE_DETAIL_NOT_EXISTS = new ErrorCode(1_040_707_200, "外协发料单明细不存在");
+ ErrorCode WM_OUTSOURCE_ISSUE_WORK_ORDER_TYPE_INVALID = new ErrorCode(1_040_707_008, "工单类型不是外协(代工)类型");
+
+ // ========== MES 仓库管理-生产领料出库单(1-040-708-000) ==========
+ ErrorCode WM_PRODUCT_ISSUE_NOT_EXISTS = new ErrorCode(1_040_708_000, "生产领料出库单不存在");
+ ErrorCode WM_PRODUCT_ISSUE_STATUS_INVALID = new ErrorCode(1_040_708_001, "生产领料出库单状态不正确,无法执行该操作");
+ ErrorCode WM_PRODUCT_ISSUE_NO_LINE = new ErrorCode(1_040_708_002, "生产领料出库单至少需要一条行数据");
+ ErrorCode WM_PRODUCT_ISSUE_DETAIL_QUANTITY_MISMATCH = new ErrorCode(1_040_708_003, "领料出库单行数量与明细数量不一致");
+ ErrorCode WM_PRODUCT_ISSUE_WORKORDER_NOT_EXISTS = new ErrorCode(1_040_708_004, "生产工单不存在");
+ ErrorCode WM_PRODUCT_ISSUE_WORKSTATION_NOT_EXISTS = new ErrorCode(1_040_708_005, "工作站不存在");
+ ErrorCode WM_PRODUCT_ISSUE_CANCEL_NOT_ALLOWED = new ErrorCode(1_040_708_006, "生产领料出库单已完成或已取消,无法取消");
+ ErrorCode WM_PRODUCT_ISSUE_LINE_NOT_EXISTS = new ErrorCode(1_040_708_100, "生产领料出库单行不存在");
+ ErrorCode WM_PRODUCT_ISSUE_LINE_ITEM_NOT_IN_BOM = new ErrorCode(1_040_708_101, "当前物料不在生产工单的 BOM 物料清单中");
+ ErrorCode WM_PRODUCT_ISSUE_CODE_DUPLICATE = new ErrorCode(1_040_708_102, "领料出库单编码已存在");
+ ErrorCode WM_PRODUCT_ISSUE_DETAIL_NOT_EXISTS = new ErrorCode(1_040_708_200, "生产领料出库单明细不存在");
+ ErrorCode WM_PRODUCT_ISSUE_DETAIL_ITEM_MISMATCH = new ErrorCode(1_040_708_201, "拣货明细的物料与领料单行的物料不一致");
+
+ // ========== MES 仓库管理-生产入库单(1-040-709-000) ==========
+ ErrorCode WM_PRODUCT_PRODUCE_NOT_EXISTS = new ErrorCode(1_040_709_000, "生产入库单不存在");
+ ErrorCode WM_PRODUCT_PRODUCE_STATUS_INVALID = new ErrorCode(1_040_709_001, "生产入库单状态不正确,无法执行该操作");
+ ErrorCode WM_PRODUCT_PRODUCE_NO_LINE = new ErrorCode(1_040_709_002, "生产入库单至少需要一条行数据");
+ ErrorCode WM_PRODUCT_PRODUCE_DETAIL_QUANTITY_MISMATCH = new ErrorCode(1_040_709_003, "生产入库单行数量与明细数量不一致");
+ ErrorCode WM_PRODUCT_PRODUCE_CANCEL_NOT_ALLOWED = new ErrorCode(1_040_709_004, "生产入库单已完成或已取消,无法取消");
+ ErrorCode WM_PRODUCT_PRODUCE_LINE_NOT_EXISTS = new ErrorCode(1_040_709_100, "生产入库单行不存在");
+ ErrorCode WM_PRODUCT_PRODUCE_DETAIL_NOT_EXISTS = new ErrorCode(1_040_709_200, "生产入库单明细不存在");
+
+ // ========== MES 仓库管理-转移调拨(1-040-710-000) ==========
+ ErrorCode WM_TRANSFER_NOT_EXISTS = new ErrorCode(1_040_710_000, "转移单不存在");
+ ErrorCode WM_TRANSFER_NOT_EDITABLE = new ErrorCode(1_040_710_001, "当前转移单状态不允许编辑");
+ ErrorCode WM_TRANSFER_CODE_DUPLICATE = new ErrorCode(1_040_710_002, "转移单编号已存在");
+ ErrorCode WM_TRANSFER_NOT_DRAFT = new ErrorCode(1_040_710_003, "只有草稿状态的转移单才可操作");
+ ErrorCode WM_TRANSFER_NOT_CONFIRMED = new ErrorCode(1_040_710_004, "只有待确认状态的转移单才可执行确认");
+ ErrorCode WM_TRANSFER_NOT_APPROVING = new ErrorCode(1_040_710_005, "只有待上架状态的转移单才可执行上架");
+ ErrorCode WM_TRANSFER_NOT_APPROVED = new ErrorCode(1_040_710_006, "只有待执行状态的转移单才可完成");
+ ErrorCode WM_TRANSFER_ALREADY_FINISHED = new ErrorCode(1_040_710_007, "转移单已完成或已取消,无法继续操作");
+ ErrorCode WM_TRANSFER_NO_LINE = new ErrorCode(1_040_710_008, "转移单至少需要一条行数据");
+ ErrorCode WM_TRANSFER_DETAIL_QUANTITY_MISMATCH = new ErrorCode(1_040_710_009, "转移单行数量与明细数量不一致");
+ ErrorCode WM_TRANSFER_LINE_NOT_EXISTS = new ErrorCode(1_040_710_100, "转移单行不存在");
+ ErrorCode WM_TRANSFER_LINE_QUANTITY_EXCEED_STOCK = new ErrorCode(1_040_710_101, "转移数量不能超过库存数量");
+ ErrorCode WM_TRANSFER_DETAIL_NOT_EXISTS = new ErrorCode(1_040_710_200, "调拨明细不存在");
+ ErrorCode WM_TRANSFER_DETAIL_QUANTITY_EXCEED = new ErrorCode(1_040_710_201, "调拨明细总数量不能超过调拨单行数量");
+ ErrorCode WM_TRANSFER_DETAIL_MIXED_GOODS = new ErrorCode(1_040_710_202, "同一目标仓位下已存在其他物料的明细,不允许混货");
+
+ // ========== MES 仓库管理-生产退料单(1-040-711-000) ==========
+ ErrorCode WM_RETURN_ISSUE_NOT_EXISTS = new ErrorCode(1_040_710_000, "生产退料单不存在");
+ ErrorCode WM_RETURN_ISSUE_STATUS_INVALID = new ErrorCode(1_040_710_001, "生产退料单状态不正确,无法执行该操作");
+ ErrorCode WM_RETURN_ISSUE_NOT_PREPARE = new ErrorCode(1_040_710_002, "只有草稿状态的退料单才可操作");
+ ErrorCode WM_RETURN_ISSUE_NOT_CONFIRMED = new ErrorCode(1_040_710_003, "只有待检验状态的退料单才可提交");
+ ErrorCode WM_RETURN_ISSUE_NOT_APPROVING = new ErrorCode(1_040_710_004, "只有待上架状态的退料单才可入库上架");
+ ErrorCode WM_RETURN_ISSUE_NOT_APPROVED = new ErrorCode(1_040_710_005, "只有待执行退料状态的退料单才可完成");
+ ErrorCode WM_RETURN_ISSUE_NO_LINE = new ErrorCode(1_040_710_006, "生产退料单至少需要一条行数据");
+ ErrorCode WM_RETURN_ISSUE_DETAIL_QUANTITY_MISMATCH = new ErrorCode(1_040_710_007, "退料单行数量与明细数量不一致");
+ ErrorCode WM_RETURN_ISSUE_CANCEL_NOT_ALLOWED = new ErrorCode(1_040_710_008, "生产退料单已完成或已取消,无法取消");
+ ErrorCode WM_RETURN_ISSUE_LINE_NOT_EXISTS = new ErrorCode(1_040_710_100, "生产退料单行不存在");
+ ErrorCode WM_RETURN_ISSUE_DETAIL_NOT_EXISTS = new ErrorCode(1_040_710_200, "生产退料单明细不存在");
+ ErrorCode WM_RETURN_ISSUE_DETAIL_QUANTITY_INVALID = new ErrorCode(1_040_710_201, "退料明细数量必须大于0");
+ ErrorCode WM_RETURN_ISSUE_DETAIL_QUANTITY_EXCEED = new ErrorCode(1_040_710_202, "退料明细总数量不能超过退料单行数量");
+ ErrorCode WM_RETURN_ISSUE_CODE_DUPLICATE = new ErrorCode(1_040_710_203, "退料单编码已存在");
+
+ // ========== MES 仓库管理-供应商退货单(1-040-711-000) ==========
+ ErrorCode WM_RETURN_VENDOR_NOT_EXISTS = new ErrorCode(1_040_711_000, "供应商退货单不存在");
+ ErrorCode WM_RETURN_VENDOR_STATUS_INVALID = new ErrorCode(1_040_711_001, "供应商退货单状态不正确,无法执行该操作");
+ ErrorCode WM_RETURN_VENDOR_NO_LINE = new ErrorCode(1_040_711_002, "供应商退货单至少需要一条行数据");
+ ErrorCode WM_RETURN_VENDOR_DETAIL_QUANTITY_MISMATCH = new ErrorCode(1_040_711_003, "供应商退货单行数量与明细数量不一致");
+ ErrorCode WM_RETURN_VENDOR_CANCEL_NOT_ALLOWED = new ErrorCode(1_040_711_004, "供应商退货单已完成或已取消,无法取消");
+ ErrorCode WM_RETURN_VENDOR_CODE_DUPLICATE = new ErrorCode(1_040_711_005, "供应商退货单编号已存在");
+ ErrorCode WM_RETURN_VENDOR_NO_DETAIL = new ErrorCode(1_040_711_006, "供应商退货单没有拣货明细,无法执行退货");
+ ErrorCode WM_RETURN_VENDOR_DETAIL_ITEM_MISMATCH = new ErrorCode(1_040_711_007, "拣货明细的物料与退货单行的物料不一致");
+ ErrorCode WM_RETURN_VENDOR_LINE_NOT_EXISTS = new ErrorCode(1_040_711_100, "供应商退货单行不存在");
+ ErrorCode WM_RETURN_VENDOR_DETAIL_NOT_EXISTS = new ErrorCode(1_040_711_200, "供应商退货单明细不存在");
+ ErrorCode WM_RETURN_VENDOR_DETAIL_QUANTITY_INVALID = new ErrorCode(1_040_711_201, "退货明细数量必须大于 0");
+
+ // ========== MES 仓库管理-产品收货单(1-040-712-000) ==========
+ ErrorCode WM_PRODUCT_RECPT_NOT_EXISTS = new ErrorCode(1_040_712_000, "产品收货单不存在");
+ ErrorCode WM_PRODUCT_RECPT_CODE_DUPLICATE = new ErrorCode(1_040_712_001, "产品收货单编码已存在");
+ ErrorCode WM_PRODUCT_RECPT_STATUS_NOT_PREPARE = new ErrorCode(1_040_712_002, "只有草稿或待上架状态才允许此操作");
+ ErrorCode WM_PRODUCT_RECPT_NO_LINE = new ErrorCode(1_040_712_003, "至少需要一条行项目");
+ ErrorCode WM_PRODUCT_RECPT_DETAIL_QUANTITY_MISMATCH = new ErrorCode(1_040_712_004, "明细上架总数与行收货数量不匹配");
+ ErrorCode WM_PRODUCT_RECPT_STATUS_ERROR = new ErrorCode(1_040_712_005, "收货单状态不正确");
+ ErrorCode WM_PRODUCT_RECPT_CANCEL_NOT_ALLOWED = new ErrorCode(1_040_712_006, "已完成或已取消的收货单不允许取消");
+ ErrorCode WM_PRODUCT_RECPT_NO_DETAIL = new ErrorCode(1_040_712_007, "收货单没有上架明细,无法执行入库");
+ ErrorCode WM_PRODUCT_RECPT_LINE_NOT_EXISTS = new ErrorCode(1_040_712_100, "产品收货单行不存在");
+ ErrorCode WM_PRODUCT_RECPT_DETAIL_NOT_EXISTS = new ErrorCode(1_040_712_200, "产品收货明细不存在");
+
+ // ========== MES 仓库管理-外协入库单(1-040-713-000) ==========
+ ErrorCode WM_OUTSOURCE_RECEIPT_NOT_EXISTS = new ErrorCode(1_040_713_000, "外协入库单不存在");
+ ErrorCode WM_OUTSOURCE_RECEIPT_CODE_DUPLICATE = new ErrorCode(1_040_713_001, "外协入库单编码已存在");
+ ErrorCode WM_OUTSOURCE_RECEIPT_STATUS_NOT_PREPARE = new ErrorCode(1_040_713_002, "只有草稿状态才允许此操作");
+ ErrorCode WM_OUTSOURCE_RECEIPT_NO_LINE = new ErrorCode(1_040_713_003, "至少需要一条行项目");
+ ErrorCode WM_OUTSOURCE_RECEIPT_DETAIL_QUANTITY_MISMATCH = new ErrorCode(1_040_713_004, "明细上架总数与行入库数量不匹配");
+ ErrorCode WM_OUTSOURCE_RECEIPT_STATUS_ERROR = new ErrorCode(1_040_713_005, "入库单状态不正确");
+ ErrorCode WM_OUTSOURCE_RECEIPT_CANCEL_NOT_ALLOWED = new ErrorCode(1_040_713_006, "已完成或已取消的入库单不允许取消");
+ ErrorCode WM_OUTSOURCE_RECEIPT_LINE_NOT_EXISTS = new ErrorCode(1_040_713_100, "外协入库单行不存在");
+ ErrorCode WM_OUTSOURCE_RECEIPT_DETAIL_NOT_EXISTS = new ErrorCode(1_040_713_200, "外协入库明细不存在");
+
+ // ========== MES 仓库管理-销售退货单(1-040-713-000) ==========
+ ErrorCode WM_RETURN_SALES_NOT_EXISTS = new ErrorCode(1_040_713_000, "销售退货单不存在");
+ ErrorCode WM_RETURN_SALES_CODE_DUPLICATE = new ErrorCode(1_040_713_001, "销售退货单编码已存在");
+ ErrorCode WM_RETURN_SALES_STATUS_NOT_PREPARE = new ErrorCode(1_040_713_002, "只有草稿状态才允许此操作");
+ ErrorCode WM_RETURN_SALES_STATUS_NOT_APPROVING = new ErrorCode(1_040_713_003, "只有待执行状态才允许执行退货");
+ ErrorCode WM_RETURN_SALES_STATUS_NOT_APPROVED = new ErrorCode(1_040_713_004, "只有待上架状态才允许执行上架");
+ ErrorCode WM_RETURN_SALES_NO_LINE = new ErrorCode(1_040_713_005, "销售退货单至少需要一条行数据");
+ ErrorCode WM_RETURN_SALES_DETAIL_QUANTITY_MISMATCH = new ErrorCode(1_040_713_006, "销售退货单行数量与明细数量不一致");
+ ErrorCode WM_RETURN_SALES_CANCEL_NOT_ALLOWED = new ErrorCode(1_040_713_007, "销售退货单已完成或已取消,无法取消");
+ ErrorCode WM_RETURN_SALES_LINE_NOT_EXISTS = new ErrorCode(1_040_713_100, "销售退货单行不存在");
+ ErrorCode WM_RETURN_SALES_DETAIL_NOT_EXISTS = new ErrorCode(1_040_713_200, "销售退货单明细不存在");
+ ErrorCode WM_RETURN_SALES_DETAIL_QUANTITY_EXCEED = new ErrorCode(1_040_713_201, "上架明细总数量不能超过退货行数量");
+
+ // ========== MES 仓库管理-盘点方案/任务/结果(1-040-714-100) ==========
+ ErrorCode WM_STOCK_TAKING_PLAN_NOT_EXISTS = new ErrorCode(1_040_714_100, "盘点方案不存在");
+ ErrorCode WM_STOCK_TAKING_PLAN_CODE_DUPLICATE = new ErrorCode(1_040_714_101, "盘点方案编码已存在");
+ ErrorCode WM_STOCK_TAKING_PLAN_NOT_DISABLED = new ErrorCode(1_040_714_102, "只有禁用状态的盘点方案才允许修改、删除或维护参数");
+ ErrorCode WM_STOCK_TAKING_PLAN_NOT_ENABLED = new ErrorCode(1_040_714_103, "只有启用状态的盘点方案才允许生成任务");
+ ErrorCode WM_STOCK_TAKING_PLAN_PARAM_NOT_EXISTS = new ErrorCode(1_040_714_104, "盘点方案参数不存在");
+ ErrorCode WM_STOCK_TAKING_PLAN_PARAM_EMPTY = new ErrorCode(1_040_714_105, "盘点方案参数不能为空,请先配置盘点参数");
+ ErrorCode WM_STOCK_TAKING_PLAN_DYNAMIC_TIME_INVALID = new ErrorCode(1_040_714_106, "动态盘点方案必须设置开始时间和结束时间,且结束时间必须晚于开始时间");
+ ErrorCode WM_STOCK_TAKING_TASK_NOT_EXISTS = new ErrorCode(1_040_714_110, "盘点任务不存在");
+ ErrorCode WM_STOCK_TAKING_TASK_CODE_DUPLICATE = new ErrorCode(1_040_714_111, "盘点任务编码已存在");
+ ErrorCode WM_STOCK_TAKING_TASK_NOT_PREPARE = new ErrorCode(1_040_714_112, "只有草稿状态的盘点任务才允许此操作");
+ ErrorCode WM_STOCK_TAKING_TASK_NOT_APPROVING = new ErrorCode(1_040_714_113, "只有盘点中状态的任务才允许此操作");
+ ErrorCode WM_STOCK_TAKING_TASK_CANNOT_CANCEL = new ErrorCode(1_040_714_114, "已完成或已取消的盘点任务不允许取消");
+ ErrorCode WM_STOCK_TAKING_TASK_NO_STOCK = new ErrorCode(1_040_714_115, "未找到符合条件的库存数据");
+ ErrorCode WM_STOCK_TAKING_TASK_NO_LINE = new ErrorCode(1_040_714_116, "盘点任务至少需要一条任务行");
+ ErrorCode WM_STOCK_TAKING_TASK_LINE_NOT_EXISTS = new ErrorCode(1_040_714_117, "盘点任务行不存在");
+ ErrorCode WM_STOCK_TAKING_TASK_DYNAMIC_TIME_REQUIRED = new ErrorCode(1_040_714_118, "动态盘点必须选择开始时间和结束时间");
+ ErrorCode WM_STOCK_TAKING_TASK_RESULT_NOT_EXISTS = new ErrorCode(1_040_714_119, "盘点结果不存在");
+ ErrorCode WM_STOCK_TAKING_TASK_LINE_ALREADY_TAKEN = new ErrorCode(1_040_714_120, "该盘点清单行已有盘点记录,不能重复盘点");
+
+ // ========== MES 仓库管理-销售出库单(1-040-714-000) ==========
+ ErrorCode WM_PRODUCT_SALES_NOT_EXISTS = new ErrorCode(1_040_714_000, "销售出库单不存在");
+ ErrorCode WM_PRODUCT_SALES_CODE_DUPLICATE = new ErrorCode(1_040_714_001, "销售出库单号已存在");
+ ErrorCode WM_PRODUCT_SALES_NOT_PREPARE = new ErrorCode(1_040_714_002, "只有草稿状态才可操作");
+ ErrorCode WM_PRODUCT_SALES_LINES_EMPTY = new ErrorCode(1_040_714_003, "销售出库单行不能为空");
+ ErrorCode WM_PRODUCT_SALES_CANNOT_SUBMIT = new ErrorCode(1_040_714_004, "当前状态不允许提交");
+ ErrorCode WM_PRODUCT_SALES_CANNOT_PICK = new ErrorCode(1_040_714_005, "当前状态不允许拣货");
+ ErrorCode WM_PRODUCT_SALES_CANNOT_SHIPPING = new ErrorCode(1_040_714_006, "当前状态不允许填写运单");
+ ErrorCode WM_PRODUCT_SALES_CANNOT_FINISH = new ErrorCode(1_040_714_007, "当前状态不允许执行出库");
+ ErrorCode WM_PRODUCT_SALES_CANNOT_CANCEL = new ErrorCode(1_040_714_008, "当前状态不允许取消");
+ ErrorCode WM_PRODUCT_SALES_CANNOT_CONFIRM = new ErrorCode(1_040_714_009, "当前状态不允许确认检验通过");
+ ErrorCode WM_PRODUCT_SALES_DETAILS_EMPTY = new ErrorCode(1_040_714_020, "拣货明细不能为空");
+ ErrorCode WM_PRODUCT_SALES_DETAIL_QUANTITY_MISMATCH = new ErrorCode(1_040_714_010, "拣货数量与出库数量不匹配");
+ ErrorCode WM_PRODUCT_SALES_LINE_NOT_EXISTS = new ErrorCode(1_040_714_011, "销售出库单行不存在");
+ ErrorCode WM_PRODUCT_SALES_DETAIL_NOT_EXISTS = new ErrorCode(1_040_714_012, "销售出库明细不存在");
+ ErrorCode WM_PRODUCT_SALES_STOCK_INSUFFICIENT = new ErrorCode(1_040_714_013, "库存不足,无法拣货");
+ ErrorCode WM_PRODUCT_SALES_LINE_QUANTITY_INVALID = new ErrorCode(1_040_714_014, "出库数量必须大于 0");
+
+ // ========== MES 仓库管理-杂项出库单(1-040-715-000) ==========
+ ErrorCode WM_MISC_ISSUE_NOT_EXISTS = new ErrorCode(1_040_715_000, "杂项出库单不存在");
+ ErrorCode WM_MISC_ISSUE_CODE_DUPLICATE = new ErrorCode(1_040_715_001, "杂项出库单编码已存在");
+ ErrorCode WM_MISC_ISSUE_STATUS_INVALID = new ErrorCode(1_040_715_002, "杂项出库单状态不正确,无法执行该操作");
+ ErrorCode WM_MISC_ISSUE_NO_LINE = new ErrorCode(1_040_715_003, "杂项出库单至少需要一条行数据");
+ ErrorCode WM_MISC_ISSUE_CANCEL_NOT_ALLOWED = new ErrorCode(1_040_715_004, "杂项出库单已完成或已取消,无法取消");
+ ErrorCode WM_MISC_ISSUE_DETAIL_QUANTITY_MISMATCH = new ErrorCode(1_040_715_005, "杂项出库单行数量与明细数量不一致");
+ ErrorCode WM_MISC_ISSUE_LINE_NOT_EXISTS = new ErrorCode(1_040_715_100, "杂项出库单行不存在");
+ ErrorCode WM_MISC_ISSUE_DETAIL_NOT_EXISTS = new ErrorCode(1_040_715_200, "杂项出库单明细不存在");
+
+ // ========== MES 仓库管理-杂项入库单(1-040-716-000) ==========
+ ErrorCode WM_MISC_RECEIPT_NOT_EXISTS = new ErrorCode(1_040_716_000, "杂项入库单不存在");
+ ErrorCode WM_MISC_RECEIPT_CODE_DUPLICATE = new ErrorCode(1_040_716_001, "杂项入库单编码已存在");
+ ErrorCode WM_MISC_RECEIPT_STATUS_NOT_PREPARE = new ErrorCode(1_040_716_002, "只有草稿状态才允许此操作");
+ ErrorCode WM_MISC_RECEIPT_STATUS_NOT_APPROVED = new ErrorCode(1_040_716_003, "只有已审批状态才允许执行入库");
+ ErrorCode WM_MISC_RECEIPT_NO_LINE = new ErrorCode(1_040_716_004, "至少需要一条行项目");
+ ErrorCode WM_MISC_RECEIPT_CANCEL_NOT_ALLOWED = new ErrorCode(1_040_716_005, "已完成或已取消的入库单不允许取消");
+ ErrorCode WM_MISC_RECEIPT_LINE_NOT_EXISTS = new ErrorCode(1_040_716_100, "杂项入库单行不存在");
+ ErrorCode WM_MISC_RECEIPT_WAREHOUSE_REQUIRED = new ErrorCode(1_040_716_101, "仓库不能为空");
+ ErrorCode WM_MISC_RECEIPT_QUANTITY_INVALID = new ErrorCode(1_040_716_102, "入库数量必须大于 0");
+ ErrorCode WM_MISC_RECEIPT_DETAIL_NOT_EXISTS = new ErrorCode(1_040_716_200, "杂项入库单明细不存在");
+
+ // ========== MES 仓库管理-发货通知单(1-040-720-000) ==========
+ ErrorCode WM_SALES_NOTICE_NOT_EXISTS = new ErrorCode(1_040_720_000, "发货通知单不存在");
+ ErrorCode WM_SALES_NOTICE_CODE_DUPLICATE = new ErrorCode(1_040_720_001, "通知单编号重复");
+ ErrorCode WM_SALES_NOTICE_STATUS_NOT_ALLOW_DELETE = new ErrorCode(1_040_720_002, "单据状态不允许删除");
+ ErrorCode WM_SALES_NOTICE_STATUS_NOT_ALLOW_UPDATE = new ErrorCode(1_040_720_003, "单据状态不允许修改");
+ ErrorCode WM_SALES_NOTICE_LINE_NOT_EXISTS = new ErrorCode(1_040_720_010, "发货通知单行不存在");
+ ErrorCode WM_SALES_NOTICE_LINE_EMPTY = new ErrorCode(1_040_720_011, "发货通知单行为空,不能提交");
+
+ // ========== MES 仓库管理-条码配置(1-040-730-000) ==========
+ ErrorCode WM_BARCODE_CONFIG_NOT_EXISTS = new ErrorCode(1_040_730_000, "条码配置不存在");
+ ErrorCode WM_BARCODE_CONFIG_BIZ_TYPE_DUPLICATE = new ErrorCode(1_040_730_001, "该业务类型的条码配置已存在");
+ ErrorCode WM_BARCODE_CONFIG_HAS_BARCODE = new ErrorCode(1_040_730_002, "该条码配置已被条码记录关联,无法删除");
+
+ // ========== MES 仓库管理-条码清单(1-040-731-000) ==========
+ ErrorCode WM_BARCODE_NOT_EXISTS = new ErrorCode(1_040_731_000, "条码不存在");
+ ErrorCode WM_BARCODE_ALREADY_EXISTS = new ErrorCode(1_040_731_001, "该业务对象的条码已存在");
+ ErrorCode WM_BARCODE_CONTENT_DUPLICATE = new ErrorCode(1_040_731_002, "条码内容已存在");
+ ErrorCode BARCODE_BIZ_TYPE_NOT_EXISTS = new ErrorCode(1_040_731_003, "业务类型不能为空");
+ ErrorCode BARCODE_BIZ_CODE_NOT_EXISTS = new ErrorCode(1_040_731_004, "业务编码不能为空");
+ ErrorCode BARCODE_CONFIG_NOT_EXISTS = new ErrorCode(1_040_731_005, "条码配置不存在");
+
+ // ========== MES 仓库管理-装箱单(1-040-740-000) ==========
+ ErrorCode WM_PACKAGE_NOT_EXISTS = new ErrorCode(1_040_740_000, "装箱单不存在");
+ ErrorCode WM_PACKAGE_CODE_DUPLICATE = new ErrorCode(1_040_740_001, "装箱单编码已存在");
+ ErrorCode WM_PACKAGE_STATUS_NOT_PREPARE = new ErrorCode(1_040_740_002, "只有草稿状态才允许此操作");
+ ErrorCode WM_PACKAGE_PARENT_NOT_EXISTS = new ErrorCode(1_040_740_003, "父箱不存在");
+ ErrorCode WM_PACKAGE_PARENT_SELF = new ErrorCode(1_040_740_004, "不能选择自己作为父箱");
+ ErrorCode WM_PACKAGE_CHILD_HAS_PARENT = new ErrorCode(1_040_740_005, "该装箱单已有父箱,不能重复添加");
+ ErrorCode WM_PACKAGE_PARENT_IS_CHILD = new ErrorCode(1_040_740_006, "不能选择子箱的后代作为父箱,会形成环路");
+ ErrorCode WM_PACKAGE_CHILD_NOT_FINISHED = new ErrorCode(1_040_740_007, "子箱必须是已完成状态才能添加");
+ ErrorCode WM_PACKAGE_HAS_CHILDREN = new ErrorCode(1_040_740_008, "存在子箱,不允许删除");
+ ErrorCode WM_PACKAGE_LINE_NOT_EXISTS = new ErrorCode(1_040_740_100, "装箱明细不存在");
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/MesBizTypeConstants.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/MesBizTypeConstants.java
new file mode 100644
index 000000000..2bef47c2e
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/MesBizTypeConstants.java
@@ -0,0 +1,82 @@
+package cn.iocoder.yudao.module.mes.enums;
+
+/**
+ * MES 业务类型常量
+ *
+ * 集中管理业务类型枚举的编号,按业务域分段。
+ * 各枚举类引用此处常量,避免硬编码数字。(也避免冲突!!!)
+ *
+ * @author 芋道源码
+ */
+public final class MesBizTypeConstants {
+
+ private MesBizTypeConstants() {}
+
+ // ========== QC 质检模块 [1, 100) ==========
+
+ public static final int QC_IQC = 1; // 来料检验:MesQcIqcDO
+ public static final int QC_IPQC = 2; // 过程检验:MesQcIpqcDO
+ public static final int QC_OQC = 3; // 出货检验:MesQcOqcDO
+ public static final int QC_RQC = 4; // 退货检验:MesQcRqcDO
+
+ // ========== WM 仓库模块 [100, 200) ==========
+
+ public static final int WM_ARRIVAL_NOTICE = 100; // 到货通知单:MesWmArrivalNoticeDO
+ public static final int WM_WAREHOUSE = 102; // 仓库:MesWmWarehouseDO
+ public static final int WM_LOCATION = 103; // 库位:MesWmLocationDO
+ public static final int WM_AREA = 104; // 库位:MesWmStorageAreaDO
+ public static final int WM_PACKAGE = 105; // 装箱单:MesWmPackageDO
+ public static final int WM_STOCK = 106; // 库存:MesWmMaterialStockDO
+ public static final int WM_BATCH = 107; // 批次:MesWmBatchDO
+ public static final int WM_TRANSACTION = 108; // 库存事务流水:MesWmTransactionDO
+ public static final int WM_ITEM_RECEIPT_IN = 110; // 采购入库:MesWmItemReceiptDO
+ public static final int WM_TRANSFER_OUT = 111; // 调拨出库:MesWmTransferDO
+ public static final int WM_TRANSFER_IN = 112; // 调拨入库:MesWmTransferDO
+ public static final int WM_MISC_ISSUE = 113; // 其他出库:MesWmMiscIssueDO
+ public static final int WM_MISC_RECPT = 114; // 其他入库:MesWmMiscReceiptDO
+ public static final int WM_ISSUE = 115; // 生产领料:MesWmProductIssueDO
+ public static final int WM_RETURN_ISSUE = 116; // 生产退料:MesWmReturnIssueDO
+ public static final int WM_PRODUCT_RECPT = 117; // 生产入库:MesWmProductReceiptDO
+ public static final int WM_PRODUCT_SALES = 118; // 销售出库:MesWmProductSalesDO
+ public static final int WM_RETURN_SALES = 119; // 销售退货入库:MesWmReturnSalesDO
+ public static final int WM_OUTSOURCE_ISSUE = 120; // 外协发料:MesWmOutsourceIssueDO
+ public static final int WM_OUTSOURCE_RECPT = 121; // 外协入库:MesWmOutsourceReceiptDO
+ public static final int WM_ITEM_CONSUME = 122; // 生产消耗:MesWmItemConsumeDO
+ public static final int WM_PRODUCT_PRODUCE = 123; // 产品产出:MesWmProductProduceDO
+ public static final int WM_RETURN_VENDOR = 124; // 供应商退货出库:MesWmReturnVendorDO
+
+ // ========== CAL 排班模块 [200, 300) ==========
+
+ // TODO @芋艿【暂时忽略】:MesProWorkOrderTypeEnum
+ // TODO @芋艿【暂时忽略】:MesProWorkOrderSourceTypeEnum
+
+ // ========== PRO 生产模块 [300, 400) ==========
+
+ public static final int PRO_CARD = 300; // 流转卡:MesProCardDO
+ public static final int PRO_WORKORDER = 301; // 工单:MesProWorkOrderDO
+ public static final int PRO_TRANS_ORDER = 302; // 流转单:MesProTransOrderDO
+ public static final int PRO_TASK = 303; // 生产任务:MesProTaskDO
+ public static final int PRO_FEEDBACK = 304; // 生产报工:MesProFeedbackDO
+
+ // ========== DV 设备模块 [400, 500) ==========
+
+ public static final int DV_MACHINERY = 400; // 设备:MesDvMachineryDO
+
+ // ========== TM 工装夹具模块 [500, 600) ==========
+
+ public static final int TM_TOOL = 500; // 工装:MesToolDO
+
+ // ========== MD 主数据模块 [600, 700) ==========
+
+ public static final int MD_ITEM = 600; // 物料:MesMdItemDO
+ public static final int MD_VENDOR = 601; // 供应商:MesMdVendorDO
+ public static final int MD_WORKSTATION = 602; // 工作站:MesMdWorkstationDO
+ public static final int MD_WORKSHOP = 603; // 车间:MesMdWorkshopDO
+ public static final int MD_USER = 604; // 人员:系统用户
+ public static final int MD_CLIENT = 605; // 客户:MesMdClientDO
+
+ // ========== 特殊类型(非业务实体) [900, 1000) ==========
+
+ public static final int QUALITY_STATUS = 900; // 质量状态:非实体,用于盘点等场景的状态筛选
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/MesOrderStatusConstants.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/MesOrderStatusConstants.java
new file mode 100644
index 000000000..de5a9ab0e
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/MesOrderStatusConstants.java
@@ -0,0 +1,40 @@
+package cn.iocoder.yudao.module.mes.enums;
+
+/**
+ * MES 单据状态常量
+ *
+ * 集中管理各模块单据状态的编号,作为状态值的中央注册中心。
+ * 各枚举类引用此处常量,避免硬编码数字。
+ *
+ * @author 芋道源码
+ */
+public final class MesOrderStatusConstants {
+
+ /**
+ * 草稿
+ */
+ public static final int PREPARE = 0;
+
+ /**
+ * 已确认
+ */
+ public static final int CONFIRMED = 1;
+ /**
+ * 审批中
+ */
+ public static final int APPROVING = 2;
+ /**
+ * 已审批
+ */
+ public static final int APPROVED = 3;
+
+ /**
+ * 已完成
+ */
+ public static final int FINISHED = 4;
+ /**
+ * 已取消
+ */
+ public static final int CANCELLED = 5;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/cal/MesCalHolidayTypeEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/cal/MesCalHolidayTypeEnum.java
new file mode 100644
index 000000000..027350a33
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/cal/MesCalHolidayTypeEnum.java
@@ -0,0 +1,34 @@
+package cn.iocoder.yudao.module.mes.enums.cal;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 假期类型枚举
+ *
+ * 对应字典 mes_cal_holiday_type
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesCalHolidayTypeEnum implements ArrayValuable {
+
+ WORKDAY(1, "工作日"),
+ HOLIDAY(2, "节假日");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values())
+ .map(MesCalHolidayTypeEnum::getType).toArray(Integer[]::new);
+
+ private final Integer type;
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/cal/MesCalPlanStatusEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/cal/MesCalPlanStatusEnum.java
new file mode 100644
index 000000000..c4cb84a85
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/cal/MesCalPlanStatusEnum.java
@@ -0,0 +1,37 @@
+package cn.iocoder.yudao.module.mes.enums.cal;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 排班计划状态枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesCalPlanStatusEnum implements ArrayValuable {
+
+ PREPARE(0, "草稿"),
+ CONFIRMED(1, "已确认");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesCalPlanStatusEnum::getStatus).toArray(Integer[]::new);
+
+ /**
+ * 状态值
+ */
+ private final Integer status;
+ /**
+ * 状态名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/cal/MesCalShiftMethodEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/cal/MesCalShiftMethodEnum.java
new file mode 100644
index 000000000..4c6336066
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/cal/MesCalShiftMethodEnum.java
@@ -0,0 +1,39 @@
+package cn.iocoder.yudao.module.mes.enums.cal;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 倒班方式枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesCalShiftMethodEnum implements ArrayValuable {
+
+ QUARTER(1, "按季度"),
+ MONTH(2, "按月"),
+ WEEK(3, "按周"),
+ DAY(4, "按天");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesCalShiftMethodEnum::getMethod).toArray(Integer[]::new);
+
+ /**
+ * 方式值
+ */
+ private final Integer method;
+ /**
+ * 方式名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/cal/MesCalShiftTypeEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/cal/MesCalShiftTypeEnum.java
new file mode 100644
index 000000000..f801e1006
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/cal/MesCalShiftTypeEnum.java
@@ -0,0 +1,82 @@
+package cn.iocoder.yudao.module.mes.enums.cal;
+
+import cn.hutool.core.lang.Pair;
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * MES 轮班方式枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesCalShiftTypeEnum implements ArrayValuable {
+
+ SINGLE(1, "单白班", List.of(
+ Pair.of("白班", new String[]{"08:00", "17:00"})
+ )),
+ TWO(2, "两班倒", List.of(
+ Pair.of("白班", new String[]{"08:00", "20:00"}),
+ Pair.of("夜班", new String[]{"20:00", "08:00"})
+ )),
+ THREE(3, "三班倒", List.of(
+ Pair.of("白班", new String[]{"08:00", "16:00"}),
+ Pair.of("中班", new String[]{"16:00", "00:00"}),
+ Pair.of("夜班", new String[]{"00:00", "08:00"})
+ ));
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesCalShiftTypeEnum::getType).toArray(Integer[]::new);
+
+ /**
+ * 类型值
+ */
+ private final Integer type;
+ /**
+ * 类型名
+ */
+ private final String name;
+ /**
+ * 班次配置列表
+ *
+ * key: 班次名称(如 "白班", "夜班", "中班")
+ * value: [startTime, endTime](如 ["08:00", "17:00"])
+ */
+ private final List> shifts;
+
+ /**
+ * 获取班次数量上限
+ */
+ public int getShiftCount() {
+ return shifts.size();
+ }
+
+ /**
+ * 获取所需的最少班组数量
+ */
+ public int getRequiredTeamCount() {
+ return shifts.size();
+ }
+
+ /**
+ * 根据类型值获取枚举
+ */
+ public static MesCalShiftTypeEnum valueOf(Integer type) {
+ for (MesCalShiftTypeEnum value : values()) {
+ if (value.getType().equals(type)) {
+ return value;
+ }
+ }
+ throw new IllegalArgumentException("不支持的轮班方式: " + type);
+ }
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/dv/MesDvCheckPlanStatusEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/dv/MesDvCheckPlanStatusEnum.java
new file mode 100644
index 000000000..c37852082
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/dv/MesDvCheckPlanStatusEnum.java
@@ -0,0 +1,37 @@
+package cn.iocoder.yudao.module.mes.enums.dv;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 点检保养方案状态枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesDvCheckPlanStatusEnum implements ArrayValuable {
+
+ PREPARE(0, "草稿"),
+ ENABLED(1, "已启用");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesDvCheckPlanStatusEnum::getStatus).toArray(Integer[]::new);
+
+ /**
+ * 状态值
+ */
+ private final Integer status;
+ /**
+ * 状态名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/dv/MesDvCheckRecordStatusEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/dv/MesDvCheckRecordStatusEnum.java
new file mode 100644
index 000000000..ce675a16a
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/dv/MesDvCheckRecordStatusEnum.java
@@ -0,0 +1,37 @@
+package cn.iocoder.yudao.module.mes.enums.dv;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 设备点检记录状态枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesDvCheckRecordStatusEnum implements ArrayValuable {
+
+ DRAFT(10, "草稿"),
+ FINISHED(20, "已完成");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesDvCheckRecordStatusEnum::getStatus).toArray(Integer[]::new);
+
+ /**
+ * 状态值
+ */
+ private final Integer status;
+ /**
+ * 状态名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/dv/MesDvCheckResultEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/dv/MesDvCheckResultEnum.java
new file mode 100644
index 000000000..6d1cd1e45
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/dv/MesDvCheckResultEnum.java
@@ -0,0 +1,37 @@
+package cn.iocoder.yudao.module.mes.enums.dv;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 设备点检结果枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesDvCheckResultEnum implements ArrayValuable {
+
+ NORMAL(1, "正常"),
+ ABNORMAL(2, "异常");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesDvCheckResultEnum::getResult).toArray(Integer[]::new);
+
+ /**
+ * 结果值
+ */
+ private final Integer result;
+ /**
+ * 结果名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/dv/MesDvMachineryStatusEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/dv/MesDvMachineryStatusEnum.java
new file mode 100644
index 000000000..4a1568a2b
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/dv/MesDvMachineryStatusEnum.java
@@ -0,0 +1,38 @@
+package cn.iocoder.yudao.module.mes.enums.dv;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 设备状态枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesDvMachineryStatusEnum implements ArrayValuable {
+
+ STOP(1, "停机"),
+ PRODUCING(2, "生产中"),
+ MAINTENANCE(3, "维护中");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesDvMachineryStatusEnum::getStatus).toArray(Integer[]::new);
+
+ /**
+ * 状态值
+ */
+ private final Integer status;
+ /**
+ * 状态名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/dv/MesDvMaintenRecordStatusEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/dv/MesDvMaintenRecordStatusEnum.java
new file mode 100644
index 000000000..4ebf320f0
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/dv/MesDvMaintenRecordStatusEnum.java
@@ -0,0 +1,38 @@
+package cn.iocoder.yudao.module.mes.enums.dv;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 设备保养记录状态枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesDvMaintenRecordStatusEnum implements ArrayValuable {
+
+ PREPARE(1, "草稿"),
+ SUBMITTED(2, "已提交");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesDvMaintenRecordStatusEnum::getStatus)
+ .toArray(Integer[]::new);
+
+ /**
+ * 状态值
+ */
+ private final Integer status;
+ /**
+ * 状态名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/dv/MesDvMaintenStatusEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/dv/MesDvMaintenStatusEnum.java
new file mode 100644
index 000000000..6b4ba2270
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/dv/MesDvMaintenStatusEnum.java
@@ -0,0 +1,37 @@
+package cn.iocoder.yudao.module.mes.enums.dv;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 设备保养明细结果枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesDvMaintenStatusEnum implements ArrayValuable {
+
+ NORMAL(1, "正常"),
+ ABNORMAL(2, "异常");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesDvMaintenStatusEnum::getStatus).toArray(Integer[]::new);
+
+ /**
+ * 状态值
+ */
+ private final Integer status;
+ /**
+ * 状态名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/dv/MesDvRepairResultEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/dv/MesDvRepairResultEnum.java
new file mode 100644
index 000000000..8e062593b
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/dv/MesDvRepairResultEnum.java
@@ -0,0 +1,37 @@
+package cn.iocoder.yudao.module.mes.enums.dv;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 维修结果枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesDvRepairResultEnum implements ArrayValuable {
+
+ PASS(1, "通过"),
+ FAIL(2, "不通过");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesDvRepairResultEnum::getResult).toArray(Integer[]::new);
+
+ /**
+ * 结果值
+ */
+ private final Integer result;
+ /**
+ * 结果名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/dv/MesDvRepairStatusEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/dv/MesDvRepairStatusEnum.java
new file mode 100644
index 000000000..c10698fb7
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/dv/MesDvRepairStatusEnum.java
@@ -0,0 +1,62 @@
+package cn.iocoder.yudao.module.mes.enums.dv;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import cn.iocoder.yudao.module.mes.enums.MesOrderStatusConstants;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 维修工单状态枚举
+ *
+ * 状态流转:草稿 → 维修中 → 待验收 → 已确认
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesDvRepairStatusEnum implements ArrayValuable {
+
+ /**
+ * 草稿
+ *
+ * 对应 MesDvRepairService#createRepair 方法
+ */
+ PREPARE(MesOrderStatusConstants.PREPARE, "草稿"),
+ /**
+ * 维修中(提交后,维修人接单)
+ *
+ * 对应 MesDvRepairService#submitRepair 方法
+ */
+ CONFIRMED(MesOrderStatusConstants.CONFIRMED, "维修中"),
+ /**
+ * 待验收(维修完成,等待验收)
+ *
+ * 对应 MesDvRepairService#confirmRepair 方法
+ */
+ APPROVING(MesOrderStatusConstants.APPROVING, "待验收"),
+ /**
+ * 已确认(验收通过或不通过,终态)
+ *
+ * 对应 MesDvRepairService#finishRepair 方法
+ */
+ FINISHED(MesOrderStatusConstants.FINISHED, "已确认");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesDvRepairStatusEnum::getStatus).toArray(Integer[]::new);
+
+ /**
+ * 状态值
+ */
+ private final Integer status;
+ /**
+ * 状态名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/md/MesMdItemTypeEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/md/MesMdItemTypeEnum.java
new file mode 100644
index 000000000..b39392e50
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/md/MesMdItemTypeEnum.java
@@ -0,0 +1,40 @@
+package cn.iocoder.yudao.module.mes.enums.md;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * MES 物料产品分类 - 物料/产品标识枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesMdItemTypeEnum {
+
+ /**
+ * 物料
+ */
+ ITEM("ITEM", "物料"),
+ /**
+ * 产品
+ */
+ PRODUCT("PRODUCT", "产品");
+
+ /**
+ * 标识值
+ */
+ private final String value;
+ /**
+ * 标识名
+ */
+ private final String name;
+
+ /**
+ * 判断给定值是否为产品类型
+ */
+ public static boolean isProduct(String value) {
+ return PRODUCT.getValue().equals(value);
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/md/autocode/MesMdAutoCodeCycleMethodEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/md/autocode/MesMdAutoCodeCycleMethodEnum.java
new file mode 100644
index 000000000..315d9ced8
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/md/autocode/MesMdAutoCodeCycleMethodEnum.java
@@ -0,0 +1,41 @@
+package cn.iocoder.yudao.module.mes.enums.md.autocode;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 编码规则循环方式枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesMdAutoCodeCycleMethodEnum implements ArrayValuable {
+
+ YEAR(1, "按年"),
+ MONTH(2, "按月"),
+ DAY(3, "按天"),
+ HOUR(4, "按小时"),
+ MINUTE(5, "按分钟"),
+ INPUT_CHAR(10, "按传入字符");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesMdAutoCodeCycleMethodEnum::getMethod).toArray(Integer[]::new);
+
+ /**
+ * 方式
+ */
+ private final Integer method;
+ /**
+ * 名称
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/md/autocode/MesMdAutoCodePaddedMethodEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/md/autocode/MesMdAutoCodePaddedMethodEnum.java
new file mode 100644
index 000000000..f13b91baa
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/md/autocode/MesMdAutoCodePaddedMethodEnum.java
@@ -0,0 +1,37 @@
+package cn.iocoder.yudao.module.mes.enums.md.autocode;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 编码规则补齐方式枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesMdAutoCodePaddedMethodEnum implements ArrayValuable {
+
+ LEFT(1, "左补齐"),
+ RIGHT(2, "右补齐");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesMdAutoCodePaddedMethodEnum::getMethod).toArray(Integer[]::new);
+
+ /**
+ * 方式
+ */
+ private final Integer method;
+ /**
+ * 名称
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/md/autocode/MesMdAutoCodePartTypeEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/md/autocode/MesMdAutoCodePartTypeEnum.java
new file mode 100644
index 000000000..864b818e3
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/md/autocode/MesMdAutoCodePartTypeEnum.java
@@ -0,0 +1,39 @@
+package cn.iocoder.yudao.module.mes.enums.md.autocode;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 编码规则分段类型枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesMdAutoCodePartTypeEnum implements ArrayValuable {
+
+ INPUT_CHAR(1, "输入字符"),
+ DATE(2, "当前日期"),
+ FIXED_CHAR(3, "固定字符"),
+ SERIAL_NUMBER(4, "流水号");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesMdAutoCodePartTypeEnum::getType).toArray(Integer[]::new);
+
+ /**
+ * 类型
+ */
+ private final Integer type;
+ /**
+ * 名称
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/md/autocode/MesMdAutoCodeRuleCodeEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/md/autocode/MesMdAutoCodeRuleCodeEnum.java
new file mode 100644
index 000000000..698ec85dd
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/md/autocode/MesMdAutoCodeRuleCodeEnum.java
@@ -0,0 +1,64 @@
+package cn.iocoder.yudao.module.mes.enums.md.autocode;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * MES 编码规则代码枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesMdAutoCodeRuleCodeEnum {
+
+ MD_ITEM_CODE("MD_ITEM_CODE", "物料编码"),
+ MD_VENDOR_CODE("MD_VENDOR_CODE", "供应商编码"),
+ MD_CLIENT_CODE("MD_CLIENT_CODE", "客户编码"),
+ MD_WORKSTATION_CODE("MD_WORKSTATION_CODE", "工作站编码"),
+ TM_TOOL_TYPE_CODE("TM_TOOL_TYPE_CODE", "工具类型编码"),
+ WM_ARRIVAL_NOTICE_CODE("WM_ARRIVAL_NOTICE_CODE", "到货通知单编码"),
+ WM_ITEM_RECEIPT_CODE("WM_ITEM_RECEIPT_CODE", "采购入库单编码"),
+ WM_RETURN_VENDOR_CODE("WM_RETURN_VENDOR_CODE", "采购退货单编码"),
+ WM_RETURN_ISSUE_CODE("WM_RETURN_ISSUE_CODE", "生产退料单编码"),
+ WM_SN_CODE("WM_SN_CODE", "SN 码"),
+ WM_PACKAGE_CODE("WM_PACKAGE_CODE", "装箱单编码"),
+ WM_BATCH_CODE("WM_BATCH_CODE", "批次编码"),
+ PRO_TASK_CODE("PRO_TASK_CODE", "生产任务编码"),
+ QC_IQC_CODE("QC_IQC_CODE", "来料检验单编码"),
+ QC_IPQC_CODE("QC_IPQC_CODE", "过程检验单编码"),
+ QC_OQC_CODE("QC_OQC_CODE", "出货检验单编码"),
+ QC_RQC_CODE("QC_RQC_CODE", "退货检验单编码"),
+ WM_WAREHOUSE_CODE("WM_WAREHOUSE_CODE", "仓库编码"),
+ WM_LOCATION_CODE("WM_LOCATION_CODE", "库区编码"),
+ WM_AREA_CODE("WM_AREA_CODE", "库位编码"),
+ WM_PRODUCT_SALES_CODE("WM_PRODUCT_SALES_CODE", "销售出库单编码"),
+ WM_MISC_RECEIPT_CODE("WM_MISC_RECEIPT_CODE", "杂项入库单编码"),
+ WM_STOCK_TAKING_PLAN_CODE("WM_STOCK_TAKING_PLAN_CODE", "盘点方案编码"),
+ WM_STOCK_TAKING_CODE("WM_STOCK_TAKING_CODE", "盘点任务编码"),
+ TRANSFER_CODE("TRANSFER_CODE", "转移调拨单编码"),
+ WM_OUTSOURCE_ISSUE_CODE("WM_OUTSOURCE_ISSUE_CODE", "外协发料单编码"),
+ DV_MACHINERY_CODE("DV_MACHINERY_CODE", "设备编码"),
+ DV_MACHINERY_TYPE_CODE("DV_MACHINERY_TYPE_CODE", "设备类型编码"),
+ DV_SUBJECT_CODE("DV_SUBJECT_CODE", "点检保养项目编码"),
+ DV_REPAIR_CODE("DV_REPAIR_CODE", "维修单编码"),
+ WM_SALES_NOTICE_CODE("WM_SALES_NOTICE_CODE", "发货通知单编码"),
+ WM_RETURN_SALES_CODE("WM_RETURN_SALES_CODE", "销售退货单编码"),
+ WM_MISC_ISSUE_CODE("WM_MISC_ISSUE_CODE", "杂项出库单编码"),
+ PRO_ROUTE_CODE("PRO_ROUTE_CODE", "工艺路线编码"),
+ PRO_FEEDBACK_CODE("PRO_FEEDBACK_CODE", "生产报工单编码"),
+ PRO_WORK_ORDER_CODE("PRO_WORK_ORDER_CODE", "生产工单编码"),
+ QC_DEFECT_CODE("QC_DEFECT_CODE", "缺陷类型编码"),
+ QC_INDICATOR_RESULT_CODE("QC_INDICATOR_RESULT_CODE", "样品检验结果编码"),
+ WM_OUTSOURCE_RECEIPT_CODE("WM_OUTSOURCE_RECEIPT_CODE", "外协入库单编码");
+
+ /**
+ * 规则代码
+ */
+ private final String code;
+ /**
+ * 规则名称
+ */
+ private final String name;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/pro/MesProAndonLevelEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/pro/MesProAndonLevelEnum.java
new file mode 100644
index 000000000..d12c86192
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/pro/MesProAndonLevelEnum.java
@@ -0,0 +1,38 @@
+package cn.iocoder.yudao.module.mes.enums.pro;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 安灯级别枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesProAndonLevelEnum implements ArrayValuable {
+
+ LEVEL1(1, "一级"),
+ LEVEL2(2, "二级"),
+ LEVEL3(3, "三级");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesProAndonLevelEnum::getLevel).toArray(Integer[]::new);
+
+ /**
+ * 级别值
+ */
+ private final Integer level;
+ /**
+ * 级别名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/pro/MesProAndonStatusEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/pro/MesProAndonStatusEnum.java
new file mode 100644
index 000000000..3a7f75922
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/pro/MesProAndonStatusEnum.java
@@ -0,0 +1,37 @@
+package cn.iocoder.yudao.module.mes.enums.pro;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 安灯处置状态枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesProAndonStatusEnum implements ArrayValuable {
+
+ ACTIVE(0, "未处置"),
+ HANDLED(1, "已处置");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesProAndonStatusEnum::getStatus).toArray(Integer[]::new);
+
+ /**
+ * 状态值
+ */
+ private final Integer status;
+ /**
+ * 状态名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/pro/MesProFeedbackStatusEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/pro/MesProFeedbackStatusEnum.java
new file mode 100644
index 000000000..cfa907668
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/pro/MesProFeedbackStatusEnum.java
@@ -0,0 +1,60 @@
+package cn.iocoder.yudao.module.mes.enums.pro;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import cn.iocoder.yudao.module.mes.enums.MesOrderStatusConstants;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 生产报工状态枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesProFeedbackStatusEnum implements ArrayValuable {
+
+ /**
+ * 草稿
+ *
+ * 对应 MesProFeedbackService#createFeedback 方法
+ */
+ PREPARE(MesOrderStatusConstants.PREPARE, "草稿"),
+ /**
+ * 审批中
+ *
+ * 对应 MesProFeedbackService#submitFeedback 方法
+ */
+ APPROVING(MesOrderStatusConstants.APPROVING, "审批中"),
+ /**
+ * 待检验(质检工序特有)
+ *
+ * 对应 MesProFeedbackService#submitFeedback 方法
+ */
+ UNCHECK(MesOrderStatusConstants.APPROVED, "待检验"),
+ /**
+ * 已完成
+ *
+ * 对应 MesProFeedbackService#approveFeedback 方法
+ */
+ FINISHED(MesOrderStatusConstants.FINISHED, "已完成");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesProFeedbackStatusEnum::getStatus).toArray(Integer[]::new);
+
+ /**
+ * 状态值
+ */
+ private final Integer status;
+ /**
+ * 状态名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/pro/MesProFeedbackTypeEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/pro/MesProFeedbackTypeEnum.java
new file mode 100644
index 000000000..14db1e361
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/pro/MesProFeedbackTypeEnum.java
@@ -0,0 +1,37 @@
+package cn.iocoder.yudao.module.mes.enums.pro;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 生产报工类型枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesProFeedbackTypeEnum implements ArrayValuable {
+
+ SELF(1, "自行报工"),
+ UNIFIED(2, "统一报工");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesProFeedbackTypeEnum::getType).toArray(Integer[]::new);
+
+ /**
+ * 类型值
+ */
+ private final Integer type;
+ /**
+ * 类型名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/pro/MesProLinkTypeEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/pro/MesProLinkTypeEnum.java
new file mode 100644
index 000000000..8ad8deb96
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/pro/MesProLinkTypeEnum.java
@@ -0,0 +1,39 @@
+package cn.iocoder.yudao.module.mes.enums.pro;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 工序关系类型枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesProLinkTypeEnum implements ArrayValuable {
+
+ START_START(0, "开始-开始"),
+ FINISH_FINISH(1, "结束-结束"),
+ START_FINISH(2, "开始-结束"),
+ FINISH_START(3, "结束-开始");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesProLinkTypeEnum::getType).toArray(Integer[]::new);
+
+ /**
+ * 类型值
+ */
+ private final Integer type;
+ /**
+ * 类型名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/pro/MesProTaskStatusEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/pro/MesProTaskStatusEnum.java
new file mode 100644
index 000000000..8f5ba7b40
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/pro/MesProTaskStatusEnum.java
@@ -0,0 +1,66 @@
+package cn.iocoder.yudao.module.mes.enums.pro;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import cn.iocoder.yudao.module.mes.enums.MesOrderStatusConstants;
+import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 生产任务状态枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesProTaskStatusEnum implements ArrayValuable {
+
+ /**
+ * 草稿
+ *
+ * 对应 MesProTaskService#createTask 方法
+ */
+ PREPARE(MesOrderStatusConstants.PREPARE, "草稿"),
+ /**
+ * 已完成
+ *
+ * 对应 MesProTaskService#finishTaskByOrderId 方法
+ */
+ FINISHED(MesOrderStatusConstants.FINISHED, "已完成"),
+ /**
+ * 已取消
+ *
+ * 对应 MesProTaskService#cancelTaskByOrderId 方法
+ */
+ CANCELED(MesOrderStatusConstants.CANCELLED, "已取消");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesProTaskStatusEnum::getStatus).toArray(Integer[]::new);
+
+ /**
+ * 状态值
+ */
+ private final Integer status;
+ /**
+ * 状态名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+ /**
+ * 判断是否为终态(已完成 或 已取消)
+ *
+ * @param status 状态值
+ * @return 是否为终态
+ */
+ public static boolean isEndStatus(Integer status) {
+ return ObjectUtils.equalsAny(status, FINISHED.status, CANCELED.status);
+ }
+
+}
+
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/pro/MesProWorkOrderSourceTypeEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/pro/MesProWorkOrderSourceTypeEnum.java
new file mode 100644
index 000000000..47836b7df
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/pro/MesProWorkOrderSourceTypeEnum.java
@@ -0,0 +1,37 @@
+package cn.iocoder.yudao.module.mes.enums.pro;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 工单来源类型枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesProWorkOrderSourceTypeEnum implements ArrayValuable {
+
+ ORDER(1, "客户订单"),
+ STORE(2, "库存备货");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesProWorkOrderSourceTypeEnum::getType).toArray(Integer[]::new);
+
+ /**
+ * 类型值
+ */
+ private final Integer type;
+ /**
+ * 类型名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/pro/MesProWorkOrderStatusEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/pro/MesProWorkOrderStatusEnum.java
new file mode 100644
index 000000000..1bd2ffa59
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/pro/MesProWorkOrderStatusEnum.java
@@ -0,0 +1,39 @@
+package cn.iocoder.yudao.module.mes.enums.pro;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 生产工单状态枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesProWorkOrderStatusEnum implements ArrayValuable {
+
+ PREPARE(0, "草稿"),
+ CONFIRMED(1, "已确认"),
+ FINISHED(2, "已完成"),
+ CANCELED(3, "已取消");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesProWorkOrderStatusEnum::getStatus).toArray(Integer[]::new);
+
+ /**
+ * 状态值
+ */
+ private final Integer status;
+ /**
+ * 状态名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/pro/MesProWorkOrderTypeEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/pro/MesProWorkOrderTypeEnum.java
new file mode 100644
index 000000000..3c7b15039
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/pro/MesProWorkOrderTypeEnum.java
@@ -0,0 +1,38 @@
+package cn.iocoder.yudao.module.mes.enums.pro;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 工单类型枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesProWorkOrderTypeEnum implements ArrayValuable {
+
+ SELF(1, "自行生产"),
+ OUTSOURCE(2, "代工"),
+ PURCHASE(3, "采购");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesProWorkOrderTypeEnum::getType).toArray(Integer[]::new);
+
+ /**
+ * 类型值
+ */
+ private final Integer type;
+ /**
+ * 类型名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/pro/MesProWorkRecordTypeEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/pro/MesProWorkRecordTypeEnum.java
new file mode 100644
index 000000000..1629a0e04
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/pro/MesProWorkRecordTypeEnum.java
@@ -0,0 +1,37 @@
+package cn.iocoder.yudao.module.mes.enums.pro;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 上下工操作类型枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesProWorkRecordTypeEnum implements ArrayValuable {
+
+ CLOCK_IN(1, "上工"),
+ CLOCK_OUT(2, "下工");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesProWorkRecordTypeEnum::getType).toArray(Integer[]::new);
+
+ /**
+ * 操作类型
+ */
+ private final Integer type;
+ /**
+ * 操作名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/pro/MesTimeUnitTypeEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/pro/MesTimeUnitTypeEnum.java
new file mode 100644
index 000000000..b6fa8b399
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/pro/MesTimeUnitTypeEnum.java
@@ -0,0 +1,38 @@
+package cn.iocoder.yudao.module.mes.enums.pro;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 时间单位枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesTimeUnitTypeEnum implements ArrayValuable {
+
+ MINUTE("MINUTE", "分钟"),
+ HOUR("HOUR", "小时"),
+ DAY("DAY", "天");
+
+ public static final String[] ARRAYS = Arrays.stream(values()).map(MesTimeUnitTypeEnum::getType).toArray(String[]::new);
+
+ /**
+ * 类型值
+ */
+ private final String type;
+ /**
+ * 类型名
+ */
+ private final String name;
+
+ @Override
+ public String[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcCheckResultEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcCheckResultEnum.java
new file mode 100644
index 000000000..a8ae07cbc
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcCheckResultEnum.java
@@ -0,0 +1,37 @@
+package cn.iocoder.yudao.module.mes.enums.qc;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 检测结果枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesQcCheckResultEnum implements ArrayValuable {
+
+ PASS(1, "检验通过"),
+ FAIL(2, "检验不通过");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesQcCheckResultEnum::getType).toArray(Integer[]::new);
+
+ /**
+ * 结果值
+ */
+ private final Integer type;
+ /**
+ * 结果名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcDefectLevelEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcDefectLevelEnum.java
new file mode 100644
index 000000000..0ceba0949
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcDefectLevelEnum.java
@@ -0,0 +1,38 @@
+package cn.iocoder.yudao.module.mes.enums.qc;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 缺陷等级枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesQcDefectLevelEnum implements ArrayValuable {
+
+ CRITICAL(1, "致命"),
+ MAJOR(2, "严重"),
+ MINOR(3, "轻微");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesQcDefectLevelEnum::getType).toArray(Integer[]::new);
+
+ /**
+ * 等级值
+ */
+ private final Integer type;
+ /**
+ * 等级名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcResultValueTypeEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcResultValueTypeEnum.java
new file mode 100644
index 000000000..659a42d72
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcResultValueTypeEnum.java
@@ -0,0 +1,40 @@
+package cn.iocoder.yudao.module.mes.enums.qc;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 质检值类型枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesQcResultValueTypeEnum implements ArrayValuable {
+
+ FLOAT(1, "浮点"),
+ INTEGER(2, "整数"),
+ TEXT(3, "文本"),
+ DICT(4, "字典"),
+ FILE(5, "文件");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesQcResultValueTypeEnum::getType).toArray(Integer[]::new);
+
+ /**
+ * 类型值
+ */
+ private final Integer type;
+ /**
+ * 类型名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcSourceDocTypeEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcSourceDocTypeEnum.java
new file mode 100644
index 000000000..01c8050d8
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcSourceDocTypeEnum.java
@@ -0,0 +1,50 @@
+package cn.iocoder.yudao.module.mes.enums.qc;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 质检来源单据类型枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesQcSourceDocTypeEnum implements ArrayValuable {
+
+ // === IQC 来源单据 ===
+ ARRIVAL_NOTICE(MesBizTypeConstants.WM_ARRIVAL_NOTICE, "到货通知单"),
+ OUTSOURCE_RECPT(MesBizTypeConstants.WM_OUTSOURCE_RECPT, "外协入库单"),
+
+ // === IPQC 来源单据 ===
+ PRO_FEEDBACK(MesBizTypeConstants.PRO_FEEDBACK, "生产报工"),
+
+ // === OQC 来源单据 ===
+ PRODUCT_SALES(MesBizTypeConstants.WM_PRODUCT_SALES, "销售出库单"),
+
+ // === RQC 来源单据 ===
+ RETURN_ISSUE(MesBizTypeConstants.WM_RETURN_ISSUE, "生产退料单"),
+ RETURN_SALES(MesBizTypeConstants.WM_RETURN_SALES, "销售退货单"),
+ ;
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesQcSourceDocTypeEnum::getType).toArray(Integer[]::new);
+
+ /**
+ * 类型值
+ */
+ private final Integer type;
+ /**
+ * 类型名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcStatusEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcStatusEnum.java
new file mode 100644
index 000000000..c16bc6d57
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcStatusEnum.java
@@ -0,0 +1,42 @@
+package cn.iocoder.yudao.module.mes.enums.qc;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import cn.iocoder.yudao.module.mes.enums.MesOrderStatusConstants;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 质检单状态枚举
+ *
+ * 适用于:IQC(来料检验)、IPQC(过程检验)、OQC(出货检验)、RQC(退货检验)
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesQcStatusEnum implements ArrayValuable {
+
+ DRAFT(MesOrderStatusConstants.PREPARE, "草稿"),
+ FINISHED(MesOrderStatusConstants.FINISHED, "已完成");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values())
+ .map(MesQcStatusEnum::getStatus).toArray(Integer[]::new);
+
+ /**
+ * 状态值
+ */
+ private final Integer status;
+
+ /**
+ * 状态名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcTypeEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcTypeEnum.java
new file mode 100644
index 000000000..c47c1ba18
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcTypeEnum.java
@@ -0,0 +1,40 @@
+package cn.iocoder.yudao.module.mes.enums.qc;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 检测种类枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesQcTypeEnum implements ArrayValuable {
+
+ IQC(MesBizTypeConstants.QC_IQC, "来料检验"),
+ IPQC(MesBizTypeConstants.QC_IPQC, "过程检验"),
+ OQC(MesBizTypeConstants.QC_OQC, "出货检验"),
+ RQC(MesBizTypeConstants.QC_RQC, "退货检验");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesQcTypeEnum::getType).toArray(Integer[]::new);
+
+ /**
+ * 类型值
+ */
+ private final Integer type;
+ /**
+ * 类型名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/tm/MesTmMaintenTypeEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/tm/MesTmMaintenTypeEnum.java
new file mode 100644
index 000000000..16cdffcb2
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/tm/MesTmMaintenTypeEnum.java
@@ -0,0 +1,37 @@
+package cn.iocoder.yudao.module.mes.enums.tm;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 保养维护类型枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesTmMaintenTypeEnum implements ArrayValuable {
+
+ REGULAR(1, "定期维护"),
+ USAGE(2, "按使用次数维护");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesTmMaintenTypeEnum::getType).toArray(Integer[]::new);
+
+ /**
+ * 类型值
+ */
+ private final Integer type;
+ /**
+ * 类型名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/tm/MesTmToolStatusEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/tm/MesTmToolStatusEnum.java
new file mode 100644
index 000000000..5152bd398
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/tm/MesTmToolStatusEnum.java
@@ -0,0 +1,39 @@
+package cn.iocoder.yudao.module.mes.enums.tm;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 工具状态枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesTmToolStatusEnum implements ArrayValuable {
+
+ STORE(1, "在库"),
+ ISSUE(2, "领用中"),
+ REPAIR(3, "维修中"),
+ SCRAP(4, "报废");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesTmToolStatusEnum::getStatus).toArray(Integer[]::new);
+
+ /**
+ * 状态值
+ */
+ private final Integer status;
+ /**
+ * 状态名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/BarcodeBizTypeEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/BarcodeBizTypeEnum.java
new file mode 100644
index 000000000..4b25d41c9
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/BarcodeBizTypeEnum.java
@@ -0,0 +1,53 @@
+package cn.iocoder.yudao.module.mes.enums.wm;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 条码业务类型枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum BarcodeBizTypeEnum implements ArrayValuable {
+
+ WAREHOUSE(MesBizTypeConstants.WM_WAREHOUSE, "仓库"),
+ LOCATION(MesBizTypeConstants.WM_LOCATION, "库区"),
+ AREA(MesBizTypeConstants.WM_AREA, "库位"),
+ PACKAGE(MesBizTypeConstants.WM_PACKAGE, "装箱单"),
+ STOCK(MesBizTypeConstants.WM_STOCK, "库存"),
+ BATCH(MesBizTypeConstants.WM_BATCH, "批次"),
+ PROCARD(MesBizTypeConstants.PRO_CARD, "流转卡"),
+ WORKORDER(MesBizTypeConstants.PRO_WORKORDER, "工单"),
+ TRANSORDER(MesBizTypeConstants.PRO_TRANS_ORDER, "流转单"),
+ MACHINERY(MesBizTypeConstants.DV_MACHINERY, "设备"),
+ TOOL(MesBizTypeConstants.TM_TOOL, "工具"),
+ ITEM(MesBizTypeConstants.MD_ITEM, "物料"),
+ VENDOR(MesBizTypeConstants.MD_VENDOR, "供应商"),
+ CLIENT(MesBizTypeConstants.MD_CLIENT, "客户"),
+ WORKSTATION(MesBizTypeConstants.MD_WORKSTATION, "工作站"),
+ WORKSHOP(MesBizTypeConstants.MD_WORKSHOP, "车间"),
+ USER(MesBizTypeConstants.MD_USER, "人员");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(BarcodeBizTypeEnum::getValue).toArray(Integer[]::new);
+
+ /**
+ * 业务类型值
+ */
+ private final Integer value;
+ /**
+ * 业务类型名称
+ */
+ private final String label;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/BarcodeFormatEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/BarcodeFormatEnum.java
new file mode 100644
index 000000000..ef1c900d3
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/BarcodeFormatEnum.java
@@ -0,0 +1,39 @@
+package cn.iocoder.yudao.module.mes.enums.wm;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 条码格式枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum BarcodeFormatEnum implements ArrayValuable {
+
+ QR_CODE(1, "二维码"),
+ EAN13(2, "EAN13 商品条码"),
+ CODE39(3, "CODE39 工业条码"),
+ UPC_A(4, "UPC-A 美国商品码");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(BarcodeFormatEnum::getValue).toArray(Integer[]::new);
+
+ /**
+ * 格式值
+ */
+ private final Integer value;
+ /**
+ * 格式名称
+ */
+ private final String label;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmArrivalNoticeStatusEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmArrivalNoticeStatusEnum.java
new file mode 100644
index 000000000..25acc1543
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmArrivalNoticeStatusEnum.java
@@ -0,0 +1,62 @@
+package cn.iocoder.yudao.module.mes.enums.wm;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import cn.iocoder.yudao.module.mes.enums.MesOrderStatusConstants;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 到货通知单状态枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesWmArrivalNoticeStatusEnum implements ArrayValuable {
+
+ /**
+ * 草稿
+ *
+ * 对应 MesWmArrivalNoticeService#createArrivalNotice 方法
+ */
+ PREPARE(MesOrderStatusConstants.PREPARE, "草稿"),
+ /**
+ * 待质检(需要检验时),对接 qc 模块的 MesQcIqcDO 后续流程
+ *
+ * 对应 MesWmArrivalNoticeService#submitArrivalNotice 方法
+ */
+ PENDING_QC(MesOrderStatusConstants.APPROVING, "待质检"),
+ /**
+ * 待入库(不需要检验时,或检验完成时),对接 wm 模块的 MesWmItemReceiptDO 后续流程
+ *
+ * 对应方法:
+ * 1. 不需要检验时:MesWmArrivalNoticeService#submitArrivalNotice 方法
+ * 2. 或检验完成时:MesWmArrivalNoticeService#updateArrivalNoticeWhenIqcFinish 方法
+ */
+ PENDING_RECEIPT(MesOrderStatusConstants.APPROVED, "待入库"),
+ /**
+ * 已完成
+ *
+ * 对应 MesWmArrivalNoticeService#finishArrivalNotice 方法
+ */
+ FINISHED(MesOrderStatusConstants.FINISHED, "已完成");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmArrivalNoticeStatusEnum::getStatus).toArray(Integer[]::new);
+
+ /**
+ * 状态值
+ */
+ private final Integer status;
+ /**
+ * 状态名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmItemConsumeStatusEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmItemConsumeStatusEnum.java
new file mode 100644
index 000000000..c510555b6
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmItemConsumeStatusEnum.java
@@ -0,0 +1,48 @@
+package cn.iocoder.yudao.module.mes.enums.wm;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import cn.iocoder.yudao.module.mes.enums.MesOrderStatusConstants;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 物料消耗记录状态枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesWmItemConsumeStatusEnum implements ArrayValuable {
+
+ /**
+ * 草稿
+ *
+ * 对应 MesWmItemConsumeService#generateItemConsume 方法
+ */
+ PREPARE(MesOrderStatusConstants.PREPARE, "草稿"),
+ /**
+ * 已完成
+ *
+ * 对应 MesWmItemConsumeService#finishItemConsume 方法
+ */
+ FINISHED(MesOrderStatusConstants.FINISHED, "已完成");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmItemConsumeStatusEnum::getStatus).toArray(Integer[]::new);
+
+ /**
+ * 状态值
+ */
+ private final Integer status;
+ /**
+ * 状态名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmItemReceiptStatusEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmItemReceiptStatusEnum.java
new file mode 100644
index 000000000..4b1a80abf
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmItemReceiptStatusEnum.java
@@ -0,0 +1,66 @@
+package cn.iocoder.yudao.module.mes.enums.wm;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import cn.iocoder.yudao.module.mes.enums.MesOrderStatusConstants;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 采购入库单状态枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesWmItemReceiptStatusEnum implements ArrayValuable {
+
+ /**
+ * 草稿
+ *
+ * 对应 MesWmItemReceiptService#createItemReceipt 方法
+ */
+ PREPARE(MesOrderStatusConstants.PREPARE, "草稿"),
+ /**
+ * 待上架
+ *
+ * 对应 MesWmItemReceiptService#submitItemReceipt 方法
+ */
+ APPROVING(MesOrderStatusConstants.APPROVING, "待上架"),
+ /**
+ * 待入库
+ *
+ * 对应 MesWmItemReceiptService#stockItemReceipt 方法
+ */
+ APPROVED(MesOrderStatusConstants.APPROVED, "待执行入库"),
+ /**
+ * 已完成
+ *
+ * 对应 MesWmItemReceiptService#finishItemReceipt 方法
+ */
+ FINISHED(MesOrderStatusConstants.FINISHED, "已完成"),
+ /**
+ * 已取消
+ *
+ * 对应 MesWmItemReceiptService#cancelItemReceipt 方法
+ */
+ CANCELED(MesOrderStatusConstants.CANCELLED, "已取消");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmItemReceiptStatusEnum::getStatus).toArray(Integer[]::new);
+
+ /**
+ * 状态值
+ */
+ private final Integer status;
+ /**
+ * 状态名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmMiscIssueStatusEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmMiscIssueStatusEnum.java
new file mode 100644
index 000000000..17168f48a
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmMiscIssueStatusEnum.java
@@ -0,0 +1,62 @@
+package cn.iocoder.yudao.module.mes.enums.wm;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import cn.iocoder.yudao.module.mes.enums.MesOrderStatusConstants;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 杂项出库单状态枚举
+ *
+ * 对应字典 mes_wm_misc_issue_status
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesWmMiscIssueStatusEnum implements ArrayValuable {
+
+ /**
+ * 草稿
+ *
+ * 对应 MesWmMiscIssueService#createMiscIssue 方法
+ */
+ PREPARE(MesOrderStatusConstants.PREPARE, "草稿"),
+ /**
+ * 待执行出库
+ *
+ * 对应 MesWmMiscIssueService#submitMiscIssue 方法
+ */
+ APPROVED(MesOrderStatusConstants.APPROVED, "待执行出库"),
+ /**
+ * 已完成
+ *
+ * 对应 MesWmMiscIssueService#finishMiscIssue 方法
+ */
+ FINISHED(MesOrderStatusConstants.FINISHED, "已完成"),
+ /**
+ * 已取消
+ *
+ * 对应 MesWmMiscIssueService#cancelMiscIssue 方法
+ */
+ CANCELED(MesOrderStatusConstants.CANCELLED, "已取消");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmMiscIssueStatusEnum::getStatus).toArray(Integer[]::new);
+
+ /**
+ * 状态值
+ */
+ private final Integer status;
+ /**
+ * 状态名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmMiscIssueTypeEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmMiscIssueTypeEnum.java
new file mode 100644
index 000000000..5162329d0
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmMiscIssueTypeEnum.java
@@ -0,0 +1,24 @@
+package cn.iocoder.yudao.module.mes.enums.wm;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+@Getter
+@AllArgsConstructor
+public enum MesWmMiscIssueTypeEnum implements ArrayValuable {
+
+ ADJUST(1, "库存调整"),
+ SCRAP(2, "报废出库");
+
+ private final Integer type;
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return Arrays.stream(values()).map(MesWmMiscIssueTypeEnum::getType).toArray(Integer[]::new);
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmMiscReceiptStatusEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmMiscReceiptStatusEnum.java
new file mode 100644
index 000000000..8fc3092c8
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmMiscReceiptStatusEnum.java
@@ -0,0 +1,60 @@
+package cn.iocoder.yudao.module.mes.enums.wm;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import cn.iocoder.yudao.module.mes.enums.MesOrderStatusConstants;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 杂项入库单状态枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesWmMiscReceiptStatusEnum implements ArrayValuable {
+
+ /**
+ * 草稿
+ *
+ * 对应 MesWmMiscReceiptService#createMiscReceipt 方法
+ */
+ PREPARE(MesOrderStatusConstants.PREPARE, "草稿"),
+ /**
+ * 已审批
+ *
+ * 对应 MesWmMiscReceiptService#submitMiscReceipt 方法
+ */
+ APPROVED(MesOrderStatusConstants.APPROVED, "已审批"),
+ /**
+ * 已完成
+ *
+ * 对应 MesWmMiscReceiptService#finishMiscReceipt 方法
+ */
+ FINISHED(MesOrderStatusConstants.FINISHED, "已完成"),
+ /**
+ * 已取消
+ *
+ * 对应 MesWmMiscReceiptService#cancelMiscReceipt 方法
+ */
+ CANCELED(MesOrderStatusConstants.CANCELLED, "已取消");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmMiscReceiptStatusEnum::getStatus).toArray(Integer[]::new);
+
+ /**
+ * 状态值
+ */
+ private final Integer status;
+ /**
+ * 状态名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmMiscReceiptTypeEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmMiscReceiptTypeEnum.java
new file mode 100644
index 000000000..072637efb
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmMiscReceiptTypeEnum.java
@@ -0,0 +1,34 @@
+package cn.iocoder.yudao.module.mes.enums.wm;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 杂项入库类型枚举
+ */
+@Getter
+@AllArgsConstructor
+public enum MesWmMiscReceiptTypeEnum implements ArrayValuable {
+
+ ADJUST(1, "库存调整");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmMiscReceiptTypeEnum::getType).toArray(Integer[]::new);
+
+ /**
+ * 类型值
+ */
+ private final Integer type;
+ /**
+ * 类型名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmOutsourceIssueStatusEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmOutsourceIssueStatusEnum.java
new file mode 100644
index 000000000..8569a982d
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmOutsourceIssueStatusEnum.java
@@ -0,0 +1,68 @@
+package cn.iocoder.yudao.module.mes.enums.wm;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import cn.iocoder.yudao.module.mes.enums.MesOrderStatusConstants;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 外协发料单状态枚举
+ *
+ * 对应字典 mes_wm_outsource_issue_status
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesWmOutsourceIssueStatusEnum implements ArrayValuable {
+
+ /**
+ * 草稿
+ *
+ * 对应 MesWmOutsourceIssueService#createOutsourceIssue 方法
+ */
+ PREPARE(MesOrderStatusConstants.PREPARE, "草稿"),
+ /**
+ * 待拣货
+ *
+ * 对应 MesWmOutsourceIssueService#submitOutsourceIssue 方法
+ */
+ APPROVING(MesOrderStatusConstants.APPROVING, "待拣货"),
+ /**
+ * 待执行出库
+ *
+ * 对应 MesWmOutsourceIssueService#stockOutsourceIssue 方法
+ */
+ APPROVED(MesOrderStatusConstants.APPROVED, "待执行出库"),
+ /**
+ * 已完成
+ *
+ * 对应 MesWmOutsourceIssueService#finishOutsourceIssue 方法
+ */
+ FINISHED(MesOrderStatusConstants.FINISHED, "已完成"),
+ /**
+ * 已取消
+ *
+ * 对应 MesWmOutsourceIssueService#cancelOutsourceIssue 方法
+ */
+ CANCELLED(MesOrderStatusConstants.CANCELLED, "已取消");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmOutsourceIssueStatusEnum::getStatus).toArray(Integer[]::new);
+
+ /**
+ * 状态值
+ */
+ private final Integer status;
+ /**
+ * 状态名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmOutsourceReceiptStatusEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmOutsourceReceiptStatusEnum.java
new file mode 100644
index 000000000..5024a5f2f
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmOutsourceReceiptStatusEnum.java
@@ -0,0 +1,74 @@
+package cn.iocoder.yudao.module.mes.enums.wm;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import cn.iocoder.yudao.module.mes.enums.MesOrderStatusConstants;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 外协入库单状态枚举
+ *
+ * 对应字典 mes_wm_outsource_receipt_status
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesWmOutsourceReceiptStatusEnum implements ArrayValuable {
+
+ /**
+ * 草稿
+ *
+ * 对应 MesWmOutsourceReceiptService#createOutsourceReceipt 方法
+ */
+ PREPARE(MesOrderStatusConstants.PREPARE, "草稿"),
+ /**
+ * 待检验(已确认,等待质检)
+ *
+ * 对应 MesWmOutsourceReceiptService#submitOutsourceReceipt 方法
+ */
+ CONFIRMED(MesOrderStatusConstants.CONFIRMED, "待检验"),
+ /**
+ * 待上架(检验完成,等待仓库上架)
+ *
+ * 对应 MesWmOutsourceReceiptService#submitOutsourceReceipt 方法
+ */
+ APPROVING(MesOrderStatusConstants.APPROVING, "待上架"),
+ /**
+ * 待执行入库(上架完成,等待执行入库操作)
+ *
+ * 对应 MesWmOutsourceReceiptService#stockOutsourceReceipt 方法
+ */
+ APPROVED(MesOrderStatusConstants.APPROVED, "待执行入库"),
+ /**
+ * 已完成(入库执行完成,库存已更新)
+ *
+ * 对应 MesWmOutsourceReceiptService#finishOutsourceReceipt 方法
+ */
+ FINISHED(MesOrderStatusConstants.FINISHED, "已完成"),
+ /**
+ * 已取消
+ *
+ * 对应 MesWmOutsourceReceiptService#cancelOutsourceReceipt 方法
+ */
+ CANCELED(MesOrderStatusConstants.CANCELLED, "已取消");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmOutsourceReceiptStatusEnum::getStatus).toArray(Integer[]::new);
+
+ /**
+ * 状态值
+ */
+ private final Integer status;
+ /**
+ * 状态名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmPackageStatusEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmPackageStatusEnum.java
new file mode 100644
index 000000000..54820b8cf
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmPackageStatusEnum.java
@@ -0,0 +1,49 @@
+package cn.iocoder.yudao.module.mes.enums.wm;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import cn.iocoder.yudao.module.mes.enums.MesOrderStatusConstants;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 装箱单状态枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesWmPackageStatusEnum implements ArrayValuable {
+
+ /**
+ * 草稿
+ *
+ * 对应 MesWmPackageService#createPackage 方法
+ */
+ PREPARE(MesOrderStatusConstants.PREPARE, "草稿"),
+ /**
+ * 已完成
+ *
+ * 对应 MesWmPackageService#finishPackage 方法
+ */
+ FINISHED(MesOrderStatusConstants.FINISHED, "已完成");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmPackageStatusEnum::getStatus)
+ .toArray(Integer[]::new);
+
+ /**
+ * 状态值
+ */
+ private final Integer status;
+ /**
+ * 状态名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmProductIssueStatusEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmProductIssueStatusEnum.java
new file mode 100644
index 000000000..e395e6c33
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmProductIssueStatusEnum.java
@@ -0,0 +1,66 @@
+package cn.iocoder.yudao.module.mes.enums.wm;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import cn.iocoder.yudao.module.mes.enums.MesOrderStatusConstants;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 领料出库单状态枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesWmProductIssueStatusEnum implements ArrayValuable {
+
+ /**
+ * 草稿
+ *
+ * 对应 MesWmProductIssueService#createProductIssue 方法
+ */
+ PREPARE(MesOrderStatusConstants.PREPARE, "草稿"),
+ /**
+ * 待拣货
+ *
+ * 对应 MesWmProductIssueService#submitProductIssue 方法
+ */
+ APPROVING(MesOrderStatusConstants.APPROVING, "待拣货"),
+ /**
+ * 待执行领出
+ *
+ * 对应 MesWmProductIssueService#stockProductIssue 方法
+ */
+ APPROVED(MesOrderStatusConstants.APPROVED, "待执行领出"),
+ /**
+ * 已完成
+ *
+ * 对应 MesWmProductIssueService#finishProductIssue 方法
+ */
+ FINISHED(MesOrderStatusConstants.FINISHED, "已完成"),
+ /**
+ * 已取消
+ *
+ * 对应 MesWmProductIssueService#cancelProductIssue 方法
+ */
+ CANCELED(MesOrderStatusConstants.CANCELLED, "已取消");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmProductIssueStatusEnum::getStatus).toArray(Integer[]::new);
+
+ /**
+ * 状态值
+ */
+ private final Integer status;
+ /**
+ * 状态名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmProductProduceStatusEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmProductProduceStatusEnum.java
new file mode 100644
index 000000000..e89c29c23
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmProductProduceStatusEnum.java
@@ -0,0 +1,52 @@
+package cn.iocoder.yudao.module.mes.enums.wm;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import cn.iocoder.yudao.module.mes.enums.MesOrderStatusConstants;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 生产入库单状态枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesWmProductProduceStatusEnum implements ArrayValuable {
+
+ /**
+ * 草稿
+ *
+ * 对应 MesWmProductProduceService#generateProductProduce 方法
+ */
+ PREPARE(MesOrderStatusConstants.PREPARE, "草稿"),
+ /**
+ * 已完成
+ *
+ * 对应 MesWmProductProduceService#finishProductProduce 方法
+ */
+ FINISHED(MesOrderStatusConstants.FINISHED, "已完成"),
+ /**
+ * 已取消
+ */
+ CANCELED(MesOrderStatusConstants.CANCELLED, "已取消");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmProductProduceStatusEnum::getStatus).toArray(Integer[]::new);
+
+ /**
+ * 状态值
+ */
+ private final Integer status;
+ /**
+ * 状态名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmProductReceiptStatusEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmProductReceiptStatusEnum.java
new file mode 100644
index 000000000..707dfad0d
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmProductReceiptStatusEnum.java
@@ -0,0 +1,66 @@
+package cn.iocoder.yudao.module.mes.enums.wm;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import cn.iocoder.yudao.module.mes.enums.MesOrderStatusConstants;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 产品入库单状态枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesWmProductReceiptStatusEnum implements ArrayValuable {
+
+ /**
+ * 草稿
+ *
+ * 对应 MesWmProductReceiptService#createProductReceipt 方法
+ */
+ PREPARE(MesOrderStatusConstants.PREPARE, "草稿"),
+ /**
+ * 待上架
+ *
+ * 对应 MesWmProductReceiptService#submitProductReceipt 方法
+ */
+ APPROVING(MesOrderStatusConstants.APPROVING, "待上架"),
+ /**
+ * 待执行入库
+ *
+ * 对应 MesWmProductReceiptService#stockProductReceipt 方法
+ */
+ APPROVED(MesOrderStatusConstants.APPROVED, "待执行入库"),
+ /**
+ * 已完成
+ *
+ * 对应 MesWmProductReceiptService#finishProductReceipt 方法
+ */
+ FINISHED(MesOrderStatusConstants.FINISHED, "已完成"),
+ /**
+ * 已取消
+ *
+ * 对应 MesWmProductReceiptService#cancelProductReceipt 方法
+ */
+ CANCELED(MesOrderStatusConstants.CANCELLED, "已取消");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmProductReceiptStatusEnum::getStatus).toArray(Integer[]::new);
+
+ /**
+ * 状态值
+ */
+ private final Integer status;
+ /**
+ * 状态名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmProductSalesStatusEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmProductSalesStatusEnum.java
new file mode 100644
index 000000000..34325040b
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmProductSalesStatusEnum.java
@@ -0,0 +1,82 @@
+package cn.iocoder.yudao.module.mes.enums.wm;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import cn.iocoder.yudao.module.mes.enums.MesOrderStatusConstants;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 销售出库单状态枚举
+ *
+ * 对应字典 mes_wm_product_sales_status
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesWmProductSalesStatusEnum implements ArrayValuable {
+
+ /**
+ * 草稿
+ *
+ * 对应 MesWmProductSalesService#createProductSales 方法
+ */
+ PREPARE(MesOrderStatusConstants.PREPARE, "草稿"),
+ /**
+ * 待检测(需要 OQC 检验时),对接 qc 模块的 MesQcOqcDO 后续流程
+ *
+ * 对应 MesWmProductSalesService#submitProductSales 方法
+ */
+ CONFIRMED(MesOrderStatusConstants.CONFIRMED, "待检测"),
+ /**
+ * 待拣货
+ *
+ * 对应方法:
+ * 1. 不需要 OQC 检验时:MesWmProductSalesService#submitProductSales 方法
+ * 2. 或 OQC 检验完成时:MesWmProductSalesService#confirmProductSales 方法
+ */
+ APPROVING(MesOrderStatusConstants.APPROVING, "待拣货"),
+ /**
+ * 待填写运单
+ *
+ * 对应 MesWmProductSalesService#shippingProductSales 方法
+ */
+ SHIPPING(10, "待填写运单"), // 10 是一个特殊的状态值,不在 MesOrderStatusConstants 中,单独定义
+ /**
+ * 待执行出库
+ *
+ * 对应 MesWmProductSalesService#stockProductSales 方法
+ */
+ APPROVED(MesOrderStatusConstants.APPROVED, "待执行出库"),
+ /**
+ * 已完成
+ *
+ * 对应 MesWmProductSalesService#finishProductSales 方法
+ */
+ FINISHED(MesOrderStatusConstants.FINISHED, "已完成"),
+ /**
+ * 已取消
+ *
+ * 对应 MesWmProductSalesService#cancelProductSales 方法
+ */
+ CANCELED(MesOrderStatusConstants.CANCELLED, "已取消");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmProductSalesStatusEnum::getStatus).toArray(Integer[]::new);
+
+ /**
+ * 状态值
+ */
+ private final Integer status;
+ /**
+ * 状态名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmQualityStatusEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmQualityStatusEnum.java
new file mode 100644
index 000000000..00bd23332
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmQualityStatusEnum.java
@@ -0,0 +1,49 @@
+package cn.iocoder.yudao.module.mes.enums.wm;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 质量状态枚举
+ *
+ * 对应字典 mes_wm_quality_status
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesWmQualityStatusEnum implements ArrayValuable {
+
+ /**
+ * 待检验
+ */
+ PENDING(0, "待检验"),
+ /**
+ * 合格
+ */
+ PASS(1, "合格"),
+ /**
+ * 不合格
+ */
+ FAIL(2, "不合格");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmQualityStatusEnum::getStatus).toArray(Integer[]::new);
+
+ /**
+ * 状态值
+ */
+ private final Integer status;
+ /**
+ * 状态名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmReturnIssueStatusEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmReturnIssueStatusEnum.java
new file mode 100644
index 000000000..2b90d96f8
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmReturnIssueStatusEnum.java
@@ -0,0 +1,74 @@
+package cn.iocoder.yudao.module.mes.enums.wm;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import cn.iocoder.yudao.module.mes.enums.MesOrderStatusConstants;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 生产退料单状态枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesWmReturnIssueStatusEnum implements ArrayValuable {
+
+ /**
+ * 草稿
+ *
+ * 对应 MesWmReturnIssueService#createReturnIssue 方法
+ */
+ PREPARE(MesOrderStatusConstants.PREPARE, "草稿"),
+ /**
+ * 待检验(已确认,等待质检)
+ *
+ * 对应 MesWmReturnIssueService#submitReturnIssue 方法
+ */
+ CONFIRMED(MesOrderStatusConstants.CONFIRMED, "待检验"), // "UNCHECK"
+ /**
+ * 待上架(检验完成,等待仓库上架)
+ *
+ * 对应 MesWmReturnIssueService#submitReturnIssue 方法
+ */
+ APPROVING(MesOrderStatusConstants.APPROVING, "待上架"), // "UNSTOCK"
+ /**
+ * 待执行退料(上架完成,等待执行退料操作)
+ *
+ * 对应 MesWmReturnIssueService#stockReturnIssue 方法
+ */
+ APPROVED(MesOrderStatusConstants.APPROVED, "待执行退料"), // "UNEXECUTE"
+ /**
+ * 已完成(退料执行完成,库存已更新)
+ *
+ * 对应 MesWmReturnIssueService#finishReturnIssue 方法
+ */
+ FINISHED(MesOrderStatusConstants.FINISHED, "已完成"),
+ /**
+ * 已取消
+ *
+ * 对应 MesWmReturnIssueService#cancelReturnIssue 方法
+ */
+ CANCELED(MesOrderStatusConstants.CANCELLED, "已取消");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmReturnIssueStatusEnum::getStatus).toArray(Integer[]::new);
+
+ /**
+ * 状态值
+ */
+ private final Integer status;
+ /**
+ * 状态名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
+
+// DONE @AI:状态流转逻辑已在 MesWmReturnIssueServiceImpl 中实现,参考 confirmReturnIssue、submitReturnIssue、stockReturnIssue、finishReturnIssue 方法
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmReturnIssueTypeEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmReturnIssueTypeEnum.java
new file mode 100644
index 000000000..e57904ff4
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmReturnIssueTypeEnum.java
@@ -0,0 +1,49 @@
+package cn.iocoder.yudao.module.mes.enums.wm;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 生产退料类型枚举
+ *
+ * 对应字典 mes_wm_return_issue_type
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesWmReturnIssueTypeEnum implements ArrayValuable {
+
+ /**
+ * 余料退料(余料退回,直接合格)
+ */
+ REMAINDER(1, "余料退料"),
+ /**
+ * 不良退料(不良品退回)
+ */
+ DEFECTIVE(2, "不良退料"),
+ /**
+ * 其他退料(其他原因退料)
+ */
+ OTHER(3, "其他退料");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmReturnIssueTypeEnum::getType).toArray(Integer[]::new);
+
+ /**
+ * 类型值
+ */
+ private final Integer type;
+ /**
+ * 类型名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmReturnSalesStatusEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmReturnSalesStatusEnum.java
new file mode 100644
index 000000000..2b75e5996
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmReturnSalesStatusEnum.java
@@ -0,0 +1,72 @@
+package cn.iocoder.yudao.module.mes.enums.wm;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import cn.iocoder.yudao.module.mes.enums.MesOrderStatusConstants;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 销售退货单状态枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesWmReturnSalesStatusEnum implements ArrayValuable {
+
+ /**
+ * 草稿
+ *
+ * 对应 MesWmReturnSalesService#createReturnSales 方法
+ */
+ PREPARE(MesOrderStatusConstants.PREPARE, "草稿"),
+ /**
+ * 待检验(已确认,等待质检)
+ *
+ * 对应 MesWmReturnSalesService#submitReturnSales 方法
+ */
+ CONFIRMED(MesOrderStatusConstants.CONFIRMED, "待检验"), // "UNCHECK"
+ /**
+ * 待执行(检验完成或免检,等待执行退货)
+ *
+ * 对应 MesWmReturnSalesService#submitReturnSales 方法
+ */
+ APPROVING(MesOrderStatusConstants.APPROVING, "待执行"), // "UNEXECUTE"
+ /**
+ * 待上架(退货执行完成,等待仓库上架)
+ *
+ * 对应 MesWmReturnSalesService#finishReturnSales 方法
+ */
+ APPROVED(MesOrderStatusConstants.APPROVED, "待上架"), // "UNSTOCK"
+ /**
+ * 已完成(上架完成,库存已更新)
+ *
+ * 对应 MesWmReturnSalesService#stockReturnSales 方法
+ */
+ FINISHED(MesOrderStatusConstants.FINISHED, "已完成"),
+ /**
+ * 已取消
+ *
+ * 对应 MesWmReturnSalesService#cancelReturnSales 方法
+ */
+ CANCELED(MesOrderStatusConstants.CANCELLED, "已取消");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmReturnSalesStatusEnum::getStatus).toArray(Integer[]::new);
+
+ /**
+ * 状态值
+ */
+ private final Integer status;
+ /**
+ * 状态名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmReturnVendorStatusEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmReturnVendorStatusEnum.java
new file mode 100644
index 000000000..1c8bc68de
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmReturnVendorStatusEnum.java
@@ -0,0 +1,66 @@
+package cn.iocoder.yudao.module.mes.enums.wm;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import cn.iocoder.yudao.module.mes.enums.MesOrderStatusConstants;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 供应商退货单状态枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesWmReturnVendorStatusEnum implements ArrayValuable {
+
+ /**
+ * 草稿
+ *
+ * 对应 MesWmReturnVendorService#createReturnVendor 方法
+ */
+ PREPARE(MesOrderStatusConstants.PREPARE, "草稿"),
+ /**
+ * 待拣货
+ *
+ * 对应 MesWmReturnVendorService#submitReturnVendor 方法
+ */
+ APPROVING(MesOrderStatusConstants.APPROVING, "待拣货"),
+ /**
+ * 待执行退货
+ *
+ * 对应 MesWmReturnVendorService#stockReturnVendor 方法
+ */
+ APPROVED(MesOrderStatusConstants.APPROVED, "待执行退货"),
+ /**
+ * 已完成
+ *
+ * 对应 MesWmReturnVendorService#finishReturnVendor 方法
+ */
+ FINISHED(MesOrderStatusConstants.FINISHED, "已完成"),
+ /**
+ * 已取消
+ *
+ * 对应 MesWmReturnVendorService#cancelReturnVendor 方法
+ */
+ CANCELED(MesOrderStatusConstants.CANCELLED, "已取消");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmReturnVendorStatusEnum::getStatus).toArray(Integer[]::new);
+
+ /**
+ * 状态值
+ */
+ private final Integer status;
+ /**
+ * 状态名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmSalesNoticeStatusEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmSalesNoticeStatusEnum.java
new file mode 100644
index 000000000..01ab066a7
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmSalesNoticeStatusEnum.java
@@ -0,0 +1,49 @@
+package cn.iocoder.yudao.module.mes.enums.wm;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import cn.iocoder.yudao.module.mes.enums.MesOrderStatusConstants;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 发货通知单状态枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesWmSalesNoticeStatusEnum implements ArrayValuable {
+
+ /**
+ * 草稿
+ *
+ * 对应 MesWmSalesNoticeService#createSalesNotice 方法
+ */
+ PREPARE(MesOrderStatusConstants.PREPARE, "草稿"),
+ /**
+ * 待出库,对接 wm 模块的 MesWmProductSalesDO 后续流程
+ *
+ * 对应 MesWmSalesNoticeService#submitSalesNotice 方法
+ */
+ APPROVED(MesOrderStatusConstants.APPROVED, "待出库");
+ // TODO @芋艿:【对齐】暂时无后续流程,看看后续要怎么支持下。
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmSalesNoticeStatusEnum::getStatus).toArray(Integer[]::new);
+
+ /**
+ * 状态值
+ */
+ private final Integer status;
+ /**
+ * 状态名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmStockTakingPlanParamTypeEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmStockTakingPlanParamTypeEnum.java
new file mode 100644
index 000000000..d45078a84
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmStockTakingPlanParamTypeEnum.java
@@ -0,0 +1,41 @@
+package cn.iocoder.yudao.module.mes.enums.wm;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 盘点方案参数类型枚举
+ */
+@Getter
+@AllArgsConstructor
+public enum MesWmStockTakingPlanParamTypeEnum implements ArrayValuable {
+
+ WAREHOUSE(MesBizTypeConstants.WM_WAREHOUSE, "仓库"),
+ LOCATION(MesBizTypeConstants.WM_LOCATION, "库区"),
+ AREA(MesBizTypeConstants.WM_AREA, "库位"),
+ ITEM(MesBizTypeConstants.MD_ITEM, "物料"),
+ BATCH(MesBizTypeConstants.WM_BATCH, "批次"),
+ QUALITY_STATUS(MesBizTypeConstants.QUALITY_STATUS, "质量状态");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values())
+ .map(MesWmStockTakingPlanParamTypeEnum::getType).toArray(Integer[]::new);
+
+ /**
+ * 参数类型
+ */
+ private final Integer type;
+ /**
+ * 类型名称
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmStockTakingTaskLineStatusEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmStockTakingTaskLineStatusEnum.java
new file mode 100644
index 000000000..b5448a9bb
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmStockTakingTaskLineStatusEnum.java
@@ -0,0 +1,37 @@
+package cn.iocoder.yudao.module.mes.enums.wm;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 盘点任务行状态枚举
+ */
+@Getter
+@AllArgsConstructor
+public enum MesWmStockTakingTaskLineStatusEnum implements ArrayValuable {
+
+ NORMAL(1, "正常"),
+ GAIN(2, "盘盈"),
+ LOSS(3, "盘亏");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values())
+ .map(MesWmStockTakingTaskLineStatusEnum::getStatus).toArray(Integer[]::new);
+
+ /**
+ * 状态
+ */
+ private final Integer status;
+ /**
+ * 状态名称
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmStockTakingTaskStatusEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmStockTakingTaskStatusEnum.java
new file mode 100644
index 000000000..7756783f8
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmStockTakingTaskStatusEnum.java
@@ -0,0 +1,61 @@
+package cn.iocoder.yudao.module.mes.enums.wm;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import cn.iocoder.yudao.module.mes.enums.MesOrderStatusConstants;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 盘点任务状态枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesWmStockTakingTaskStatusEnum implements ArrayValuable {
+
+ /**
+ * 草稿
+ *
+ * 对应 MesWmStockTakingTaskService#createStockTakingTask 方法
+ */
+ PREPARE(MesOrderStatusConstants.PREPARE, "草稿"),
+ /**
+ * 审批中
+ *
+ * 对应 MesWmStockTakingTaskService#submitStockTakingTask 方法
+ */
+ APPROVING(MesOrderStatusConstants.APPROVING, "审批中"),
+ /**
+ * 已完成
+ *
+ * 对应 MesWmStockTakingTaskService#finishStockTakingTask 方法
+ */
+ FINISHED(MesOrderStatusConstants.FINISHED, "已完成"),
+ /**
+ * 已取消
+ *
+ * 对应 MesWmStockTakingTaskService#cancelStockTakingTask 方法
+ */
+ CANCELED(MesOrderStatusConstants.CANCELLED, "已取消");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values())
+ .map(MesWmStockTakingTaskStatusEnum::getStatus).toArray(Integer[]::new);
+
+ /**
+ * 状态
+ */
+ private final Integer status;
+ /**
+ * 状态名称
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmStockTakingTypeEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmStockTakingTypeEnum.java
new file mode 100644
index 000000000..5538fd993
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmStockTakingTypeEnum.java
@@ -0,0 +1,36 @@
+package cn.iocoder.yudao.module.mes.enums.wm;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 盘点类型枚举
+ */
+@Getter
+@AllArgsConstructor
+public enum MesWmStockTakingTypeEnum implements ArrayValuable {
+
+ STATIC(1, "静态盘点"),
+ DYNAMIC(2, "动态盘点");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values())
+ .map(MesWmStockTakingTypeEnum::getType).toArray(Integer[]::new);
+
+ /**
+ * 盘点类型
+ */
+ private final Integer type;
+ /**
+ * 类型名称
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmTransactionTypeEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmTransactionTypeEnum.java
new file mode 100644
index 000000000..ec1471526
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmTransactionTypeEnum.java
@@ -0,0 +1,70 @@
+package cn.iocoder.yudao.module.mes.enums.wm;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjUtil;
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 库存事务类型枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesWmTransactionTypeEnum implements ArrayValuable {
+
+ /**
+ * 入库
+ */
+ IN(1, "入库", true),
+ /**
+ * 出库
+ */
+ OUT(2, "出库", false),
+ /**
+ * 调拨移出
+ */
+ MOVE_OUT(3, "调拨移出", false),
+ /**
+ * 调拨移入
+ */
+ MOVE_IN(4, "调拨移入", true),
+ /**
+ * 盘盈
+ */
+ ADJUST_IN(5, "盘盈", true),
+ /**
+ * 盘亏
+ */
+ ADJUST_OUT(6, "盘亏", false);
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmTransactionTypeEnum::getType).toArray(Integer[]::new);
+
+ /**
+ * 类型值
+ */
+ private final Integer type;
+ /**
+ * 类型名
+ */
+ private final String name;
+ /**
+ * 是否为入库方向
+ */
+ private final boolean inbound;
+
+ public static MesWmTransactionTypeEnum valueOf(Integer type) {
+ return CollUtil.findOne(CollUtil.newArrayList(values()),
+ e -> ObjUtil.equal(e.getType(), type));
+ }
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmTransferStatusEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmTransferStatusEnum.java
new file mode 100644
index 000000000..d57bc1d3d
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmTransferStatusEnum.java
@@ -0,0 +1,72 @@
+package cn.iocoder.yudao.module.mes.enums.wm;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import cn.iocoder.yudao.module.mes.enums.MesOrderStatusConstants;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 转移单状态枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesWmTransferStatusEnum implements ArrayValuable {
+
+ /**
+ * 草稿
+ *
+ * 对应 MesWmTransferService#createTransfer 方法
+ */
+ PREPARE(MesOrderStatusConstants.PREPARE, "草稿"),
+ /**
+ * 待确认(仅配送模式)
+ *
+ * 对应 MesWmTransferService#submitTransfer 方法
+ */
+ UNCONFIRMED(MesOrderStatusConstants.CONFIRMED, "待确认"),
+ /**
+ * 待上架
+ *
+ * 对应 MesWmTransferService#submitTransfer 方法、MesWmTransferService#confirmTransfer 方法
+ */
+ APPROVING(MesOrderStatusConstants.APPROVING, "待上架"),
+ /**
+ * 待执行
+ *
+ * 对应 MesWmTransferService#stockTransfer 方法
+ */
+ APPROVED(MesOrderStatusConstants.APPROVED, "待执行"),
+ /**
+ * 已完成
+ *
+ * 对应 MesWmTransferService#finishTransfer 方法
+ */
+ FINISHED(MesOrderStatusConstants.FINISHED, "已完成"),
+ /**
+ * 已取消
+ *
+ * 对应 MesWmTransferService#cancelTransfer 方法
+ */
+ CANCELED(MesOrderStatusConstants.CANCELLED, "已取消");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmTransferStatusEnum::getStatus).toArray(Integer[]::new);
+
+ /**
+ * 状态值
+ */
+ private final Integer status;
+ /**
+ * 状态名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmTransferTypeEnum.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmTransferTypeEnum.java
new file mode 100644
index 000000000..7b9356062
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmTransferTypeEnum.java
@@ -0,0 +1,47 @@
+package cn.iocoder.yudao.module.mes.enums.wm;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 转移单类型枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum MesWmTransferTypeEnum implements ArrayValuable {
+
+ /**
+ * 内部调拨
+ */
+ INNER(1, "内部调拨"),
+ /**
+ * 外部调拨
+ */
+ OUTER(2, "外部调拨");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmTransferTypeEnum::getType).toArray(Integer[]::new);
+
+ /**
+ * 类型值
+ */
+ private final Integer type;
+ /**
+ * 类型名
+ */
+ private final String name;
+
+ public static MesWmTransferTypeEnum valueOf(Integer type) {
+ return Arrays.stream(values()).filter(e -> e.getType().equals(type)).findFirst().orElse(null);
+ }
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/Dockerfile b/yudao-module-mes/yudao-module-mes-server/Dockerfile
new file mode 100644
index 000000000..bf00536e1
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/Dockerfile
@@ -0,0 +1,19 @@
+## AdoptOpenJDK 停止发布 OpenJDK 二进制,而 Eclipse Temurin 是它的延伸,提供更好的稳定性
+## 感谢复旦核博士的建议!灰子哥,牛皮!
+FROM eclipse-temurin:21-jre
+
+## 创建目录,并使用它作为工作目录
+RUN mkdir -p /yudao-module-mes-server
+WORKDIR /yudao-module-mes-server
+## 将后端项目的 Jar 文件,复制到镜像中
+COPY ./target/yudao-module-mes-server.jar app.jar
+
+## 设置 TZ 时区
+## 设置 JAVA_OPTS 环境变量,可通过 docker run -e "JAVA_OPTS=" 进行覆盖
+ENV TZ=Asia/Shanghai JAVA_OPTS="-Xms512m -Xmx512m"
+
+## 暴露后端项目的 48091 端口
+EXPOSE 48091
+
+## 启动后端项目
+CMD java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar app.jar
diff --git a/yudao-module-mes/yudao-module-mes-server/pom.xml b/yudao-module-mes/yudao-module-mes-server/pom.xml
new file mode 100644
index 000000000..c8956ccb0
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/pom.xml
@@ -0,0 +1,119 @@
+
+
+
+ cn.iocoder.cloud
+ yudao-module-mes
+ ${revision}
+
+ 4.0.0
+ yudao-module-mes-server
+
+ ${project.artifactId}
+
+ mes 包下,制造执行系统(Manufacturing Execution System)。
+ 例如说:基础数据、排班日历、设备管理、工具管理、生产管理、质量管理、仓库管理等等
+
+
+
+
+
+ cn.iocoder.cloud
+ yudao-spring-boot-starter-env
+
+
+
+
+ cn.iocoder.cloud
+ yudao-module-system-api
+ ${revision}
+
+
+ cn.iocoder.cloud
+ yudao-module-mes-api
+ ${revision}
+
+
+
+
+ cn.iocoder.cloud
+ yudao-spring-boot-starter-biz-tenant
+
+
+
+
+ cn.iocoder.cloud
+ yudao-spring-boot-starter-security
+
+
+
+
+ cn.iocoder.cloud
+ yudao-spring-boot-starter-mybatis
+
+
+
+ cn.iocoder.cloud
+ yudao-spring-boot-starter-redis
+
+
+
+
+ cn.iocoder.cloud
+ yudao-spring-boot-starter-rpc
+
+
+
+
+ com.alibaba.cloud
+ spring-cloud-starter-alibaba-nacos-discovery
+
+
+
+
+ com.alibaba.cloud
+ spring-cloud-starter-alibaba-nacos-config
+
+
+
+
+ cn.iocoder.cloud
+ yudao-spring-boot-starter-excel
+
+
+
+
+ cn.iocoder.cloud
+ yudao-spring-boot-starter-monitor
+
+
+
+
+ cn.iocoder.cloud
+ yudao-spring-boot-starter-test
+
+
+
+
+
+
+ ${project.artifactId}
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring.boot.version}
+
+
+
+ repackage
+
+
+
+
+
+
+
+
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/MesServerApplication.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/MesServerApplication.java
new file mode 100644
index 000000000..fc5c5cafe
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/MesServerApplication.java
@@ -0,0 +1,30 @@
+package cn.iocoder.yudao.module.mes;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * 项目的启动类
+ *
+ * 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
+ * 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
+ * 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
+ *
+ * @author 芋道源码
+ */
+@SpringBootApplication
+public class MesServerApplication {
+
+ public static void main(String[] args) {
+ // 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
+ // 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
+ // 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
+
+ SpringApplication.run(MesServerApplication.class, args);
+
+ // 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
+ // 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
+ // 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/calendar/MesCalCalendarController.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/calendar/MesCalCalendarController.java
new file mode 100644
index 000000000..a7345534e
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/calendar/MesCalCalendarController.java
@@ -0,0 +1,212 @@
+package cn.iocoder.yudao.module.mes.controller.admin.cal.calendar;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.date.DatePattern;
+import cn.hutool.core.date.LocalDateTimeUtil;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.module.mes.controller.admin.cal.calendar.vo.MesCalCalendarListReqVO;
+import cn.iocoder.yudao.module.mes.controller.admin.cal.calendar.vo.MesCalCalendarRespVO;
+import cn.iocoder.yudao.module.mes.controller.admin.cal.team.vo.shift.MesCalTeamShiftListReqVO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.cal.holiday.MesCalHolidayDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.cal.plan.MesCalPlanDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.cal.plan.MesCalPlanShiftDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.cal.team.MesCalTeamDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.cal.team.MesCalTeamMemberDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.cal.team.MesCalTeamShiftDO;
+import cn.iocoder.yudao.module.mes.enums.cal.MesCalHolidayTypeEnum;
+import cn.iocoder.yudao.module.mes.service.cal.holiday.MesCalHolidayService;
+import cn.iocoder.yudao.module.mes.service.cal.plan.MesCalPlanService;
+import cn.iocoder.yudao.module.mes.service.cal.plan.MesCalPlanShiftService;
+import cn.iocoder.yudao.module.mes.service.cal.team.MesCalTeamMemberService;
+import cn.iocoder.yudao.module.mes.service.cal.team.MesCalTeamService;
+import cn.iocoder.yudao.module.mes.service.cal.team.MesCalTeamShiftService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import jakarta.validation.Valid;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.time.LocalDateTime;
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
+
+@Tag(name = "管理后台 - MES 排班日历")
+@RestController
+@RequestMapping("/mes/cal/calendar")
+@Validated
+public class MesCalCalendarController {
+
+ @Resource
+ private MesCalTeamShiftService teamShiftService;
+ @Resource
+ private MesCalTeamService teamService;
+ @Resource
+ private MesCalPlanShiftService planShiftService;
+ @Resource
+ private MesCalPlanService planService;
+ @Resource
+ private MesCalTeamMemberService teamMemberService;
+ @Resource
+ private MesCalHolidayService holidayService;
+
+ @GetMapping("/list")
+ @Operation(summary = "查询排班日历")
+ @PreAuthorize("@ss.hasPermission('mes:cal-team-shift:query')")
+ public CommonResult> getCalendarList(@Valid MesCalCalendarListReqVO reqVO) {
+ // 1.1 根据查询类型获取班组排班记录
+ List teamShifts = getTeamShifts(reqVO);
+ if (CollUtil.isEmpty(teamShifts)) {
+ return success(Collections.emptyList());
+ }
+ // 1.2 按日期范围查询假期,构建节假日日期集合
+ Set holidaySet = buildHolidaySet(reqVO.getStartDay(), reqVO.getEndDay());
+ // 1.3 批量查询关联数据:班组、班次、排班计划
+ Map teamMap = teamService.getTeamMap(
+ convertSet(teamShifts, MesCalTeamShiftDO::getTeamId));
+ Map shiftMap = planShiftService.getPlanShiftMap(
+ convertSet(teamShifts, MesCalTeamShiftDO::getShiftId));
+ Map planMap = planService.getPlanMap(
+ convertSet(teamShifts, MesCalTeamShiftDO::getPlanId));
+
+ // 2. 按 day 分组聚合
+ Map> dayGroupMap = convertMultiMap(teamShifts,
+ teamShift -> LocalDateTimeUtil.format(teamShift.getDay(), DatePattern.NORM_DATE_PATTERN));
+
+ // 3. 遍历分组,过滤假期,构建日历响应
+ List result = new ArrayList<>();
+ for (Map.Entry> entry : dayGroupMap.entrySet()) {
+ String dayStr = entry.getKey();
+ // 3.1 过滤节假日
+ if (holidaySet.contains(dayStr)) {
+ continue;
+ }
+ List dayShifts = entry.getValue();
+ dayShifts.sort(Comparator.comparing(ts -> ts.getSort() != null ? ts.getSort() : 0));
+ // 3.2 获取轮班方式(取第一条记录关联的排班计划)
+ Integer shiftType = null;
+ MesCalTeamShiftDO first = dayShifts.get(0);
+ if (first.getPlanId() != null) {
+ MesCalPlanDO plan = planMap.get(first.getPlanId());
+ if (plan != null) {
+ shiftType = plan.getShiftType();
+ }
+ }
+ // 3.3 构建班组排班项列表
+ List items = convertList(dayShifts,
+ teamShift -> buildTeamShiftItem(teamShift, teamMap, shiftMap));
+
+ // 3.4 构建日历项,添加到结果列表
+ MesCalCalendarRespVO calendarVO = MesCalCalendarRespVO.builder()
+ .day(LocalDateTimeUtil.parseDate(dayStr, DatePattern.NORM_DATE_FORMATTER).atStartOfDay())
+ .shiftType(shiftType)
+ .teamShifts(items)
+ .build();
+ result.add(calendarVO);
+ }
+ return success(result);
+ }
+
+ /**
+ * 根据查询类型获取班组排班记录
+ */
+ @SuppressWarnings("EnhancedSwitchMigration")
+ private List getTeamShifts(MesCalCalendarListReqVO reqVO) {
+ LocalDateTime startDay = reqVO.getStartDay();
+ LocalDateTime endDay = reqVO.getEndDay();
+ switch (reqVO.getQueryType()) {
+ case MesCalCalendarListReqVO.QUERY_TYPE_TYPE:
+ return getTeamShiftsByCalendarType(reqVO.getCalendarType(), startDay, endDay);
+ case MesCalCalendarListReqVO.QUERY_TYPE_TEAM:
+ return getTeamShiftsByTeamId(reqVO.getTeamId(), startDay, endDay);
+ case MesCalCalendarListReqVO.QUERY_TYPE_USER:
+ return getTeamShiftsByUserId(reqVO.getUserId(), startDay, endDay);
+ default:
+ return Collections.emptyList();
+ }
+ }
+
+ /**
+ * 构建单条 TeamShiftItem
+ */
+ private MesCalCalendarRespVO.TeamShiftItem buildTeamShiftItem(MesCalTeamShiftDO ts,
+ Map teamMap,
+ Map shiftMap) {
+ MesCalTeamDO team = teamMap.get(ts.getTeamId());
+ MesCalPlanShiftDO shift = shiftMap.get(ts.getShiftId());
+ return MesCalCalendarRespVO.TeamShiftItem.builder()
+ .teamId(ts.getTeamId()).teamName(team != null ? team.getName() : null)
+ .shiftId(ts.getShiftId()).shiftName(shift != null ? shift.getName() : null)
+ .sort(ts.getSort()).build();
+ }
+
+ /**
+ * 按班组类型查询排班记录
+ */
+ private List getTeamShiftsByCalendarType(Integer calendarType,
+ LocalDateTime startDay, LocalDateTime endDay) {
+ if (calendarType == null) {
+ return Collections.emptyList();
+ }
+ // 1. 查询指定类型的所有班组
+ List teams = teamService.getTeamList().stream()
+ .filter(t -> calendarType.equals(t.getCalendarType()))
+ .collect(Collectors.toList());
+ if (CollUtil.isEmpty(teams)) {
+ return Collections.emptyList();
+ }
+ // 2. 一次 IN 查询这些班组在日期范围内的排班记录
+ MesCalTeamShiftListReqVO reqVO = new MesCalTeamShiftListReqVO()
+ .setTeamIds(convertSet(teams, MesCalTeamDO::getId))
+ .setStartDay(startDay).setEndDay(endDay);
+ return teamShiftService.getTeamShiftList(reqVO);
+ }
+
+ /**
+ * 按班组编号查询排班记录
+ */
+ private List getTeamShiftsByTeamId(Long teamId, LocalDateTime startDay, LocalDateTime endDay) {
+ if (teamId == null) {
+ return Collections.emptyList();
+ }
+ MesCalTeamShiftListReqVO reqVO = new MesCalTeamShiftListReqVO()
+ .setTeamId(teamId).setStartDay(startDay).setEndDay(endDay);
+ return teamShiftService.getTeamShiftList(reqVO);
+ }
+
+ /**
+ * 按用户编号查询排班记录(先查用户所属班组,再查班组排班)
+ */
+ private List getTeamShiftsByUserId(Long userId,
+ LocalDateTime startDay, LocalDateTime endDay) {
+ if (userId == null) {
+ return Collections.emptyList();
+ }
+ // 1. 查询用户所属的班组(一个用户只属于一个班组)
+ MesCalTeamMemberDO member = teamMemberService.getTeamMemberByUserId(userId);
+ if (member == null) {
+ return Collections.emptyList();
+ }
+ // 2. 查询该班组在日期范围内的排班记录
+ MesCalTeamShiftListReqVO reqVO = new MesCalTeamShiftListReqVO()
+ .setTeamId(member.getTeamId()).setStartDay(startDay).setEndDay(endDay);
+ return teamShiftService.getTeamShiftList(reqVO);
+ }
+
+ /**
+ * 按日期范围查询假期,构建节假日日期集合(yyyy-MM-dd 格式)
+ */
+ private Set buildHolidaySet(LocalDateTime startDay, LocalDateTime endDay) {
+ List holidays = holidayService.getHolidayList(startDay, endDay);
+ return convertSet(holidays,
+ holiday -> LocalDateTimeUtil.format(holiday.getDay(), DatePattern.NORM_DATE_PATTERN),
+ holiday -> MesCalHolidayTypeEnum.HOLIDAY.getType().equals(holiday.getType()));
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/calendar/vo/MesCalCalendarListReqVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/calendar/vo/MesCalCalendarListReqVO.java
new file mode 100644
index 000000000..ac4774dad
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/calendar/vo/MesCalCalendarListReqVO.java
@@ -0,0 +1,44 @@
+package cn.iocoder.yudao.module.mes.controller.admin.cal.calendar.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+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 = "管理后台 - MES 排班日历查询 Request VO")
+@Data
+public class MesCalCalendarListReqVO {
+
+ public static final String QUERY_TYPE_TYPE = "TYPE";
+ public static final String QUERY_TYPE_TEAM = "TEAM";
+ public static final String QUERY_TYPE_USER = "USER";
+
+ @Schema(description = "开始日期", requiredMode = Schema.RequiredMode.REQUIRED)
+ @NotNull(message = "开始日期不能为空")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private LocalDateTime startDay;
+
+ @Schema(description = "结束日期", requiredMode = Schema.RequiredMode.REQUIRED)
+ @NotNull(message = "结束日期不能为空")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private LocalDateTime endDay;
+
+ @Schema(description = "查询类型:TYPE-按分类,TEAM-按班组,USER-按个人", requiredMode = Schema.RequiredMode.REQUIRED, example = "TYPE")
+ @NotEmpty(message = "查询类型不能为空")
+ private String queryType;
+
+ @Schema(description = "班组类型(queryType=TYPE 时使用)", example = "1")
+ private Integer calendarType;
+
+ @Schema(description = "班组编号(queryType=TEAM 时使用)", example = "201")
+ private Long teamId;
+
+ @Schema(description = "用户编号(queryType=USER 时使用)", example = "1")
+ private Long userId;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/calendar/vo/MesCalCalendarRespVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/calendar/vo/MesCalCalendarRespVO.java
new file mode 100644
index 000000000..254857ea7
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/calendar/vo/MesCalCalendarRespVO.java
@@ -0,0 +1,52 @@
+package cn.iocoder.yudao.module.mes.controller.admin.cal.calendar.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+@Schema(description = "管理后台 - MES 排班日历 Response VO")
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class MesCalCalendarRespVO {
+
+ @Schema(description = "日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "2025-01-15 00:00:00")
+ private LocalDateTime day;
+
+ @Schema(description = "轮班方式", example = "2")
+ private Integer shiftType; // 对应 MesCalShiftTypeEnum 枚举值
+
+ @Schema(description = "班组排班列表")
+ private List teamShifts;
+
+ @Schema(description = "班组排班项")
+ @Data
+ @Builder
+ @NoArgsConstructor
+ @AllArgsConstructor
+ public static class TeamShiftItem {
+
+ @Schema(description = "班组编号", example = "201")
+ private Long teamId;
+
+ @Schema(description = "班组名称", example = "注塑A组")
+ private String teamName;
+
+ @Schema(description = "班次编号", example = "1")
+ private Long shiftId;
+
+ @Schema(description = "班次名称", example = "白班")
+ private String shiftName;
+
+ @Schema(description = "排序", example = "1")
+ private Integer sort;
+
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/holiday/MesCalHolidayController.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/holiday/MesCalHolidayController.java
new file mode 100644
index 000000000..a8cfd0915
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/holiday/MesCalHolidayController.java
@@ -0,0 +1,64 @@
+package cn.iocoder.yudao.module.mes.controller.admin.cal.holiday;
+
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.mes.controller.admin.cal.holiday.vo.MesCalHolidayRespVO;
+import cn.iocoder.yudao.module.mes.controller.admin.cal.holiday.vo.MesCalHolidaySaveReqVO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.cal.holiday.MesCalHolidayDO;
+import cn.iocoder.yudao.module.mes.service.cal.holiday.MesCalHolidayService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import jakarta.validation.Valid;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+@Tag(name = "管理后台 - MES 假期设置")
+@RestController
+@RequestMapping("/mes/cal/holiday")
+@Validated
+public class MesCalHolidayController {
+
+ @Resource
+ private MesCalHolidayService holidayService;
+
+ @PostMapping("/save")
+ @Operation(summary = "保存假期设置", description = "如果该日期已存在记录,则更新")
+ @PreAuthorize("@ss.hasPermission('mes:cal-holiday:create')")
+ public CommonResult saveHoliday(@Valid @RequestBody MesCalHolidaySaveReqVO saveReqVO) {
+ return success(holidayService.saveHoliday(saveReqVO));
+ }
+
+ @GetMapping("/get-by-day")
+ @Operation(summary = "根据日期获得假期设置")
+ @Parameter(name = "day", description = "日期", required = true)
+ @PreAuthorize("@ss.hasPermission('mes:cal-holiday:query')")
+ public CommonResult getHolidayByDay(
+ @RequestParam("day") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) LocalDateTime day) {
+ MesCalHolidayDO holiday = holidayService.getHolidayByDay(day);
+ return success(BeanUtils.toBean(holiday, MesCalHolidayRespVO.class));
+ }
+
+ @GetMapping("/list")
+ @Operation(summary = "获得假期设置列表", description = "支持可选日期范围过滤,不传则返回全量数据")
+ @PreAuthorize("@ss.hasPermission('mes:cal-holiday:query')")
+ public CommonResult> getHolidayList(
+ @RequestParam(value = "startDay", required = false)
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) LocalDateTime startDay,
+ @RequestParam(value = "endDay", required = false)
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) LocalDateTime endDay) {
+ List list = holidayService.getHolidayList(startDay, endDay);
+ return success(BeanUtils.toBean(list, MesCalHolidayRespVO.class));
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/holiday/vo/MesCalHolidayRespVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/holiday/vo/MesCalHolidayRespVO.java
new file mode 100644
index 000000000..cfde7a045
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/holiday/vo/MesCalHolidayRespVO.java
@@ -0,0 +1,24 @@
+package cn.iocoder.yudao.module.mes.controller.admin.cal.holiday.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - MES 假期设置 Response VO")
+@Data
+public class MesCalHolidayRespVO {
+
+ @Schema(description = "编号", example = "1024")
+ private Long id;
+
+ @Schema(description = "日期")
+ private LocalDateTime day;
+
+ @Schema(description = "日期类型")
+ private Integer type;
+
+ @Schema(description = "备注")
+ private String remark;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/holiday/vo/MesCalHolidaySaveReqVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/holiday/vo/MesCalHolidaySaveReqVO.java
new file mode 100644
index 000000000..0a8517271
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/holiday/vo/MesCalHolidaySaveReqVO.java
@@ -0,0 +1,27 @@
+package cn.iocoder.yudao.module.mes.controller.admin.cal.holiday.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - MES 假期设置新增/修改 Request VO")
+@Data
+public class MesCalHolidaySaveReqVO {
+
+ @Schema(description = "编号", example = "1024")
+ private Long id;
+
+ @Schema(description = "日期", requiredMode = Schema.RequiredMode.REQUIRED)
+ @NotNull(message = "日期不能为空")
+ private LocalDateTime day;
+
+ @Schema(description = "日期类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
+ @NotNull(message = "日期类型不能为空")
+ private Integer type;
+
+ @Schema(description = "备注")
+ private String remark;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/package-info.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/package-info.java
new file mode 100644
index 000000000..4b2f9f3b6
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * MES 日历排班(Calendar / Shift Planning):班次、班组、班组成员、排班计划、假期设置等生产人员轮班与工作日历
+ */
+package cn.iocoder.yudao.module.mes.controller.admin.cal;
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/MesCalPlanController.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/MesCalPlanController.java
new file mode 100644
index 000000000..5a1a782a5
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/MesCalPlanController.java
@@ -0,0 +1,102 @@
+package cn.iocoder.yudao.module.mes.controller.admin.cal.plan;
+
+import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+import cn.iocoder.yudao.module.mes.controller.admin.cal.plan.vo.MesCalPlanPageReqVO;
+import cn.iocoder.yudao.module.mes.controller.admin.cal.plan.vo.MesCalPlanRespVO;
+import cn.iocoder.yudao.module.mes.controller.admin.cal.plan.vo.MesCalPlanSaveReqVO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.cal.plan.MesCalPlanDO;
+import cn.iocoder.yudao.module.mes.service.cal.plan.MesCalPlanService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.Valid;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.io.IOException;
+import java.util.List;
+
+import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+@Tag(name = "管理后台 - MES 排班计划")
+@RestController
+@RequestMapping("/mes/cal/plan")
+@Validated
+public class MesCalPlanController {
+
+ @Resource
+ private MesCalPlanService planService;
+
+ @PostMapping("/create")
+ @Operation(summary = "创建排班计划")
+ @PreAuthorize("@ss.hasPermission('mes:cal-plan:create')")
+ public CommonResult createPlan(@Valid @RequestBody MesCalPlanSaveReqVO createReqVO) {
+ return success(planService.createPlan(createReqVO));
+ }
+
+ @PutMapping("/update")
+ @Operation(summary = "更新排班计划")
+ @PreAuthorize("@ss.hasPermission('mes:cal-plan:update')")
+ public CommonResult updatePlan(@Valid @RequestBody MesCalPlanSaveReqVO updateReqVO) {
+ planService.updatePlan(updateReqVO);
+ return success(true);
+ }
+
+ @PutMapping("/confirm")
+ @Operation(summary = "确认排班计划")
+ @Parameter(name = "id", description = "编号", required = true)
+ @PreAuthorize("@ss.hasPermission('mes:cal-plan:update')")
+ public CommonResult confirmPlan(@RequestParam("id") Long id) {
+ planService.confirmPlan(id);
+ return success(true);
+ }
+
+ @DeleteMapping("/delete")
+ @Operation(summary = "删除排班计划")
+ @Parameter(name = "id", description = "编号", required = true)
+ @PreAuthorize("@ss.hasPermission('mes:cal-plan:delete')")
+ public CommonResult deletePlan(@RequestParam("id") Long id) {
+ planService.deletePlan(id);
+ return success(true);
+ }
+
+ @GetMapping("/get")
+ @Operation(summary = "获得排班计划")
+ @Parameter(name = "id", description = "编号", required = true, example = "1024")
+ @PreAuthorize("@ss.hasPermission('mes:cal-plan:query')")
+ public CommonResult getPlan(@RequestParam("id") Long id) {
+ MesCalPlanDO plan = planService.getPlan(id);
+ return success(BeanUtils.toBean(plan, MesCalPlanRespVO.class));
+ }
+
+ @GetMapping("/page")
+ @Operation(summary = "获得排班计划分页")
+ @PreAuthorize("@ss.hasPermission('mes:cal-plan:query')")
+ public CommonResult> getPlanPage(@Valid MesCalPlanPageReqVO pageReqVO) {
+ PageResult pageResult = planService.getPlanPage(pageReqVO);
+ return success(BeanUtils.toBean(pageResult, MesCalPlanRespVO.class));
+ }
+
+ @GetMapping("/export-excel")
+ @Operation(summary = "导出排班计划 Excel")
+ @PreAuthorize("@ss.hasPermission('mes:cal-plan:export')")
+ @ApiAccessLog(operateType = EXPORT)
+ public void exportPlanExcel(@Valid MesCalPlanPageReqVO pageReqVO,
+ HttpServletResponse response) throws IOException {
+ pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+ List list = planService.getPlanPage(pageReqVO).getList();
+ // 导出 Excel
+ ExcelUtils.write(response, "排班计划.xls", "数据", MesCalPlanRespVO.class,
+ BeanUtils.toBean(list, MesCalPlanRespVO.class));
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/MesCalPlanShiftController.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/MesCalPlanShiftController.java
new file mode 100644
index 000000000..1f6013e8f
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/MesCalPlanShiftController.java
@@ -0,0 +1,83 @@
+package cn.iocoder.yudao.module.mes.controller.admin.cal.plan;
+
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.mes.controller.admin.cal.plan.vo.shift.MesCalPlanShiftPageReqVO;
+import cn.iocoder.yudao.module.mes.controller.admin.cal.plan.vo.shift.MesCalPlanShiftRespVO;
+import cn.iocoder.yudao.module.mes.controller.admin.cal.plan.vo.shift.MesCalPlanShiftSaveReqVO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.cal.plan.MesCalPlanShiftDO;
+import cn.iocoder.yudao.module.mes.service.cal.plan.MesCalPlanShiftService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import jakarta.validation.Valid;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+@Tag(name = "管理后台 - MES 计划班次")
+@RestController
+@RequestMapping("/mes/cal/plan-shift")
+@Validated
+public class MesCalPlanShiftController {
+
+ @Resource
+ private MesCalPlanShiftService planShiftService;
+
+ @PostMapping("/create")
+ @Operation(summary = "创建计划班次")
+ @PreAuthorize("@ss.hasPermission('mes:cal-plan:update')")
+ public CommonResult createPlanShift(@Valid @RequestBody MesCalPlanShiftSaveReqVO createReqVO) {
+ return success(planShiftService.createPlanShift(createReqVO));
+ }
+
+ @PutMapping("/update")
+ @Operation(summary = "更新计划班次")
+ @PreAuthorize("@ss.hasPermission('mes:cal-plan:update')")
+ public CommonResult updatePlanShift(@Valid @RequestBody MesCalPlanShiftSaveReqVO updateReqVO) {
+ planShiftService.updatePlanShift(updateReqVO);
+ return success(true);
+ }
+
+ @DeleteMapping("/delete")
+ @Operation(summary = "删除计划班次")
+ @Parameter(name = "id", description = "编号", required = true)
+ @PreAuthorize("@ss.hasPermission('mes:cal-plan:update')")
+ public CommonResult deletePlanShift(@RequestParam("id") Long id) {
+ planShiftService.deletePlanShift(id);
+ return success(true);
+ }
+
+ @GetMapping("/get")
+ @Operation(summary = "获得计划班次")
+ @Parameter(name = "id", description = "编号", required = true, example = "1024")
+ @PreAuthorize("@ss.hasPermission('mes:cal-plan:query')")
+ public CommonResult getPlanShift(@RequestParam("id") Long id) {
+ MesCalPlanShiftDO planShift = planShiftService.getPlanShift(id);
+ return success(BeanUtils.toBean(planShift, MesCalPlanShiftRespVO.class));
+ }
+
+ @GetMapping("/page")
+ @Operation(summary = "获得计划班次分页")
+ @PreAuthorize("@ss.hasPermission('mes:cal-plan:query')")
+ public CommonResult> getPlanShiftPage(@Valid MesCalPlanShiftPageReqVO pageReqVO) {
+ PageResult pageResult = planShiftService.getPlanShiftPage(pageReqVO);
+ return success(BeanUtils.toBean(pageResult, MesCalPlanShiftRespVO.class));
+ }
+
+ @GetMapping("/list-by-plan")
+ @Operation(summary = "获得指定排班计划的班次列表")
+ @Parameter(name = "planId", description = "排班计划编号", required = true)
+ @PreAuthorize("@ss.hasPermission('mes:cal-plan:query')")
+ public CommonResult> getPlanShiftListByPlan(@RequestParam("planId") Long planId) {
+ List list = planShiftService.getPlanShiftListByPlanId(planId);
+ return success(BeanUtils.toBean(list, MesCalPlanShiftRespVO.class));
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/MesCalPlanTeamController.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/MesCalPlanTeamController.java
new file mode 100644
index 000000000..7170ac531
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/MesCalPlanTeamController.java
@@ -0,0 +1,77 @@
+package cn.iocoder.yudao.module.mes.controller.admin.cal.plan;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.mes.controller.admin.cal.plan.vo.team.MesCalPlanTeamRespVO;
+import cn.iocoder.yudao.module.mes.controller.admin.cal.plan.vo.team.MesCalPlanTeamSaveReqVO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.cal.plan.MesCalPlanTeamDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.cal.team.MesCalTeamDO;
+import cn.iocoder.yudao.module.mes.service.cal.plan.MesCalPlanTeamService;
+import cn.iocoder.yudao.module.mes.service.cal.team.MesCalTeamService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import jakarta.validation.Valid;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
+
+@Tag(name = "管理后台 - MES 计划班组关联")
+@RestController
+@RequestMapping("/mes/cal/plan-team")
+@Validated
+public class MesCalPlanTeamController {
+
+ @Resource
+ private MesCalPlanTeamService planTeamService;
+ @Resource
+ private MesCalTeamService teamService;
+
+ @PostMapping("/create")
+ @Operation(summary = "创建计划班组关联")
+ @PreAuthorize("@ss.hasPermission('mes:cal-plan:update')")
+ public CommonResult createPlanTeam(@Valid @RequestBody MesCalPlanTeamSaveReqVO createReqVO) {
+ return success(planTeamService.createPlanTeam(createReqVO));
+ }
+
+ @DeleteMapping("/delete")
+ @Operation(summary = "删除计划班组关联")
+ @Parameter(name = "id", description = "编号", required = true)
+ @PreAuthorize("@ss.hasPermission('mes:cal-plan:update')")
+ public CommonResult deletePlanTeam(@RequestParam("id") Long id) {
+ planTeamService.deletePlanTeam(id);
+ return success(true);
+ }
+
+ @GetMapping("/list-by-plan")
+ @Operation(summary = "获得指定排班计划的班组列表")
+ @Parameter(name = "planId", description = "排班计划编号", required = true)
+ @PreAuthorize("@ss.hasPermission('mes:cal-plan:query')")
+ public CommonResult> getPlanTeamListByPlan(@RequestParam("planId") Long planId) {
+ List list = planTeamService.getPlanTeamListByPlanId(planId);
+ List respList = BeanUtils.toBean(list, MesCalPlanTeamRespVO.class);
+ // 拼装班组编码/名称
+ // TODO @AI:if return
+ if (CollUtil.isNotEmpty(respList)) {
+ Map teamMap = teamService.getTeamMap(
+ convertList(respList, MesCalPlanTeamRespVO::getTeamId));
+ respList.forEach(resp -> {
+ // TODO @AI:findand then
+ MesCalTeamDO team = teamMap.get(resp.getTeamId());
+ if (team != null) {
+ resp.setTeamCode(team.getCode()).setTeamName(team.getName());
+ }
+ });
+ }
+ return success(respList);
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/vo/MesCalPlanPageReqVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/vo/MesCalPlanPageReqVO.java
new file mode 100644
index 000000000..b88ef25b1
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/vo/MesCalPlanPageReqVO.java
@@ -0,0 +1,43 @@
+package cn.iocoder.yudao.module.mes.controller.admin.cal.plan.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 = "管理后台 - MES 排班计划分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class MesCalPlanPageReqVO extends PageParam {
+
+ @Schema(description = "计划编码", example = "PLAN001")
+ private String code;
+
+ @Schema(description = "计划名称", example = "2024年排班")
+ private String name;
+
+ @Schema(description = "轮班方式", example = "1")
+ private Integer shiftType;
+
+ @Schema(description = "状态", example = "0")
+ private Integer status;
+
+ @Schema(description = "班组类型", example = "1")
+ private Integer calendarType;
+
+ @Schema(description = "开始日期")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private LocalDateTime[] startDate;
+
+ @Schema(description = "结束日期")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private LocalDateTime[] endDate;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/vo/MesCalPlanRespVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/vo/MesCalPlanRespVO.java
new file mode 100644
index 000000000..d68086899
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/vo/MesCalPlanRespVO.java
@@ -0,0 +1,63 @@
+package cn.iocoder.yudao.module.mes.controller.admin.cal.plan.vo;
+
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - MES 排班计划 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class MesCalPlanRespVO {
+
+ @Schema(description = "计划编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+ @ExcelProperty("计划编号")
+ private Long id;
+
+ @Schema(description = "计划编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "PLAN001")
+ @ExcelProperty("计划编码")
+ private String code;
+
+ @Schema(description = "计划名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024年排班计划")
+ @ExcelProperty("计划名称")
+ private String name;
+
+ @Schema(description = "班组类型", example = "1")
+ @ExcelProperty("班组类型")
+ private Integer calendarType;
+
+ @Schema(description = "开始日期", requiredMode = Schema.RequiredMode.REQUIRED)
+ @ExcelProperty("开始日期")
+ private LocalDateTime startDate;
+
+ @Schema(description = "结束日期", requiredMode = Schema.RequiredMode.REQUIRED)
+ @ExcelProperty("结束日期")
+ private LocalDateTime endDate;
+
+ @Schema(description = "轮班方式", example = "1")
+ @ExcelProperty("轮班方式")
+ private Integer shiftType;
+
+ @Schema(description = "倒班方式", example = "1")
+ @ExcelProperty("倒班方式")
+ private Integer shiftMethod;
+
+ @Schema(description = "倒班天数", example = "7")
+ @ExcelProperty("倒班天数")
+ private Integer shiftCount;
+
+ @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
+ @ExcelProperty("状态")
+ private Integer status;
+
+ @Schema(description = "备注")
+ @ExcelProperty("备注")
+ private String remark;
+
+ @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+ @ExcelProperty("创建时间")
+ private LocalDateTime createTime;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/vo/MesCalPlanSaveReqVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/vo/MesCalPlanSaveReqVO.java
new file mode 100644
index 000000000..4de150128
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/vo/MesCalPlanSaveReqVO.java
@@ -0,0 +1,53 @@
+package cn.iocoder.yudao.module.mes.controller.admin.cal.plan.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - MES 排班计划新增/修改 Request VO")
+@Data
+public class MesCalPlanSaveReqVO {
+
+ @Schema(description = "计划编号", example = "1024")
+ private Long id;
+
+ @Schema(description = "计划编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "PLAN001")
+ @NotEmpty(message = "计划编码不能为空")
+ private String code;
+
+ @Schema(description = "计划名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024年排班计划")
+ @NotEmpty(message = "计划名称不能为空")
+ private String name;
+
+ @Schema(description = "班组类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @NotNull(message = "班组类型不能为空")
+ private Integer calendarType;
+
+ @Schema(description = "开始日期", requiredMode = Schema.RequiredMode.REQUIRED)
+ @NotNull(message = "开始日期不能为空")
+ private LocalDateTime startDate;
+
+ @Schema(description = "结束日期", requiredMode = Schema.RequiredMode.REQUIRED)
+ @NotNull(message = "结束日期不能为空")
+ private LocalDateTime endDate;
+
+ @Schema(description = "轮班方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @NotNull(message = "轮班方式不能为空")
+ private Integer shiftType;
+
+ @Schema(description = "倒班方式", example = "1")
+ private Integer shiftMethod;
+
+ @Schema(description = "倒班天数", example = "7")
+ private Integer shiftCount;
+
+ @Schema(description = "状态", example = "0")
+ private Integer status;
+
+ @Schema(description = "备注")
+ private String remark;
+
+ }
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/vo/shift/MesCalPlanShiftPageReqVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/vo/shift/MesCalPlanShiftPageReqVO.java
new file mode 100644
index 000000000..525e16856
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/vo/shift/MesCalPlanShiftPageReqVO.java
@@ -0,0 +1,21 @@
+package cn.iocoder.yudao.module.mes.controller.admin.cal.plan.vo.shift;
+
+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;
+
+@Schema(description = "管理后台 - MES 计划班次分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class MesCalPlanShiftPageReqVO extends PageParam {
+
+ @Schema(description = "排班计划编号", example = "1")
+ private Long planId;
+
+ @Schema(description = "班次名称", example = "白班")
+ private String name;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/vo/shift/MesCalPlanShiftRespVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/vo/shift/MesCalPlanShiftRespVO.java
new file mode 100644
index 000000000..c0613a95f
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/vo/shift/MesCalPlanShiftRespVO.java
@@ -0,0 +1,36 @@
+package cn.iocoder.yudao.module.mes.controller.admin.cal.plan.vo.shift;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - MES 计划班次 Response VO")
+@Data
+public class MesCalPlanShiftRespVO {
+
+ @Schema(description = "班次编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+ private Long id;
+
+ @Schema(description = "排班计划编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ private Long planId;
+
+ @Schema(description = "显示顺序", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ private Integer sort;
+
+ @Schema(description = "班次名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "白班")
+ private String name;
+
+ @Schema(description = "开始时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "08:00")
+ private String startTime;
+
+ @Schema(description = "结束时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "17:00")
+ private String endTime;
+
+ @Schema(description = "备注")
+ private String remark;
+
+ @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+ private LocalDateTime createTime;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/vo/shift/MesCalPlanShiftSaveReqVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/vo/shift/MesCalPlanShiftSaveReqVO.java
new file mode 100644
index 000000000..cf2cefbf9
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/vo/shift/MesCalPlanShiftSaveReqVO.java
@@ -0,0 +1,38 @@
+package cn.iocoder.yudao.module.mes.controller.admin.cal.plan.vo.shift;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+@Schema(description = "管理后台 - MES 计划班次新增/修改 Request VO")
+@Data
+public class MesCalPlanShiftSaveReqVO {
+
+ @Schema(description = "班次编号", example = "1024")
+ private Long id;
+
+ @Schema(description = "排班计划编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @NotNull(message = "排班计划不能为空")
+ private Long planId;
+
+ @Schema(description = "显示顺序", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @NotNull(message = "显示顺序不能为空")
+ private Integer sort;
+
+ @Schema(description = "班次名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "白班")
+ @NotEmpty(message = "班次名称不能为空")
+ private String name;
+
+ @Schema(description = "开始时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "08:00")
+ @NotEmpty(message = "开始时间不能为空")
+ private String startTime;
+
+ @Schema(description = "结束时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "17:00")
+ @NotEmpty(message = "结束时间不能为空")
+ private String endTime;
+
+ @Schema(description = "备注")
+ private String remark;
+
+ }
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/vo/team/MesCalPlanTeamRespVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/vo/team/MesCalPlanTeamRespVO.java
new file mode 100644
index 000000000..d2a0a0d95
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/vo/team/MesCalPlanTeamRespVO.java
@@ -0,0 +1,33 @@
+package cn.iocoder.yudao.module.mes.controller.admin.cal.plan.vo.team;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - MES 计划班组关联 Response VO")
+@Data
+public class MesCalPlanTeamRespVO {
+
+ @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+ private Long id;
+
+ @Schema(description = "排班计划编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ private Long planId;
+
+ @Schema(description = "班组编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ private Long teamId;
+
+ @Schema(description = "班组编码", example = "T001")
+ private String teamCode;
+
+ @Schema(description = "班组名称", example = "A组")
+ private String teamName;
+
+ @Schema(description = "备注")
+ private String remark;
+
+ @Schema(description = "创建时间")
+ private LocalDateTime createTime;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/vo/team/MesCalPlanTeamSaveReqVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/vo/team/MesCalPlanTeamSaveReqVO.java
new file mode 100644
index 000000000..1ea116530
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/vo/team/MesCalPlanTeamSaveReqVO.java
@@ -0,0 +1,25 @@
+package cn.iocoder.yudao.module.mes.controller.admin.cal.plan.vo.team;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+@Schema(description = "管理后台 - MES 计划班组关联新增 Request VO")
+@Data
+public class MesCalPlanTeamSaveReqVO {
+
+ @Schema(description = "编号", example = "1024")
+ private Long id;
+
+ @Schema(description = "排班计划编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @NotNull(message = "排班计划不能为空")
+ private Long planId;
+
+ @Schema(description = "班组编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @NotNull(message = "班组不能为空")
+ private Long teamId;
+
+ @Schema(description = "备注")
+ private String remark;
+
+ }
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/team/MesCalTeamController.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/team/MesCalTeamController.java
new file mode 100644
index 000000000..5ba5108a3
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/team/MesCalTeamController.java
@@ -0,0 +1,101 @@
+package cn.iocoder.yudao.module.mes.controller.admin.cal.team;
+
+import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+import cn.iocoder.yudao.module.mes.controller.admin.cal.team.vo.MesCalTeamPageReqVO;
+import cn.iocoder.yudao.module.mes.controller.admin.cal.team.vo.MesCalTeamRespVO;
+import cn.iocoder.yudao.module.mes.controller.admin.cal.team.vo.MesCalTeamSaveReqVO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.cal.team.MesCalTeamDO;
+import cn.iocoder.yudao.module.mes.service.cal.team.MesCalTeamService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.Valid;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.io.IOException;
+import java.util.List;
+
+import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+@Tag(name = "管理后台 - MES 班组")
+@RestController
+@RequestMapping("/mes/cal/team")
+@Validated
+public class MesCalTeamController {
+
+ @Resource
+ private MesCalTeamService teamService;
+
+ @PostMapping("/create")
+ @Operation(summary = "创建班组")
+ @PreAuthorize("@ss.hasPermission('mes:cal-team:create')")
+ public CommonResult createTeam(@Valid @RequestBody MesCalTeamSaveReqVO createReqVO) {
+ return success(teamService.createTeam(createReqVO));
+ }
+
+ @PutMapping("/update")
+ @Operation(summary = "更新班组")
+ @PreAuthorize("@ss.hasPermission('mes:cal-team:update')")
+ public CommonResult updateTeam(@Valid @RequestBody MesCalTeamSaveReqVO updateReqVO) {
+ teamService.updateTeam(updateReqVO);
+ return success(true);
+ }
+
+ @DeleteMapping("/delete")
+ @Operation(summary = "删除班组")
+ @Parameter(name = "id", description = "编号", required = true)
+ @PreAuthorize("@ss.hasPermission('mes:cal-team:delete')")
+ public CommonResult deleteTeam(@RequestParam("id") Long id) {
+ teamService.deleteTeam(id);
+ return success(true);
+ }
+
+ @GetMapping("/get")
+ @Operation(summary = "获得班组")
+ @Parameter(name = "id", description = "编号", required = true, example = "1024")
+ @PreAuthorize("@ss.hasPermission('mes:cal-team:query')")
+ public CommonResult getTeam(@RequestParam("id") Long id) {
+ MesCalTeamDO team = teamService.getTeam(id);
+ return success(BeanUtils.toBean(team, MesCalTeamRespVO.class));
+ }
+
+ @GetMapping("/page")
+ @Operation(summary = "获得班组分页")
+ @PreAuthorize("@ss.hasPermission('mes:cal-team:query')")
+ public CommonResult> getTeamPage(@Valid MesCalTeamPageReqVO pageReqVO) {
+ PageResult pageResult = teamService.getTeamPage(pageReqVO);
+ return success(BeanUtils.toBean(pageResult, MesCalTeamRespVO.class));
+ }
+
+ @GetMapping("/list")
+ @Operation(summary = "获得班组列表")
+ @PreAuthorize("@ss.hasPermission('mes:cal-team:query')")
+ public CommonResult> getTeamList() {
+ List list = teamService.getTeamList();
+ return success(BeanUtils.toBean(list, MesCalTeamRespVO.class));
+ }
+
+ @GetMapping("/export-excel")
+ @Operation(summary = "导出班组 Excel")
+ @PreAuthorize("@ss.hasPermission('mes:cal-team:export')")
+ @ApiAccessLog(operateType = EXPORT)
+ public void exportTeamExcel(@Valid MesCalTeamPageReqVO pageReqVO,
+ HttpServletResponse response) throws IOException {
+ pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+ List list = teamService.getTeamPage(pageReqVO).getList();
+ // 导出 Excel
+ ExcelUtils.write(response, "班组.xls", "数据", MesCalTeamRespVO.class,
+ BeanUtils.toBean(list, MesCalTeamRespVO.class));
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/team/MesCalTeamMemberController.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/team/MesCalTeamMemberController.java
new file mode 100644
index 000000000..78bc15d9c
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/team/MesCalTeamMemberController.java
@@ -0,0 +1,108 @@
+package cn.iocoder.yudao.module.mes.controller.admin.cal.team;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.mes.controller.admin.cal.team.vo.member.MesCalTeamMemberPageReqVO;
+import cn.iocoder.yudao.module.mes.controller.admin.cal.team.vo.member.MesCalTeamMemberRespVO;
+import cn.iocoder.yudao.module.mes.controller.admin.cal.team.vo.member.MesCalTeamMemberSaveReqVO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.cal.team.MesCalTeamMemberDO;
+import cn.iocoder.yudao.module.mes.service.cal.team.MesCalTeamMemberService;
+import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
+import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import jakarta.validation.Valid;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
+
+@Tag(name = "管理后台 - MES 班组成员")
+@RestController
+@RequestMapping("/mes/cal/team-member")
+@Validated
+public class MesCalTeamMemberController {
+
+ @Resource
+ private MesCalTeamMemberService teamMemberService;
+ @Resource
+ private AdminUserApi adminUserApi;
+
+ @PostMapping("/create")
+ @Operation(summary = "创建班组成员")
+ @PreAuthorize("@ss.hasPermission('mes:cal-team:create')")
+ public CommonResult createTeamMember(@Valid @RequestBody MesCalTeamMemberSaveReqVO createReqVO) {
+ return success(teamMemberService.createTeamMember(createReqVO));
+ }
+
+ @DeleteMapping("/delete")
+ @Operation(summary = "删除班组成员")
+ @Parameter(name = "id", description = "编号", required = true)
+ @PreAuthorize("@ss.hasPermission('mes:cal-team:delete')")
+ public CommonResult deleteTeamMember(@RequestParam("id") Long id) {
+ teamMemberService.deleteTeamMember(id);
+ return success(true);
+ }
+
+ @GetMapping("/get")
+ @Operation(summary = "获得班组成员")
+ @Parameter(name = "id", description = "编号", required = true, example = "1024")
+ @PreAuthorize("@ss.hasPermission('mes:cal-team:query')")
+ public CommonResult getTeamMember(@RequestParam("id") Long id) {
+ MesCalTeamMemberDO member = teamMemberService.getTeamMember(id);
+ return success(BeanUtils.toBean(member, MesCalTeamMemberRespVO.class));
+ }
+
+ @GetMapping("/page")
+ @Operation(summary = "获得班组成员分页")
+ @PreAuthorize("@ss.hasPermission('mes:cal-team:query')")
+ public CommonResult> getTeamMemberPage(@Valid MesCalTeamMemberPageReqVO pageReqVO) {
+ PageResult pageResult = teamMemberService.getTeamMemberPage(pageReqVO);
+ return success(BeanUtils.toBean(pageResult, MesCalTeamMemberRespVO.class));
+ }
+
+ @GetMapping("/list-by-team")
+ @Operation(summary = "获得班组成员列表", description = "支持单个 teamId 或多个 teamIds")
+ @PreAuthorize("@ss.hasPermission('mes:cal-team:query')")
+ public CommonResult> getTeamMemberListByTeam(
+ @RequestParam(value = "teamId", required = false) Long teamId,
+ @RequestParam(value = "teamIds", required = false) Collection teamIds) {
+ List list;
+ if (CollUtil.isNotEmpty(teamIds)) {
+ list = teamMemberService.getTeamMemberListByTeamIds(teamIds);
+ } else if (teamId != null) {
+ list = teamMemberService.getTeamMemberListByTeamId(teamId);
+ } else {
+ list = Collections.emptyList();
+ }
+ return success(buildMemberRespVOList(list));
+ }
+
+ // ==================== 拼接 VO ====================
+
+ private List buildMemberRespVOList(List list) {
+ if (CollUtil.isEmpty(list)) {
+ return Collections.emptyList();
+ }
+ Map userMap = adminUserApi.getUserMap(
+ convertSet(list, MesCalTeamMemberDO::getUserId));
+ return BeanUtils.toBean(list, MesCalTeamMemberRespVO.class, vo ->
+ MapUtils.findAndThen(userMap, vo.getUserId(), user -> {
+ vo.setNickname(user.getNickname());
+ vo.setTelephone(user.getMobile());
+ }));
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/team/MesCalTeamShiftController.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/team/MesCalTeamShiftController.java
new file mode 100644
index 000000000..165aa76fa
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/team/MesCalTeamShiftController.java
@@ -0,0 +1,64 @@
+package cn.iocoder.yudao.module.mes.controller.admin.cal.team;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.mes.controller.admin.cal.team.vo.shift.MesCalTeamShiftListReqVO;
+import cn.iocoder.yudao.module.mes.controller.admin.cal.team.vo.shift.MesCalTeamShiftRespVO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.cal.plan.MesCalPlanShiftDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.cal.team.MesCalTeamDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.cal.team.MesCalTeamShiftDO;
+import cn.iocoder.yudao.module.mes.service.cal.plan.MesCalPlanShiftService;
+import cn.iocoder.yudao.module.mes.service.cal.team.MesCalTeamService;
+import cn.iocoder.yudao.module.mes.service.cal.team.MesCalTeamShiftService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import jakarta.validation.Valid;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
+
+@Tag(name = "管理后台 - MES 班组排班")
+@RestController
+@RequestMapping("/mes/cal/team-shift")
+@Validated
+public class MesCalTeamShiftController {
+
+ @Resource
+ private MesCalTeamShiftService teamShiftService;
+ @Resource
+ private MesCalTeamService teamService;
+ @Resource
+ private MesCalPlanShiftService planShiftService;
+
+ @GetMapping("/list")
+ @Operation(summary = "获得班组排班列表")
+ @PreAuthorize("@ss.hasPermission('mes:cal-team-shift:query')")
+ public CommonResult> getTeamShiftList(@Valid MesCalTeamShiftListReqVO reqVO) {
+ List list = teamShiftService.getTeamShiftList(reqVO);
+ if (CollUtil.isEmpty(list)) {
+ return success(Collections.emptyList());
+ }
+ // 关联查询班组名称和班次名称
+ Map teamMap = teamService.getTeamMap(
+ convertSet(list, MesCalTeamShiftDO::getTeamId));
+ Map shiftMap = planShiftService.getPlanShiftMap(
+ convertSet(list, MesCalTeamShiftDO::getShiftId));
+ return success(BeanUtils.toBean(list, MesCalTeamShiftRespVO.class, vo -> {
+ MapUtils.findAndThen(teamMap, vo.getTeamId(), team -> vo.setTeamName(team.getName()));
+ MapUtils.findAndThen(shiftMap, vo.getShiftId(), shift -> vo.setShiftName(shift.getName()));
+ }));
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/team/vo/MesCalTeamPageReqVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/team/vo/MesCalTeamPageReqVO.java
new file mode 100644
index 000000000..ddc36812f
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/team/vo/MesCalTeamPageReqVO.java
@@ -0,0 +1,24 @@
+package cn.iocoder.yudao.module.mes.controller.admin.cal.team.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;
+
+@Schema(description = "管理后台 - MES 班组分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class MesCalTeamPageReqVO extends PageParam {
+
+ @Schema(description = "班组编码", example = "TEAM-A")
+ private String code;
+
+ @Schema(description = "班组名称", example = "注塑")
+ private String name;
+
+ @Schema(description = "班组类型", example = "1")
+ private Integer calendarType;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/team/vo/MesCalTeamRespVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/team/vo/MesCalTeamRespVO.java
new file mode 100644
index 000000000..27d411755
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/team/vo/MesCalTeamRespVO.java
@@ -0,0 +1,39 @@
+package cn.iocoder.yudao.module.mes.controller.admin.cal.team.vo;
+
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - MES 班组 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class MesCalTeamRespVO {
+
+ @Schema(description = "班组编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+ @ExcelProperty("班组编号")
+ private Long id;
+
+ @Schema(description = "班组编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "TEAM-A")
+ @ExcelProperty("班组编码")
+ private String code;
+
+ @Schema(description = "班组名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "注塑A组")
+ @ExcelProperty("班组名称")
+ private String name;
+
+ @Schema(description = "班组类型", example = "1")
+ @ExcelProperty("班组类型")
+ private Integer calendarType;
+
+ @Schema(description = "备注")
+ @ExcelProperty("备注")
+ private String remark;
+
+ @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+ @ExcelProperty("创建时间")
+ private LocalDateTime createTime;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/team/vo/MesCalTeamSaveReqVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/team/vo/MesCalTeamSaveReqVO.java
new file mode 100644
index 000000000..e2f10f93f
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/team/vo/MesCalTeamSaveReqVO.java
@@ -0,0 +1,30 @@
+package cn.iocoder.yudao.module.mes.controller.admin.cal.team.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+@Schema(description = "管理后台 - MES 班组新增/修改 Request VO")
+@Data
+public class MesCalTeamSaveReqVO {
+
+ @Schema(description = "班组编号", example = "1024")
+ private Long id;
+
+ @Schema(description = "班组编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "TEAM-A")
+ @NotEmpty(message = "班组编码不能为空")
+ private String code;
+
+ @Schema(description = "班组名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "注塑A组")
+ @NotEmpty(message = "班组名称不能为空")
+ private String name;
+
+ @Schema(description = "班组类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @NotNull(message = "班组类型不能为空")
+ private Integer calendarType;
+
+ @Schema(description = "备注")
+ private String remark;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/team/vo/member/MesCalTeamMemberPageReqVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/team/vo/member/MesCalTeamMemberPageReqVO.java
new file mode 100644
index 000000000..c225375c8
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/team/vo/member/MesCalTeamMemberPageReqVO.java
@@ -0,0 +1,20 @@
+package cn.iocoder.yudao.module.mes.controller.admin.cal.team.vo.member;
+
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+@Schema(description = "管理后台 - MES 班组成员分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class MesCalTeamMemberPageReqVO extends PageParam {
+
+ @Schema(description = "班组编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "201")
+ @NotNull(message = "班组编号不能为空")
+ private Long teamId;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/team/vo/member/MesCalTeamMemberRespVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/team/vo/member/MesCalTeamMemberRespVO.java
new file mode 100644
index 000000000..023538bbc
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/team/vo/member/MesCalTeamMemberRespVO.java
@@ -0,0 +1,33 @@
+package cn.iocoder.yudao.module.mes.controller.admin.cal.team.vo.member;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - MES 班组成员 Response VO")
+@Data
+public class MesCalTeamMemberRespVO {
+
+ @Schema(description = "班组成员编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+ private Long id;
+
+ @Schema(description = "班组编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "201")
+ private Long teamId;
+
+ @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ private Long userId;
+
+ @Schema(description = "用户昵称", example = "管理员")
+ private String nickname;
+
+ @Schema(description = "电话", example = "13800138000")
+ private String telephone;
+
+ @Schema(description = "备注")
+ private String remark;
+
+ @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+ private LocalDateTime createTime;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/team/vo/member/MesCalTeamMemberSaveReqVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/team/vo/member/MesCalTeamMemberSaveReqVO.java
new file mode 100644
index 000000000..71a2658f2
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/team/vo/member/MesCalTeamMemberSaveReqVO.java
@@ -0,0 +1,25 @@
+package cn.iocoder.yudao.module.mes.controller.admin.cal.team.vo.member;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+@Schema(description = "管理后台 - MES 班组成员新增 Request VO")
+@Data
+public class MesCalTeamMemberSaveReqVO {
+
+ @Schema(description = "班组成员编号", example = "1024")
+ private Long id;
+
+ @Schema(description = "班组编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "201")
+ @NotNull(message = "班组编号不能为空")
+ private Long teamId;
+
+ @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @NotNull(message = "用户编号不能为空")
+ private Long userId;
+
+ @Schema(description = "备注")
+ private String remark;
+
+ }
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/team/vo/shift/MesCalTeamShiftListReqVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/team/vo/shift/MesCalTeamShiftListReqVO.java
new file mode 100644
index 000000000..459be38e8
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/team/vo/shift/MesCalTeamShiftListReqVO.java
@@ -0,0 +1,33 @@
+package cn.iocoder.yudao.module.mes.controller.admin.cal.team.vo.shift;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDateTime;
+import java.util.Collection;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@Schema(description = "管理后台 - MES 班组排班列表 Request VO")
+@Data
+public class MesCalTeamShiftListReqVO {
+
+ @Schema(description = "班组编号", example = "201")
+ private Long teamId;
+
+ @Schema(description = "班组编号集合")
+ private Collection teamIds;
+
+ @Schema(description = "排班计划编号", example = "1")
+ private Long planId;
+
+ @Schema(description = "开始日期")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private LocalDateTime startDay;
+
+ @Schema(description = "结束日期")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private LocalDateTime endDay;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/team/vo/shift/MesCalTeamShiftRespVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/team/vo/shift/MesCalTeamShiftRespVO.java
new file mode 100644
index 000000000..a1af1bbb0
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/team/vo/shift/MesCalTeamShiftRespVO.java
@@ -0,0 +1,42 @@
+package cn.iocoder.yudao.module.mes.controller.admin.cal.team.vo.shift;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - MES 班组排班 Response VO")
+@Data
+public class MesCalTeamShiftRespVO {
+
+ @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+ private Long id;
+
+ @Schema(description = "排班计划编号", example = "1")
+ private Long planId;
+
+ @Schema(description = "班组编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "201")
+ private Long teamId;
+
+ @Schema(description = "班组名称", example = "注塑A组")
+ private String teamName;
+
+ @Schema(description = "班次编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ private Long shiftId;
+
+ @Schema(description = "班次名称", example = "白班")
+ private String shiftName;
+
+ @Schema(description = "日期", requiredMode = Schema.RequiredMode.REQUIRED)
+ private LocalDateTime day;
+
+ @Schema(description = "排序", example = "1")
+ private Integer sort;
+
+ @Schema(description = "备注")
+ private String remark;
+
+ @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+ private LocalDateTime createTime;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkplan/MesDvCheckPlanController.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkplan/MesDvCheckPlanController.java
new file mode 100644
index 000000000..55872f11a
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkplan/MesDvCheckPlanController.java
@@ -0,0 +1,111 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.checkplan;
+
+import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+import cn.iocoder.yudao.module.mes.controller.admin.dv.checkplan.vo.MesDvCheckPlanPageReqVO;
+import cn.iocoder.yudao.module.mes.controller.admin.dv.checkplan.vo.MesDvCheckPlanRespVO;
+import cn.iocoder.yudao.module.mes.controller.admin.dv.checkplan.vo.MesDvCheckPlanSaveReqVO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.dv.checkplan.MesDvCheckPlanDO;
+import cn.iocoder.yudao.module.mes.service.dv.checkplan.MesDvCheckPlanService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.Valid;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.io.IOException;
+import java.util.List;
+
+import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+@Tag(name = "管理后台 - MES 点检保养方案")
+@RestController
+@RequestMapping("/mes/dv/check-plan")
+@Validated
+public class MesDvCheckPlanController {
+
+ @Resource
+ private MesDvCheckPlanService checkPlanService;
+
+ @PostMapping("/create")
+ @Operation(summary = "创建点检保养方案")
+ @PreAuthorize("@ss.hasPermission('mes:dv-check-plan:create')")
+ public CommonResult createCheckPlan(@Valid @RequestBody MesDvCheckPlanSaveReqVO createReqVO) {
+ return success(checkPlanService.createCheckPlan(createReqVO));
+ }
+
+ @PutMapping("/update")
+ @Operation(summary = "更新点检保养方案")
+ @PreAuthorize("@ss.hasPermission('mes:dv-check-plan:update')")
+ public CommonResult updateCheckPlan(@Valid @RequestBody MesDvCheckPlanSaveReqVO updateReqVO) {
+ checkPlanService.updateCheckPlan(updateReqVO);
+ return success(true);
+ }
+
+ @PutMapping("/enable")
+ @Operation(summary = "启用点检保养方案")
+ @Parameter(name = "id", description = "编号", required = true)
+ @PreAuthorize("@ss.hasPermission('mes:dv-check-plan:update')")
+ public CommonResult enableCheckPlan(@RequestParam("id") Long id) {
+ checkPlanService.enableCheckPlan(id);
+ return success(true);
+ }
+
+ @PutMapping("/disable")
+ @Operation(summary = "停用点检保养方案")
+ @Parameter(name = "id", description = "编号", required = true)
+ @PreAuthorize("@ss.hasPermission('mes:dv-check-plan:update')")
+ public CommonResult disableCheckPlan(@RequestParam("id") Long id) {
+ checkPlanService.disableCheckPlan(id);
+ return success(true);
+ }
+
+ @DeleteMapping("/delete")
+ @Operation(summary = "删除点检保养方案")
+ @Parameter(name = "id", description = "编号", required = true)
+ @PreAuthorize("@ss.hasPermission('mes:dv-check-plan:delete')")
+ public CommonResult deleteCheckPlan(@RequestParam("id") Long id) {
+ checkPlanService.deleteCheckPlan(id);
+ return success(true);
+ }
+
+ @GetMapping("/get")
+ @Operation(summary = "获得点检保养方案")
+ @Parameter(name = "id", description = "编号", required = true, example = "1024")
+ @PreAuthorize("@ss.hasPermission('mes:dv-check-plan:query')")
+ public CommonResult getCheckPlan(@RequestParam("id") Long id) {
+ MesDvCheckPlanDO checkPlan = checkPlanService.getCheckPlan(id);
+ return success(BeanUtils.toBean(checkPlan, MesDvCheckPlanRespVO.class));
+ }
+
+ @GetMapping("/page")
+ @Operation(summary = "获得点检保养方案分页")
+ @PreAuthorize("@ss.hasPermission('mes:dv-check-plan:query')")
+ public CommonResult> getCheckPlanPage(@Valid MesDvCheckPlanPageReqVO pageReqVO) {
+ PageResult pageResult = checkPlanService.getCheckPlanPage(pageReqVO);
+ return success(BeanUtils.toBean(pageResult, MesDvCheckPlanRespVO.class));
+ }
+
+ @GetMapping("/export-excel")
+ @Operation(summary = "导出点检保养方案 Excel")
+ @PreAuthorize("@ss.hasPermission('mes:dv-check-plan:export')")
+ @ApiAccessLog(operateType = EXPORT)
+ public void exportCheckPlanExcel(@Valid MesDvCheckPlanPageReqVO pageReqVO,
+ HttpServletResponse response) throws IOException {
+ pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+ List list = checkPlanService.getCheckPlanPage(pageReqVO).getList();
+ // 导出 Excel
+ ExcelUtils.write(response, "点检保养方案.xls", "数据", MesDvCheckPlanRespVO.class,
+ BeanUtils.toBean(list, MesDvCheckPlanRespVO.class));
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkplan/MesDvCheckPlanMachineryController.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkplan/MesDvCheckPlanMachineryController.java
new file mode 100644
index 000000000..ef7a3d011
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkplan/MesDvCheckPlanMachineryController.java
@@ -0,0 +1,83 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.checkplan;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.mes.controller.admin.dv.checkplan.vo.machinery.MesDvCheckPlanMachineryRespVO;
+import cn.iocoder.yudao.module.mes.controller.admin.dv.checkplan.vo.machinery.MesDvCheckPlanMachinerySaveReqVO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.dv.checkplan.MesDvCheckPlanMachineryDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.dv.machinery.MesDvMachineryDO;
+import cn.iocoder.yudao.module.mes.service.dv.checkplan.MesDvCheckPlanMachineryService;
+import cn.iocoder.yudao.module.mes.service.dv.machinery.MesDvMachineryService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import jakarta.validation.Valid;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
+
+@Tag(name = "管理后台 - MES 点检保养方案设备")
+@RestController
+@RequestMapping("/mes/dv/check-plan-machinery")
+@Validated
+public class MesDvCheckPlanMachineryController {
+
+ @Resource
+ private MesDvCheckPlanMachineryService checkPlanMachineryService;
+ @Resource
+ private MesDvMachineryService machineryService;
+
+ @PostMapping("/create")
+ @Operation(summary = "创建方案设备关联")
+ @PreAuthorize("@ss.hasPermission('mes:dv-check-plan:update')")
+ public CommonResult createCheckPlanMachinery(@Valid @RequestBody MesDvCheckPlanMachinerySaveReqVO createReqVO) {
+ return success(checkPlanMachineryService.createCheckPlanMachinery(createReqVO));
+ }
+
+ @DeleteMapping("/delete")
+ @Operation(summary = "删除方案设备关联")
+ @Parameter(name = "id", description = "编号", required = true)
+ @PreAuthorize("@ss.hasPermission('mes:dv-check-plan:update')")
+ public CommonResult deleteCheckPlanMachinery(@RequestParam("id") Long id) {
+ checkPlanMachineryService.deleteCheckPlanMachinery(id);
+ return success(true);
+ }
+
+ @GetMapping("/list-by-plan")
+ @Operation(summary = "获得指定方案的设备列表")
+ @Parameter(name = "planId", description = "方案编号", required = true)
+ @PreAuthorize("@ss.hasPermission('mes:dv-check-plan:query')")
+ public CommonResult> getCheckPlanMachineryListByPlan(
+ @RequestParam("planId") Long planId) {
+ List list = checkPlanMachineryService.getCheckPlanMachineryListByPlanId(planId);
+ return success(buildCheckPlanMachineryRespVOList(list));
+ }
+
+ // ==================== 拼接 VO ====================
+
+ private List buildCheckPlanMachineryRespVOList(
+ List list) {
+ if (CollUtil.isEmpty(list)) {
+ return Collections.emptyList();
+ }
+ Map machineryMap = machineryService.getMachineryMap(
+ convertSet(list, MesDvCheckPlanMachineryDO::getMachineryId));
+ return BeanUtils.toBean(list, MesDvCheckPlanMachineryRespVO.class, vo ->
+ MapUtils.findAndThen(machineryMap, vo.getMachineryId(), machinery ->
+ vo.setMachineryCode(machinery.getCode()).setMachineryName(machinery.getName())
+ .setMachineryBrand(machinery.getBrand()).setMachinerySpec(machinery.getSpec())
+ )
+ );
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkplan/MesDvCheckPlanSubjectController.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkplan/MesDvCheckPlanSubjectController.java
new file mode 100644
index 000000000..ce0d56fd4
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkplan/MesDvCheckPlanSubjectController.java
@@ -0,0 +1,81 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.checkplan;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.mes.controller.admin.dv.checkplan.vo.subject.MesDvCheckPlanSubjectRespVO;
+import cn.iocoder.yudao.module.mes.controller.admin.dv.checkplan.vo.subject.MesDvCheckPlanSubjectSaveReqVO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.dv.checkplan.MesDvCheckPlanSubjectDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.dv.subject.MesDvSubjectDO;
+import cn.iocoder.yudao.module.mes.service.dv.checkplan.MesDvCheckPlanSubjectService;
+import cn.iocoder.yudao.module.mes.service.dv.subject.MesDvSubjectService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import jakarta.validation.Valid;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+@Tag(name = "管理后台 - MES 点检保养方案项目")
+@RestController
+@RequestMapping("/mes/dv/check-plan-subject")
+@Validated
+public class MesDvCheckPlanSubjectController {
+
+ @Resource
+ private MesDvCheckPlanSubjectService checkPlanSubjectService;
+ @Resource
+ private MesDvSubjectService subjectService;
+
+ @PostMapping("/create")
+ @Operation(summary = "创建方案项目关联")
+ @PreAuthorize("@ss.hasPermission('mes:dv-check-plan:update')")
+ public CommonResult createCheckPlanSubject(@Valid @RequestBody MesDvCheckPlanSubjectSaveReqVO createReqVO) {
+ return success(checkPlanSubjectService.createCheckPlanSubject(createReqVO));
+ }
+
+ @DeleteMapping("/delete")
+ @Operation(summary = "删除方案项目关联")
+ @Parameter(name = "id", description = "编号", required = true)
+ @PreAuthorize("@ss.hasPermission('mes:dv-check-plan:update')")
+ public CommonResult deleteCheckPlanSubject(@RequestParam("id") Long id) {
+ checkPlanSubjectService.deleteCheckPlanSubject(id);
+ return success(true);
+ }
+
+ @GetMapping("/list-by-plan")
+ @Operation(summary = "获得指定方案的项目列表")
+ @Parameter(name = "planId", description = "方案编号", required = true)
+ @PreAuthorize("@ss.hasPermission('mes:dv-check-plan:query')")
+ public CommonResult> getCheckPlanSubjectListByPlan(
+ @RequestParam("planId") Long planId) {
+ List list = checkPlanSubjectService.getCheckPlanSubjectListByPlanId(planId);
+ List respList = BeanUtils.toBean(list, MesDvCheckPlanSubjectRespVO.class);
+ // 拼装项目编码/名称/类型/内容/标准
+ // MesDvCheckPlanMachineryController.java 参考下里面的 todo;
+ if (CollUtil.isNotEmpty(respList)) {
+ List subjectIds = CollectionUtils.convertList(respList, MesDvCheckPlanSubjectRespVO::getSubjectId);
+ Map subjectMap = subjectService.getSubjectMap(subjectIds);
+ respList.forEach(resp -> {
+ MesDvSubjectDO subject = subjectMap.get(resp.getSubjectId());
+ if (subject != null) {
+ resp.setSubjectCode(subject.getCode());
+ resp.setSubjectName(subject.getName());
+ resp.setSubjectType(subject.getType());
+ resp.setSubjectContent(subject.getContent());
+ resp.setSubjectStandard(subject.getStandard());
+ }
+ });
+ }
+ return success(respList);
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkplan/vo/MesDvCheckPlanPageReqVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkplan/vo/MesDvCheckPlanPageReqVO.java
new file mode 100644
index 000000000..c7c13196e
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkplan/vo/MesDvCheckPlanPageReqVO.java
@@ -0,0 +1,36 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.checkplan.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 = "管理后台 - MES 点检保养方案分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class MesDvCheckPlanPageReqVO extends PageParam {
+
+ @Schema(description = "方案编码", example = "CHP001")
+ private String code;
+
+ @Schema(description = "方案名称", example = "注塑机")
+ private String name;
+
+ @Schema(description = "方案类型", example = "1")
+ private Integer type;
+
+ @Schema(description = "状态", example = "0")
+ private Integer status;
+
+ @Schema(description = "创建时间")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private LocalDateTime[] createTime;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkplan/vo/MesDvCheckPlanRespVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkplan/vo/MesDvCheckPlanRespVO.java
new file mode 100644
index 000000000..ff9c79df7
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkplan/vo/MesDvCheckPlanRespVO.java
@@ -0,0 +1,59 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.checkplan.vo;
+
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - MES 点检保养方案 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class MesDvCheckPlanRespVO {
+
+ @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+ @ExcelProperty("编号")
+ private Long id;
+
+ @Schema(description = "方案编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "CHP001")
+ @ExcelProperty("方案编码")
+ private String code;
+
+ @Schema(description = "方案名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "注塑机日检方案")
+ @ExcelProperty("方案名称")
+ private String name;
+
+ @Schema(description = "方案类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @ExcelProperty("方案类型")
+ private Integer type;
+
+ @Schema(description = "开始日期")
+ @ExcelProperty("开始日期")
+ private LocalDateTime startDate;
+
+ @Schema(description = "结束日期")
+ @ExcelProperty("结束日期")
+ private LocalDateTime endDate;
+
+ @Schema(description = "周期类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @ExcelProperty("周期类型")
+ private Integer cycleType;
+
+ @Schema(description = "周期数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @ExcelProperty("周期数量")
+ private Integer cycleCount;
+
+ @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
+ @ExcelProperty("状态")
+ private Integer status;
+
+ @Schema(description = "备注")
+ @ExcelProperty("备注")
+ private String remark;
+
+ @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+ @ExcelProperty("创建时间")
+ private LocalDateTime createTime;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkplan/vo/MesDvCheckPlanSaveReqVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkplan/vo/MesDvCheckPlanSaveReqVO.java
new file mode 100644
index 000000000..fe4832e58
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkplan/vo/MesDvCheckPlanSaveReqVO.java
@@ -0,0 +1,49 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.checkplan.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - MES 点检保养方案新增/修改 Request VO")
+@Data
+public class MesDvCheckPlanSaveReqVO {
+
+ @Schema(description = "编号", example = "1024")
+ private Long id;
+
+ @Schema(description = "方案编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "CHP001")
+ @NotEmpty(message = "方案编码不能为空")
+ private String code;
+
+ @Schema(description = "方案名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "注塑机日检方案")
+ @NotEmpty(message = "方案名称不能为空")
+ private String name;
+
+ @Schema(description = "方案类型(1=设备点检,2=设备保养)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @NotNull(message = "方案类型不能为空")
+ private Integer type;
+
+ @Schema(description = "开始日期")
+ private LocalDateTime startDate;
+
+ @Schema(description = "结束日期")
+ private LocalDateTime endDate;
+
+ @Schema(description = "周期类型(1=天,2=周,3=月,4=年)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @NotNull(message = "周期类型不能为空")
+ private Integer cycleType;
+
+ @Schema(description = "周期数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @NotNull(message = "周期数量不能为空")
+ private Integer cycleCount;
+
+ @Schema(description = "状态", example = "0")
+ private Integer status;
+
+ @Schema(description = "备注")
+ private String remark;
+
+ }
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkplan/vo/machinery/MesDvCheckPlanMachineryRespVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkplan/vo/machinery/MesDvCheckPlanMachineryRespVO.java
new file mode 100644
index 000000000..0d2b74267
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkplan/vo/machinery/MesDvCheckPlanMachineryRespVO.java
@@ -0,0 +1,39 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.checkplan.vo.machinery;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - MES 点检保养方案设备 Response VO")
+@Data
+public class MesDvCheckPlanMachineryRespVO {
+
+ @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+ private Long id;
+
+ @Schema(description = "方案编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ private Long planId;
+
+ @Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ private Long machineryId;
+
+ @Schema(description = "设备编码", example = "EQ001")
+ private String machineryCode;
+
+ @Schema(description = "设备名称", example = "注塑机A")
+ private String machineryName;
+
+ @Schema(description = "品牌", example = "海天")
+ private String machineryBrand;
+
+ @Schema(description = "规格型号", example = "HTF120")
+ private String machinerySpec;
+
+ @Schema(description = "备注")
+ private String remark;
+
+ @Schema(description = "创建时间")
+ private LocalDateTime createTime;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkplan/vo/machinery/MesDvCheckPlanMachinerySaveReqVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkplan/vo/machinery/MesDvCheckPlanMachinerySaveReqVO.java
new file mode 100644
index 000000000..8a0bc036b
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkplan/vo/machinery/MesDvCheckPlanMachinerySaveReqVO.java
@@ -0,0 +1,25 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.checkplan.vo.machinery;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+@Schema(description = "管理后台 - MES 点检保养方案设备新增 Request VO")
+@Data
+public class MesDvCheckPlanMachinerySaveReqVO {
+
+ @Schema(description = "编号", example = "1024")
+ private Long id;
+
+ @Schema(description = "方案编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @NotNull(message = "方案编号不能为空")
+ private Long planId;
+
+ @Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @NotNull(message = "设备不能为空")
+ private Long machineryId;
+
+ @Schema(description = "备注")
+ private String remark;
+
+ }
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkplan/vo/subject/MesDvCheckPlanSubjectRespVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkplan/vo/subject/MesDvCheckPlanSubjectRespVO.java
new file mode 100644
index 000000000..545700678
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkplan/vo/subject/MesDvCheckPlanSubjectRespVO.java
@@ -0,0 +1,42 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.checkplan.vo.subject;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - MES 点检保养方案项目 Response VO")
+@Data
+public class MesDvCheckPlanSubjectRespVO {
+
+ @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+ private Long id;
+
+ @Schema(description = "方案编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ private Long planId;
+
+ @Schema(description = "项目编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ private Long subjectId;
+
+ @Schema(description = "项目编码", example = "CHK001")
+ private String subjectCode;
+
+ @Schema(description = "项目名称", example = "油温检查")
+ private String subjectName;
+
+ @Schema(description = "项目类型", example = "1")
+ private Integer subjectType;
+
+ @Schema(description = "项目内容", example = "检查油温是否正常")
+ private String subjectContent;
+
+ @Schema(description = "标准", example = "40-60°C")
+ private String subjectStandard;
+
+ @Schema(description = "备注")
+ private String remark;
+
+ @Schema(description = "创建时间")
+ private LocalDateTime createTime;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkplan/vo/subject/MesDvCheckPlanSubjectSaveReqVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkplan/vo/subject/MesDvCheckPlanSubjectSaveReqVO.java
new file mode 100644
index 000000000..ad633a3d4
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkplan/vo/subject/MesDvCheckPlanSubjectSaveReqVO.java
@@ -0,0 +1,25 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.checkplan.vo.subject;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+@Schema(description = "管理后台 - MES 点检保养方案项目新增 Request VO")
+@Data
+public class MesDvCheckPlanSubjectSaveReqVO {
+
+ @Schema(description = "编号", example = "1024")
+ private Long id;
+
+ @Schema(description = "方案编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @NotNull(message = "方案编号不能为空")
+ private Long planId;
+
+ @Schema(description = "项目编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @NotNull(message = "点检保养项目不能为空")
+ private Long subjectId;
+
+ @Schema(description = "备注")
+ private String remark;
+
+ }
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkrecord/MesDvCheckRecordController.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkrecord/MesDvCheckRecordController.java
new file mode 100644
index 000000000..d6b55292e
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkrecord/MesDvCheckRecordController.java
@@ -0,0 +1,152 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.checkrecord;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+import cn.iocoder.yudao.module.mes.controller.admin.dv.checkrecord.vo.MesDvCheckRecordPageReqVO;
+import cn.iocoder.yudao.module.mes.controller.admin.dv.checkrecord.vo.MesDvCheckRecordRespVO;
+import cn.iocoder.yudao.module.mes.controller.admin.dv.checkrecord.vo.MesDvCheckRecordSaveReqVO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.dv.checkplan.MesDvCheckPlanDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.dv.checkrecord.MesDvCheckRecordDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.dv.machinery.MesDvMachineryDO;
+import cn.iocoder.yudao.module.mes.service.dv.checkplan.MesDvCheckPlanService;
+import cn.iocoder.yudao.module.mes.service.dv.checkrecord.MesDvCheckRecordService;
+import cn.iocoder.yudao.module.mes.service.dv.machinery.MesDvMachineryService;
+import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
+import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.Valid;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
+
+@Tag(name = "管理后台 - MES 设备点检记录")
+@RestController
+@RequestMapping("/mes/dv/check-record")
+@Validated
+public class MesDvCheckRecordController {
+
+ @Resource
+ private MesDvCheckRecordService checkRecordService;
+
+ @Resource
+ private MesDvCheckPlanService checkPlanService;
+
+ @Resource
+ private MesDvMachineryService machineryService;
+
+ @Resource
+ private AdminUserApi adminUserApi;
+
+ @PostMapping("/create")
+ @Operation(summary = "创建设备点检记录")
+ @PreAuthorize("@ss.hasPermission('mes:dv-check-record:create')")
+ public CommonResult createCheckRecord(@Valid @RequestBody MesDvCheckRecordSaveReqVO createReqVO) {
+ return success(checkRecordService.createCheckRecord(createReqVO));
+ }
+
+ @PutMapping("/update")
+ @Operation(summary = "更新设备点检记录")
+ @PreAuthorize("@ss.hasPermission('mes:dv-check-record:update')")
+ public CommonResult updateCheckRecord(@Valid @RequestBody MesDvCheckRecordSaveReqVO updateReqVO) {
+ checkRecordService.updateCheckRecord(updateReqVO);
+ return success(true);
+ }
+
+ @PutMapping("/submit")
+ @Operation(summary = "提交设备点检记录(草稿→已完成)")
+ @Parameter(name = "id", description = "编号", required = true)
+ @PreAuthorize("@ss.hasPermission('mes:dv-check-record:update')")
+ public CommonResult submitCheckRecord(@RequestParam("id") Long id) {
+ checkRecordService.submitCheckRecord(id);
+ return success(true);
+ }
+
+ @DeleteMapping("/delete")
+ @Operation(summary = "删除设备点检记录")
+ @Parameter(name = "id", description = "编号", required = true)
+ @PreAuthorize("@ss.hasPermission('mes:dv-check-record:delete')")
+ public CommonResult deleteCheckRecord(@RequestParam("id") Long id) {
+ checkRecordService.deleteCheckRecord(id);
+ return success(true);
+ }
+
+ @GetMapping("/get")
+ @Operation(summary = "获得设备点检记录")
+ @Parameter(name = "id", description = "编号", required = true, example = "1024")
+ @PreAuthorize("@ss.hasPermission('mes:dv-check-record:query')")
+ public CommonResult getCheckRecord(@RequestParam("id") Long id) {
+ MesDvCheckRecordDO checkRecord = checkRecordService.getCheckRecord(id);
+ if (checkRecord == null) {
+ return success(null);
+ }
+ return success(buildCheckRecordRespVOList(Collections.singletonList(checkRecord)).get(0));
+ }
+
+ @GetMapping("/page")
+ @Operation(summary = "获得设备点检记录分页")
+ @PreAuthorize("@ss.hasPermission('mes:dv-check-record:query')")
+ public CommonResult> getCheckRecordPage(@Valid MesDvCheckRecordPageReqVO pageReqVO) {
+ PageResult pageResult = checkRecordService.getCheckRecordPage(pageReqVO);
+ return success(new PageResult<>(buildCheckRecordRespVOList(pageResult.getList()), pageResult.getTotal()));
+ }
+
+ @GetMapping("/export-excel")
+ @Operation(summary = "导出设备点检记录 Excel")
+ @PreAuthorize("@ss.hasPermission('mes:dv-check-record:export')")
+ @ApiAccessLog(operateType = EXPORT)
+ public void exportCheckRecordExcel(@Valid MesDvCheckRecordPageReqVO pageReqVO,
+ HttpServletResponse response) throws IOException {
+ pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+ List list = checkRecordService.getCheckRecordPage(pageReqVO).getList();
+ ExcelUtils.write(response, "设备点检记录.xls", "数据", MesDvCheckRecordRespVO.class,
+ buildCheckRecordRespVOList(list));
+ }
+
+ // ==================== 拼接 VO ====================
+
+ @SuppressWarnings("DuplicatedCode")
+ private List buildCheckRecordRespVOList(List list) {
+ if (CollUtil.isEmpty(list)) {
+ return Collections.emptyList();
+ }
+ // 1. 批量获取关联数据
+ Map planMap = checkPlanService.getCheckPlanMap(
+ convertSet(list, MesDvCheckRecordDO::getPlanId));
+ Map machineryMap = machineryService.getMachineryMap(
+ convertSet(list, MesDvCheckRecordDO::getMachineryId));
+ Map userMap = adminUserApi.getUserMap(
+ convertSet(list, MesDvCheckRecordDO::getUserId));
+ // 2. 拼接 VO
+ return BeanUtils.toBean(list, MesDvCheckRecordRespVO.class, vo -> {
+ MapUtils.findAndThen(planMap, vo.getPlanId(),
+ plan -> vo.setPlanName(plan.getName()).setPlanCode(plan.getCode())
+ .setPlanStartDate(plan.getStartDate()).setPlanEndDate(plan.getEndDate())
+ .setPlanCycleType(plan.getCycleType()).setPlanCycleCount(plan.getCycleCount()));
+ MapUtils.findAndThen(machineryMap, vo.getMachineryId(), machinery -> vo
+ .setMachineryCode(machinery.getCode()).setMachineryName(machinery.getName())
+ .setMachineryBrand(machinery.getBrand()).setMachinerySpec(machinery.getSpec()));
+ MapUtils.findAndThen(userMap, vo.getUserId(),
+ user -> vo.setNickname(user.getNickname()));
+ });
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkrecord/MesDvCheckRecordLineController.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkrecord/MesDvCheckRecordLineController.java
new file mode 100644
index 000000000..95e61d2fd
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkrecord/MesDvCheckRecordLineController.java
@@ -0,0 +1,103 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.checkrecord;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.mes.controller.admin.dv.checkrecord.vo.line.MesDvCheckRecordLinePageReqVO;
+import cn.iocoder.yudao.module.mes.controller.admin.dv.checkrecord.vo.line.MesDvCheckRecordLineRespVO;
+import cn.iocoder.yudao.module.mes.controller.admin.dv.checkrecord.vo.line.MesDvCheckRecordLineSaveReqVO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.dv.checkrecord.MesDvCheckRecordLineDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.dv.subject.MesDvSubjectDO;
+import cn.iocoder.yudao.module.mes.service.dv.checkrecord.MesDvCheckRecordLineService;
+import cn.iocoder.yudao.module.mes.service.dv.subject.MesDvSubjectService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import jakarta.validation.Valid;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
+
+@Tag(name = "管理后台 - MES 设备点检记录明细")
+@RestController
+@RequestMapping("/mes/dv/check-record-line")
+@Validated
+public class MesDvCheckRecordLineController {
+
+ @Resource
+ private MesDvCheckRecordLineService checkRecordLineService;
+
+ @Resource
+ private MesDvSubjectService subjectService;
+
+ @PostMapping("/create")
+ @Operation(summary = "创建设备点检记录明细")
+ @PreAuthorize("@ss.hasPermission('mes:dv-check-record:create')")
+ public CommonResult createCheckRecordLine(@Valid @RequestBody MesDvCheckRecordLineSaveReqVO createReqVO) {
+ return success(checkRecordLineService.createCheckRecordLine(createReqVO));
+ }
+
+ @PutMapping("/update")
+ @Operation(summary = "更新设备点检记录明细")
+ @PreAuthorize("@ss.hasPermission('mes:dv-check-record:update')")
+ public CommonResult updateCheckRecordLine(@Valid @RequestBody MesDvCheckRecordLineSaveReqVO updateReqVO) {
+ checkRecordLineService.updateCheckRecordLine(updateReqVO);
+ return success(true);
+ }
+
+ @DeleteMapping("/delete")
+ @Operation(summary = "删除设备点检记录明细")
+ @Parameter(name = "id", description = "编号", required = true)
+ @PreAuthorize("@ss.hasPermission('mes:dv-check-record:delete')")
+ public CommonResult deleteCheckRecordLine(@RequestParam("id") Long id) {
+ checkRecordLineService.deleteCheckRecordLine(id);
+ return success(true);
+ }
+
+ @GetMapping("/get")
+ @Operation(summary = "获得设备点检记录明细")
+ @Parameter(name = "id", description = "编号", required = true, example = "1024")
+ @PreAuthorize("@ss.hasPermission('mes:dv-check-record:query')")
+ public CommonResult getCheckRecordLine(@RequestParam("id") Long id) {
+ MesDvCheckRecordLineDO line = checkRecordLineService.getCheckRecordLine(id);
+ if (line == null) {
+ return success(null);
+ }
+ return success(buildCheckRecordLineRespVOList(Collections.singletonList(line)).get(0));
+ }
+
+ @GetMapping("/page")
+ @Operation(summary = "获得设备点检记录明细分页")
+ @PreAuthorize("@ss.hasPermission('mes:dv-check-record:query')")
+ public CommonResult> getCheckRecordLinePage(@Valid MesDvCheckRecordLinePageReqVO pageReqVO) {
+ PageResult pageResult = checkRecordLineService.getCheckRecordLinePage(pageReqVO);
+ return success(new PageResult<>(buildCheckRecordLineRespVOList(pageResult.getList()), pageResult.getTotal()));
+ }
+
+ // ==================== 拼接 VO ====================
+
+ private List buildCheckRecordLineRespVOList(List list) {
+ if (CollUtil.isEmpty(list)) {
+ return Collections.emptyList();
+ }
+ // 1. 批量获取关联数据
+ Map subjectMap = subjectService.getSubjectMap(
+ convertSet(list, MesDvCheckRecordLineDO::getSubjectId));
+ // 2. 拼接 VO
+ return BeanUtils.toBean(list, MesDvCheckRecordLineRespVO.class, vo ->
+ MapUtils.findAndThen(subjectMap, vo.getSubjectId(), subject -> vo
+ .setSubjectCode(subject.getCode()).setSubjectName(subject.getName())
+ .setSubjectType(subject.getType()).setSubjectContent(subject.getContent()).setSubjectStandard(subject.getStandard())));
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkrecord/vo/MesDvCheckRecordPageReqVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkrecord/vo/MesDvCheckRecordPageReqVO.java
new file mode 100644
index 000000000..340a2a21c
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkrecord/vo/MesDvCheckRecordPageReqVO.java
@@ -0,0 +1,36 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.checkrecord.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 = "管理后台 - MES 设备点检记录分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class MesDvCheckRecordPageReqVO extends PageParam {
+
+ @Schema(description = "点检计划编号", example = "1")
+ private Long planId;
+
+ @Schema(description = "设备编号", example = "1")
+ private Long machineryId;
+
+ @Schema(description = "点检人编号", example = "1")
+ private Long userId;
+
+ @Schema(description = "状态", example = "10")
+ private Integer status;
+
+ @Schema(description = "点检时间")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private LocalDateTime[] checkTime;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkrecord/vo/MesDvCheckRecordRespVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkrecord/vo/MesDvCheckRecordRespVO.java
new file mode 100644
index 000000000..857d9dc10
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkrecord/vo/MesDvCheckRecordRespVO.java
@@ -0,0 +1,93 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.checkrecord.vo;
+
+import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
+import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
+import cn.iocoder.yudao.module.mes.enums.DictTypeConstants;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - MES 设备点检记录 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class MesDvCheckRecordRespVO {
+
+ @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+ @ExcelProperty("编号")
+ private Long id;
+
+ @Schema(description = "点检计划编号", example = "1")
+ private Long planId;
+
+ @Schema(description = "计划名称", example = "日常点检计划")
+ @ExcelProperty("计划名称")
+ private String planName;
+
+ @Schema(description = "计划编码", example = "P001")
+ @ExcelProperty("计划编码")
+ private String planCode;
+
+ @Schema(description = "开始时间")
+ @ExcelProperty("开始时间")
+ private LocalDateTime planStartDate;
+
+ @Schema(description = "结束日期")
+ @ExcelProperty("结束日期")
+ private LocalDateTime planEndDate;
+
+ @Schema(description = "频率类型", example = "1")
+ @ExcelProperty(value = "频率类型", converter = DictConvert.class)
+ @DictFormat(DictTypeConstants.MES_DV_CYCLE_TYPE)
+ private Integer planCycleType;
+
+ @Schema(description = "频率数量", example = "5")
+ @ExcelProperty(value = "频率数量")
+ private Integer planCycleCount;
+
+ @Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ private Long machineryId;
+
+ @Schema(description = "设备编码", example = "M001")
+ @ExcelProperty("设备编码")
+ private String machineryCode;
+
+ @Schema(description = "设备名称", example = "机床A")
+ @ExcelProperty("设备名称")
+ private String machineryName;
+
+ @Schema(description = "品牌", example = "西门子")
+ @ExcelProperty("品牌")
+ private String machineryBrand;
+
+ @Schema(description = "规格型号", example = "X-100")
+ @ExcelProperty("规格型号")
+ private String machinerySpec;
+
+ @Schema(description = "点检时间", requiredMode = Schema.RequiredMode.REQUIRED)
+ @ExcelProperty("点检时间")
+ private LocalDateTime checkTime;
+
+ @Schema(description = "点检人编号", example = "1")
+ private Long userId;
+
+ @Schema(description = "点检人名称", example = "张三")
+ @ExcelProperty("点检人")
+ private String nickname;
+
+ @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
+ @ExcelProperty(value = "状态", converter = DictConvert.class)
+ @DictFormat(DictTypeConstants.MES_DV_CHECK_RECORD_STATUS)
+ private Integer status;
+
+ @Schema(description = "备注", example = "测试备注")
+ @ExcelProperty("备注")
+ private String remark;
+
+ @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+ @ExcelProperty("创建时间")
+ private LocalDateTime createTime;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkrecord/vo/MesDvCheckRecordSaveReqVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkrecord/vo/MesDvCheckRecordSaveReqVO.java
new file mode 100644
index 000000000..3abbc1bac
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkrecord/vo/MesDvCheckRecordSaveReqVO.java
@@ -0,0 +1,33 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.checkrecord.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import jakarta.validation.constraints.NotNull;
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - MES 设备点检记录新增/修改 Request VO")
+@Data
+public class MesDvCheckRecordSaveReqVO {
+
+ @Schema(description = "编号", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "1024")
+ private Long id;
+
+ @Schema(description = "点检计划编号", example = "1")
+ private Long planId;
+
+ @Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @NotNull(message = "设备不能为空")
+ private Long machineryId;
+
+ @Schema(description = "点检时间", requiredMode = Schema.RequiredMode.REQUIRED)
+ @NotNull(message = "点检时间不能为空")
+ private LocalDateTime checkTime;
+
+ @Schema(description = "点检人编号", example = "1")
+ private Long userId;
+
+ @Schema(description = "备注", example = "测试备注")
+ private String remark;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkrecord/vo/line/MesDvCheckRecordLinePageReqVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkrecord/vo/line/MesDvCheckRecordLinePageReqVO.java
new file mode 100644
index 000000000..166fc553e
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkrecord/vo/line/MesDvCheckRecordLinePageReqVO.java
@@ -0,0 +1,18 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.checkrecord.vo.line;
+
+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;
+
+@Schema(description = "管理后台 - MES 设备点检记录明细分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class MesDvCheckRecordLinePageReqVO extends PageParam {
+
+ @Schema(description = "点检记录编号", example = "1")
+ private Long recordId;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkrecord/vo/line/MesDvCheckRecordLineRespVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkrecord/vo/line/MesDvCheckRecordLineRespVO.java
new file mode 100644
index 000000000..27a90ab76
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkrecord/vo/line/MesDvCheckRecordLineRespVO.java
@@ -0,0 +1,65 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.checkrecord.vo.line;
+
+import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
+import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
+import cn.iocoder.yudao.module.mes.enums.DictTypeConstants;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - MES 设备点检记录明细 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class MesDvCheckRecordLineRespVO {
+
+ @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+ @ExcelProperty("编号")
+ private Long id;
+
+ @Schema(description = "点检记录编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ private Long recordId;
+
+ @Schema(description = "点检项目编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ private Long subjectId;
+
+ @Schema(description = "项目编码", example = "S001")
+ @ExcelProperty("项目编码")
+ private String subjectCode;
+
+ @Schema(description = "项目名称", example = "润滑油检查")
+ @ExcelProperty("项目名称")
+ private String subjectName;
+
+ @Schema(description = "项目类型", example = "1")
+ @ExcelProperty("项目类型")
+ private Integer subjectType;
+
+ @Schema(description = "检查内容", example = "检查润滑油是否充足")
+ @ExcelProperty("检查内容")
+ private String subjectContent;
+
+ @Schema(description = "检查标准", example = "油位不低于最低刻度")
+ @ExcelProperty("检查标准")
+ private String subjectStandard;
+
+ @Schema(description = "点检结果", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @ExcelProperty(value = "点检结果", converter = DictConvert.class)
+ @DictFormat(DictTypeConstants.MES_DV_CHECK_RESULT)
+ private Integer checkStatus;
+
+ @Schema(description = "异常描述", example = "设备异响")
+ @ExcelProperty("异常描述")
+ private String checkResult;
+
+ @Schema(description = "备注", example = "测试备注")
+ @ExcelProperty("备注")
+ private String remark;
+
+ @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+ @ExcelProperty("创建时间")
+ private LocalDateTime createTime;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkrecord/vo/line/MesDvCheckRecordLineSaveReqVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkrecord/vo/line/MesDvCheckRecordLineSaveReqVO.java
new file mode 100644
index 000000000..9ece0852a
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/checkrecord/vo/line/MesDvCheckRecordLineSaveReqVO.java
@@ -0,0 +1,33 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.checkrecord.vo.line;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import jakarta.validation.constraints.NotNull;
+
+@Schema(description = "管理后台 - MES 设备点检记录明细新增/修改 Request VO")
+@Data
+public class MesDvCheckRecordLineSaveReqVO {
+
+ @Schema(description = "编号", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "1024")
+ private Long id;
+
+ @Schema(description = "点检记录编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @NotNull(message = "点检记录不能为空")
+ private Long recordId;
+
+ @Schema(description = "点检项目编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @NotNull(message = "点检项目不能为空")
+ private Long subjectId;
+
+ @Schema(description = "点检结果", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @NotNull(message = "点检结果不能为空")
+ private Integer checkStatus;
+
+ @Schema(description = "异常描述", example = "设备异响")
+ private String checkResult;
+
+ @Schema(description = "备注", example = "测试备注")
+ private String remark;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/MesDvMachineryController.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/MesDvMachineryController.java
new file mode 100644
index 000000000..e6d89e54d
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/MesDvMachineryController.java
@@ -0,0 +1,170 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.machinery;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+import cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.MesDvMachineryImportExcelVO;
+import cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.MesDvMachineryImportRespVO;
+import cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.MesDvMachineryPageReqVO;
+import cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.MesDvMachineryRespVO;
+import cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.MesDvMachinerySaveReqVO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.dv.machinery.MesDvMachineryDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.dv.machinery.MesDvMachineryTypeDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkshopDO;
+import cn.iocoder.yudao.module.mes.service.dv.machinery.MesDvMachineryService;
+import cn.iocoder.yudao.module.mes.service.dv.machinery.MesDvMachineryTypeService;
+import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkshopService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.Parameters;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.Valid;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
+
+@Tag(name = "管理后台 - MES 设备台账")
+@RestController
+@RequestMapping("/mes/dv/machinery")
+@Validated
+public class MesDvMachineryController {
+
+ @Resource
+ private MesDvMachineryService machineryService;
+
+ @Resource
+ private MesDvMachineryTypeService machineryTypeService;
+
+ @Resource
+ private MesMdWorkshopService workshopService;
+
+ @PostMapping("/create")
+ @Operation(summary = "创建设备")
+ @PreAuthorize("@ss.hasPermission('mes:dv-machinery:create')")
+ public CommonResult createMachinery(@Valid @RequestBody MesDvMachinerySaveReqVO createReqVO) {
+ return success(machineryService.createMachinery(createReqVO));
+ }
+
+ @PutMapping("/update")
+ @Operation(summary = "更新设备")
+ @PreAuthorize("@ss.hasPermission('mes:dv-machinery:update')")
+ public CommonResult updateMachinery(@Valid @RequestBody MesDvMachinerySaveReqVO updateReqVO) {
+ machineryService.updateMachinery(updateReqVO);
+ return success(true);
+ }
+
+ @DeleteMapping("/delete")
+ @Operation(summary = "删除设备")
+ @Parameter(name = "id", description = "编号", required = true)
+ @PreAuthorize("@ss.hasPermission('mes:dv-machinery:delete')")
+ public CommonResult deleteMachinery(@RequestParam("id") Long id) {
+ machineryService.deleteMachinery(id);
+ return success(true);
+ }
+
+ @GetMapping("/get")
+ @Operation(summary = "获得设备")
+ @Parameter(name = "id", description = "编号", required = true, example = "1024")
+ @PreAuthorize("@ss.hasPermission('mes:dv-machinery:query')")
+ public CommonResult getMachinery(@RequestParam("id") Long id) {
+ MesDvMachineryDO machinery = machineryService.getMachinery(id);
+ if (machinery == null) {
+ return success(null);
+ }
+ return success(buildMachineryRespVOList(Collections.singletonList(machinery)).get(0));
+ }
+
+ @GetMapping("/page")
+ @Operation(summary = "获得设备分页")
+ @PreAuthorize("@ss.hasPermission('mes:dv-machinery:query')")
+ public CommonResult> getMachineryPage(@Valid MesDvMachineryPageReqVO pageReqVO) {
+ PageResult pageResult = machineryService.getMachineryPage(pageReqVO);
+ return success(new PageResult<>(buildMachineryRespVOList(pageResult.getList()), pageResult.getTotal()));
+ }
+
+ @GetMapping("/export-excel")
+ @Operation(summary = "导出设备 Excel")
+ @PreAuthorize("@ss.hasPermission('mes:dv-machinery:export')")
+ @ApiAccessLog(operateType = EXPORT)
+ public void exportMachineryExcel(@Valid MesDvMachineryPageReqVO pageReqVO,
+ HttpServletResponse response) throws IOException {
+ pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+ List list = machineryService.getMachineryPage(pageReqVO).getList();
+ // 导出 Excel
+ ExcelUtils.write(response, "设备台账.xls", "数据", MesDvMachineryRespVO.class,
+ buildMachineryRespVOList(list));
+ }
+
+ @GetMapping("/simple-list")
+ @Operation(summary = "获得设备精简列表", description = "主要用于前端的下拉选项")
+ @PreAuthorize("@ss.hasPermission('mes:dv-machinery:query')")
+ public CommonResult> getMachinerySimpleList() {
+ List list = machineryService.getMachineryList();
+ return success(BeanUtils.toBean(list, MesDvMachineryRespVO.class));
+ }
+
+ @GetMapping("/get-import-template")
+ @Operation(summary = "获得设备导入模板")
+ public void importTemplate(HttpServletResponse response) throws IOException {
+ // 手动创建导出 demo
+ List list = Collections.singletonList(
+ MesDvMachineryImportExcelVO.builder().code("EQ-001").name("示例设备")
+ .brand("示例品牌").spec("型号A").machineryTypeCode("MT-001")
+ .workshopCode("WS-001").status(0).build()
+ );
+ // 输出
+ ExcelUtils.write(response, "设备导入模板.xls", "设备列表", MesDvMachineryImportExcelVO.class, list);
+ }
+
+ @PostMapping("/import")
+ @Operation(summary = "导入设备")
+ @Parameters({
+ @Parameter(name = "file", description = "Excel 文件", required = true),
+ @Parameter(name = "updateSupport", description = "是否支持更新,默认为 false", example = "true")
+ })
+ @PreAuthorize("@ss.hasPermission('mes:dv-machinery:import')")
+ public CommonResult importExcel(@RequestParam("file") MultipartFile file,
+ @RequestParam(value = "updateSupport", required = false,
+ defaultValue = "false") Boolean updateSupport) throws Exception {
+ List list = ExcelUtils.read(file, MesDvMachineryImportExcelVO.class);
+ return success(machineryService.importMachineryList(list, updateSupport));
+ }
+
+ // ==================== 拼接 VO ====================
+
+ private List buildMachineryRespVOList(List list) {
+ if (CollUtil.isEmpty(list)) {
+ return Collections.emptyList();
+ }
+ // 1. 批量获取设备类型和车间信息
+ Map machineryTypeMap = machineryTypeService.getMachineryTypeMap(
+ convertSet(list, MesDvMachineryDO::getMachineryTypeId));
+ Map workshopMap = workshopService.getWorkshopMap(
+ convertSet(list, MesDvMachineryDO::getWorkshopId));
+ // 2. 拼接 VO
+ return BeanUtils.toBean(list, MesDvMachineryRespVO.class, vo -> {
+ MapUtils.findAndThen(machineryTypeMap, vo.getMachineryTypeId(),
+ machineryType -> vo.setMachineryTypeName(machineryType.getName()));
+ MapUtils.findAndThen(workshopMap, vo.getWorkshopId(),
+ workshop -> vo.setWorkshopName(workshop.getName()));
+ });
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/MesDvMachineryTypeController.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/MesDvMachineryTypeController.java
new file mode 100644
index 000000000..e534d76a9
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/MesDvMachineryTypeController.java
@@ -0,0 +1,85 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.machinery;
+
+import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.type.MesDvMachineryTypeListReqVO;
+import cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.type.MesDvMachineryTypeRespVO;
+import cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.type.MesDvMachineryTypeSaveReqVO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.dv.machinery.MesDvMachineryTypeDO;
+import cn.iocoder.yudao.module.mes.service.dv.machinery.MesDvMachineryTypeService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import jakarta.validation.Valid;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
+
+@Tag(name = "管理后台 - MES 设备类型")
+@RestController
+@RequestMapping("/mes/dv/machinery-type")
+@Validated
+public class MesDvMachineryTypeController {
+
+ @Resource
+ private MesDvMachineryTypeService machineryTypeService;
+
+ @PostMapping("/create")
+ @Operation(summary = "创建设备类型")
+ @PreAuthorize("@ss.hasPermission('mes:dv-machinery-type:create')")
+ public CommonResult createMachineryType(@Valid @RequestBody MesDvMachineryTypeSaveReqVO createReqVO) {
+ return success(machineryTypeService.createMachineryType(createReqVO));
+ }
+
+ @PutMapping("/update")
+ @Operation(summary = "更新设备类型")
+ @PreAuthorize("@ss.hasPermission('mes:dv-machinery-type:update')")
+ public CommonResult updateMachineryType(@Valid @RequestBody MesDvMachineryTypeSaveReqVO updateReqVO) {
+ machineryTypeService.updateMachineryType(updateReqVO);
+ return success(true);
+ }
+
+ @DeleteMapping("/delete")
+ @Operation(summary = "删除设备类型")
+ @Parameter(name = "id", description = "编号", required = true)
+ @PreAuthorize("@ss.hasPermission('mes:dv-machinery-type:delete')")
+ public CommonResult deleteMachineryType(@RequestParam("id") Long id) {
+ machineryTypeService.deleteMachineryType(id);
+ return success(true);
+ }
+
+ @GetMapping("/get")
+ @Operation(summary = "获得设备类型")
+ @Parameter(name = "id", description = "编号", required = true, example = "1024")
+ @PreAuthorize("@ss.hasPermission('mes:dv-machinery-type:query')")
+ public CommonResult getMachineryType(@RequestParam("id") Long id) {
+ MesDvMachineryTypeDO machineryType = machineryTypeService.getMachineryType(id);
+ return success(BeanUtils.toBean(machineryType, MesDvMachineryTypeRespVO.class));
+ }
+
+ @GetMapping("/list")
+ @Operation(summary = "获得设备类型列表")
+ @PreAuthorize("@ss.hasPermission('mes:dv-machinery-type:query')")
+ public CommonResult> getMachineryTypeList(@Valid MesDvMachineryTypeListReqVO listReqVO) {
+ List list = machineryTypeService.getMachineryTypeList(listReqVO);
+ return success(BeanUtils.toBean(list, MesDvMachineryTypeRespVO.class));
+ }
+
+ @GetMapping("/simple-list")
+ @Operation(summary = "获得设备类型精简列表", description = "只包含被开启的类型,主要用于前端的下拉选项")
+ public CommonResult> getMachineryTypeSimpleList() {
+ List list = machineryTypeService.getMachineryTypeList(
+ new MesDvMachineryTypeListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus()));
+ return success(convertList(list, machineryType -> new MesDvMachineryTypeRespVO()
+ .setId(machineryType.getId()).setName(machineryType.getName()).setParentId(machineryType.getParentId())
+ .setCode(machineryType.getCode()).setRemark(machineryType.getRemark())));
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/MesDvMachineryImportExcelVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/MesDvMachineryImportExcelVO.java
new file mode 100644
index 000000000..64f8d824c
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/MesDvMachineryImportExcelVO.java
@@ -0,0 +1,46 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo;
+
+import cn.idev.excel.annotation.ExcelProperty;
+import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
+import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
+import cn.iocoder.yudao.module.mes.enums.DictTypeConstants;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 设备台账 Excel 导入 VO
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class MesDvMachineryImportExcelVO {
+
+ @ExcelProperty("设备编码")
+ private String code;
+
+ @ExcelProperty("设备名称")
+ private String name;
+
+ @ExcelProperty("品牌")
+ private String brand;
+
+ @ExcelProperty("规格型号")
+ private String spec;
+
+ @ExcelProperty("设备类型编码")
+ private String machineryTypeCode;
+
+ @ExcelProperty("所属车间编码")
+ private String workshopCode;
+
+ @ExcelProperty(value = "设备状态", converter = DictConvert.class)
+ @DictFormat(DictTypeConstants.MES_DV_MACHINERY_STATUS)
+ private Integer status;
+
+ @ExcelProperty("备注")
+ private String remark;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/MesDvMachineryImportRespVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/MesDvMachineryImportRespVO.java
new file mode 100644
index 000000000..aef4a69e0
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/MesDvMachineryImportRespVO.java
@@ -0,0 +1,24 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Builder;
+import lombok.Data;
+
+import java.util.List;
+import java.util.Map;
+
+@Schema(description = "管理后台 - MES 设备台账导入 Response VO")
+@Data
+@Builder
+public class MesDvMachineryImportRespVO {
+
+ @Schema(description = "创建成功的设备编码数组", requiredMode = Schema.RequiredMode.REQUIRED)
+ private List createCodes;
+
+ @Schema(description = "更新成功的设备编码数组", requiredMode = Schema.RequiredMode.REQUIRED)
+ private List updateCodes;
+
+ @Schema(description = "导入失败的设备集合,key 为设备编码,value 为失败原因", requiredMode = Schema.RequiredMode.REQUIRED)
+ private Map failureCodes;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/MesDvMachineryPageReqVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/MesDvMachineryPageReqVO.java
new file mode 100644
index 000000000..aefad442e
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/MesDvMachineryPageReqVO.java
@@ -0,0 +1,38 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.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 java.util.Set;
+
+@Schema(description = "管理后台 - MES 设备台账分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class MesDvMachineryPageReqVO extends PageParam {
+
+ @Schema(description = "设备编码", example = "EQ-001")
+ private String code;
+
+ @Schema(description = "设备名称", example = "CNC 加工中心")
+ private String name;
+
+ @Schema(description = "品牌", example = "西门子")
+ private String brand;
+
+ @Schema(description = "设备类型编号", example = "100")
+ private Long machineryTypeId;
+
+ @Schema(description = "设备类型编号列表(含子类型,由后端自动填充)", hidden = true)
+ private Set machineryTypeIds;
+
+ @Schema(description = "所属车间编号", example = "200")
+ private Long workshopId;
+
+ @Schema(description = "设备状态", example = "1")
+ private Integer status;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/MesDvMachineryRespVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/MesDvMachineryRespVO.java
new file mode 100644
index 000000000..5e29fa881
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/MesDvMachineryRespVO.java
@@ -0,0 +1,73 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo;
+
+import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
+import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
+import cn.iocoder.yudao.module.mes.enums.DictTypeConstants;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - MES 设备台账 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class MesDvMachineryRespVO {
+
+ @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+ @ExcelProperty("编号")
+ private Long id;
+
+ @Schema(description = "设备编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "EQ-001")
+ @ExcelProperty("设备编码")
+ private String code;
+
+ @Schema(description = "设备名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "CNC 加工中心")
+ @ExcelProperty("设备名称")
+ private String name;
+
+ @Schema(description = "品牌", example = "西门子")
+ @ExcelProperty("品牌")
+ private String brand;
+
+ @Schema(description = "规格型号", example = "S7-300")
+ @ExcelProperty("规格型号")
+ private String spec;
+
+ @Schema(description = "设备类型编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
+ private Long machineryTypeId;
+
+ @Schema(description = "设备类型名称", example = "数控机床")
+ @ExcelProperty("设备类型")
+ private String machineryTypeName;
+
+ @Schema(description = "所属车间编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "200")
+ private Long workshopId;
+
+ @Schema(description = "所属车间名称", example = "一号车间")
+ @ExcelProperty("所属车间")
+ private String workshopName;
+
+ @Schema(description = "设备状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @ExcelProperty(value = "设备状态", converter = DictConvert.class)
+ @DictFormat(DictTypeConstants.MES_DV_MACHINERY_STATUS)
+ private Integer status;
+
+ @Schema(description = "最近保养时间")
+ @ExcelProperty("最近保养时间")
+ private LocalDateTime lastMaintenTime;
+
+ @Schema(description = "最近点检时间")
+ @ExcelProperty("最近点检时间")
+ private LocalDateTime lastCheckTime;
+
+ @Schema(description = "备注", example = "备注")
+ @ExcelProperty("备注")
+ private String remark;
+
+ @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+ @ExcelProperty("创建时间")
+ private LocalDateTime createTime;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/MesDvMachinerySaveReqVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/MesDvMachinerySaveReqVO.java
new file mode 100644
index 000000000..9ff0c5d84
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/MesDvMachinerySaveReqVO.java
@@ -0,0 +1,52 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - MES 设备台账新增/修改 Request VO")
+@Data
+public class MesDvMachinerySaveReqVO {
+
+ @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+ private Long id;
+
+ @Schema(description = "设备编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "EQ-001")
+ @NotEmpty(message = "设备编码不能为空")
+ private String code;
+
+ @Schema(description = "设备名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "CNC 加工中心")
+ @NotEmpty(message = "设备名称不能为空")
+ private String name;
+
+ @Schema(description = "品牌", example = "西门子")
+ private String brand;
+
+ @Schema(description = "规格型号", example = "S7-300")
+ private String spec;
+
+ @Schema(description = "设备类型编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
+ @NotNull(message = "设备类型不能为空")
+ private Long machineryTypeId;
+
+ @Schema(description = "所属车间编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "200")
+ @NotNull(message = "所属车间不能为空")
+ private Long workshopId;
+
+ @Schema(description = "设备状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @NotNull(message = "设备状态不能为空")
+ private Integer status;
+
+ @Schema(description = "最近保养时间")
+ private LocalDateTime lastMaintenTime;
+
+ @Schema(description = "最近点检时间")
+ private LocalDateTime lastCheckTime;
+
+ @Schema(description = "备注", example = "备注")
+ private String remark;
+
+ }
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/type/MesDvMachineryTypeListReqVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/type/MesDvMachineryTypeListReqVO.java
new file mode 100644
index 000000000..47c530dfd
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/type/MesDvMachineryTypeListReqVO.java
@@ -0,0 +1,18 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.type;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+@Schema(description = "管理后台 - MES 设备类型列表 Request VO")
+@Data
+@Accessors(chain = true)
+public class MesDvMachineryTypeListReqVO {
+
+ @Schema(description = "类型名称", example = "数控机床")
+ private String name;
+
+ @Schema(description = "状态", example = "0")
+ private Integer status;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/type/MesDvMachineryTypeRespVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/type/MesDvMachineryTypeRespVO.java
new file mode 100644
index 000000000..80859d859
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/type/MesDvMachineryTypeRespVO.java
@@ -0,0 +1,46 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.type;
+
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - MES 设备类型 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class MesDvMachineryTypeRespVO {
+
+ @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+ @ExcelProperty("编号")
+ private Long id;
+
+ @Schema(description = "类型编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "MT-001")
+ @ExcelProperty("类型编码")
+ private String code;
+
+ @Schema(description = "类型名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "数控机床")
+ @ExcelProperty("类型名称")
+ private String name;
+
+ @Schema(description = "父类型编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
+ private Long parentId;
+
+ @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
+ @ExcelProperty("状态")
+ private Integer status;
+
+ @Schema(description = "显示排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
+ @ExcelProperty("显示排序")
+ private Integer sort;
+
+ @Schema(description = "备注", example = "备注")
+ @ExcelProperty("备注")
+ private String remark;
+
+ @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+ @ExcelProperty("创建时间")
+ private LocalDateTime createTime;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/type/MesDvMachineryTypeSaveReqVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/type/MesDvMachineryTypeSaveReqVO.java
new file mode 100644
index 000000000..1a0f1edf3
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/type/MesDvMachineryTypeSaveReqVO.java
@@ -0,0 +1,38 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.type;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+@Schema(description = "管理后台 - MES 设备类型新增/修改 Request VO")
+@Data
+public class MesDvMachineryTypeSaveReqVO {
+
+ @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+ private Long id;
+
+ @Schema(description = "类型编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "MT-001")
+ @NotEmpty(message = "类型编码不能为空")
+ private String code;
+
+ @Schema(description = "类型名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "数控机床")
+ @NotEmpty(message = "类型名称不能为空")
+ private String name;
+
+ @Schema(description = "父类型编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
+ @NotNull(message = "父类型编号不能为空")
+ private Long parentId;
+
+ @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
+ @NotNull(message = "状态不能为空")
+ private Integer status;
+
+ @Schema(description = "显示排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
+ @NotNull(message = "显示排序不能为空")
+ private Integer sort;
+
+ @Schema(description = "备注", example = "备注")
+ private String remark;
+
+ }
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/maintenrecord/MesDvMaintenRecordController.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/maintenrecord/MesDvMaintenRecordController.java
new file mode 100644
index 000000000..5a9400c87
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/maintenrecord/MesDvMaintenRecordController.java
@@ -0,0 +1,155 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.maintenrecord;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+import cn.iocoder.yudao.module.mes.controller.admin.dv.maintenrecord.vo.MesDvMaintenRecordPageReqVO;
+import cn.iocoder.yudao.module.mes.controller.admin.dv.maintenrecord.vo.MesDvMaintenRecordRespVO;
+import cn.iocoder.yudao.module.mes.controller.admin.dv.maintenrecord.vo.MesDvMaintenRecordSaveReqVO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.dv.checkplan.MesDvCheckPlanDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.dv.machinery.MesDvMachineryDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.dv.maintenrecord.MesDvMaintenRecordDO;
+import cn.iocoder.yudao.module.mes.service.dv.checkplan.MesDvCheckPlanService;
+import cn.iocoder.yudao.module.mes.service.dv.machinery.MesDvMachineryService;
+import cn.iocoder.yudao.module.mes.service.dv.maintenrecord.MesDvMaintenRecordService;
+import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
+import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.Valid;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
+
+@Tag(name = "管理后台 - MES 设备保养记录")
+@RestController
+@RequestMapping("/mes/dv/mainten-record")
+@Validated
+public class MesDvMaintenRecordController {
+
+ @Resource
+ private MesDvMaintenRecordService maintenRecordService;
+
+ @Resource
+ private MesDvCheckPlanService checkPlanService;
+
+ @Resource
+ private MesDvMachineryService machineryService;
+
+ @Resource
+ private AdminUserApi adminUserApi;
+
+ @PostMapping("/create")
+ @Operation(summary = "创建设备保养记录")
+ @PreAuthorize("@ss.hasPermission('mes:dv-mainten-record:create')")
+ public CommonResult createMaintenRecord(@Valid @RequestBody MesDvMaintenRecordSaveReqVO createReqVO) {
+ return success(maintenRecordService.createMaintenRecord(createReqVO));
+ }
+
+ @PutMapping("/update")
+ @Operation(summary = "更新设备保养记录")
+ @PreAuthorize("@ss.hasPermission('mes:dv-mainten-record:update')")
+ public CommonResult updateMaintenRecord(@Valid @RequestBody MesDvMaintenRecordSaveReqVO updateReqVO) {
+ maintenRecordService.updateMaintenRecord(updateReqVO);
+ return success(true);
+ }
+
+ @DeleteMapping("/delete")
+ @Operation(summary = "删除设备保养记录")
+ @Parameter(name = "id", description = "编号", required = true)
+ @PreAuthorize("@ss.hasPermission('mes:dv-mainten-record:delete')")
+ public CommonResult deleteMaintenRecord(@RequestParam("id") Long id) {
+ maintenRecordService.deleteMaintenRecord(id);
+ return success(true);
+ }
+
+ @GetMapping("/get")
+ @Operation(summary = "获得设备保养记录")
+ @Parameter(name = "id", description = "编号", required = true, example = "1024")
+ @PreAuthorize("@ss.hasPermission('mes:dv-mainten-record:query')")
+ public CommonResult getMaintenRecord(@RequestParam("id") Long id) {
+ MesDvMaintenRecordDO maintenRecord = maintenRecordService.getMaintenRecord(id);
+ if (maintenRecord == null) {
+ return success(null);
+ }
+ return success(buildMaintenRecordRespVOList(Collections.singletonList(maintenRecord)).get(0));
+ }
+
+ @GetMapping("/page")
+ @Operation(summary = "获得设备保养记录分页")
+ @PreAuthorize("@ss.hasPermission('mes:dv-mainten-record:query')")
+ public CommonResult> getMaintenRecordPage(@Valid MesDvMaintenRecordPageReqVO pageReqVO) {
+ PageResult pageResult = maintenRecordService.getMaintenRecordPage(pageReqVO);
+ return success(new PageResult<>(buildMaintenRecordRespVOList(pageResult.getList()), pageResult.getTotal()));
+ }
+
+ @GetMapping("/export-excel")
+ @Operation(summary = "导出设备保养记录 Excel")
+ @PreAuthorize("@ss.hasPermission('mes:dv-mainten-record:export')")
+ @ApiAccessLog(operateType = EXPORT)
+ public void exportMaintenRecordExcel(@Valid MesDvMaintenRecordPageReqVO pageReqVO,
+ HttpServletResponse response) throws IOException {
+ pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+ List list = maintenRecordService.getMaintenRecordPage(pageReqVO).getList();
+ // 导出 Excel
+ ExcelUtils.write(response, "设备保养记录.xls", "数据", MesDvMaintenRecordRespVO.class,
+ buildMaintenRecordRespVOList(list));
+ }
+
+ @PutMapping("/submit")
+ @Operation(summary = "提交设备保养记录(草稿→已提交)")
+ @Parameter(name = "id", description = "编号", required = true)
+ @PreAuthorize("@ss.hasPermission('mes:dv-mainten-record:update')")
+ public CommonResult submitMaintenRecord(@RequestParam("id") Long id) {
+ maintenRecordService.submitMaintenRecord(id);
+ return success(true);
+ }
+
+ // ==================== 拼接 VO ====================
+
+ private List buildMaintenRecordRespVOList(List list) {
+ if (CollUtil.isEmpty(list)) {
+ return Collections.emptyList();
+ }
+ // 1. 批量获取关联数据
+ Map planMap = checkPlanService.getCheckPlanMap(
+ convertSet(list, MesDvMaintenRecordDO::getPlanId));
+ Map machineryMap = machineryService.getMachineryMap(
+ convertSet(list, MesDvMaintenRecordDO::getMachineryId));
+ Map userMap = adminUserApi.getUserMap(
+ convertSet(list, MesDvMaintenRecordDO::getUserId));
+ // 2. 拼接 VO
+ return BeanUtils.toBean(list, MesDvMaintenRecordRespVO.class, vo -> {
+ MapUtils.findAndThen(planMap, vo.getPlanId(),
+ plan -> vo.setPlanName(plan.getName())
+ .setPlanCode(plan.getCode())
+ .setPlanStartDate(plan.getStartDate())
+ .setPlanEndDate(plan.getEndDate())
+ .setPlanCycleType(plan.getCycleType())
+ .setPlanCycleCount(plan.getCycleCount()));
+ MapUtils.findAndThen(machineryMap, vo.getMachineryId(), machinery -> vo
+ .setMachineryCode(machinery.getCode()).setMachineryName(machinery.getName())
+ .setMachineryBrand(machinery.getBrand()).setMachinerySpec(machinery.getSpec()));
+ MapUtils.findAndThen(userMap, vo.getUserId(),
+ user -> vo.setNickname(user.getNickname()));
+ });
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/maintenrecord/MesDvMaintenRecordLineController.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/maintenrecord/MesDvMaintenRecordLineController.java
new file mode 100644
index 000000000..e3616cb0b
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/maintenrecord/MesDvMaintenRecordLineController.java
@@ -0,0 +1,122 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.maintenrecord;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+import cn.iocoder.yudao.module.mes.controller.admin.dv.maintenrecord.vo.line.MesDvMaintenRecordLinePageReqVO;
+import cn.iocoder.yudao.module.mes.controller.admin.dv.maintenrecord.vo.line.MesDvMaintenRecordLineRespVO;
+import cn.iocoder.yudao.module.mes.controller.admin.dv.maintenrecord.vo.line.MesDvMaintenRecordLineSaveReqVO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.dv.maintenrecord.MesDvMaintenRecordLineDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.dv.subject.MesDvSubjectDO;
+import cn.iocoder.yudao.module.mes.service.dv.maintenrecord.MesDvMaintenRecordLineService;
+import cn.iocoder.yudao.module.mes.service.dv.subject.MesDvSubjectService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.Valid;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
+
+@Tag(name = "管理后台 - MES 设备保养记录明细")
+@RestController
+@RequestMapping("/mes/dv/mainten-record-line")
+@Validated
+public class MesDvMaintenRecordLineController {
+
+ @Resource
+ private MesDvMaintenRecordLineService maintenRecordLineService;
+
+ @Resource
+ private MesDvSubjectService subjectService;
+
+ @PostMapping("/create")
+ @Operation(summary = "创建设备保养记录明细")
+ @PreAuthorize("@ss.hasPermission('mes:dv-mainten-record:create')")
+ public CommonResult createMaintenRecordLine(@Valid @RequestBody MesDvMaintenRecordLineSaveReqVO createReqVO) {
+ return success(maintenRecordLineService.createMaintenRecordLine(createReqVO));
+ }
+
+ @PutMapping("/update")
+ @Operation(summary = "更新设备保养记录明细")
+ @PreAuthorize("@ss.hasPermission('mes:dv-mainten-record:update')")
+ public CommonResult updateMaintenRecordLine(@Valid @RequestBody MesDvMaintenRecordLineSaveReqVO updateReqVO) {
+ maintenRecordLineService.updateMaintenRecordLine(updateReqVO);
+ return success(true);
+ }
+
+ @DeleteMapping("/delete")
+ @Operation(summary = "删除设备保养记录明细")
+ @Parameter(name = "id", description = "编号", required = true)
+ @PreAuthorize("@ss.hasPermission('mes:dv-mainten-record:delete')")
+ public CommonResult deleteMaintenRecordLine(@RequestParam("id") Long id) {
+ maintenRecordLineService.deleteMaintenRecordLine(id);
+ return success(true);
+ }
+
+ @GetMapping("/get")
+ @Operation(summary = "获得设备保养记录明细")
+ @Parameter(name = "id", description = "编号", required = true, example = "1024")
+ @PreAuthorize("@ss.hasPermission('mes:dv-mainten-record:query')")
+ public CommonResult getMaintenRecordLine(@RequestParam("id") Long id) {
+ MesDvMaintenRecordLineDO maintenRecordLine = maintenRecordLineService.getMaintenRecordLine(id);
+ if (maintenRecordLine == null) {
+ return success(null);
+ }
+ return success(buildMaintenRecordLineRespVOList(Collections.singletonList(maintenRecordLine)).get(0));
+ }
+
+ @GetMapping("/page")
+ @Operation(summary = "获得设备保养记录明细分页")
+ @PreAuthorize("@ss.hasPermission('mes:dv-mainten-record:query')")
+ public CommonResult> getMaintenRecordLinePage(@Valid MesDvMaintenRecordLinePageReqVO pageReqVO) {
+ PageResult pageResult = maintenRecordLineService.getMaintenRecordLinePage(pageReqVO);
+ return success(new PageResult<>(buildMaintenRecordLineRespVOList(pageResult.getList()), pageResult.getTotal()));
+ }
+
+ @GetMapping("/export-excel")
+ @Operation(summary = "导出设备保养记录明细 Excel")
+ @PreAuthorize("@ss.hasPermission('mes:dv-mainten-record:export')")
+ @ApiAccessLog(operateType = EXPORT)
+ public void exportMaintenRecordLineExcel(@Valid MesDvMaintenRecordLinePageReqVO pageReqVO,
+ HttpServletResponse response) throws IOException {
+ pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+ List list = maintenRecordLineService.getMaintenRecordLinePage(pageReqVO).getList();
+ // 导出 Excel
+ ExcelUtils.write(response, "设备保养记录明细.xls", "数据", MesDvMaintenRecordLineRespVO.class,
+ buildMaintenRecordLineRespVOList(list));
+ }
+
+ // ==================== 拼接 VO ====================
+
+ private List buildMaintenRecordLineRespVOList(List list) {
+ if (CollUtil.isEmpty(list)) {
+ return Collections.emptyList();
+ }
+ // 1. 批量获取关联数据
+ Map subjectMap = subjectService.getSubjectMap(
+ convertSet(list, MesDvMaintenRecordLineDO::getSubjectId));
+ // 2. 拼接 VO
+ return BeanUtils.toBean(list, MesDvMaintenRecordLineRespVO.class, vo ->
+ MapUtils.findAndThen(subjectMap, vo.getSubjectId(), subject -> vo
+ .setSubjectName(subject.getName()).setSubjectContent(subject.getContent())
+ .setSubjectStandard(subject.getStandard())));
+ }
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/maintenrecord/vo/MesDvMaintenRecordPageReqVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/maintenrecord/vo/MesDvMaintenRecordPageReqVO.java
new file mode 100644
index 000000000..1e75613f6
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/maintenrecord/vo/MesDvMaintenRecordPageReqVO.java
@@ -0,0 +1,33 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.maintenrecord.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 = "管理后台 - MES 设备保养记录分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class MesDvMaintenRecordPageReqVO extends PageParam {
+
+ @Schema(description = "保养计划编号", example = "1")
+ private Long planId;
+
+ @Schema(description = "设备编号", example = "1")
+ private Long machineryId;
+
+ @Schema(description = "保养人编号", example = "1")
+ private Long userId;
+
+ @Schema(description = "保养时间")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private LocalDateTime[] maintenTime;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/maintenrecord/vo/MesDvMaintenRecordRespVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/maintenrecord/vo/MesDvMaintenRecordRespVO.java
new file mode 100644
index 000000000..7b8d96266
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/maintenrecord/vo/MesDvMaintenRecordRespVO.java
@@ -0,0 +1,93 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.maintenrecord.vo;
+
+import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
+import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
+import cn.iocoder.yudao.module.mes.enums.DictTypeConstants;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - MES 设备保养记录 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class MesDvMaintenRecordRespVO {
+
+ @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+ @ExcelProperty("编号")
+ private Long id;
+
+ @Schema(description = "计划编号", example = "1")
+ private Long planId;
+
+ @Schema(description = "计划名称", example = "保养计划1")
+ @ExcelProperty("计划名称")
+ private String planName;
+
+ @Schema(description = "计划编码", example = "P001")
+ @ExcelProperty("计划编码")
+ private String planCode;
+
+ @Schema(description = "开始时间")
+ @ExcelProperty("开始时间")
+ private LocalDateTime planStartDate;
+
+ @Schema(description = "结束日期")
+ @ExcelProperty("结束日期")
+ private LocalDateTime planEndDate;
+
+ @Schema(description = "频率类型", example = "1")
+ @ExcelProperty(value = "频率类型", converter = DictConvert.class)
+ @DictFormat(DictTypeConstants.MES_DV_CYCLE_TYPE)
+ private Integer planCycleType;
+
+ @Schema(description = "频率数量", example = "5")
+ @ExcelProperty(value = "频率数量")
+ private Integer planCycleCount;
+
+ @Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ private Long machineryId;
+
+ @Schema(description = "设备编码", example = "M001")
+ @ExcelProperty("设备编码")
+ private String machineryCode;
+
+ @Schema(description = "设备名称", example = "机床A")
+ @ExcelProperty("设备名称")
+ private String machineryName;
+
+ @Schema(description = "品牌", example = "西门子")
+ @ExcelProperty("品牌")
+ private String machineryBrand;
+
+ @Schema(description = "规格型号", example = "X-100")
+ @ExcelProperty("规格型号")
+ private String machinerySpec;
+
+ @Schema(description = "保养时间", requiredMode = Schema.RequiredMode.REQUIRED)
+ @ExcelProperty("保养时间")
+ private LocalDateTime maintenTime;
+
+ @Schema(description = "用户编号", example = "1")
+ private Long userId;
+
+ @Schema(description = "保养人名称", example = "张三")
+ @ExcelProperty("保养人")
+ private String nickname;
+
+ @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
+ @ExcelProperty(value = "状态", converter = DictConvert.class)
+ @DictFormat(DictTypeConstants.MES_MAINTEN_RECORD_STATUS)
+ private Integer status;
+
+ @Schema(description = "备注", example = "测试备注")
+ @ExcelProperty("备注")
+ private String remark;
+
+ @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+ @ExcelProperty("创建时间")
+ private LocalDateTime createTime;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/maintenrecord/vo/MesDvMaintenRecordSaveReqVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/maintenrecord/vo/MesDvMaintenRecordSaveReqVO.java
new file mode 100644
index 000000000..2e44d4167
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/maintenrecord/vo/MesDvMaintenRecordSaveReqVO.java
@@ -0,0 +1,33 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.maintenrecord.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import jakarta.validation.constraints.NotNull;
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - MES 设备保养记录新增/修改 Request VO")
+@Data
+public class MesDvMaintenRecordSaveReqVO {
+
+ @Schema(description = "编号", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "1024")
+ private Long id;
+
+ @Schema(description = "计划编号", example = "1")
+ private Long planId;
+
+ @Schema(description = "设备编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @NotNull(message = "设备不能为空")
+ private Long machineryId;
+
+ @Schema(description = "保养时间", requiredMode = Schema.RequiredMode.REQUIRED)
+ @NotNull(message = "保养时间不能为空")
+ private LocalDateTime maintenTime;
+
+ @Schema(description = "用户编号", example = "1")
+ private Long userId;
+
+ @Schema(description = "备注", example = "测试备注")
+ private String remark;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/maintenrecord/vo/line/MesDvMaintenRecordLinePageReqVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/maintenrecord/vo/line/MesDvMaintenRecordLinePageReqVO.java
new file mode 100644
index 000000000..047fb32e4
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/maintenrecord/vo/line/MesDvMaintenRecordLinePageReqVO.java
@@ -0,0 +1,18 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.maintenrecord.vo.line;
+
+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;
+
+@Schema(description = "管理后台 - MES 设备保养记录明细分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class MesDvMaintenRecordLinePageReqVO extends PageParam {
+
+ @Schema(description = "保养记录ID", example = "1")
+ private Long recordId;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/maintenrecord/vo/line/MesDvMaintenRecordLineRespVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/maintenrecord/vo/line/MesDvMaintenRecordLineRespVO.java
new file mode 100644
index 000000000..adea3c993
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/maintenrecord/vo/line/MesDvMaintenRecordLineRespVO.java
@@ -0,0 +1,57 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.maintenrecord.vo.line;
+
+import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
+import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
+import cn.iocoder.yudao.module.mes.enums.DictTypeConstants;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - MES 设备保养记录明细 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class MesDvMaintenRecordLineRespVO {
+
+ @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+ @ExcelProperty("编号")
+ private Long id;
+
+ @Schema(description = "保养记录编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ private Long recordId;
+
+ @Schema(description = "项目编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ private Long subjectId;
+
+ @Schema(description = "项目名称", example = "检查机油")
+ @ExcelProperty("项目名称")
+ private String subjectName;
+
+ @Schema(description = "项目内容", example = "检查机油是否充足")
+ @ExcelProperty("项目内容")
+ private String subjectContent;
+
+ @Schema(description = "项目标准", example = "无漏油")
+ @ExcelProperty("标准")
+ private String subjectStandard;
+
+ @Schema(description = "保养结果", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @ExcelProperty(value = "保养结果", converter = DictConvert.class)
+ @DictFormat(DictTypeConstants.MES_MAINTEN_STATUS)
+ private Integer status;
+
+ @Schema(description = "异常描述", example = "发现损坏")
+ @ExcelProperty("异常描述")
+ private String result;
+
+ @Schema(description = "备注", example = "测试备注")
+ @ExcelProperty("备注")
+ private String remark;
+
+ @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+ @ExcelProperty("创建时间")
+ private LocalDateTime createTime;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/maintenrecord/vo/line/MesDvMaintenRecordLineSaveReqVO.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/maintenrecord/vo/line/MesDvMaintenRecordLineSaveReqVO.java
new file mode 100644
index 000000000..b6913060c
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/maintenrecord/vo/line/MesDvMaintenRecordLineSaveReqVO.java
@@ -0,0 +1,33 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.maintenrecord.vo.line;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import jakarta.validation.constraints.NotNull;
+
+@Schema(description = "管理后台 - MES 设备保养记录明细新增/修改 Request VO")
+@Data
+public class MesDvMaintenRecordLineSaveReqVO {
+
+ @Schema(description = "编号", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "1024")
+ private Long id;
+
+ @Schema(description = "保养记录编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @NotNull(message = "保养记录不能为空")
+ private Long recordId;
+
+ @Schema(description = "项目编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @NotNull(message = "项目不能为空")
+ private Long subjectId;
+
+ @Schema(description = "保养结果", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @NotNull(message = "保养结果不能为空")
+ private Integer status;
+
+ @Schema(description = "异常描述", example = "发现损坏")
+ private String result;
+
+ @Schema(description = "备注", example = "测试备注")
+ private String remark;
+
+}
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/package-info.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/package-info.java
new file mode 100644
index 000000000..8cdd365a1
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * MES 设备管理(Device / Equipment Management):设备类型、设备台账、点检计划与记录、保养记录、维修工单等设备全生命周期管理
+ */
+package cn.iocoder.yudao.module.mes.controller.admin.dv;
diff --git a/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/repair/MesDvRepairController.java b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/repair/MesDvRepairController.java
new file mode 100644
index 000000000..7b958cef8
--- /dev/null
+++ b/yudao-module-mes/yudao-module-mes-server/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/repair/MesDvRepairController.java
@@ -0,0 +1,171 @@
+package cn.iocoder.yudao.module.mes.controller.admin.dv.repair;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+import cn.iocoder.yudao.module.mes.controller.admin.dv.repair.vo.MesDvRepairPageReqVO;
+import cn.iocoder.yudao.module.mes.controller.admin.dv.repair.vo.MesDvRepairRespVO;
+import cn.iocoder.yudao.module.mes.controller.admin.dv.repair.vo.MesDvRepairSaveReqVO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.dv.machinery.MesDvMachineryDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.dv.repair.MesDvRepairDO;
+import cn.iocoder.yudao.module.mes.service.dv.machinery.MesDvMachineryService;
+import cn.iocoder.yudao.module.mes.service.dv.repair.MesDvRepairService;
+import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
+import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.Parameters;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.Valid;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Stream;
+
+import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSetByFlatMap;
+import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
+
+@Tag(name = "管理后台 - MES 维修工单")
+@RestController
+@RequestMapping("/mes/dv/repair")
+@Validated
+public class MesDvRepairController {
+
+ @Resource
+ private MesDvRepairService repairService;
+
+ @Resource
+ private MesDvMachineryService machineryService;
+
+ @Resource
+ private AdminUserApi adminUserApi;
+
+ @PostMapping("/create")
+ @Operation(summary = "创建维修工单")
+ @PreAuthorize("@ss.hasPermission('mes:dv-repair:create')")
+ public CommonResult createRepair(@Valid @RequestBody MesDvRepairSaveReqVO createReqVO) {
+ return success(repairService.createRepair(createReqVO));
+ }
+
+ @PutMapping("/update")
+ @Operation(summary = "更新维修工单")
+ @PreAuthorize("@ss.hasPermission('mes:dv-repair:update')")
+ public CommonResult updateRepair(@Valid @RequestBody MesDvRepairSaveReqVO updateReqVO) {
+ repairService.updateRepair(updateReqVO);
+ return success(true);
+ }
+
+ @DeleteMapping("/delete")
+ @Operation(summary = "删除维修工单")
+ @Parameter(name = "id", description = "编号", required = true)
+ @PreAuthorize("@ss.hasPermission('mes:dv-repair:delete')")
+ public CommonResult deleteRepair(@RequestParam("id") Long id) {
+ repairService.deleteRepair(id);
+ return success(true);
+ }
+
+ @GetMapping("/get")
+ @Operation(summary = "获得维修工单")
+ @Parameter(name = "id", description = "编号", required = true, example = "1024")
+ @PreAuthorize("@ss.hasPermission('mes:dv-repair:query')")
+ public CommonResult getRepair(@RequestParam("id") Long id) {
+ MesDvRepairDO repair = repairService.getRepair(id);
+ if (repair == null) {
+ return success(null);
+ }
+ return success(buildRepairRespVOList(Collections.singletonList(repair)).get(0));
+ }
+
+ @GetMapping("/page")
+ @Operation(summary = "获得维修工单分页")
+ @PreAuthorize("@ss.hasPermission('mes:dv-repair:query')")
+ public CommonResult> getRepairPage(@Valid MesDvRepairPageReqVO pageReqVO) {
+ PageResult pageResult = repairService.getRepairPage(pageReqVO);
+ return success(new PageResult<>(buildRepairRespVOList(pageResult.getList()), pageResult.getTotal()));
+ }
+
+ @GetMapping("/export-excel")
+ @Operation(summary = "导出维修工单 Excel")
+ @PreAuthorize("@ss.hasPermission('mes:dv-repair:export')")
+ @ApiAccessLog(operateType = EXPORT)
+ public void exportRepairExcel(@Valid MesDvRepairPageReqVO pageReqVO,
+ HttpServletResponse response) throws IOException {
+ pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+ List list = repairService.getRepairPage(pageReqVO).getList();
+ // 导出 Excel
+ ExcelUtils.write(response, "维修工单.xls", "数据", MesDvRepairRespVO.class,
+ buildRepairRespVOList(list));
+ }
+
+ // DONE @AI:submit=>confirm=>finish(然后里面有是 resultstatus 这样的字段【对齐实体?】)
+
+ @PutMapping("/submit")
+ @Operation(summary = "提交维修工单(草稿→维修中)")
+ @Parameter(name = "id", description = "编号", required = true)
+ @PreAuthorize("@ss.hasPermission('mes:dv-repair:update')")
+ public CommonResult submitRepair(@RequestParam("id") Long id) {
+ repairService.submitRepair(id, getLoginUserId());
+ return success(true);
+ }
+
+ @PutMapping("/confirm")
+ @Operation(summary = "确认维修完成(维修中→待验收)")
+ @PreAuthorize("@ss.hasPermission('mes:dv-repair:update')")
+ public CommonResult confirmRepair(@Valid @RequestBody cn.iocoder.yudao.module.mes.controller.admin.dv.repair.vo.MesDvRepairConfirmReqVO confirmReqVO) {
+ repairService.confirmRepair(confirmReqVO);
+ return success(true);
+ }
+
+ @PutMapping("/finish")
+ @Operation(summary = "完成验收(待验收→已确认)")
+ @Parameters({
+ @Parameter(name = "id", description = "编号", required = true),
+ @Parameter(name = "result", description = "验收结果", required = true)
+ })
+ @PreAuthorize("@ss.hasPermission('mes:dv-repair:update')")
+ public CommonResult finishRepair(@RequestParam("id") Long id,
+ @RequestParam("result") Integer result) {
+ repairService.finishRepair(id, result, getLoginUserId());
+ return success(true);
+ }
+
+ // ==================== 拼接 VO ====================
+
+ private List buildRepairRespVOList(List