liusheng
8 天以前 34f78281cf395a24e1f3f1c3b861186ff8a03b7b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package com.ruoyi.common.core.service.dto;
 
import java.io.Serializable;
 
/**
 * 一条「循环任务组计划」的滚动结果({@link com.ruoyi.common.core.service.ScheduleRollPort#rollOneSchedule} 的返回)。
 *
 * <h3>为什么需要它(第 9 步的关键设计说明)</h3>
 * 任务组轮次滚动的核心 {@code rollOneSchedule} 要做一次
 * <b>ServiceSubtask 的全字段深拷贝</b>:
 * <pre>
 * ServiceSubtask copy = JSON.parseObject(JSON.toJSONString(src), ServiceSubtask.class);
 * copy.setId(null); copy.setSenduuid(null); ... // 清 6 个字段
 * </pre>
 * 而 {@code ServiceSubtask} 有 <b>116 个字段</b>。
 * 如果在两个模块之间传"116 字段的 DTO"来做这件事,字段映射本身就是巨大风险面 ——
 * 而且这个风险<b>换不来任何收益</b>(全字段拷贝的语义由 JSON 序列化保证,不需要我们逐字段搬运)。
 *
 * <p>所以第 9 步的切分方式是:
 * <ul>
 *   <li><b>下沉到接口</b>({@link com.ruoyi.common.core.service.ScheduleRollPort}):
 *       "查一批待评估的循环计划" + "滚动单个计划"。<b>整个 roll 动作是原子的</b>,
 *       深拷贝留在实现侧(smartor 的过渡 Bridge),不跨越模块边界;</li>
 *   <li><b>留在本模块</b>({@code ruoyi-inhospvisit}):批次上限、逐条 try/catch、
 *       计数与日志 —— 也就是"编排"。</li>
 * </ul>
 *
 * <p>本 DTO 只承载"用于日志与计数"的信息:原实现在滚动成功后打印
 * <pre>
 * log.info("[任务组-滚动] scheduleId={} 推进到第 {} 轮, 新建 {} 条 subtask", scheduleId, nextLoop, produced);
 * </pre>
 * 但那个方法返回的是 {@code boolean},调度侧拿不到 nextLoop / produced。
 * 搬迁后用本 DTO 把这两个值带出来,让 inhospvisit 能打出<b>与原实现完全相同的日志</b>。
 */
public class VisitScheduleRollResultDto implements Serializable {
 
    private static final long serialVersionUID = 1L;
 
    /** 计划ID */
    private Long scheduleId;
 
    /** 滚动后推进到的轮次号(原实现里的 {@code nextLoop = currentLoop + 1}) */
    private Long nextLoop;
 
    /** 本轮新建的 subtask 条数(原实现里的 {@code produced}) */
    private Integer produced;
 
    /** 是否真的推进了(原方法返回的 boolean) */
    private boolean rolled;
 
    /** 未推进的原因(仅用于日志排查;推进成功时为 null) */
    private String skipReason;
 
    public static VisitScheduleRollResultDto skipped(Long scheduleId, String reason) {
        VisitScheduleRollResultDto d = new VisitScheduleRollResultDto();
        d.setScheduleId(scheduleId);
        d.setRolled(false);
        d.setSkipReason(reason);
        return d;
    }
 
    public static VisitScheduleRollResultDto rolled(Long scheduleId, long nextLoop, int produced) {
        VisitScheduleRollResultDto d = new VisitScheduleRollResultDto();
        d.setScheduleId(scheduleId);
        d.setNextLoop(nextLoop);
        d.setProduced(produced);
        d.setRolled(true);
        return d;
    }
 
    public Long getScheduleId() {
        return scheduleId;
    }
 
    public void setScheduleId(Long scheduleId) {
        this.scheduleId = scheduleId;
    }
 
    public Long getNextLoop() {
        return nextLoop;
    }
 
    public void setNextLoop(Long nextLoop) {
        this.nextLoop = nextLoop;
    }
 
    public Integer getProduced() {
        return produced;
    }
 
    public void setProduced(Integer produced) {
        this.produced = produced;
    }
 
    public boolean isRolled() {
        return rolled;
    }
 
    public void setRolled(boolean rolled) {
        this.rolled = rolled;
    }
 
    public String getSkipReason() {
        return skipReason;
    }
 
    public void setSkipReason(String skipReason) {
        this.skipReason = skipReason;
    }
}