优化
This commit is contained in:
@@ -18,6 +18,6 @@ public class InboundProperties {
|
||||
private boolean allowRejectedMeasurement = false;
|
||||
private BigDecimal defaultPalletCapacityCbm = new BigDecimal("1.200000");
|
||||
private Duration reservationTtl = Duration.ofMinutes(30);
|
||||
/** 共享收货仓资源所属租户;0 表示与入库业务租户一致。 */
|
||||
/** 历史配置兼容字段;平台公共仓资源当前固定使用技术作用域 0。 */
|
||||
private long warehouseResourceTenantId = 0L;
|
||||
}
|
||||
|
||||
+3
-10
@@ -3,10 +3,9 @@ package com.baiyue.firstleg.controller;
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import com.baiyue.common.core.api.ApiResponse;
|
||||
import com.baiyue.common.core.api.ResultCode;
|
||||
import com.baiyue.common.core.exception.BizException;
|
||||
import com.baiyue.common.security.AuthenticatedUser;
|
||||
import com.baiyue.firstleg.dto.MerchantInboundBillingResponse;
|
||||
import com.baiyue.firstleg.service.FirstlegScopeGuard;
|
||||
import com.baiyue.firstleg.service.MerchantInboundBillingService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
@@ -33,10 +32,7 @@ public class MerchantInboundBillingController {
|
||||
description = "客户只读查看客服审核通过后发布的费用,不需要确认费用。")
|
||||
public ApiResponse<MerchantInboundBillingResponse> find(
|
||||
@AuthenticationPrincipal AuthenticatedUser user, @PathVariable long orderId) {
|
||||
if (user == null || !"MERCHANT".equals(user.appCode()) || user.tenantId() == null) {
|
||||
throw new BizException(ResultCode.FORBIDDEN, "仅允许客户端访问");
|
||||
}
|
||||
return ApiResponse.success(service.find(user.tenantId(), orderId));
|
||||
return ApiResponse.success(service.find(FirstlegScopeGuard.merchant(user), orderId));
|
||||
}
|
||||
|
||||
@GetMapping("/{orderId}/inbound-billing/images/{fileId}")
|
||||
@@ -46,10 +42,7 @@ public class MerchantInboundBillingController {
|
||||
@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@PathVariable long orderId,
|
||||
@PathVariable long fileId) {
|
||||
if (user == null || !"MERCHANT".equals(user.appCode()) || user.tenantId() == null) {
|
||||
throw new BizException(ResultCode.FORBIDDEN, "仅允许客户端访问");
|
||||
}
|
||||
var image = service.downloadImage(user.tenantId(), orderId, fileId);
|
||||
var image = service.downloadImage(FirstlegScopeGuard.merchant(user), orderId, fileId);
|
||||
return ResponseEntity.ok().cacheControl(CacheControl.noStore())
|
||||
.contentType(MediaType.parseMediaType(image.contentType()))
|
||||
.contentLength(image.content().length).body(image.content());
|
||||
|
||||
+1
-5
@@ -4,8 +4,6 @@ import jakarta.annotation.Resource;
|
||||
|
||||
import com.baiyue.common.audit.BusinessAudit;
|
||||
import com.baiyue.common.core.api.ApiResponse;
|
||||
import com.baiyue.common.core.api.ResultCode;
|
||||
import com.baiyue.common.core.exception.BizException;
|
||||
import com.baiyue.common.security.AuthenticatedUser;
|
||||
import com.baiyue.firstleg.dto.FbaPricingDtos.CarrierRateVersionRequest;
|
||||
import com.baiyue.firstleg.dto.FbaPricingDtos.CustomerRuleVersionRequest;
|
||||
@@ -114,9 +112,7 @@ public class PlatformFbaMasterDataController {
|
||||
}
|
||||
|
||||
private static Long optionalPlatformTenant(AuthenticatedUser user, Long tenantId) {
|
||||
if (user == null || !"PLATFORM".equals(user.appCode())) {
|
||||
throw new BizException(ResultCode.FORBIDDEN, "仅允许平台端访问");
|
||||
}
|
||||
FirstlegScopeGuard.platform(user);
|
||||
return tenantId == null ? null : FirstlegScopeGuard.platform(user, tenantId);
|
||||
}
|
||||
}
|
||||
|
||||
+6
-23
@@ -3,14 +3,13 @@ package com.baiyue.firstleg.controller;
|
||||
import com.baiyue.common.audit.BusinessAudit;
|
||||
import com.baiyue.common.core.api.ApiResponse;
|
||||
import com.baiyue.common.core.api.PageResult;
|
||||
import com.baiyue.common.core.api.ResultCode;
|
||||
import com.baiyue.common.core.exception.BizException;
|
||||
import com.baiyue.common.security.AuthenticatedUser;
|
||||
import com.baiyue.firstleg.dto.AssignRequest;
|
||||
import com.baiyue.firstleg.dto.FulfillmentTaskQuery;
|
||||
import com.baiyue.firstleg.entity.AssignmentHistoryEntity;
|
||||
import com.baiyue.firstleg.entity.FulfillmentTaskEntity;
|
||||
import com.baiyue.firstleg.service.FulfillmentTaskService;
|
||||
import com.baiyue.firstleg.service.FirstlegScopeGuard;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
||||
@@ -65,8 +64,7 @@ public class PlatformFulfillmentAssignmentController {
|
||||
@Parameter(description = "First-leg fulfillment task ID / 头程履约任务 ID", example = "190000000000000101", required = true)
|
||||
@PathVariable long taskId,
|
||||
@Valid @RequestBody AssignRequest request) {
|
||||
requirePlatform(user);
|
||||
requireTenant(tenantId);
|
||||
FirstlegScopeGuard.platform(user, tenantId);
|
||||
service.assign(
|
||||
tenantId,
|
||||
user.userId(),
|
||||
@@ -89,8 +87,7 @@ public class PlatformFulfillmentAssignmentController {
|
||||
@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@RequestParam long tenantId,
|
||||
@Valid FulfillmentTaskQuery query) {
|
||||
requirePlatform(user);
|
||||
requireTenant(tenantId);
|
||||
FirstlegScopeGuard.platform(user, tenantId);
|
||||
return ApiResponse.success(service.page(tenantId, query));
|
||||
}
|
||||
|
||||
@@ -105,8 +102,7 @@ public class PlatformFulfillmentAssignmentController {
|
||||
@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@RequestParam long tenantId,
|
||||
@PathVariable long taskId) {
|
||||
requirePlatform(user);
|
||||
requireTenant(tenantId);
|
||||
FirstlegScopeGuard.platform(user, tenantId);
|
||||
return ApiResponse.success(service.detail(tenantId, taskId));
|
||||
}
|
||||
|
||||
@@ -121,8 +117,7 @@ public class PlatformFulfillmentAssignmentController {
|
||||
@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@RequestParam long tenantId,
|
||||
@PathVariable long orderId) {
|
||||
requirePlatform(user);
|
||||
requireTenant(tenantId);
|
||||
FirstlegScopeGuard.platform(user, tenantId);
|
||||
return ApiResponse.success(service.byOrder(tenantId, orderId));
|
||||
}
|
||||
|
||||
@@ -139,20 +134,8 @@ public class PlatformFulfillmentAssignmentController {
|
||||
@PathVariable long taskId,
|
||||
@RequestParam(defaultValue = "1") @Min(1) long page,
|
||||
@RequestParam(defaultValue = "20") @Min(1) @Max(200) long size) {
|
||||
requirePlatform(user);
|
||||
requireTenant(tenantId);
|
||||
FirstlegScopeGuard.platform(user, tenantId);
|
||||
return ApiResponse.success(service.assignmentHistory(tenantId, taskId, page, size));
|
||||
}
|
||||
|
||||
private static void requirePlatform(AuthenticatedUser user) {
|
||||
if (user == null || !"PLATFORM".equals(user.appCode())) {
|
||||
throw new BizException(ResultCode.FORBIDDEN, "仅允许平台端访问");
|
||||
}
|
||||
}
|
||||
|
||||
private static void requireTenant(long tenantId) {
|
||||
if (tenantId <= 0) {
|
||||
throw new BizException(ResultCode.BAD_REQUEST, "必须指定有效目标租户");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-4
@@ -9,6 +9,7 @@ import com.baiyue.common.core.exception.BizException;
|
||||
import com.baiyue.common.security.AuthenticatedUser;
|
||||
import com.baiyue.firstleg.dto.InboundMeasurementRequests;
|
||||
import com.baiyue.firstleg.dto.InboundMeasurementResponses;
|
||||
import com.baiyue.firstleg.service.FirstlegScopeGuard;
|
||||
import com.baiyue.firstleg.service.InboundMeasurementService;
|
||||
import com.baiyue.firstleg.service.MeasurementSubmissionService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
@@ -120,10 +121,8 @@ public class PlatformInboundMeasurementController {
|
||||
}
|
||||
|
||||
private static void requirePlatformTenant(AuthenticatedUser user, long tenantId) {
|
||||
if (user == null || !"PLATFORM".equals(user.appCode())) {
|
||||
throw new BizException(ResultCode.FORBIDDEN, "仅允许平台端访问");
|
||||
}
|
||||
if (tenantId <= 0 || user.userId() == null || user.userId() <= 0) {
|
||||
FirstlegScopeGuard.platform(user, tenantId);
|
||||
if (user.userId() == null || user.userId() <= 0) {
|
||||
throw new BizException(ResultCode.BAD_REQUEST, "必须指定有效目标租户和操作人");
|
||||
}
|
||||
}
|
||||
|
||||
+2
-8
@@ -5,14 +5,13 @@ import jakarta.annotation.Resource;
|
||||
import com.baiyue.common.audit.BusinessAudit;
|
||||
import com.baiyue.common.core.api.ApiResponse;
|
||||
import com.baiyue.common.core.api.PageResult;
|
||||
import com.baiyue.common.core.api.ResultCode;
|
||||
import com.baiyue.common.core.exception.BizException;
|
||||
import com.baiyue.common.security.AuthenticatedUser;
|
||||
import com.baiyue.firstleg.dto.ExceptionReleaseRequest;
|
||||
import com.baiyue.firstleg.dto.MeasurementReviewRequest;
|
||||
import com.baiyue.firstleg.entity.MeasureReviewRecordEntity;
|
||||
import com.baiyue.firstleg.service.MeasurementReviewService;
|
||||
import com.baiyue.firstleg.service.AutomaticInboundCompletionService;
|
||||
import com.baiyue.firstleg.service.FirstlegScopeGuard;
|
||||
import com.baiyue.firstleg.dto.FbaPricingDtos.FeeSnapshotResponse;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
@@ -108,11 +107,6 @@ public class PlatformInboundMeasurementReviewController {
|
||||
}
|
||||
|
||||
private static void validateScope(AuthenticatedUser user, long tenantId) {
|
||||
if (user == null || !"PLATFORM".equals(user.appCode())) {
|
||||
throw new BizException(ResultCode.FORBIDDEN, "仅允许平台端访问");
|
||||
}
|
||||
if (tenantId <= 0) {
|
||||
throw new BizException(ResultCode.BAD_REQUEST, "必须指定有效目标租户");
|
||||
}
|
||||
FirstlegScopeGuard.platform(user, tenantId);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-7
@@ -10,6 +10,7 @@ import com.baiyue.common.security.AuthenticatedUser;
|
||||
import com.baiyue.firstleg.dto.InboundOrderDetail;
|
||||
import com.baiyue.firstleg.dto.InboundOrderQuery;
|
||||
import com.baiyue.firstleg.dto.InboundOrderSummary;
|
||||
import com.baiyue.firstleg.service.FirstlegScopeGuard;
|
||||
import com.baiyue.firstleg.service.InboundOrderQueryService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
@@ -61,15 +62,10 @@ public class PlatformInboundOrderController {
|
||||
}
|
||||
|
||||
private static void requirePlatformTenant(AuthenticatedUser user, long tenantId) {
|
||||
requirePlatform(user);
|
||||
if (tenantId <= 0) {
|
||||
throw new BizException(ResultCode.BAD_REQUEST, "必须指定有效目标租户");
|
||||
}
|
||||
FirstlegScopeGuard.platform(user, tenantId);
|
||||
}
|
||||
|
||||
private static void requirePlatform(AuthenticatedUser user) {
|
||||
if (user == null || !"PLATFORM".equals(user.appCode())) {
|
||||
throw new BizException(ResultCode.FORBIDDEN, "仅允许平台端访问");
|
||||
}
|
||||
FirstlegScopeGuard.platform(user);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,8 @@ public interface InboundIdempotencyMapper extends BaseMapper<InboundIdempotencyE
|
||||
@Update("""
|
||||
UPDATE fl_inbound_idempotency
|
||||
SET status = 'SUCCESS', result_json = #{resultJson}, completed_at = CURRENT_TIMESTAMP(3)
|
||||
WHERE id = #{id} AND status = 'PROCESSING'
|
||||
WHERE tenant_id = #{tenantId} AND id = #{id} AND status = 'PROCESSING'
|
||||
""")
|
||||
int complete(@Param("id") long id, @Param("resultJson") String resultJson);
|
||||
int complete(@Param("tenantId") long tenantId, @Param("id") long id,
|
||||
@Param("resultJson") String resultJson);
|
||||
}
|
||||
|
||||
@@ -250,6 +250,7 @@ public class FbaPricingRepository {
|
||||
|
||||
public int completeIdempotency(InboundPricingIdempotencyEntity value, long resourceId, LocalDateTime now) {
|
||||
return idempotencies.update(null, new LambdaUpdateWrapper<InboundPricingIdempotencyEntity>()
|
||||
.eq(InboundPricingIdempotencyEntity::getTenantId, value.getTenantId())
|
||||
.eq(InboundPricingIdempotencyEntity::getId, value.getId())
|
||||
.eq(InboundPricingIdempotencyEntity::getStatus, "PROCESSING")
|
||||
.set(InboundPricingIdempotencyEntity::getStatus, "COMPLETED")
|
||||
|
||||
@@ -60,11 +60,15 @@ public class FeeItemRepository {
|
||||
}
|
||||
|
||||
public int updateItem(FeeItemEntity item) {
|
||||
return feeItems.updateById(item);
|
||||
return feeItems.update(item, new LambdaUpdateWrapper<FeeItemEntity>()
|
||||
.eq(FeeItemEntity::getTenantId, item.getTenantId())
|
||||
.eq(FeeItemEntity::getId, item.getId()));
|
||||
}
|
||||
|
||||
public int deleteItem(long id) {
|
||||
return feeItems.deleteById(id);
|
||||
public int deleteItem(long tenantId, long id) {
|
||||
return feeItems.delete(new LambdaQueryWrapper<FeeItemEntity>()
|
||||
.eq(FeeItemEntity::getTenantId, tenantId)
|
||||
.eq(FeeItemEntity::getId, id));
|
||||
}
|
||||
|
||||
public long countBindings(long tenantId, long feeItemId) {
|
||||
@@ -99,11 +103,15 @@ public class FeeItemRepository {
|
||||
}
|
||||
|
||||
public int updateDetail(InboundFeeDetailEntity detail) {
|
||||
return feeDetails.updateById(detail);
|
||||
return feeDetails.update(detail, new LambdaUpdateWrapper<InboundFeeDetailEntity>()
|
||||
.eq(InboundFeeDetailEntity::getTenantId, detail.getTenantId())
|
||||
.eq(InboundFeeDetailEntity::getId, detail.getId()));
|
||||
}
|
||||
|
||||
public int deleteDetail(long detailId) {
|
||||
return feeDetails.deleteById(detailId);
|
||||
public int deleteDetail(long tenantId, long detailId) {
|
||||
return feeDetails.delete(new LambdaQueryWrapper<InboundFeeDetailEntity>()
|
||||
.eq(InboundFeeDetailEntity::getTenantId, tenantId)
|
||||
.eq(InboundFeeDetailEntity::getId, detailId));
|
||||
}
|
||||
|
||||
public int review(long tenantId, long inboundId, long detailId, String targetStatus,
|
||||
|
||||
+4
-1
@@ -5,6 +5,7 @@ import jakarta.annotation.Resource;
|
||||
import com.baiyue.common.core.api.PageResult;
|
||||
import com.baiyue.firstleg.dto.FulfillmentTaskQuery;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baiyue.firstleg.entity.AssignmentHistoryEntity;
|
||||
import com.baiyue.firstleg.entity.FulfillmentTaskEntity;
|
||||
@@ -53,7 +54,9 @@ public class FulfillmentTaskRepository {
|
||||
}
|
||||
|
||||
public boolean update(FulfillmentTaskEntity task) {
|
||||
return tasks.updateById(task) == 1;
|
||||
return tasks.update(task, new LambdaUpdateWrapper<FulfillmentTaskEntity>()
|
||||
.eq(FulfillmentTaskEntity::getTenantId, task.getTenantId())
|
||||
.eq(FulfillmentTaskEntity::getId, task.getId())) == 1;
|
||||
}
|
||||
|
||||
public void insertHistory(AssignmentHistoryEntity history) {
|
||||
|
||||
+10
-3
@@ -3,6 +3,7 @@ package com.baiyue.firstleg.repository;
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baiyue.firstleg.entity.InboundMeasurementEntity;
|
||||
import com.baiyue.firstleg.entity.InboundMeasurementItemEntity;
|
||||
import com.baiyue.firstleg.entity.InboundOrderEntity;
|
||||
@@ -42,7 +43,9 @@ public class InboundMeasurementRepository {
|
||||
}
|
||||
|
||||
public boolean updateInbound(InboundOrderEntity inbound) {
|
||||
return inboundOrders.updateById(inbound) == 1;
|
||||
return inboundOrders.update(inbound, new LambdaUpdateWrapper<InboundOrderEntity>()
|
||||
.eq(InboundOrderEntity::getTenantId, inbound.getTenantId())
|
||||
.eq(InboundOrderEntity::getId, inbound.getId())) == 1;
|
||||
}
|
||||
|
||||
public InboundMeasurementEntity findMeasurement(long tenantId, long inboundId, long measurementId) {
|
||||
@@ -72,7 +75,9 @@ public class InboundMeasurementRepository {
|
||||
}
|
||||
|
||||
public boolean updateMeasurement(InboundMeasurementEntity measurement) {
|
||||
return measurements.updateById(measurement) == 1;
|
||||
return measurements.update(measurement, new LambdaUpdateWrapper<InboundMeasurementEntity>()
|
||||
.eq(InboundMeasurementEntity::getTenantId, measurement.getTenantId())
|
||||
.eq(InboundMeasurementEntity::getId, measurement.getId())) == 1;
|
||||
}
|
||||
|
||||
public void replaceItems(long tenantId, long measurementId,
|
||||
@@ -109,7 +114,9 @@ public class InboundMeasurementRepository {
|
||||
}
|
||||
|
||||
public boolean updateWeight(InboundWeightResultEntity weight) {
|
||||
return weights.updateById(weight) == 1;
|
||||
return weights.update(weight, new LambdaUpdateWrapper<InboundWeightResultEntity>()
|
||||
.eq(InboundWeightResultEntity::getTenantId, weight.getTenantId())
|
||||
.eq(InboundWeightResultEntity::getId, weight.getId())) == 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+2
-2
@@ -108,8 +108,8 @@ public class InboundWorkflowRepository {
|
||||
.eq(InboundIdempotencyEntity::getIdempotencyKey, key));
|
||||
}
|
||||
|
||||
public int completeIdempotency(long id, String resultJson) {
|
||||
return idempotencies.complete(id, resultJson);
|
||||
public int completeIdempotency(long tenantId, long id, String resultJson) {
|
||||
return idempotencies.complete(tenantId, id, resultJson);
|
||||
}
|
||||
|
||||
public InboundFeeEntity findConfirmedFee(long tenantId, long inboundId, long feeId) {
|
||||
|
||||
@@ -67,7 +67,7 @@ public class FeeItemService {
|
||||
if (repository.countBindings(tenantId, id) > 0) {
|
||||
throw conflict("费用项目已被入库费用明细使用,只能停用,不能删除");
|
||||
}
|
||||
if (repository.deleteItem(id) != 1) throw conflict("费用项目删除冲突");
|
||||
if (repository.deleteItem(tenantId, id) != 1) throw conflict("费用项目删除冲突");
|
||||
}
|
||||
|
||||
private FeeItemEntity required(long tenantId, long id) {
|
||||
|
||||
@@ -4,17 +4,30 @@ import com.baiyue.common.core.api.ResultCode;
|
||||
import com.baiyue.common.core.exception.BizException;
|
||||
import com.baiyue.common.security.AuthenticatedUser;
|
||||
|
||||
/** 头程平台接口租户边界校验。 */
|
||||
/** 头程平台与客户接口的主体边界校验。 */
|
||||
public final class FirstlegScopeGuard {
|
||||
private FirstlegScopeGuard() {}
|
||||
|
||||
public static long platform(AuthenticatedUser user, long targetTenantId) {
|
||||
if (user == null || !"PLATFORM".equals(user.appCode())) {
|
||||
throw new BizException(ResultCode.FORBIDDEN, "仅允许平台端访问");
|
||||
}
|
||||
platform(user);
|
||||
if (targetTenantId <= 0) {
|
||||
throw new BizException(ResultCode.BAD_REQUEST, "必须指定有效目标租户");
|
||||
}
|
||||
return targetTenantId;
|
||||
}
|
||||
|
||||
public static void platform(AuthenticatedUser user) {
|
||||
if (user == null || !"PLATFORM".equals(user.appCode())
|
||||
|| user.tenantId() == null || user.tenantId() != 0L) {
|
||||
throw new BizException(ResultCode.FORBIDDEN, "仅允许平台端访问");
|
||||
}
|
||||
}
|
||||
|
||||
public static long merchant(AuthenticatedUser user) {
|
||||
if (user == null || !"MERCHANT".equals(user.appCode())
|
||||
|| user.tenantId() == null || user.tenantId() <= 0L) {
|
||||
throw new BizException(ResultCode.FORBIDDEN, "仅允许客户端访问");
|
||||
}
|
||||
return user.tenantId();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ public class InboundFeeDetailService {
|
||||
@Transactional
|
||||
public void delete(long tenantId, long inboundId, long detailId) {
|
||||
requiredEditable(tenantId, inboundId, detailId);
|
||||
if (repository.deleteDetail(detailId) != 1) throw conflict("费用明细删除冲突");
|
||||
if (repository.deleteDetail(tenantId, detailId) != 1) throw conflict("费用明细删除冲突");
|
||||
}
|
||||
|
||||
@Transactional
|
||||
|
||||
@@ -44,7 +44,7 @@ public class InboundIdempotencyService {
|
||||
record.setUpdatedAt(record.getCreatedAt());
|
||||
try {
|
||||
repository.insertIdempotency(record);
|
||||
return new Context(record.getId(), false);
|
||||
return new Context(tenantId, record.getId(), false);
|
||||
} catch (DuplicateKeyException duplicate) {
|
||||
InboundIdempotencyEntity existing = repository.findIdempotency(
|
||||
tenantId, operation, operatorId, key);
|
||||
@@ -53,7 +53,7 @@ public class InboundIdempotencyService {
|
||||
"Idempotency-Key 已用于不同请求");
|
||||
}
|
||||
if ("SUCCESS".equals(existing.getStatus())) {
|
||||
return new Context(existing.getId(), true);
|
||||
return new Context(tenantId, existing.getId(), true);
|
||||
}
|
||||
throw new BizException(ResultCode.CONFLICT, "相同请求正在处理中,请稍后重试");
|
||||
}
|
||||
@@ -61,7 +61,8 @@ public class InboundIdempotencyService {
|
||||
|
||||
public void complete(Context context, long inboundId) {
|
||||
if (!context.replayed()
|
||||
&& repository.completeIdempotency(context.id(), "{\"inboundId\":\"" + inboundId + "\"}") != 1) {
|
||||
&& repository.completeIdempotency(context.tenantId(), context.id(),
|
||||
"{\"inboundId\":\"" + inboundId + "\"}") != 1) {
|
||||
throw new BizException(ResultCode.CONFLICT, "幂等记录已被并发修改");
|
||||
}
|
||||
}
|
||||
@@ -75,6 +76,6 @@ public class InboundIdempotencyService {
|
||||
}
|
||||
}
|
||||
|
||||
public record Context(long id, boolean replayed) {
|
||||
public record Context(long tenantId, long id, boolean replayed) {
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -20,6 +20,7 @@ import java.time.LocalDateTime;
|
||||
@Service
|
||||
public class MeasurementLocationOccupationService {
|
||||
private static final String SOURCE_SERVICE = "firstleg-service";
|
||||
private static final long PLATFORM_WAREHOUSE_RESOURCE_TENANT_ID = 0L;
|
||||
@Resource
|
||||
private WarehousePalletLocationClient warehouse;
|
||||
@Resource
|
||||
@@ -35,8 +36,7 @@ public class MeasurementLocationOccupationService {
|
||||
int measurementVersion) {
|
||||
InboundOrderEntity order = requireOrder(tenantId, inboundId);
|
||||
long warehouseId = requireWarehouse(order);
|
||||
long resourceTenantId = properties.getWarehouseResourceTenantId() > 0
|
||||
? properties.getWarehouseResourceTenantId() : tenantId;
|
||||
long resourceTenantId = PLATFORM_WAREHOUSE_RESOURCE_TENANT_ID;
|
||||
BigDecimal volume = requireVolume(order);
|
||||
String key = "measure-" + inboundId + "-" + measurementId + "-" + measurementVersion;
|
||||
WarehousePalletLocationClient.BatchResult reserved = requireSuccess(call(() -> warehouse.reserve(
|
||||
|
||||
@@ -4,6 +4,7 @@ import jakarta.annotation.Resource;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baiyue.firstleg.config.MeasurementOpenApiProperties;
|
||||
import com.baiyue.firstleg.entity.ThirdPartyCallLogEntity;
|
||||
import com.baiyue.firstleg.mapper.ThirdPartyCallLogMapper;
|
||||
@@ -55,6 +56,10 @@ public class ThirdPartyCallLogService {
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void complete(long id, String status, String code, String message, String resultJson) {
|
||||
Long tenantId = tenantId(id);
|
||||
if (tenantId == null) {
|
||||
return;
|
||||
}
|
||||
ThirdPartyCallLogEntity update = new ThirdPartyCallLogEntity();
|
||||
update.setId(id);
|
||||
update.setProcessingStatus(status);
|
||||
@@ -62,18 +67,25 @@ public class ThirdPartyCallLogService {
|
||||
update.setResultMessage(limit(message, 1000));
|
||||
update.setResultJson(resultJson);
|
||||
update.setProcessedAt(LocalDateTime.now());
|
||||
mapper.updateById(update);
|
||||
mapper.update(update, new LambdaUpdateWrapper<ThirdPartyCallLogEntity>()
|
||||
.eq(ThirdPartyCallLogEntity::getTenantId, tenantId)
|
||||
.eq(ThirdPartyCallLogEntity::getId, id));
|
||||
}
|
||||
|
||||
/** 签名通过后原子认领 Idempotency-Key;非法签名不会污染幂等空间。 */
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public boolean claimIdempotency(long logId) {
|
||||
Long tenantId = tenantId(logId);
|
||||
if (tenantId == null) {
|
||||
return false;
|
||||
}
|
||||
ThirdPartyCallLogEntity update = new ThirdPartyCallLogEntity();
|
||||
update.setId(logId);
|
||||
update.setIdempotencyAnchor(1);
|
||||
try {
|
||||
mapper.updateById(update);
|
||||
return true;
|
||||
return mapper.update(update, new LambdaUpdateWrapper<ThirdPartyCallLogEntity>()
|
||||
.eq(ThirdPartyCallLogEntity::getTenantId, tenantId)
|
||||
.eq(ThirdPartyCallLogEntity::getId, logId)) == 1;
|
||||
} catch (DuplicateKeyException exception) {
|
||||
return false;
|
||||
}
|
||||
@@ -87,6 +99,11 @@ public class ThirdPartyCallLogService {
|
||||
.eq(ThirdPartyCallLogEntity::getIdempotencyAnchor, 1));
|
||||
}
|
||||
|
||||
private Long tenantId(long id) {
|
||||
ThirdPartyCallLogEntity log = mapper.selectById(id);
|
||||
return log == null ? null : log.getTenantId();
|
||||
}
|
||||
|
||||
private String limit(String value, int max) {
|
||||
if (value == null || value.length() <= max) {
|
||||
return value;
|
||||
|
||||
Reference in New Issue
Block a user