diff --git a/ruoyi-modules/hwmom-wms/pom.xml b/ruoyi-modules/hwmom-wms/pom.xml
index e9c20e0..e5f5ca2 100644
--- a/ruoyi-modules/hwmom-wms/pom.xml
+++ b/ruoyi-modules/hwmom-wms/pom.xml
@@ -126,6 +126,22 @@
+
+ org.dromara
+ hwmom-api-wms
+ ${revision}
+ compile
+
+
+
+
+ org.dromara
+ ruoyi-api-job
+ 2.2.2
+ compile
+
+
+
diff --git a/ruoyi-modules/hwmom-wms/src/main/java/org/dromara/wms/controller/WmsCheckTaskController.java b/ruoyi-modules/hwmom-wms/src/main/java/org/dromara/wms/controller/WmsCheckTaskController.java
new file mode 100644
index 0000000..47f7946
--- /dev/null
+++ b/ruoyi-modules/hwmom-wms/src/main/java/org/dromara/wms/controller/WmsCheckTaskController.java
@@ -0,0 +1,118 @@
+package org.dromara.wms.controller;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.wms.domain.bo.WmsCheckTaskBo;
+import org.dromara.wms.domain.vo.WmsCheckTaskVo;
+import org.dromara.wms.service.IWmsCheckTaskService;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 仓储盘点任务
+ * 前端访问路由地址为:/wms/wmsCheckTask
+ *
+ * @author zch
+ * @date 2025-08-20
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/wmsCheckTask")
+public class WmsCheckTaskController extends BaseController {
+
+ private final IWmsCheckTaskService wmsCheckTaskService;
+
+ /**
+ * 查询仓储盘点任务列表
+ */
+ @SaCheckPermission("wms:wmsCheckTask:list")
+ @GetMapping("/list")
+ public TableDataInfo list(WmsCheckTaskBo bo, PageQuery pageQuery) {
+ return wmsCheckTaskService.queryPageList(bo, pageQuery);
+ }
+
+ /**
+ * 导出仓储盘点任务列表
+ */
+ @SaCheckPermission("wms:wmsCheckTask:export")
+ @Log(title = "仓储盘点任务", businessType = BusinessType.EXPORT)
+ @PostMapping("/export")
+ public void export(WmsCheckTaskBo bo, HttpServletResponse response) {
+ List list = wmsCheckTaskService.queryList(bo);
+ ExcelUtil.exportExcel(list, "仓储盘点任务", WmsCheckTaskVo.class, response);
+ }
+
+ /**
+ * 获取仓储盘点任务详细信息
+ *
+ * @param taskId 主键
+ */
+ @SaCheckPermission("wms:wmsCheckTask:query")
+ @GetMapping("/{taskId}")
+ public R getInfo(@NotNull(message = "主键不能为空")
+ @PathVariable Long taskId) {
+ return R.ok(wmsCheckTaskService.queryById(taskId));
+ }
+
+ /**
+ * 新增仓储盘点任务
+ */
+ @SaCheckPermission("wms:wmsCheckTask:add")
+ @Log(title = "仓储盘点任务", businessType = BusinessType.INSERT)
+ @RepeatSubmit()
+ @PostMapping()
+ public R add(@Validated(AddGroup.class) @RequestBody WmsCheckTaskBo bo) {
+ return toAjax(wmsCheckTaskService.insertByBo(bo));
+ }
+
+ /**
+ * 修改仓储盘点任务
+ */
+ @SaCheckPermission("wms:wmsCheckTask:edit")
+ @Log(title = "仓储盘点任务", businessType = BusinessType.UPDATE)
+ @RepeatSubmit()
+ @PutMapping()
+ public R edit(@Validated(EditGroup.class) @RequestBody WmsCheckTaskBo bo) {
+ return toAjax(wmsCheckTaskService.updateByBo(bo));
+ }
+
+ /**
+ * 删除仓储盘点任务
+ *
+ * @param taskIds 主键串
+ */
+ @SaCheckPermission("wms:wmsCheckTask:remove")
+ @Log(title = "仓储盘点任务", businessType = BusinessType.DELETE)
+ @DeleteMapping("/{taskIds}")
+ public R remove(@NotEmpty(message = "主键不能为空")
+ @PathVariable Long[] taskIds) {
+ return toAjax(wmsCheckTaskService.deleteWithValidByIds(List.of(taskIds), true));
+ }
+
+
+ /**
+ * 下拉框查询仓储盘点任务列表
+ */
+
+ @GetMapping("/getWmsCheckTaskList")
+ public R> getWmsCheckTaskList(WmsCheckTaskBo bo) {
+ List list = wmsCheckTaskService.queryList(bo);
+ return R.ok(list);
+ }
+}
diff --git a/ruoyi-modules/hwmom-wms/src/main/java/org/dromara/wms/domain/WmsCheckTask.java b/ruoyi-modules/hwmom-wms/src/main/java/org/dromara/wms/domain/WmsCheckTask.java
new file mode 100644
index 0000000..a4e3354
--- /dev/null
+++ b/ruoyi-modules/hwmom-wms/src/main/java/org/dromara/wms/domain/WmsCheckTask.java
@@ -0,0 +1,99 @@
+package org.dromara.wms.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.dromara.common.tenant.core.TenantEntity;
+
+import java.io.Serial;
+import java.math.BigDecimal;
+
+/**
+ * 仓储盘点任务对象 wms_check_task
+ *
+ * @author zch
+ * @date 2025-08-20
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("wms_check_task")
+public class WmsCheckTask extends TenantEntity {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 任务主键
+ */
+ @TableId(type = IdType.ASSIGN_ID)
+ private Long taskId;
+
+ /**
+ * 任务编码
+ */
+ private String taskCode;
+
+ /**
+ * 任务名称
+ */
+ private String taskName;
+
+ /**
+ * 任务类型(0抽检,1暂停其他)
+ */
+ private String wmsCheckTaskType;
+
+ /**
+ * 物料类型
+ */
+ private Long materialTypeId;
+
+ /**
+ * 抽检率(百分比)
+ */
+ private BigDecimal checkRate;
+
+ /**
+ * 定时任务
+ */
+ private String cron;
+
+ /**
+ * 仓库主键
+ */
+ private Long warehouseId;
+
+ /**
+ * 定时任务频率选项(0月度计划,1年度计划,2其它)
+ */
+ private String wmsCheckTaskFrequency;
+
+ /**
+ * 定时任务主键
+ */
+ private Long jobId;
+
+
+ /**
+ * 执行日期 (1-31 or 'L' for last day)
+ */
+ @TableField(exist = false)
+ private String executeDay;
+
+ /**
+ * 间隔月数 (for monthly, e.g., 1 for every month, 2 for every 2 months)
+ */
+ @TableField(exist = false)
+ private Integer intervalMonths;
+
+ /**
+ * 执行月份 (1-12 for yearly)
+ */
+ @TableField(exist = false)
+ private Integer executeMonth;
+
+
+}
diff --git a/ruoyi-modules/hwmom-wms/src/main/java/org/dromara/wms/domain/bo/WmsCheckTaskBo.java b/ruoyi-modules/hwmom-wms/src/main/java/org/dromara/wms/domain/bo/WmsCheckTaskBo.java
new file mode 100644
index 0000000..4575ffb
--- /dev/null
+++ b/ruoyi-modules/hwmom-wms/src/main/java/org/dromara/wms/domain/bo/WmsCheckTaskBo.java
@@ -0,0 +1,106 @@
+package org.dromara.wms.domain.bo;
+
+import io.github.linpeilie.annotations.AutoMapper;
+import jakarta.validation.constraints.NotBlank;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.wms.domain.WmsCheckTask;
+
+import java.math.BigDecimal;
+
+/**
+ * 仓储盘点任务业务对象 wms_check_task
+ *
+ * @author zch
+ * @date 2025-08-20
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = WmsCheckTask.class, reverseConvertGenerate = false)
+public class WmsCheckTaskBo extends BaseEntity {
+
+ /**
+ * 任务主键
+ */
+ private Long taskId;
+
+ /**
+ * 任务编码
+ */
+ @NotBlank(message = "任务编码不能为空", groups = { AddGroup.class, EditGroup.class })
+ private String taskCode;
+
+ /**
+ * 任务名称
+ */
+ @NotBlank(message = "任务名称不能为空", groups = { AddGroup.class, EditGroup.class })
+ private String taskName;
+
+ /**
+ * 任务类型(0抽检,1暂停其他)
+ */
+ @NotBlank(message = "任务类型(0抽检,1暂停其他)不能为空", groups = { AddGroup.class, EditGroup.class })
+ private String wmsCheckTaskType;
+
+ /**
+ * 物料类型
+ */
+ private Long materialTypeId;
+
+ /**
+ * 抽检率(百分比)
+ */
+ private BigDecimal checkRate;
+
+ /**
+ * 定时任务
+ */
+ @NotBlank(message = "定时任务Cron表达式不能为空", groups = { AddGroup.class, EditGroup.class })
+ private String cron;
+
+ /**
+ * 仓库主键
+ */
+ private Long warehouseId;
+
+ /**
+ * 定时任务频率选项(0月度计划,1年度计划,2其它)
+ */
+ @NotBlank(message = "定时任务频率选项(0月度计划,1年度计划,2其它)不能为空", groups = { AddGroup.class, EditGroup.class })
+ private String wmsCheckTaskFrequency;
+
+ /**
+ * 执行日期 (1-31 or 'L' for last day)
+ */
+ private String executeDay;
+
+ /**
+ * 间隔月数 (用于月度,例如1表示每月,0表示每个月)
+ */
+ private Integer intervalMonths;
+
+ /**
+ * 执行月份 (1-12 for yearly)
+ */
+ private Integer executeMonth;
+
+ /**
+ * 物料类型名称
+ */
+ private String matrialTypeName;
+
+ /**
+ * 仓库编码
+ */
+ private String warehouseCode;
+
+ /**
+ * 仓库名称
+ */
+ private String warehouseName;
+
+
+}
diff --git a/ruoyi-modules/hwmom-wms/src/main/java/org/dromara/wms/domain/vo/WmsCheckTaskVo.java b/ruoyi-modules/hwmom-wms/src/main/java/org/dromara/wms/domain/vo/WmsCheckTaskVo.java
new file mode 100644
index 0000000..40e3ec3
--- /dev/null
+++ b/ruoyi-modules/hwmom-wms/src/main/java/org/dromara/wms/domain/vo/WmsCheckTaskVo.java
@@ -0,0 +1,113 @@
+package org.dromara.wms.domain.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import org.dromara.wms.domain.WmsCheckTask;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+
+
+/**
+ * 仓储盘点任务视图对象 wms_check_task
+ *
+ * @author zch
+ * @date 2025-08-20
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = WmsCheckTask.class)
+public class WmsCheckTaskVo implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 任务主键
+ */
+ @ExcelProperty(value = "任务主键")
+ private Long taskId;
+
+ /**
+ * 任务编码
+ */
+ @ExcelProperty(value = "任务编码")
+ private String taskCode;
+
+ /**
+ * 任务名称
+ */
+ @ExcelProperty(value = "任务名称")
+ private String taskName;
+
+ /**
+ * 任务类型(0抽检,1暂停其他)
+ */
+ @ExcelProperty(value = "任务类型", converter = ExcelDictConvert.class)
+ @ExcelDictFormat(dictType = "wms_check_task_type")
+ private String wmsCheckTaskType;
+
+ /**
+ * 物料类型
+ */
+ @ExcelProperty(value = "物料类型")
+ private Long materialTypeId;
+
+ /**
+ * 抽检率(百分比)
+ */
+ @ExcelProperty(value = "抽检率", converter = ExcelDictConvert.class)
+ @ExcelDictFormat(readConverterExp = "百=分比")
+ private BigDecimal checkRate;
+
+ /**
+ * 定时任务
+ */
+ @ExcelProperty(value = "定时任务")
+ private String cron;
+
+ /**
+ * 仓库主键
+ */
+ @ExcelProperty(value = "仓库主键")
+ private Long warehouseId;
+
+ /**
+ * 定时任务频率选项(0月度计划,1年度计划,2其它)
+ */
+ @ExcelProperty(value = "定时任务频率选项(0月度计划,1年度计划,2其它)", converter = ExcelDictConvert.class)
+ @ExcelDictFormat(dictType = "wms_check_task_frequency")
+ private String wmsCheckTaskFrequency;
+
+
+ /**
+ * 定时任务主键
+ */
+ private Long jobId;
+
+
+ /**
+ * 物料类型名称
+ */
+ private String matrialTypeName;
+
+ /**
+ * 仓库编码
+ */
+ private String warehouseCode;
+
+ /**
+ * 仓库名称
+ */
+ private String warehouseName;
+
+
+
+
+}
diff --git a/ruoyi-modules/hwmom-wms/src/main/java/org/dromara/wms/mapper/WmsCheckTaskMapper.java b/ruoyi-modules/hwmom-wms/src/main/java/org/dromara/wms/mapper/WmsCheckTaskMapper.java
new file mode 100644
index 0000000..8ff0609
--- /dev/null
+++ b/ruoyi-modules/hwmom-wms/src/main/java/org/dromara/wms/mapper/WmsCheckTaskMapper.java
@@ -0,0 +1,15 @@
+package org.dromara.wms.mapper;
+
+import org.dromara.wms.domain.WmsCheckTask;
+import org.dromara.wms.domain.vo.WmsCheckTaskVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 仓储盘点任务Mapper接口
+ *
+ * @author zch
+ * @date 2025-08-20
+ */
+public interface WmsCheckTaskMapper extends BaseMapperPlus {
+
+}
diff --git a/ruoyi-modules/hwmom-wms/src/main/java/org/dromara/wms/service/impl/WmsCheckTaskServiceImpl.java b/ruoyi-modules/hwmom-wms/src/main/java/org/dromara/wms/service/impl/WmsCheckTaskServiceImpl.java
new file mode 100644
index 0000000..9761a2c
--- /dev/null
+++ b/ruoyi-modules/hwmom-wms/src/main/java/org/dromara/wms/service/impl/WmsCheckTaskServiceImpl.java
@@ -0,0 +1,275 @@
+package org.dromara.wms.service.impl;
+
+import com.aizuda.snailjob.client.job.core.enums.AllocationAlgorithmEnum;
+import com.aizuda.snailjob.client.job.core.enums.TriggerTypeEnum;
+import com.aizuda.snailjob.common.core.enums.JobBlockStrategyEnum;
+import com.aizuda.snailjob.common.core.util.CronExpression;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.github.yulichang.toolkit.JoinWrappers;
+import com.github.yulichang.wrapper.MPJLambdaWrapper;
+import io.seata.spring.annotation.GlobalTransactional;
+import lombok.RequiredArgsConstructor;
+import org.apache.dubbo.config.annotation.DubboReference;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.job.api.RemoteJobService;
+import org.dromara.job.api.model.DmsJobEntity;
+import org.dromara.wms.domain.BaseMaterialType;
+import org.dromara.wms.domain.WmsBaseWarehouse;
+import org.dromara.wms.domain.WmsCheckTask;
+import org.dromara.wms.domain.bo.WmsCheckTaskBo;
+import org.dromara.wms.domain.vo.WmsCheckTaskVo;
+import org.dromara.wms.mapper.WmsCheckTaskMapper;
+import org.dromara.wms.service.IWmsCheckTaskService;
+import org.dromara.wms.service.IWmsInventoryCheckService;
+import org.springframework.stereotype.Service;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 仓储盘点任务Service业务层处理
+ *
+ * @author zch
+ * @date 2025-08-20
+ */
+@RequiredArgsConstructor
+@Service
+public class WmsCheckTaskServiceImpl implements IWmsCheckTaskService {
+
+ private final WmsCheckTaskMapper baseMapper;
+
+ private final IWmsInventoryCheckService wmsInventoryCheckService;//盘点工单
+
+ @DubboReference(timeout = 15000, retries = 1)
+ private final RemoteJobService remoteJobService;
+
+ /**
+ * 查询仓储盘点任务
+ *
+ * @param taskId 主键
+ * @return 仓储盘点任务
+ */
+ @Override
+ public WmsCheckTaskVo queryById(Long taskId){
+ return baseMapper.selectVoById(taskId);
+ }
+
+ /**
+ * 分页查询仓储盘点任务列表
+ *
+ * @param bo 查询条件
+ * @param pageQuery 分页参数
+ * @return 仓储盘点任务分页列表
+ */
+ @Override
+ public TableDataInfo queryPageList(WmsCheckTaskBo bo, PageQuery pageQuery) {
+ MPJLambdaWrapper lqw = buildQueryWrapper(bo);
+ Page result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+ return TableDataInfo.build(result);
+ }
+
+ /**
+ * 查询符合条件的仓储盘点任务列表
+ *
+ * @param bo 查询条件
+ * @return 仓储盘点任务列表
+ */
+ @Override
+ public List queryList(WmsCheckTaskBo bo) {
+ MPJLambdaWrapper lqw = buildQueryWrapper(bo);
+ return baseMapper.selectVoList(lqw);
+ }
+
+ private MPJLambdaWrapper buildQueryWrapper(WmsCheckTaskBo bo) {
+ Map params = bo.getParams();
+ MPJLambdaWrapper lqw = JoinWrappers.lambda(WmsCheckTask.class)
+ .selectAll(WmsCheckTask.class)
+
+ .select(BaseMaterialType::getMatrialTypeName)
+ .leftJoin(BaseMaterialType.class,BaseMaterialType::getMatrialTypeId, WmsCheckTask::getMaterialTypeId)
+
+ .select(WmsBaseWarehouse::getWarehouseCode, WmsBaseWarehouse::getWarehouseName)
+ .leftJoin(WmsBaseWarehouse.class,WmsBaseWarehouse::getWarehouseId, WmsCheckTask::getWarehouseId)
+
+ .eq(bo.getTaskId() != null, WmsCheckTask::getTaskId, bo.getTaskId())
+ .eq(StringUtils.isNotBlank(bo.getTaskCode()), WmsCheckTask::getTaskCode, bo.getTaskCode())
+ .like(StringUtils.isNotBlank(bo.getTaskName()), WmsCheckTask::getTaskName, bo.getTaskName())
+ .eq(StringUtils.isNotBlank(bo.getWmsCheckTaskType()), WmsCheckTask::getWmsCheckTaskType, bo.getWmsCheckTaskType())
+ .eq(bo.getMaterialTypeId() != null, WmsCheckTask::getMaterialTypeId, bo.getMaterialTypeId())
+ .eq(bo.getCheckRate() != null, WmsCheckTask::getCheckRate, bo.getCheckRate())
+ .eq(StringUtils.isNotBlank(bo.getCron()), WmsCheckTask::getCron, bo.getCron())
+ .eq(bo.getWarehouseId() != null, WmsCheckTask::getWarehouseId, bo.getWarehouseId())
+ .eq(StringUtils.isNotBlank(bo.getWmsCheckTaskFrequency()), WmsCheckTask::getWmsCheckTaskFrequency, bo.getWmsCheckTaskFrequency())
+ .orderByDesc(WmsCheckTask::getCreateTime);
+ return lqw;
+ }
+
+ /**
+ * 新增仓储盘点任务
+ *
+ * @param bo 仓储盘点任务
+ * @return 是否新增成功
+ */
+ @Override
+ @GlobalTransactional(rollbackFor = Exception.class)
+ public Boolean insertByBo(WmsCheckTaskBo bo) {
+ WmsCheckTask add = MapstructUtils.convert(bo, WmsCheckTask.class);
+ validEntityBeforeSave(add);
+
+ // 创建SnailJob任务
+ DmsJobEntity job = new DmsJobEntity();
+ job.setRouteKey(AllocationAlgorithmEnum.ROUND)
+ .setJobName("WMS盘点任务" + bo.getTaskCode())
+ .setExecutorInfo("wsmCheckTsk")//执行器名称
+ .setExecutorTimeout(30)//执行超时时间
+ .setBlockStrategy(JobBlockStrategyEnum.DISCARD)//阻塞策略:丢弃后续任务,避免重复执行
+ .setMaxRetryTimes(0)//最大重试次数
+ .setTriggerType(TriggerTypeEnum.CRON)//触发器类型:cron
+ .setTriggerInterval(add.getCron())//间隔时长: cron表达式
+ .setRetryInterval(10)//重试间隔时长
+ .setArgsStr("planCode")//参数
+ .setExtAttrs(bo.getTaskCode())//扩展属性
+ .setUserId(LoginHelper.getUserId().toString())//用户ID
+ .setTenantId(LoginHelper.getTenantId());//租户ID
+ R jobResp = remoteJobService.addClusterJob(job);
+ Long jobId = jobResp != null ? jobResp.getData() : null;//任务ID
+ add.setJobId(jobId);
+
+ boolean flag = baseMapper.insert(add) > 0;
+ if (flag) {
+ bo.setTaskId(add.getTaskId());
+ }
+ return flag;
+ }
+
+ /**
+ * 修改仓储盘点任务
+ *
+ * @param bo 仓储盘点任务
+ * @return 是否修改成功
+ */
+ @Override
+ @GlobalTransactional(rollbackFor = Exception.class)
+ public Boolean updateByBo(WmsCheckTaskBo bo) {
+ // 查询当前记录以获取已存在的jobId
+ WmsCheckTask current = baseMapper.selectById(bo.getTaskId());
+ Long existJobId = current != null ? current.getJobId() : null;
+
+ WmsCheckTask update = MapstructUtils.convert(bo, WmsCheckTask.class);
+ validEntityBeforeSave(update);
+
+ DmsJobEntity job = new DmsJobEntity();
+ job.setRouteKey(AllocationAlgorithmEnum.ROUND)
+ .setJobName("WMS盘点任务" + bo.getTaskCode())//任务名称
+ .setExecutorInfo("wsmCheckTsk")//执行器名称
+ .setExecutorTimeout(30)//执行超时时间
+ .setBlockStrategy(JobBlockStrategyEnum.DISCARD)//阻塞策略:丢弃后续任务,避免重复执行
+ .setMaxRetryTimes(0)//最大重试次数
+ .setTriggerType(TriggerTypeEnum.CRON)//触发器类型:cron
+ .setTriggerInterval(update.getCron())//间隔时长: cron表达式
+ .setRetryInterval(10)//重试间隔时长
+ .setArgsStr("planCode")//参数
+ .setExtAttrs(bo.getTaskCode())//扩展属性
+ .setUserId(LoginHelper.getUserId().toString())//用户ID
+ .setTenantId(LoginHelper.getTenantId());//租户ID
+
+ if (existJobId == null) {
+ R resp = remoteJobService.addClusterJob(job);//添加任务
+ Long jobId = resp != null ? resp.getData() : null;//获取任务ID
+ update.setJobId(jobId);
+ } else {
+ job.setId(existJobId);
+ remoteJobService.updateClusterJob(job);//更新任务
+ update.setJobId(existJobId);
+ }
+
+ return baseMapper.updateById(update) > 0;
+ }
+
+ /**
+ * 保存前的数据校验
+ */
+ private void validEntityBeforeSave(WmsCheckTask entity){
+ validCronBeforeSave(entity);
+ // TODO 唯一性等业务校验可在此补充
+ }
+
+ /**
+ * 保存前的cron校验
+ */
+ private void validCronBeforeSave(WmsCheckTask entity){
+ // 生成cron基于频率
+ String frequency = entity.getWmsCheckTaskFrequency();
+ if ("0".equals(frequency)) { // 月度
+ if (entity.getExecuteDay() == null || entity.getIntervalMonths() == null) {
+ throw new ServiceException("月度计划不完善");
+ }
+ String day = entity.getExecuteDay();
+ int interval = entity.getIntervalMonths();
+ String monthExpr = (interval == 0) ? "* " : "*/" + interval + " ";
+ entity.setCron("0 0 0 " + day + " " + monthExpr + "?");
+
+ // 验证
+ if (!"L".equals(day)) {
+ int dayNum = Integer.parseInt(day);
+ if (dayNum > 27) {
+ throw new ServiceException("日期超过安全限制: 月度计划日期必须在1-27或'L'");
+ }
+ }
+ } else if ("1".equals(frequency)) { // 年度
+ if (entity.getExecuteDay() == null || entity.getExecuteMonth() == null) {
+ throw new ServiceException("年度计划不完善");
+ }
+ String dayStr = entity.getExecuteDay();
+ int month = entity.getExecuteMonth();
+ int[] maxDays = {0,31,27,31,30,31,30,31,31,30,31,30,31};
+ if (!"L".equals(dayStr)) {
+ int dayNum = Integer.parseInt(dayStr);
+ if (dayNum > maxDays[month]) {
+ throw new ServiceException("无效日期: " + month + "月没有" + dayNum + "日 (安全限制,建议使用'L')");
+ }
+ }
+ String day = entity.getExecuteDay();
+ entity.setCron("0 0 0 " + day + " " + month + " ? *");
+ } else if ("2".equals(frequency)) {
+ // 使用提供的cron,已验证
+ } else {
+ throw new ServiceException("无效频率: " + frequency);
+ }
+
+ // 验证最终cron
+ if (StringUtils.isBlank(entity.getCron()) || !CronExpression.isValidExpression(entity.getCron())) {
+ throw new IllegalArgumentException("无效的Cron表达式: " + entity.getCron());
+ }
+ }
+
+ /**
+ * 校验并批量删除仓储盘点任务信息
+ *
+ * @param ids 待删除的主键集合
+ * @param isValid 是否进行有效性校验
+ * @return 是否删除成功
+ */
+ @Override
+ @GlobalTransactional(rollbackFor = Exception.class)
+ public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) {
+ if(isValid){
+ //TODO 做一些业务上的校验,判断是否需要校验
+ }
+ // 删除前关闭关联的定时任务
+ for (Long id : ids) {
+ WmsCheckTask entity = baseMapper.selectById(id);
+ if (entity != null && entity.getJobId() != null) {
+ remoteJobService.updateJobStatus(entity.getJobId(), 0L);
+ }
+ }
+ return baseMapper.deleteByIds(ids) > 0;
+ }
+}
diff --git a/ruoyi-modules/hwmom-wms/src/main/resources/mapper/wms/WmsCheckTaskMapper.xml b/ruoyi-modules/hwmom-wms/src/main/resources/mapper/wms/WmsCheckTaskMapper.xml
new file mode 100644
index 0000000..cd08e79
--- /dev/null
+++ b/ruoyi-modules/hwmom-wms/src/main/resources/mapper/wms/WmsCheckTaskMapper.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/ruoyi-modules/ruoyi-job/pom.xml b/ruoyi-modules/ruoyi-job/pom.xml
index 20ea971..478d270 100644
--- a/ruoyi-modules/ruoyi-job/pom.xml
+++ b/ruoyi-modules/ruoyi-job/pom.xml
@@ -109,6 +109,12 @@
compile
+
+ org.dromara
+ hwmom-api-wms
+ 2.2.2
+
+