| | |
| | | private final LocItemService locItemService; |
| | | private final DeviceSiteService deviceSiteService; |
| | | |
| | | @Tool(name = "rsf_query_available_inventory", description = "根据物料编码或物料名称查询当前在库且可用于出库的库存明细。") |
| | | /** |
| | | * 查询当前可用于出库的库存明细。 |
| | | * 该工具只允许按物料编码或物料名称做定向查询,不允许无条件扫描库存表。 |
| | | */ |
| | | @Tool(name = "rsf_query_available_inventory", description = "只读查询工具。根据物料编码或物料名称查询当前在库且可用于出库的库存明细。") |
| | | public List<Map<String, Object>> queryAvailableInventory( |
| | | @ToolParam(description = "物料编码,优先使用") String matnr, |
| | | @ToolParam(description = "物料名称,当没有物料编码时使用") String maktx) { |
| | | if (!StringUtils.hasText(matnr) && !StringUtils.hasText(maktx)) { |
| | | throw new CoolException("物料编码或物料名称至少需要提供一个"); |
| | | } |
| | | @ToolParam(description = "物料名称,当没有物料编码时使用") String maktx, |
| | | @ToolParam(description = "返回条数,默认 10,最大 50") Integer limit) { |
| | | String normalizedMatnr = BuiltinToolGovernanceSupport.sanitizeQueryText(matnr, "物料编码", 64); |
| | | String normalizedMaktx = BuiltinToolGovernanceSupport.sanitizeQueryText(maktx, "物料名称", 100); |
| | | BuiltinToolGovernanceSupport.requireAnyFilter("物料编码或物料名称至少需要提供一个", normalizedMatnr, normalizedMaktx); |
| | | int finalLimit = BuiltinToolGovernanceSupport.normalizeLimit(limit, 10, 50); |
| | | LambdaQueryWrapper<LocItem> queryWrapper = new LambdaQueryWrapper<>(); |
| | | if (StringUtils.hasText(matnr)) { |
| | | queryWrapper.eq(LocItem::getMatnrCode, matnr); |
| | | if (StringUtils.hasText(normalizedMatnr)) { |
| | | queryWrapper.eq(LocItem::getMatnrCode, normalizedMatnr); |
| | | } else { |
| | | queryWrapper.eq(LocItem::getMaktx, maktx); |
| | | queryWrapper.like(LocItem::getMaktx, normalizedMaktx); |
| | | } |
| | | queryWrapper.apply( |
| | | "EXISTS (SELECT 1 FROM man_loc ml WHERE ml.use_status = {0} AND ml.id = man_loc_item.loc_id)", |
| | | LocStsType.LOC_STS_TYPE_F.type |
| | | ); |
| | | queryWrapper.orderByDesc(LocItem::getId).last("LIMIT " + finalLimit); |
| | | List<LocItem> locItems = locItemService.list(queryWrapper); |
| | | List<Map<String, Object>> result = new ArrayList<>(); |
| | | for (LocItem locItem : locItems) { |
| | |
| | | return result; |
| | | } |
| | | |
| | | @Tool(name = "rsf_query_station_list", description = "根据作业类型列表查询可用站点,返回站点编号、名称、目标位置和状态等信息。") |
| | | /** |
| | | * 查询指定作业类型可用的设备站点。 |
| | | * 返回的是模型更容易消费的扁平结构,而不是直接暴露完整实体对象。 |
| | | */ |
| | | @Tool(name = "rsf_query_station_list", description = "只读查询工具。根据作业类型列表查询可用站点,返回站点编号、名称、目标位置和状态等信息。") |
| | | public List<Map<String, Object>> queryStationList( |
| | | @ToolParam(required = true, description = "作业类型列表") List<String> types) { |
| | | if (types == null || types.isEmpty()) { |
| | | throw new CoolException("站点类型列表不能为空"); |
| | | } |
| | | @ToolParam(required = true, description = "作业类型列表") List<String> types, |
| | | @ToolParam(description = "返回条数,默认 20,最大 50") Integer limit) { |
| | | List<String> normalizedTypes = BuiltinToolGovernanceSupport.sanitizeStringList(types, "站点类型列表", 10, 32); |
| | | int finalLimit = BuiltinToolGovernanceSupport.normalizeLimit(limit, 20, 50); |
| | | List<DeviceSite> sites = deviceSiteService.list(new LambdaQueryWrapper<DeviceSite>() |
| | | .in(DeviceSite::getType, types)); |
| | | .in(DeviceSite::getType, normalizedTypes) |
| | | .orderByAsc(DeviceSite::getType) |
| | | .orderByAsc(DeviceSite::getSite) |
| | | .last("LIMIT " + finalLimit)); |
| | | List<Map<String, Object>> result = new ArrayList<>(); |
| | | for (DeviceSite site : sites) { |
| | | Map<String, Object> item = new LinkedHashMap<>(); |