feat(inventory): 添加批量查询出库单条码和价格详情功能
- 新增OutboundOrderInventoryInfoToolProvider工具类,支持通过出库单号批量查询条码和价格详情 - 扩展IInventoryInfoService接口及其实现类InventoryInfoServiceImpl,添加按出库单号列表查询库存信息的方法 - 更新InventoryOuter实体类,添加outerCodeList属性 - 修改InventoryOuterMapper.xml,支持按出库单号列表查询 - 更新InventoryInfoMapper.java及InventoryInfoMapper.xml,支持按出库单号列表查询库存信息dev_1.0.2
parent
487bf5e0c6
commit
a7e0598951
|
|
@ -31,6 +31,7 @@ public class InventoryOuter extends BaseEntity
|
|||
/** 出库单号 */
|
||||
@Excel(name = "出库单号")
|
||||
private String outerCode;
|
||||
private List<String> outerCodeList;
|
||||
|
||||
/** 发货时间 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,217 @@
|
|||
package com.ruoyi.sip.llm.tools;
|
||||
|
||||
import com.ruoyi.sip.domain.InventoryInfo;
|
||||
import com.ruoyi.sip.domain.InventoryOuter;
|
||||
import com.ruoyi.sip.domain.ProductInfo;
|
||||
import com.ruoyi.sip.llm.tools.support.AbstractMcpToolProvider;
|
||||
import com.ruoyi.sip.service.IInventoryInfoService;
|
||||
import com.ruoyi.sip.service.IInventoryOuterService;
|
||||
import com.ruoyi.sip.service.IProductInfoService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
public class OutboundOrderInventoryInfoToolProvider extends AbstractMcpToolProvider {
|
||||
|
||||
@Autowired
|
||||
private IInventoryInfoService inventoryInfoService;
|
||||
|
||||
@Autowired
|
||||
private IInventoryOuterService inventoryOuterService;
|
||||
|
||||
@Autowired
|
||||
private IProductInfoService productInfoService;
|
||||
|
||||
@Override
|
||||
protected String getToolName() {
|
||||
return "outbound_order_inventory_info";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getToolDescription() {
|
||||
return "Batch query barcode and price details by outbound order codes.";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, Object> buildInputSchema() {
|
||||
Map<String, Object> outerCodeListProperty = new LinkedHashMap<>();
|
||||
outerCodeListProperty.put("type", "array");
|
||||
outerCodeListProperty.put("description", "Outbound order code list.");
|
||||
outerCodeListProperty.put("items", stringProperty("Outbound order code"));
|
||||
outerCodeListProperty.put("minItems", 1);
|
||||
|
||||
Map<String, Object> properties = new LinkedHashMap<>();
|
||||
properties.put("outer_code_list", outerCodeListProperty);
|
||||
return objectSchema(properties, "outer_code_list");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object handle(Map<String, Object> params) {
|
||||
List<String> outerCodeList = getStringList(params, "outer_code_list");
|
||||
if (outerCodeList.isEmpty()) {
|
||||
throw new RuntimeException("outer_code_list is required");
|
||||
}
|
||||
|
||||
List<InventoryOuter> inventoryOuters = loadInventoryOuters(outerCodeList);
|
||||
Map<String, String> productNameMap = loadProductNameMap(inventoryOuters);
|
||||
Map<String, List<InventoryInfo>> inventoryInfoMap = loadInventoryInfoMap(outerCodeList);
|
||||
|
||||
List<Map<String, Object>> items = new ArrayList<>();
|
||||
for (InventoryOuter inventoryOuter : inventoryOuters) {
|
||||
items.add(toOutboundOrderItem(inventoryOuter, productNameMap, inventoryInfoMap));
|
||||
}
|
||||
|
||||
Map<String, Object> query = new LinkedHashMap<>();
|
||||
query.put("outer_code_list", outerCodeList);
|
||||
|
||||
Map<String, Object> data = new LinkedHashMap<>();
|
||||
data.put("total", items.size());
|
||||
data.put("items", items);
|
||||
|
||||
Map<String, Object> metadata = new LinkedHashMap<>();
|
||||
metadata.put("tool", getToolName());
|
||||
metadata.put("description", "Batch query outbound-order barcode details from oms_inventory_info.");
|
||||
metadata.put("query_fields", mapOf(
|
||||
"outer_code_list", "Outbound order code list"
|
||||
));
|
||||
metadata.put("data_fields", mapOf(
|
||||
"total", "Matched outbound orders count",
|
||||
"items", "Outbound order detail list"
|
||||
));
|
||||
metadata.put("item_fields", mapOf(
|
||||
"outboundOrderCode", "Outbound order code",
|
||||
"orderCode", "Order code",
|
||||
"productCode", "Product code",
|
||||
"productName", "Product name",
|
||||
"quantity", "Outbound quantity",
|
||||
"inventoryCount", "Barcode detail count",
|
||||
"inventoryInfos", "Barcode detail list"
|
||||
));
|
||||
metadata.put("inventory_info_fields", mapOf(
|
||||
"productSn", "Barcode / serial number",
|
||||
"innerPrice", "Inner price",
|
||||
"outerPrice", "Outer price",
|
||||
"taxRate", "Tax rate"
|
||||
));
|
||||
|
||||
return response(metadata, query, data);
|
||||
}
|
||||
|
||||
private List<InventoryOuter> loadInventoryOuters(List<String> outerCodeList) {
|
||||
InventoryOuter query = new InventoryOuter();
|
||||
query.setOuterCodeList(outerCodeList);
|
||||
List<InventoryOuter> inventoryOuters = inventoryOuterService.selectInventoryOuterList(query);
|
||||
if (inventoryOuters == null || inventoryOuters.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
Map<String, InventoryOuter> outerMap = inventoryOuters.stream().collect(Collectors.toMap(
|
||||
InventoryOuter::getOuterCode,
|
||||
item -> item,
|
||||
(first, second) -> first,
|
||||
LinkedHashMap::new
|
||||
));
|
||||
|
||||
List<InventoryOuter> ordered = new ArrayList<>();
|
||||
for (String outerCode : outerCodeList) {
|
||||
InventoryOuter inventoryOuter = outerMap.get(outerCode);
|
||||
if (inventoryOuter != null) {
|
||||
ordered.add(inventoryOuter);
|
||||
}
|
||||
}
|
||||
return ordered;
|
||||
}
|
||||
|
||||
private Map<String, String> loadProductNameMap(List<InventoryOuter> inventoryOuters) {
|
||||
if (inventoryOuters == null || inventoryOuters.isEmpty()) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
Set<String> productCodes = inventoryOuters.stream()
|
||||
.map(InventoryOuter::getProductCode)
|
||||
.filter(code -> !isBlank(code))
|
||||
.collect(Collectors.toCollection(LinkedHashSet::new));
|
||||
if (productCodes.isEmpty()) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
List<ProductInfo> productInfos = productInfoService.selectProductInfoByCodeList(new ArrayList<>(productCodes));
|
||||
if (productInfos == null || productInfos.isEmpty()) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
return productInfos.stream().collect(Collectors.toMap(ProductInfo::getProductCode, ProductInfo::getProductName, (a, b) -> a));
|
||||
}
|
||||
|
||||
private Map<String, List<InventoryInfo>> loadInventoryInfoMap(List<String> outerCodeList) {
|
||||
List<InventoryInfo> inventoryInfos = inventoryInfoService.selectInventoryInfoByOuterCodeList(outerCodeList);
|
||||
if (inventoryInfos == null || inventoryInfos.isEmpty()) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
return inventoryInfos.stream()
|
||||
.filter(item -> !isBlank(item.getOuterCode()))
|
||||
.collect(Collectors.groupingBy(InventoryInfo::getOuterCode, LinkedHashMap::new, Collectors.toList()));
|
||||
}
|
||||
|
||||
private Map<String, Object> toOutboundOrderItem(InventoryOuter inventoryOuter,
|
||||
Map<String, String> productNameMap,
|
||||
Map<String, List<InventoryInfo>> inventoryInfoMap) {
|
||||
List<InventoryInfo> inventoryInfos = inventoryInfoMap.get(inventoryOuter.getOuterCode());
|
||||
List<Map<String, Object>> inventoryInfoItems = new ArrayList<>();
|
||||
if (inventoryInfos != null) {
|
||||
for (InventoryInfo inventoryInfo : inventoryInfos) {
|
||||
inventoryInfoItems.add(toInventoryInfoItem(inventoryInfo));
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Object> item = new LinkedHashMap<>();
|
||||
item.put("outboundOrderCode", inventoryOuter.getOuterCode());
|
||||
item.put("orderCode", inventoryOuter.getOrderCode());
|
||||
item.put("productCode", inventoryOuter.getProductCode());
|
||||
item.put("productName", productNameMap.get(inventoryOuter.getProductCode()));
|
||||
item.put("quantity", inventoryOuter.getQuantity());
|
||||
item.put("inventoryCount", inventoryInfoItems.size());
|
||||
item.put("inventoryInfos", inventoryInfoItems);
|
||||
return item;
|
||||
}
|
||||
|
||||
private Map<String, Object> toInventoryInfoItem(InventoryInfo inventoryInfo) {
|
||||
Map<String, Object> item = new LinkedHashMap<>();
|
||||
item.put("productSn", inventoryInfo.getProductSn());
|
||||
item.put("innerPrice", inventoryInfo.getInnerPrice());
|
||||
item.put("outerPrice", inventoryInfo.getOuterPrice());
|
||||
item.put("taxRate", inventoryInfo.getTaxRate());
|
||||
return item;
|
||||
}
|
||||
|
||||
private List<String> getStringList(Map<String, Object> params, String key) {
|
||||
if (params == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
Object value = params.get(key);
|
||||
if (!(value instanceof List)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<?> rawList = (List<?>) value;
|
||||
List<String> result = new ArrayList<>();
|
||||
for (Object raw : rawList) {
|
||||
if (raw == null) {
|
||||
continue;
|
||||
}
|
||||
String item = String.valueOf(raw).trim();
|
||||
if (!item.isEmpty()) {
|
||||
result.add(item);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
@ -79,4 +79,6 @@ public interface InventoryInfoMapper
|
|||
List<InventoryInfo> listByDeliveryId(Long id);
|
||||
|
||||
List<InventoryInfo> selectInventoryInfoByOrderCode(List<String> strings);
|
||||
|
||||
List<InventoryInfo> selectInventoryInfoByOuterCodeList(List<String> outerCodeList);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,4 +89,6 @@ public interface IInventoryInfoService
|
|||
List<InventoryInfo> listByDeliveryId(Long id);
|
||||
|
||||
List<InventoryInfo> selectInventoryInfoByOrderCode(List<String> strings);
|
||||
|
||||
List<InventoryInfo> selectInventoryInfoByOuterCodeList(List<String> outerCodeList);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -217,5 +217,10 @@ public class InventoryInfoServiceImpl implements IInventoryInfoService {
|
|||
return inventoryInfoMapper.selectInventoryInfoByOrderCode(strings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<InventoryInfo> selectInventoryInfoByOuterCodeList(List<String> outerCodeList) {
|
||||
return inventoryInfoMapper.selectInventoryInfoByOuterCodeList(outerCodeList);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,6 +111,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
|
||||
)
|
||||
</select>
|
||||
<select id="selectInventoryInfoByOuterCodeList" resultType="com.ruoyi.sip.domain.InventoryInfo">
|
||||
<include refid="selectInventoryInfoVo"/>
|
||||
where t1.outer_code in
|
||||
<foreach item="item" index="index" collection="list" separator="," open="(" close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
</select>
|
||||
|
||||
|
||||
<insert id="insertInventoryInfo" parameterType="InventoryInfo" useGeneratedKeys="true" keyProperty="id">
|
||||
|
|
@ -213,4 +220,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
)
|
||||
</delete>
|
||||
|
||||
</mapper>
|
||||
</mapper>
|
||||
|
|
|
|||
|
|
@ -77,6 +77,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<include refid="selectInventoryOuterRelationVo"/>
|
||||
<where>
|
||||
<if test="outerCode != null and outerCode != ''">and t1.outer_code = #{outerCode}</if>
|
||||
<if test="outerCodeList != null and outerCodeList.size>0">and t1.outer_code in
|
||||
<foreach item="item" index="index" collection="outerCodeList" separator="," open="(" close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="productCode != null and productCode != ''">and t1.product_code = #{productCode}</if>
|
||||
<if test="productCodeList != null and productCodeList.size>0">and t1.product_code in
|
||||
<foreach item="item" index="index" collection="productCodeList" separator="," open="(" close=")">
|
||||
|
|
|
|||
Loading…
Reference in New Issue