#ai
zhou zhou
昨天 1668b4ce8fb82ddfd54b44b86e78e3080b99a1cc
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
package com.vincent.rsf.server.ai.tool;
 
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.vincent.rsf.framework.exception.CoolException;
import com.vincent.rsf.server.common.utils.FieldsUtils;
import com.vincent.rsf.server.manager.entity.Task;
import com.vincent.rsf.server.manager.entity.TaskItem;
import com.vincent.rsf.server.manager.service.TaskItemService;
import com.vincent.rsf.server.manager.service.TaskService;
import lombok.RequiredArgsConstructor;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
 
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
 
@Component
@RequiredArgsConstructor
public class RsfWmsTaskTools {
 
    private final TaskService taskService;
    private final TaskItemService taskItemService;
 
    /**
     * 查询任务列表。
     * 方法要求至少带一个过滤条件,避免模型把任务表当作可直接遍历的数据源。
     */
    @Tool(name = "rsf_query_task_list", description = "只读查询工具。按任务号、状态、任务类型、源站点、目标站点等条件查询任务列表。")
    public List<Map<String, Object>> queryTaskList(
            @ToolParam(description = "任务号,可模糊查询") String taskCode,
            @ToolParam(description = "任务状态,可选") Integer taskStatus,
            @ToolParam(description = "任务类型,可选") Integer taskType,
            @ToolParam(description = "源站点,可选") String orgSite,
            @ToolParam(description = "目标站点,可选") String targSite,
            @ToolParam(description = "返回条数,默认 10,最大 50") Integer limit) {
        String normalizedTaskCode = BuiltinToolGovernanceSupport.sanitizeQueryText(taskCode, "任务号", 64);
        String normalizedOrgSite = BuiltinToolGovernanceSupport.sanitizeQueryText(orgSite, "源站点", 64);
        String normalizedTargSite = BuiltinToolGovernanceSupport.sanitizeQueryText(targSite, "目标站点", 64);
        BuiltinToolGovernanceSupport.requireAnyFilter("任务列表查询至少需要提供一个过滤条件",
                normalizedTaskCode, normalizedOrgSite, normalizedTargSite,
                taskStatus == null ? null : String.valueOf(taskStatus),
                taskType == null ? null : String.valueOf(taskType));
        LambdaQueryWrapper<Task> queryWrapper = new LambdaQueryWrapper<>();
        int finalLimit = BuiltinToolGovernanceSupport.normalizeLimit(limit, 10, 50);
        if (StringUtils.hasText(normalizedTaskCode)) {
            queryWrapper.like(Task::getTaskCode, normalizedTaskCode);
        }
        if (taskStatus != null) {
            queryWrapper.eq(Task::getTaskStatus, taskStatus);
        }
        if (taskType != null) {
            queryWrapper.eq(Task::getTaskType, taskType);
        }
        if (StringUtils.hasText(normalizedOrgSite)) {
            queryWrapper.eq(Task::getOrgSite, normalizedOrgSite);
        }
        if (StringUtils.hasText(normalizedTargSite)) {
            queryWrapper.eq(Task::getTargSite, normalizedTargSite);
        }
        queryWrapper.orderByDesc(Task::getCreateTime).last("LIMIT " + finalLimit);
        List<Task> tasks = taskService.list(queryWrapper);
        List<Map<String, Object>> result = new ArrayList<>();
        for (Task task : tasks) {
            result.add(buildTaskSummary(task));
        }
        return result;
    }
 
    /**
     * 查询单个任务详情。
     * 与列表查询不同,这里允许返回更丰富的字段,但仍然要求调用方通过任务 ID 或任务号做精确定位。
     */
    @Tool(name = "rsf_query_task_detail", description = "只读查询工具。查询任务列表有正常返回值可以根据任务ID查询任务详情。")
    public Map<String, Object> queryTaskDetail(
            @ToolParam(description = "任务 ID") Long taskId
            ) {
 
        if (taskId == null) {
            throw new CoolException("任务 ID 需要提供");
        }
        List<TaskItem> taskItems = new ArrayList<>();
        taskItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, taskId));
 
        if (taskItems.isEmpty()) {
            throw new CoolException("未查询到任务");
        }
        return buildTaskItemDetail(taskItems);
    }
 
    private Map<String, Object> buildTaskSummary(Task task) {
        /** 把任务实体收敛为适合模型阅读和前端展示的摘要结构。 */
        Map<String, Object> item = new LinkedHashMap<>();
        item.put("id", task.getId());
        item.put("taskCode", task.getTaskCode());
        item.put("taskStatus", task.getTaskStatus());
        item.put("taskStatusLabel", task.getTaskStatus$());
        item.put("taskType", task.getTaskType());
        item.put("taskTypeLabel", task.getTaskType$());
        item.put("orgSite", task.getOrgSite());
        item.put("orgSiteLabel", task.getOrgSite$());
        item.put("targSite", task.getTargSite());
        item.put("targSiteLabel", task.getTargSite$());
        item.put("status", task.getStatus());
        item.put("statusLabel", task.getStatus$());
        item.put("createTime", task.getCreateTime$());
        item.put("updateTime", task.getUpdateTime$());
        return item;
    }
 
    private Map<String, Object> buildTaskItemDetail(List<TaskItem> taskItems) {
        Map<String, Object> result = new LinkedHashMap<>();
        result.put("taskId", taskItems.get(0).getTaskId());
        result.put("itemCount", taskItems.size());
 
        double totalAnfme = 0D;
        double totalWorkQty = 0D;
        double totalQty = 0D;
        List<Map<String, Object>> items = new ArrayList<>();
        for (TaskItem taskItem : taskItems) {
            totalAnfme += taskItem.getAnfme() == null ? 0D : taskItem.getAnfme();
            totalWorkQty += taskItem.getWorkQty() == null ? 0D : taskItem.getWorkQty();
            totalQty += taskItem.getQty() == null ? 0D : taskItem.getQty();
            items.add(buildTaskItemRow(taskItem));
        }
 
        result.put("totalAnfme", totalAnfme);
        result.put("totalWorkQty", totalWorkQty);
        result.put("totalQty", totalQty);
        result.put("items", items);
        return result;
    }
 
    private Map<String, Object> buildTaskItemRow(TaskItem taskItem) {
        if (!Objects.isNull(taskItem.getFieldsIndex())) {
            taskItem.setExtendFields(FieldsUtils.getFields(taskItem.getFieldsIndex()));
        }
        Map<String, Object> item = new LinkedHashMap<>();
        item.put("id", taskItem.getId());
        item.put("taskId", taskItem.getTaskId());
        item.put("matnrId", taskItem.getMatnrId());
        item.put("matnrCode", taskItem.getMatnrCode());
        item.put("maktx", taskItem.getMaktx());
        item.put("trackCode", taskItem.getTrackCode());
        item.put("splrBatch", taskItem.getSplrBatch());
        item.put("batch", taskItem.getBatch());
        item.put("spec", taskItem.getSpec());
        item.put("model", taskItem.getModel());
        item.put("unit", taskItem.getUnit());
        item.put("anfme", taskItem.getAnfme());
        item.put("workQty", taskItem.getWorkQty());
        item.put("qty", taskItem.getQty());
        item.put("ableQty", taskItem.getAbleQty());
        item.put("source", taskItem.getSource());
        item.put("sourceId", taskItem.getSourceId());
        item.put("sourceCode", taskItem.getSourceCode());
        item.put("orderId", taskItem.getOrderId());
        item.put("orderItemId", taskItem.getOrderItemId());
        item.put("platItemId", taskItem.getPlatItemId());
        item.put("platOrderCode", taskItem.getPlatOrderCode());
        item.put("platWorkCode", taskItem.getPlatWorkCode());
        item.put("projectCode", taskItem.getProjectCode());
        item.put("orderType", taskItem.getOrderType());
        item.put("orderTypeLabel", taskItem.getOrderType$());
        item.put("wkType", taskItem.getWkType());
        item.put("wkTypeLabel", taskItem.getWkType$());
        item.put("isptResult", taskItem.getIsptResult());
        item.put("isptResultLabel", taskItem.getIsptResult$());
        item.put("fieldsIndex", taskItem.getFieldsIndex());
        item.put("extendFields", taskItem.getExtendFields());
        item.put("status", taskItem.getStatus());
        item.put("statusLabel", taskItem.getStatus$());
        item.put("memo", taskItem.getMemo());
        item.put("createTime", taskItem.getCreateTime$());
        item.put("updateTime", taskItem.getUpdateTime$());
        return item;
    }
 
}