fix: complete order measurement downstream flow
This commit is contained in:
@@ -36,6 +36,10 @@ public interface FirstlegInboundClient {
|
||||
ApiResponse<Void> updateDeclaration(@RequestHeader("X-Internal-Service-Token") String token,
|
||||
@RequestBody OrderDeclarationDtos.UpdatedEvent event);
|
||||
|
||||
@PostMapping("/order-remarks-updated")
|
||||
ApiResponse<Integer> updateRemarks(@RequestHeader("X-Internal-Service-Token") String token,
|
||||
@RequestBody OrderRemarksSyncCommand command);
|
||||
|
||||
@PostMapping("/order-channel-changes/validate")
|
||||
ApiResponse<OrderChannelChangeValidationResponse> validateOrderChannelChange(
|
||||
@RequestHeader("X-Internal-Service-Token") String token,
|
||||
@@ -51,6 +55,9 @@ public interface FirstlegInboundClient {
|
||||
String channelCode) {}
|
||||
record OrderChannelChangeValidationResponse(long orderId, long orderVersion,
|
||||
String channelCode, String mainStatus) {}
|
||||
record OrderRemarksSyncCommand(long tenantId, long orderId, String customerRemark, String internalRemark,
|
||||
String warehouseRemark, String customerServiceRemark,
|
||||
long operatorId, String operatorName) {}
|
||||
|
||||
record OrderApprovedInboundCommand(
|
||||
long tenantId, long orderId, String orderNo, String inboundCode, Long customerId, String customerName,
|
||||
|
||||
@@ -16,6 +16,8 @@ import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
@@ -32,6 +34,7 @@ import java.util.stream.Collectors;
|
||||
@RequestMapping("/internal/order/v1/cargoes")
|
||||
public class InternalOrderCargoController {
|
||||
@Resource private OrderRepository orders;
|
||||
@Resource private OrderApplicationService orderApplicationService;
|
||||
@Resource private PrintableInboundSnapshotService printableInboundSnapshots;
|
||||
@Value("${baiyue.security.internal-service-token}") private String internalToken;
|
||||
private byte[] expectedToken;
|
||||
@@ -146,6 +149,21 @@ public class InternalOrderCargoController {
|
||||
.collect(Collectors.joining("、"))));
|
||||
}
|
||||
|
||||
@PutMapping("/{tenantId}/{orderId}/remarks")
|
||||
public ApiResponse<InternalRemarksUpdateResponse> updateRemarks(
|
||||
@RequestHeader(value = "X-Internal-Service-Token", required = false) String token,
|
||||
@PathVariable long tenantId, @PathVariable long orderId,
|
||||
@RequestBody InternalRemarksUpdateRequest request) {
|
||||
requireToken(token);
|
||||
if (tenantId <= 0 || orderId <= 0 || request == null || request.operatorId() <= 0) {
|
||||
throw new BizException(ResultCode.BAD_REQUEST, "客户、订单和操作人必须大于0");
|
||||
}
|
||||
var result = orderApplicationService.updateRemarksFromFirstleg(tenantId, request.operatorId(), orderId,
|
||||
request.internalRemark(), request.warehouseRemark(), request.customerServiceRemark());
|
||||
return ApiResponse.success(new InternalRemarksUpdateResponse(result.version(), result.customerRemark(),
|
||||
result.internalRemark(), result.warehouseRemark(), result.customerServiceRemark()));
|
||||
}
|
||||
|
||||
private BigDecimal sum(List<OrderCargoEntity> cargoes,
|
||||
java.util.function.Function<OrderCargoEntity, BigDecimal> getter) {
|
||||
List<BigDecimal> values = cargoes.stream().map(getter).filter(Objects::nonNull).toList();
|
||||
@@ -205,4 +223,10 @@ public class InternalOrderCargoController {
|
||||
public record MeasurementDeclarationSnapshot(
|
||||
String referenceId, BigDecimal originalGrossWeightKg,
|
||||
BigDecimal originalVolumeCbm, String defaultActualGoodsName) {}
|
||||
|
||||
public record InternalRemarksUpdateRequest(String internalRemark, String warehouseRemark,
|
||||
String customerServiceRemark, long operatorId) {}
|
||||
public record InternalRemarksUpdateResponse(int version, String customerRemark, String internalRemark,
|
||||
String warehouseRemark, String customerServiceRemark) {}
|
||||
|
||||
}
|
||||
|
||||
@@ -122,6 +122,7 @@ public class PlatformUnifiedOrderController {
|
||||
@PathVariable long orderId,
|
||||
@Valid @RequestBody OrderRequests.RemarksUpdateRequest request) {
|
||||
long scopedTenant = OrderScopeGuard.platform(user, tenantId);
|
||||
return ApiResponse.success(orderService.updateRemarks(scopedTenant, user.userId(), orderId, request));
|
||||
return ApiResponse.success(orderService.updateRemarks(
|
||||
scopedTenant, user.userId(), user.username(), orderId, request));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,6 +271,12 @@ public class OrderApplicationService {
|
||||
@Transactional
|
||||
public OrderRequests.RemarksUpdateResponse updateRemarks(long tenantId, long userId, long id,
|
||||
OrderRequests.RemarksUpdateRequest request) {
|
||||
return updateRemarks(tenantId, userId, null, id, request);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public OrderRequests.RemarksUpdateResponse updateRemarks(long tenantId, long userId, String operatorName, long id,
|
||||
OrderRequests.RemarksUpdateRequest request) {
|
||||
OrderEntity order = require(tenantId, id);
|
||||
String internalRemark = normalizeRemark(request.internalRemark());
|
||||
String warehouseRemark = normalizeRemark(request.warehouseRemark());
|
||||
@@ -284,10 +290,57 @@ public class OrderApplicationService {
|
||||
note.setTenantId(tenantId); note.setOrderId(id); note.setContent(internalRemark);
|
||||
note.setCreatedBy(userId); note.setUpdatedBy(userId); repository.insertNote(note);
|
||||
}
|
||||
syncRemarksToFirstleg(tenantId, id, order.getCustomerRemark(), internalRemark, warehouseRemark, customerServiceRemark,
|
||||
userId, operatorName);
|
||||
return new OrderRequests.RemarksUpdateResponse(order.getVersion() + 1, order.getCustomerRemark(),
|
||||
internalRemark, warehouseRemark, customerServiceRemark);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public OrderRequests.RemarksUpdateResponse updateRemarksFromFirstleg(long tenantId, long userId, long id,
|
||||
String internalValue,
|
||||
String warehouseValue,
|
||||
String customerServiceValue) {
|
||||
requireRemarkLength(internalValue);
|
||||
requireRemarkLength(warehouseValue);
|
||||
requireRemarkLength(customerServiceValue);
|
||||
OrderEntity order = require(tenantId, id);
|
||||
String internalRemark = normalizeRemark(internalValue);
|
||||
String warehouseRemark = normalizeRemark(warehouseValue);
|
||||
String customerServiceRemark = normalizeRemark(customerServiceValue);
|
||||
if (repository.updateRemarks(tenantId, id, order.getVersion(), userId,
|
||||
internalRemark, warehouseRemark, customerServiceRemark) != 1) {
|
||||
throw new BizException(ResultCode.CONFLICT, "订单备注已被其他人修改,请刷新后重试");
|
||||
}
|
||||
if (!Objects.equals(order.getInternalRemark(), internalRemark) && internalRemark != null) {
|
||||
OrderInternalNoteEntity note = new OrderInternalNoteEntity();
|
||||
note.setTenantId(tenantId); note.setOrderId(id); note.setContent(internalRemark);
|
||||
note.setCreatedBy(userId); note.setUpdatedBy(userId); repository.insertNote(note);
|
||||
}
|
||||
return new OrderRequests.RemarksUpdateResponse(order.getVersion() + 1, order.getCustomerRemark(),
|
||||
internalRemark, warehouseRemark, customerServiceRemark);
|
||||
}
|
||||
|
||||
private void syncRemarksToFirstleg(long tenantId, long orderId, String customerRemark, String internalRemark,
|
||||
String warehouseRemark, String customerServiceRemark,
|
||||
long operatorId, String operatorName) {
|
||||
FirstlegInboundClient client = firstlegProvider == null ? null : firstlegProvider.getIfAvailable();
|
||||
if (client == null) return;
|
||||
ApiResponse<Integer> response = client.updateRemarks(internalToken,
|
||||
new FirstlegInboundClient.OrderRemarksSyncCommand(tenantId, orderId, customerRemark, internalRemark,
|
||||
warehouseRemark, customerServiceRemark, operatorId, operatorName));
|
||||
if (response == null || !response.successful()) {
|
||||
throw new BizException(ResultCode.SERVICE_UNAVAILABLE,
|
||||
response == null ? "头程备注同步暂不可用" : response.message());
|
||||
}
|
||||
}
|
||||
|
||||
private static void requireRemarkLength(String value) {
|
||||
if (value != null && value.length() > 1000) {
|
||||
throw new BizException(ResultCode.BAD_REQUEST, "每项备注不能超过1000个字符");
|
||||
}
|
||||
}
|
||||
|
||||
private static String normalizeRemark(String value) {
|
||||
if (value == null || value.trim().isEmpty()) return null;
|
||||
return value.trim();
|
||||
|
||||
@@ -59,6 +59,34 @@ paths:
|
||||
application/json:
|
||||
schema: {$ref: '#/components/schemas/CargoLabelBindingListEnvelope'}
|
||||
'403': {description: 内部服务令牌无效}
|
||||
put:
|
||||
security: []
|
||||
summary: Firstleg 维护订单权威协作备注
|
||||
description: >-
|
||||
仅接受内部服务令牌。预装清单编辑备注时写回 Order 权威订单记录;
|
||||
客户备注保持只读,内部、仓库和客服备注统一按订单版本乐观更新。
|
||||
parameters:
|
||||
- name: X-Internal-Service-Token
|
||||
in: header
|
||||
required: true
|
||||
schema: {type: string}
|
||||
- {name: tenantId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
|
||||
- {name: orderId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required: [operatorId]
|
||||
properties:
|
||||
internalRemark: {type: string, nullable: true, maxLength: 1000}
|
||||
warehouseRemark: {type: string, nullable: true, maxLength: 1000}
|
||||
customerServiceRemark: {type: string, nullable: true, maxLength: 1000}
|
||||
operatorId: {type: integer, format: int64, minimum: 1}
|
||||
responses:
|
||||
'200': {description: 返回订单最新版本和四类备注}
|
||||
'403': {description: 内部服务令牌无效}
|
||||
/internal/order/v1/cargoes/{tenantId}/{orderId}/printable-inbound-snapshot:
|
||||
post:
|
||||
security: []
|
||||
|
||||
Reference in New Issue
Block a user