feat(biz): 新增智能识别提示词配置及工头字段

- 在多个实体类和数据传输对象中增加工头(foreman)字段
- 为经销商相关类添加是否可调整比例(shareAdjusted)字段
- 引入智能识别提示词配置功能,支持动态设置AI识别规则
- 优化采购单费用更新逻辑,复用统一方法处理成本项变更
- 调整包材更新策略,使用复合键避免重复记录
- 修改发货单查询权限控制,超级管理员可见全部数据
- 更新车辆提取服务,支持从配置读取AI提示词模板
- 调整服务器端口配置,统一使用8080端口运行应用
This commit is contained in:
shenyifei 2025-11-19 19:49:13 +08:00
parent 65e031ef0b
commit b20bc69634
20 changed files with 203 additions and 212 deletions

View File

@ -14,7 +14,9 @@ import com.xunhong.erp.turbo.api.biz.dto.qry.ShipOrderListQry;
import com.xunhong.erp.turbo.api.biz.dto.qry.ShipOrderPageQry; import com.xunhong.erp.turbo.api.biz.dto.qry.ShipOrderPageQry;
import com.xunhong.erp.turbo.api.biz.dto.qry.ShipOrderShowQry; import com.xunhong.erp.turbo.api.biz.dto.qry.ShipOrderShowQry;
import com.xunhong.erp.turbo.api.biz.dto.vo.ShipOrderVO; import com.xunhong.erp.turbo.api.biz.dto.vo.ShipOrderVO;
import com.xunhong.erp.turbo.api.rbac.dto.constants.RoleConstant;
import com.xunhong.erp.turbo.base.dto.PageDTO; import com.xunhong.erp.turbo.base.dto.PageDTO;
import com.xunhong.erp.turbo.base.dto.UserSession;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@ -63,6 +65,10 @@ public class ShipOrderController {
@GetMapping("pageShipOrder") @GetMapping("pageShipOrder")
@Operation(summary = "发货单列表", method = "GET") @Operation(summary = "发货单列表", method = "GET")
public PageResponse<ShipOrderVO> pageShipOrder(@ModelAttribute @Validated ShipOrderPageQry shipOrderPageQry) { public PageResponse<ShipOrderVO> pageShipOrder(@ModelAttribute @Validated ShipOrderPageQry shipOrderPageQry) {
String roleSlug = UserSession.USER_THREAD_LOCAL.get().getRoleSlug();
if (roleSlug.equals(RoleConstant.SUPERADMIN)) {
shipOrderPageQry.setCreatedBy(null);
}
PageDTO<ShipOrderVO> page = shipOrderService.page(shipOrderPageQry); PageDTO<ShipOrderVO> page = shipOrderService.page(shipOrderPageQry);
return PageResponse.of(page.getRecords(), (int) page.getTotal(), (int) page.getSize(), (int) page.getCurrent()); return PageResponse.of(page.getRecords(), (int) page.getTotal(), (int) page.getSize(), (int) page.getCurrent());
} }

View File

@ -43,6 +43,11 @@ public class Dealer extends DTO {
*/ */
private Boolean enableShare; private Boolean enableShare;
/**
* 是否可调整比例
*/
private Boolean shareAdjusted;
/** /**
* 分成比例 * 分成比例
*/ */

View File

@ -40,6 +40,11 @@ public class PurchaseOrder extends DTO {
*/ */
private String originPrincipal; private String originPrincipal;
/**
* 工头
*/
private String foreman;
/** /**
* 报价方式1_按毛重报价2_按净重报价 * 报价方式1_按毛重报价2_按净重报价
*/ */

View File

@ -128,6 +128,12 @@ public class DealerDO extends BaseDO<DealerDO> {
@TableField(value = "company_rebate_ratio") @TableField(value = "company_rebate_ratio")
private BigDecimal companyRebateRatio; private BigDecimal companyRebateRatio;
/**
* 是否可调整比例
*/
@TableField(value = "share_adjusted")
private Boolean shareAdjusted;
/** /**
* 付款账户列表 * 付款账户列表
*/ */

View File

@ -104,6 +104,12 @@ public class OrderDealerDO extends BaseDO<OrderDealerDO> {
@TableField(value = "company_rebate_ratio") @TableField(value = "company_rebate_ratio")
private BigDecimal companyRebateRatio; private BigDecimal companyRebateRatio;
/**
* 是否可调整比例
*/
@TableField(value = "share_adjusted")
private Boolean shareAdjusted;
/** /**
* 税费补贴 * 税费补贴
*/ */

View File

@ -45,6 +45,12 @@ public class PurchaseOrderDO extends BaseDO<PurchaseOrderDO> {
@TableField(value = "origin_principal") @TableField(value = "origin_principal")
private String originPrincipal; private String originPrincipal;
/**
* 工头
*/
@TableField(value = "foreman")
private String foreman;
/** /**
* 报价方式1_按毛重报价2_按净重报价 * 报价方式1_按毛重报价2_按净重报价
*/ */

View File

@ -310,48 +310,7 @@ public class PurchaseOrderGatewayImpl implements PurchaseOrderGateway {
} }
} }
saveCostItem(purchaseOrderDO.getOrderId(), purchaseOrderApproveCmd.getOrderCostList());
// 更新费用信息精细化处理
// 获取现有的费用列表
LambdaQueryWrapper<OrderCostDO> costQueryWrapper = Wrappers.lambdaQuery(OrderCostDO.class);
costQueryWrapper.eq(OrderCostDO::getOrderId, purchaseOrderDO.getOrderId());
List<OrderCostDO> existingCosts = orderCostMapper.selectList(costQueryWrapper);
// 获取更新的费用列表
List<OrderCost> updatedCosts = purchaseOrderApproveCmd.getOrderCostList();
// 将现有费用映射到ID字典中便于查找
Map<Long, OrderCostDO> existingCostMap = existingCosts.stream()
.collect(Collectors.toMap(OrderCostDO::getOrderCostId, Function.identity()));
// 收集需要更新和新增的费用
List<OrderCostDO> costsToInsert = new ArrayList<>();
List<OrderCostDO> costsToUpdate = new ArrayList<>();
for (OrderCost updatedCost : updatedCosts) {
updatedCost.setOrderId(purchaseOrderDO.getOrderId());
OrderCostDO costDO = orderCostConvert.toOrderCostDO(updatedCost);
if (updatedCost.getOrderCostId() != null && existingCostMap.containsKey(updatedCost.getOrderCostId())) {
// 更新已存在的费用
costDO.setOrderCostId(updatedCost.getOrderCostId());
costsToUpdate.add(costDO);
// 从现有映射中移除剩下的就是需要删除的
existingCostMap.remove(updatedCost.getOrderCostId());
} else {
// 新增费用
costsToInsert.add(costDO);
}
}
// 删除不再需要的费用
existingCostMap.values().forEach(cost -> cost.deleteById());
// 执行更新操作
costsToUpdate.forEach(orderCostMapper::updateById);
// 执行插入操作
costsToInsert.forEach(orderCostMapper::insert);
} }
@Override @Override
@ -723,47 +682,7 @@ public class PurchaseOrderGatewayImpl implements PurchaseOrderGateway {
} }
} }
// 更新费用信息精细化处理 saveCostItem(purchaseOrderDO.getOrderId(), purchaseOrderStep1Cmd.getOrderCostList());
// 获取现有的费用列表
LambdaQueryWrapper<OrderCostDO> costQueryWrapper = Wrappers.lambdaQuery(OrderCostDO.class);
costQueryWrapper.eq(OrderCostDO::getOrderId, purchaseOrderDO.getOrderId());
List<OrderCostDO> existingCosts = orderCostMapper.selectList(costQueryWrapper);
// 获取更新的费用列表
List<OrderCost> updatedCosts = purchaseOrderStep1Cmd.getOrderCostList().stream().toList();
// 将现有费用映射到ID字典中便于查找
Map<Long, OrderCostDO> existingCostMap = existingCosts.stream()
.collect(Collectors.toMap(OrderCostDO::getOrderCostId, Function.identity()));
// 收集需要更新和新增的费用
List<OrderCostDO> costsToInsert = new ArrayList<>();
List<OrderCostDO> costsToUpdate = new ArrayList<>();
for (OrderCost updatedCost : updatedCosts) {
updatedCost.setOrderId(purchaseOrderDO.getOrderId());
OrderCostDO costDO = orderCostConvert.toOrderCostDO(updatedCost);
if (updatedCost.getOrderCostId() != null && existingCostMap.containsKey(updatedCost.getOrderCostId())) {
// 更新已存在的费用
costDO.setOrderCostId(updatedCost.getOrderCostId());
costsToUpdate.add(costDO);
// 从现有映射中移除剩下的就是需要删除的
existingCostMap.remove(updatedCost.getOrderCostId());
} else {
// 新增费用
costsToInsert.add(costDO);
}
}
// 删除不再需要的费用
existingCostMap.values().forEach(cost -> cost.deleteById());
// 执行更新操作
costsToUpdate.forEach(orderCostMapper::updateById);
// 执行插入操作
costsToInsert.forEach(orderCostMapper::insert);
return purchaseOrderConvert.toPurchaseOrder(purchaseOrderDO); return purchaseOrderConvert.toPurchaseOrder(purchaseOrderDO);
} }
@ -795,9 +714,6 @@ public class PurchaseOrderGatewayImpl implements PurchaseOrderGateway {
Map<Long, OrderSupplierDO> existingOrderSupplierMap = existingSuppliers.stream() Map<Long, OrderSupplierDO> existingOrderSupplierMap = existingSuppliers.stream()
.collect(Collectors.toMap(OrderSupplierDO::getSupplierId, Function.identity())); .collect(Collectors.toMap(OrderSupplierDO::getSupplierId, Function.identity()));
// 将更新后的供应商映射到ID字典中便于查找
Map<Long, Long> existingSupplierMap = existingSuppliers.stream().collect(Collectors.toMap(OrderSupplierDO::getSupplierId, OrderSupplierDO::getOrderSupplierId));
// 收集需要更新和新增的供应商 // 收集需要更新和新增的供应商
List<OrderSupplierDO> suppliersToInsert = new ArrayList<>(); List<OrderSupplierDO> suppliersToInsert = new ArrayList<>();
List<OrderSupplierDO> suppliersToUpdate = new ArrayList<>(); List<OrderSupplierDO> suppliersToUpdate = new ArrayList<>();
@ -805,13 +721,20 @@ public class PurchaseOrderGatewayImpl implements PurchaseOrderGateway {
for (OrderSupplier updatedSupplier : updatedSuppliers) { for (OrderSupplier updatedSupplier : updatedSuppliers) {
// 检查供应商ID是否为空如果为空则创建新的供应商 // 检查供应商ID是否为空如果为空则创建新的供应商
if (Objects.isNull(updatedSupplier.getSupplierId())) { if (Objects.isNull(updatedSupplier.getSupplierId())) {
SupplierDO supplierDO1 = supplierConvert.toSupplierDO(updatedSupplier); // 根据姓名查询
supplierDO1.setStatus(Boolean.TRUE); LambdaQueryWrapper<SupplierDO> queryWrapper1 = Wrappers.lambdaQuery(SupplierDO.class);
supplierDO1.setCreatedBy(purchaseOrderStep2Cmd.getCreatedBy()); queryWrapper1.eq(SupplierDO::getName, updatedSupplier.getName());
supplierDO1.setCreatedByName(purchaseOrderStep2Cmd.getCreatedByName()); SupplierDO supplierDO = supplierMapper.selectOne(queryWrapper1);
supplierMapper.insert(supplierDO1);
updatedSupplier.setSupplierId(supplierDO1.getSupplierId()); if (Objects.isNull(supplierDO)) {
supplierDO = supplierConvert.toSupplierDO(updatedSupplier);
supplierDO.setStatus(Boolean.TRUE);
supplierDO.setCreatedBy(purchaseOrderStep2Cmd.getCreatedBy());
supplierDO.setCreatedByName(purchaseOrderStep2Cmd.getCreatedByName());
supplierMapper.insert(supplierDO);
}
updatedSupplier.setSupplierId(supplierDO.getSupplierId());
} }
updatedSupplier.setOrderId(orderId); updatedSupplier.setOrderId(orderId);
@ -821,7 +744,7 @@ public class PurchaseOrderGatewayImpl implements PurchaseOrderGateway {
// 更新已存在的供应商 // 更新已存在的供应商
orderSupplierDO.setSupplierId(updatedSupplier.getSupplierId()); orderSupplierDO.setSupplierId(updatedSupplier.getSupplierId());
Long orderSupplierId = existingSupplierMap.get(updatedSupplier.getSupplierId()); Long orderSupplierId = existingOrderSupplierMap.get(updatedSupplier.getSupplierId()).getOrderSupplierId();
orderSupplierDO.setOrderSupplierId(orderSupplierId); orderSupplierDO.setOrderSupplierId(orderSupplierId);
updatedSupplier.setOrderSupplierId(orderSupplierId); updatedSupplier.setOrderSupplierId(orderSupplierId);
@ -844,49 +767,9 @@ public class PurchaseOrderGatewayImpl implements PurchaseOrderGateway {
// 执行插入操作 // 执行插入操作
suppliersToInsert.forEach(orderSupplierMapper::insert); suppliersToInsert.forEach(orderSupplierMapper::insert);
if (purchaseOrderStep2Cmd.getActive() == 3) {
// 更新费用信息精细化处理 // 更新费用信息精细化处理
// 获取现有的费用列表 // 获取现有的费用列表
LambdaQueryWrapper<OrderCostDO> costQueryWrapper = Wrappers.lambdaQuery(OrderCostDO.class); saveCostItem(orderId, purchaseOrderStep2Cmd.getOrderCostList().stream().toList());
costQueryWrapper.eq(OrderCostDO::getOrderId, orderId);
List<OrderCostDO> existingCosts = orderCostMapper.selectList(costQueryWrapper);
// 获取更新的费用列表
List<OrderCost> updatedCosts = purchaseOrderStep2Cmd.getOrderCostList().stream().toList();
// 将现有费用映射到ID字典中便于查找
Map<Long, OrderCostDO> existingCostMap = existingCosts.stream()
.collect(Collectors.toMap(OrderCostDO::getOrderCostId, Function.identity()));
// 收集需要更新和新增的费用
List<OrderCostDO> costsToInsert = new ArrayList<>();
List<OrderCostDO> costsToUpdate = new ArrayList<>();
for (OrderCost updatedCost : updatedCosts) {
updatedCost.setOrderId(orderId);
OrderCostDO costDO = orderCostConvert.toOrderCostDO(updatedCost);
if (updatedCost.getOrderCostId() != null && existingCostMap.containsKey(updatedCost.getOrderCostId())) {
// 更新已存在的费用
costDO.setOrderCostId(updatedCost.getOrderCostId());
costsToUpdate.add(costDO);
// 从现有映射中移除剩下的就是需要删除的
existingCostMap.remove(updatedCost.getOrderCostId());
} else {
// 新增费用
costsToInsert.add(costDO);
}
}
// 删除不再需要的费用
existingCostMap.values().forEach(cost -> cost.deleteById());
// 执行更新操作
costsToUpdate.forEach(orderCostMapper::updateById);
// 执行插入操作
costsToInsert.forEach(orderCostMapper::insert);
}
// 第三步处理包材 // 第三步处理包材
if (purchaseOrderStep2Cmd.getActive() == 4) { if (purchaseOrderStep2Cmd.getActive() == 4) {
@ -910,9 +793,12 @@ public class PurchaseOrderGatewayImpl implements PurchaseOrderGateway {
packageQueryWrapper.eq(OrderPackageDO::getOrderSupplierId, supplierDO.getOrderSupplierId()); packageQueryWrapper.eq(OrderPackageDO::getOrderSupplierId, supplierDO.getOrderSupplierId());
List<OrderPackageDO> existingPackages = orderPackageMapper.selectList(packageQueryWrapper); List<OrderPackageDO> existingPackages = orderPackageMapper.selectList(packageQueryWrapper);
// 将现有包材映射到ID字典中便于查找 // 将现有包材映射到(orderId, orderSupplierId, boxProductId, boxType)组合字典中便于查找
Map<Long, OrderPackageDO> existingPackageMap = existingPackages.stream() Map<String, OrderPackageDO> existingPackageMap = existingPackages.stream()
.collect(Collectors.toMap(OrderPackageDO::getOrderPackageId, Function.identity())); .collect(Collectors.toMap(
p -> p.getOrderId() + "_" + p.getOrderSupplierId() + "_" + p.getBoxProductId() + "_" + p.getBoxType().getType(),
Function.identity()
));
// 收集需要更新和新增的包材 // 收集需要更新和新增的包材
List<OrderPackageDO> packagesToInsert = new ArrayList<>(); List<OrderPackageDO> packagesToInsert = new ArrayList<>();
@ -923,12 +809,15 @@ public class PurchaseOrderGatewayImpl implements PurchaseOrderGateway {
orderPackage.setOrderId(orderId); orderPackage.setOrderId(orderId);
OrderPackageDO orderPackageDO = orderPackageConvert.toOrderPackageDO(orderPackage); OrderPackageDO orderPackageDO = orderPackageConvert.toOrderPackageDO(orderPackage);
if (orderPackage.getOrderPackageId() != null && existingPackageMap.containsKey(orderPackage.getOrderPackageId())) { // 构建唯一键
String uniqueKey = orderId + "_" + supplierDO.getOrderSupplierId() + "_" + orderPackage.getBoxProductId() + "_" + orderPackage.getBoxType().getType();
if (existingPackageMap.containsKey(uniqueKey)) {
// 更新已存在的包材 // 更新已存在的包材
orderPackageDO.setOrderPackageId(orderPackage.getOrderPackageId()); orderPackageDO.setOrderPackageId(existingPackageMap.get(uniqueKey).getOrderPackageId());
packagesToUpdate.add(orderPackageDO); packagesToUpdate.add(orderPackageDO);
// 从现有映射中移除剩下的就是需要删除的 // 从现有映射中移除剩下的就是需要删除的
existingPackageMap.remove(orderPackage.getOrderPackageId()); existingPackageMap.remove(uniqueKey);
} else { } else {
// 新增包材 // 新增包材
packagesToInsert.add(orderPackageDO); packagesToInsert.add(orderPackageDO);
@ -965,49 +854,12 @@ public class PurchaseOrderGatewayImpl implements PurchaseOrderGateway {
queryWrapper.last("limit 1"); queryWrapper.last("limit 1");
PurchaseOrderDO purchaseOrderDO = purchaseOrderMapper.selectOne(queryWrapper); PurchaseOrderDO purchaseOrderDO = purchaseOrderMapper.selectOne(queryWrapper);
purchaseOrderDO.setActive(purchaseOrderStep3Cmd.getActive()); purchaseOrderDO.setActive(purchaseOrderStep3Cmd.getActive());
purchaseOrderDO.setForeman(purchaseOrderStep3Cmd.getForeman());
purchaseOrderMapper.updateById(purchaseOrderDO); purchaseOrderMapper.updateById(purchaseOrderDO);
// 更新费用信息精细化处理 // 更新费用信息精细化处理
// 获取现有的费用列表 // 获取现有的费用列表
LambdaQueryWrapper<OrderCostDO> costQueryWrapper = Wrappers.lambdaQuery(OrderCostDO.class); saveCostItem(orderId, purchaseOrderStep3Cmd.getOrderCostList().stream().toList());
costQueryWrapper.eq(OrderCostDO::getOrderId, orderId);
List<OrderCostDO> existingCosts = orderCostMapper.selectList(costQueryWrapper);
// 获取更新的费用列表
List<OrderCost> updatedCosts = purchaseOrderStep3Cmd.getOrderCostList().stream().toList();
// 将现有费用映射到ID字典中便于查找
Map<Long, OrderCostDO> existingCostMap = existingCosts.stream()
.collect(Collectors.toMap(OrderCostDO::getOrderCostId, Function.identity()));
// 收集需要更新和新增的费用
List<OrderCostDO> costsToInsert = new ArrayList<>();
List<OrderCostDO> costsToUpdate = new ArrayList<>();
for (OrderCost updatedCost : updatedCosts) {
updatedCost.setOrderId(orderId);
OrderCostDO costDO = orderCostConvert.toOrderCostDO(updatedCost);
if (updatedCost.getOrderCostId() != null && existingCostMap.containsKey(updatedCost.getOrderCostId())) {
// 更新已存在的费用
costDO.setOrderCostId(updatedCost.getOrderCostId());
costsToUpdate.add(costDO);
// 从现有映射中移除剩下的就是需要删除的
existingCostMap.remove(updatedCost.getOrderCostId());
} else {
// 新增费用
costsToInsert.add(costDO);
}
}
// 删除不再需要的费用
existingCostMap.values().forEach(cost -> cost.deleteById());
// 执行更新操作
costsToUpdate.forEach(orderCostMapper::updateById);
// 执行插入操作
costsToInsert.forEach(orderCostMapper::insert);
// 空箱费 // 空箱费
if (purchaseOrderStep3Cmd.getOrderPackageList() != null) { if (purchaseOrderStep3Cmd.getOrderPackageList() != null) {
@ -1017,9 +869,9 @@ public class PurchaseOrderGatewayImpl implements PurchaseOrderGateway {
packageQueryWrapper.eq(OrderPackageDO::getOrderId, orderId); packageQueryWrapper.eq(OrderPackageDO::getOrderId, orderId);
List<OrderPackageDO> existingPackages = orderPackageMapper.selectList(packageQueryWrapper); List<OrderPackageDO> existingPackages = orderPackageMapper.selectList(packageQueryWrapper);
// 将现有包材映射到ID字典中便于查找 // 将现有包材映射到boxProductId字典中便于查找
Map<Long, OrderPackageDO> existingPackageMap = existingPackages.stream() Map<Long, OrderPackageDO> existingPackageMap = existingPackages.stream()
.collect(Collectors.toMap(OrderPackageDO::getOrderPackageId, Function.identity())); .collect(Collectors.toMap(OrderPackageDO::getBoxProductId, Function.identity()));
// 收集需要更新和新增的包材 // 收集需要更新和新增的包材
List<OrderPackageDO> packagesToInsert = new ArrayList<>(); List<OrderPackageDO> packagesToInsert = new ArrayList<>();
@ -1030,12 +882,12 @@ public class PurchaseOrderGatewayImpl implements PurchaseOrderGateway {
orderPackage.setOrderId(orderId); orderPackage.setOrderId(orderId);
OrderPackageDO orderPackageDO = orderPackageConvert.toOrderPackageDO(orderPackage); OrderPackageDO orderPackageDO = orderPackageConvert.toOrderPackageDO(orderPackage);
if (orderPackage.getOrderPackageId() != null && existingPackageMap.containsKey(orderPackage.getOrderPackageId())) { if (existingPackageMap.containsKey(orderPackage.getBoxProductId())) {
// 更新已存在的包材 // 更新已存在的包材
orderPackageDO.setOrderPackageId(orderPackage.getOrderPackageId()); orderPackageDO.setOrderPackageId(existingPackageMap.get(orderPackage.getBoxProductId()).getOrderPackageId());
packagesToUpdate.add(orderPackageDO); packagesToUpdate.add(orderPackageDO);
// 从现有映射中移除剩下的就是需要删除的 // 从现有映射中移除剩下的就是需要删除的
existingPackageMap.remove(orderPackage.getOrderPackageId()); existingPackageMap.remove(orderPackage.getBoxProductId());
} else { } else {
// 新增包材 // 新增包材
packagesToInsert.add(orderPackageDO); packagesToInsert.add(orderPackageDO);
@ -1063,5 +915,53 @@ public class PurchaseOrderGatewayImpl implements PurchaseOrderGateway {
OrderVehicleDO orderVehicleDO = orderVehicleMapper.selectOne(queryWrapper); OrderVehicleDO orderVehicleDO = orderVehicleMapper.selectOne(queryWrapper);
return orderVehicleDO != null ? orderVehicleDO.getVehicleNo() : null; return orderVehicleDO != null ? orderVehicleDO.getVehicleNo() : null;
} }
/**
* 更新费用信息精细化处理
* 获取现有的费用列表
*
* @param orderId 采购单Id
* @param orderCostList 更新的费用列表
*/
private void saveCostItem(Long orderId, List<OrderCost> orderCostList) {
// 更新费用信息精细化处理
// 获取现有的费用列表
LambdaQueryWrapper<OrderCostDO> costQueryWrapper = Wrappers.lambdaQuery(OrderCostDO.class);
costQueryWrapper.eq(OrderCostDO::getOrderId, orderId);
List<OrderCostDO> existingCosts = orderCostMapper.selectList(costQueryWrapper);
// 将现有费用映射到itemId字典中便于查找
Map<Long, OrderCostDO> existingCostMap = existingCosts.stream()
.collect(Collectors.toMap(OrderCostDO::getItemId, Function.identity()));
// 收集需要更新和新增的费用
List<OrderCostDO> costsToInsert = new ArrayList<>();
List<OrderCostDO> costsToUpdate = new ArrayList<>();
for (OrderCost updatedCost : orderCostList) {
updatedCost.setOrderId(orderId);
OrderCostDO costDO = orderCostConvert.toOrderCostDO(updatedCost);
if (existingCostMap.containsKey(updatedCost.getItemId())) {
// 更新已存在的费用
costDO.setOrderCostId(existingCostMap.get(updatedCost.getItemId()).getOrderCostId());
costsToUpdate.add(costDO);
// 从现有映射中移除剩下的就是需要删除的
existingCostMap.remove(updatedCost.getItemId());
} else {
// 新增费用
costsToInsert.add(costDO);
}
}
// 删除不再需要的费用
existingCostMap.values().forEach(cost -> cost.deleteById());
// 执行更新操作
costsToUpdate.forEach(orderCostMapper::updateById);
// 执行插入操作
costsToInsert.forEach(orderCostMapper::insert);
}
} }

View File

@ -18,6 +18,7 @@
<result property="accrualTaxRatio" column="accrual_tax_ratio"/> <result property="accrualTaxRatio" column="accrual_tax_ratio"/>
<result property="enableCompanyRebate" column="enable_company_rebate"/> <result property="enableCompanyRebate" column="enable_company_rebate"/>
<result property="companyRebateRatio" column="company_rebate_ratio"/> <result property="companyRebateRatio" column="company_rebate_ratio"/>
<result property="shareAdjusted" column="share_adjusted"/>
<result property="receivable" column="receivable"/> <result property="receivable" column="receivable"/>
<result property="remark" column="remark"/> <result property="remark" column="remark"/>
<result property="status" column="status"/> <result property="status" column="status"/>

View File

@ -19,6 +19,7 @@
<result property="accrualTaxRatio" column="accrual_tax_ratio"/> <result property="accrualTaxRatio" column="accrual_tax_ratio"/>
<result property="enableCompanyRebate" column="enable_company_rebate"/> <result property="enableCompanyRebate" column="enable_company_rebate"/>
<result property="companyRebateRatio" column="company_rebate_ratio"/> <result property="companyRebateRatio" column="company_rebate_ratio"/>
<result property="shareAdjusted" column="share_adjusted"/>
<result property="taxSubsidy" column="tax_subsidy"/> <result property="taxSubsidy" column="tax_subsidy"/>
<result property="taxProvision" column="tax_provision"/> <result property="taxProvision" column="tax_provision"/>
<result property="costDifference" column="cost_difference"/> <result property="costDifference" column="cost_difference"/>

View File

@ -3,9 +3,15 @@ package com.xunhong.erp.turbo.facade.app.executor.cmd;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.xunhong.erp.turbo.api.facade.dto.cmd.VehicleExtractionCmd; import com.xunhong.erp.turbo.api.facade.dto.cmd.VehicleExtractionCmd;
import com.xunhong.erp.turbo.api.facade.dto.vo.VehicleExtractionVO; import com.xunhong.erp.turbo.api.facade.dto.vo.VehicleExtractionVO;
import com.xunhong.erp.turbo.api.infra.api.SettingServiceI;
import com.xunhong.erp.turbo.api.infra.dto.common.SmartRecognitionPromptValue;
import com.xunhong.erp.turbo.api.infra.dto.enums.SettingKeyEnum;
import com.xunhong.erp.turbo.api.infra.dto.qry.SettingShowQry;
import com.xunhong.erp.turbo.api.infra.dto.vo.SettingVO;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.ai.chat.messages.SystemMessage; import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.chat.messages.UserMessage; import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.model.ChatResponse; import org.springframework.ai.chat.model.ChatResponse;
@ -22,30 +28,17 @@ public class VehicleExtractionCmdExe {
private final DeepSeekChatModel deepSeekChatModel; private final DeepSeekChatModel deepSeekChatModel;
@DubboReference(version = "1.0.0")
private final SettingServiceI settingService;
@SneakyThrows @SneakyThrows
public VehicleExtractionVO execute(VehicleExtractionCmd vehicleExtractionCmd) { public VehicleExtractionVO execute(VehicleExtractionCmd vehicleExtractionCmd) {
SystemMessage systemMessage = SystemMessage.builder().text("# 角色\n" + SettingShowQry settingShowQry = new SettingShowQry();
"你是物流信息处理助手,可以快速提取和整理运单中的关键信息(车牌号、司机、电话、出发地、目的地、运费)。\n" + settingShowQry.setSettingKey(SettingKeyEnum.SMART_RECOGNITION_PROMPT);
"# 任务1\n" + SettingVO settingVO = settingService.show(settingShowQry);
"请从运单信息中提取车牌、司机、电话、出发地、目的地、运费等信息并返回一个JSON格式的字符串。\n" + SmartRecognitionPromptValue smartRecognitionPromptValue = (SmartRecognitionPromptValue) settingVO.getSettingValue();
"# 任务2\n" +
"通过目的地去匹配经销商名称,待匹配列表如下" + SystemMessage systemMessage = SystemMessage.builder().text(smartRecognitionPromptValue.getPrompt().replace("{经销商列表}", vehicleExtractionCmd.getDealerNames())).build();
"\n" + vehicleExtractionCmd.getDealerNames() +
"\n" +
"# 限制\n" +
"只做信息提取和匹配,如果没有可提取的数据请返回 {}\n" +
"\n" +
"## 输入示例\n" +
"15号装车 9米6高栏 兴仁拉纸箱\n" +
"五合镇附近——湖北襄阳\n" +
"豫RFC220\n" +
"13937795142\n" +
"吨位 18-19吨\n" +
"运费:7000元\n" +
"工作上班时间12小时内卸完货结运费如遇雨天延迟装货不补运费\n" +
"\n" +
"## 输出示例\n" +
"{\"plate\":\"豫RFC220\",\"driver\":null,\"phone\":\"13937795142\",\"origin\":\"五合镇附近\",\"destination\":\"湖北襄阳\",\"price\":\"7000\",\"dealerName\":\"xxxx\"}").build();
UserMessage userMessage = UserMessage.builder().text(vehicleExtractionCmd.getMessage()).build(); UserMessage userMessage = UserMessage.builder().text(vehicleExtractionCmd.getMessage()).build();
Prompt prompt = Prompt.builder().messages(List.of(systemMessage, userMessage)).build(); Prompt prompt = Prompt.builder().messages(List.of(systemMessage, userMessage)).build();

View File

@ -112,5 +112,11 @@ public class DealerCreateCmd extends Command {
@Schema(title = "公司返点比例") @Schema(title = "公司返点比例")
private BigDecimal companyRebateRatio; private BigDecimal companyRebateRatio;
/**
* 是否可调整比例
*/
@Schema(title = "是否可调整比例")
private Boolean shareAdjusted;
} }

View File

@ -33,6 +33,12 @@ public class PurchaseOrderCreateCmd extends Command {
@Schema(title = "产地负责人") @Schema(title = "产地负责人")
private String originPrincipal; private String originPrincipal;
/**
* 工头
*/
@Schema(title = "工头")
private String foreman;
/** /**
* 备注 * 备注
*/ */

View File

@ -29,6 +29,12 @@ public class PurchaseOrderStep3Cmd extends Command {
@Schema(title = "步骤标识") @Schema(title = "步骤标识")
private Integer active; private Integer active;
/**
* 工头
*/
@Schema(title = "工头")
private String foreman;
/** /**
* 费用信息 * 费用信息
*/ */

View File

@ -100,6 +100,12 @@ public class OrderDealer extends Command {
@Schema(title = "公司返点比例") @Schema(title = "公司返点比例")
private BigDecimal companyRebateRatio; private BigDecimal companyRebateRatio;
/**
* 是否可调整比例
*/
@Schema(title = "是否可调整比例")
private Boolean shareAdjusted;
/** /**
* 税费补贴 * 税费补贴
*/ */

View File

@ -131,5 +131,11 @@ public class DealerVO extends DTO {
*/ */
@Schema(title = "公司返点比例") @Schema(title = "公司返点比例")
private BigDecimal companyRebateRatio; private BigDecimal companyRebateRatio;
/**
* 是否可调整比例
*/
@Schema(title = "是否可调整比例")
private Boolean shareAdjusted;
} }

View File

@ -50,6 +50,12 @@ public class PurchaseOrderVO extends DTO {
@Schema(title = "产地负责人") @Schema(title = "产地负责人")
private String originPrincipal; private String originPrincipal;
/**
* 工头
*/
@Schema(title = "工头")
private String foreman;
/** /**
* 报价方式1_按毛重报价2_按净重报价 * 报价方式1_按毛重报价2_按净重报价
*/ */

View File

@ -26,6 +26,7 @@ import com.xunhong.erp.turbo.api.infra.dto.enums.SettingKeyEnum;
@JsonSubTypes.Type(value = CustomMenuConfigValue.class, name = "CUSTOM_MENU_CONFIG"), @JsonSubTypes.Type(value = CustomMenuConfigValue.class, name = "CUSTOM_MENU_CONFIG"),
@JsonSubTypes.Type(value = WxCpNotifyConfigValue.class, name = "WX_CP_NOTIFY_CONFIG"), @JsonSubTypes.Type(value = WxCpNotifyConfigValue.class, name = "WX_CP_NOTIFY_CONFIG"),
@JsonSubTypes.Type(value = TencentMapConfigValue.class, name = "TENCENT_MAP_CONFIG"), @JsonSubTypes.Type(value = TencentMapConfigValue.class, name = "TENCENT_MAP_CONFIG"),
@JsonSubTypes.Type(value = SmartRecognitionPromptValue.class, name = "SMART_RECOGNITION_PROMPT"),
}) })
public interface SettingValue { public interface SettingValue {
// 必须包含获取类型标识的方法 // 必须包含获取类型标识的方法

View File

@ -0,0 +1,22 @@
package com.xunhong.erp.turbo.api.infra.dto.common;
import com.alibaba.cola.dto.DTO;
import com.fasterxml.jackson.annotation.JsonTypeName;
import com.xunhong.erp.turbo.api.infra.dto.enums.SettingKeyEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@JsonTypeName("SMART_RECOGNITION_PROMPT")
@Schema(title = "智能识别提示词")
@EqualsAndHashCode(callSuper = true)
public class SmartRecognitionPromptValue extends DTO implements SettingValue {
@Schema(title = "提示词", requiredMode = Schema.RequiredMode.REQUIRED)
private String prompt;
@Override
public SettingKeyEnum getSettingKey() {
return SettingKeyEnum.SMART_RECOGNITION_PROMPT;
}
}

View File

@ -66,8 +66,11 @@ public enum SettingKeyEnum {
/** /**
* 微信公众号通知配置 * 微信公众号通知配置
*/ */
WX_CP_NOTIFY_CONFIG("WX_CP_NOTIFY_CONFIG"); WX_CP_NOTIFY_CONFIG("WX_CP_NOTIFY_CONFIG"),
/**
* 智能识别提示词
*/
SMART_RECOGNITION_PROMPT("SMART_RECOGNITION_PROMPT");
@EnumValue @EnumValue
private final String key; private final String key;

View File

@ -28,7 +28,7 @@ spring:
endpoint: a15f98504b.iotda.cn-north-4.myhuaweicloud.com endpoint: a15f98504b.iotda.cn-north-4.myhuaweicloud.com
server: server:
port: 38080 port: 8080
dubbo: dubbo:
enabled: false enabled: false