优化
This commit is contained in:
+13
-7
@@ -9,6 +9,7 @@ import com.baiyue.warehouse.dto.WarehouseDetailResponse;
|
||||
import com.baiyue.warehouse.dto.WarehouseRequests;
|
||||
import com.baiyue.warehouse.entity.WarehouseEntity;
|
||||
import com.baiyue.warehouse.service.WarehouseApplicationService;
|
||||
import com.baiyue.warehouse.security.OverseasWarehousePermissions;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
||||
@@ -17,6 +18,7 @@ import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PatchMapping;
|
||||
@@ -44,7 +46,7 @@ public class PlatformWarehouseController {
|
||||
|
||||
@Operation(
|
||||
summary = "Create warehouse / 新建仓库",
|
||||
description = "Creates a warehouse, address and service capabilities for the target tenant. / 为目标租户创建仓库、地址和服务能力。"
|
||||
description = "Required authority: " + OverseasWarehousePermissions.WAREHOUSE_CREATE + ". Creates a warehouse, address and service capabilities for the target customer."
|
||||
)
|
||||
@ApiResponses({
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "Created successfully / 创建成功"),
|
||||
@@ -53,6 +55,7 @@ public class PlatformWarehouseController {
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "409", description = "Warehouse code already exists / 仓库编码已存在")
|
||||
})
|
||||
@PostMapping
|
||||
@PreAuthorize("hasAuthority('" + OverseasWarehousePermissions.WAREHOUSE_CREATE + "')")
|
||||
public ApiResponse<Long> create(@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@Valid @RequestBody WarehouseRequests.SaveRequest request) {
|
||||
requirePlatform(user);
|
||||
@@ -62,7 +65,7 @@ public class PlatformWarehouseController {
|
||||
|
||||
@Operation(
|
||||
summary = "Update warehouse / 更新仓库",
|
||||
description = "Updates the warehouse and replaces its address and capabilities. / 更新仓库,并整体替换地址和服务能力。"
|
||||
description = "Required authority: " + OverseasWarehousePermissions.WAREHOUSE_EDIT + ". Updates the warehouse and replaces its address and capabilities."
|
||||
)
|
||||
@ApiResponses({
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "Updated successfully / 更新成功"),
|
||||
@@ -72,6 +75,7 @@ public class PlatformWarehouseController {
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "409", description = "Warehouse code already exists / 仓库编码已存在")
|
||||
})
|
||||
@PutMapping("/{id}")
|
||||
@PreAuthorize("hasAuthority('" + OverseasWarehousePermissions.WAREHOUSE_EDIT + "')")
|
||||
public ApiResponse<Void> update(
|
||||
@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@Parameter(description = "Target tenant ID / 目标租户 ID", example = "10001", required = true)
|
||||
@@ -87,7 +91,7 @@ public class PlatformWarehouseController {
|
||||
|
||||
@Operation(
|
||||
summary = "List tenant warehouses / 查询租户仓库",
|
||||
description = "Returns a tenant-scoped warehouse page with optional country, capability and status filters. / 按租户分页查询仓库,可按国家、能力和状态筛选。"
|
||||
description = "Required authority: " + OverseasWarehousePermissions.WAREHOUSE_LIST + ". Returns a customer-scoped warehouse page with optional filters."
|
||||
)
|
||||
@ApiResponses({
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "Query succeeded / 查询成功"),
|
||||
@@ -95,6 +99,7 @@ public class PlatformWarehouseController {
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "Platform access required / 需要平台端权限")
|
||||
})
|
||||
@GetMapping
|
||||
@PreAuthorize("hasAuthority('" + OverseasWarehousePermissions.WAREHOUSE_LIST + "')")
|
||||
public ApiResponse<PageResult<WarehouseEntity>> page(
|
||||
@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@Parameter(description = "Target tenant ID / 目标租户 ID", example = "10001", required = true)
|
||||
@@ -107,7 +112,7 @@ public class PlatformWarehouseController {
|
||||
|
||||
@Operation(
|
||||
summary = "Get tenant warehouse details / 查询租户仓库详情",
|
||||
description = "Returns the warehouse, addresses and service capabilities in the target tenant. / 返回目标租户下的仓库、地址及服务能力。"
|
||||
description = "Required authority: " + OverseasWarehousePermissions.WAREHOUSE_LIST + ". Returns the warehouse, addresses and service capabilities for the target customer."
|
||||
)
|
||||
@ApiResponses({
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "Query succeeded / 查询成功"),
|
||||
@@ -115,6 +120,7 @@ public class PlatformWarehouseController {
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "Warehouse not found / 仓库不存在")
|
||||
})
|
||||
@GetMapping("/{id}")
|
||||
@PreAuthorize("hasAuthority('" + OverseasWarehousePermissions.WAREHOUSE_LIST + "')")
|
||||
public ApiResponse<WarehouseDetailResponse> detail(
|
||||
@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@Parameter(description = "Target tenant ID / 目标租户 ID", example = "10001", required = true)
|
||||
@@ -128,7 +134,7 @@ public class PlatformWarehouseController {
|
||||
|
||||
@Operation(
|
||||
summary = "Enable or disable warehouse / 启用或停用仓库",
|
||||
description = "Changes warehouse status to ACTIVE or INACTIVE. / 将仓库状态切换为 ACTIVE 或 INACTIVE。"
|
||||
description = "Required authority: " + OverseasWarehousePermissions.WAREHOUSE_STATUS + ". Changes warehouse status to ACTIVE or INACTIVE."
|
||||
)
|
||||
@ApiResponses({
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "Status changed / 状态变更成功"),
|
||||
@@ -137,6 +143,7 @@ public class PlatformWarehouseController {
|
||||
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "Warehouse not found / 仓库不存在")
|
||||
})
|
||||
@PatchMapping("/{id}/status")
|
||||
@PreAuthorize("hasAuthority('" + OverseasWarehousePermissions.WAREHOUSE_STATUS + "')")
|
||||
public ApiResponse<Void> status(
|
||||
@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@Parameter(description = "Target tenant ID / 目标租户 ID", example = "10001", required = true)
|
||||
@@ -152,7 +159,7 @@ public class PlatformWarehouseController {
|
||||
}
|
||||
|
||||
private static void requirePlatform(AuthenticatedUser user) {
|
||||
if (user == null || !"PLATFORM".equals(user.appCode())) {
|
||||
if (user == null || !"PLATFORM".equals(user.appCode()) || user.tenantId() == null || user.tenantId() != 0L) {
|
||||
throw new BizException(ResultCode.FORBIDDEN, "Platform application required / 仅允许平台端访问");
|
||||
}
|
||||
}
|
||||
@@ -163,4 +170,3 @@ public class PlatformWarehouseController {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+49
-36
@@ -10,10 +10,13 @@ import com.baiyue.warehouse.dto.PalletRequests;
|
||||
import com.baiyue.warehouse.entity.WarehouseLocationEntity;
|
||||
import com.baiyue.warehouse.entity.WarehousePalletEntity;
|
||||
import com.baiyue.warehouse.service.WarehouseResourceService;
|
||||
import com.baiyue.warehouse.security.OverseasWarehousePermissions;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
@@ -28,104 +31,114 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
@Validated
|
||||
@RestController
|
||||
@RequestMapping("/api/platform/v1/warehouse-admin/{warehouseId}")
|
||||
@Tag(name = "Platform overseas warehouse resources")
|
||||
public class PlatformWarehouseResourceController {
|
||||
@Resource private WarehouseResourceService service;
|
||||
|
||||
@PostMapping("/locations")
|
||||
@PreAuthorize("hasAuthority('" + OverseasWarehousePermissions.LOCATION_CREATE + "')")
|
||||
@Operation(summary = "Create a warehouse location", description = "Required authority: " + OverseasWarehousePermissions.LOCATION_CREATE)
|
||||
public ApiResponse<Long> createLocation(@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@RequestParam @NotNull Long customerId,
|
||||
@PathVariable long warehouseId,
|
||||
@Valid @RequestBody LocationRequests.SaveRequest request) {
|
||||
requirePlatform(user, customerId);
|
||||
return ApiResponse.success(service.createLocation(customerId, warehouseId, request));
|
||||
requirePlatform(user);
|
||||
return ApiResponse.success(service.createLocation(WarehouseResourceService.PUBLIC_RESOURCE_SCOPE, warehouseId, request));
|
||||
}
|
||||
|
||||
@PutMapping("/locations/{id}")
|
||||
@PreAuthorize("hasAuthority('" + OverseasWarehousePermissions.LOCATION_EDIT + "')")
|
||||
@Operation(summary = "Update a warehouse location", description = "Required authority: " + OverseasWarehousePermissions.LOCATION_EDIT)
|
||||
public ApiResponse<Void> updateLocation(@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@RequestParam @NotNull Long customerId,
|
||||
@PathVariable long warehouseId, @PathVariable long id,
|
||||
@Valid @RequestBody LocationRequests.SaveRequest request) {
|
||||
requirePlatform(user, customerId);
|
||||
service.updateLocation(customerId, warehouseId, id, request);
|
||||
requirePlatform(user);
|
||||
service.updateLocation(WarehouseResourceService.PUBLIC_RESOURCE_SCOPE, warehouseId, id, request);
|
||||
return ApiResponse.success(null);
|
||||
}
|
||||
|
||||
@GetMapping("/locations")
|
||||
@PreAuthorize("hasAuthority('" + OverseasWarehousePermissions.LOCATION_LIST + "')")
|
||||
@Operation(summary = "Page warehouse locations", description = "Required authority: " + OverseasWarehousePermissions.LOCATION_LIST)
|
||||
public ApiResponse<PageResult<WarehouseLocationEntity>> locations(
|
||||
@AuthenticationPrincipal AuthenticatedUser user, @RequestParam @NotNull Long customerId,
|
||||
@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@PathVariable long warehouseId, @Valid LocationRequests.QueryRequest query) {
|
||||
requirePlatform(user, customerId);
|
||||
return ApiResponse.success(service.locations(customerId, warehouseId, query));
|
||||
requirePlatform(user);
|
||||
return ApiResponse.success(service.locations(WarehouseResourceService.PUBLIC_RESOURCE_SCOPE, warehouseId, query));
|
||||
}
|
||||
|
||||
@GetMapping("/locations/{id}")
|
||||
@PreAuthorize("hasAuthority('" + OverseasWarehousePermissions.LOCATION_LIST + "')")
|
||||
@Operation(summary = "Get a warehouse location", description = "Required authority: " + OverseasWarehousePermissions.LOCATION_LIST)
|
||||
public ApiResponse<WarehouseLocationEntity> location(@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@RequestParam @NotNull Long customerId,
|
||||
@PathVariable long warehouseId,
|
||||
@PathVariable long id) {
|
||||
requirePlatform(user, customerId);
|
||||
return ApiResponse.success(service.location(customerId, warehouseId, id));
|
||||
requirePlatform(user);
|
||||
return ApiResponse.success(service.location(WarehouseResourceService.PUBLIC_RESOURCE_SCOPE, warehouseId, id));
|
||||
}
|
||||
|
||||
@DeleteMapping("/locations/{id}")
|
||||
@PreAuthorize("hasAuthority('" + OverseasWarehousePermissions.LOCATION_DELETE + "')")
|
||||
@Operation(summary = "Delete a warehouse location", description = "Required authority: " + OverseasWarehousePermissions.LOCATION_DELETE)
|
||||
public ApiResponse<Void> deleteLocation(@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@RequestParam @NotNull Long customerId,
|
||||
@PathVariable long warehouseId, @PathVariable long id) {
|
||||
requirePlatform(user, customerId);
|
||||
service.deleteLocation(customerId, warehouseId, id);
|
||||
requirePlatform(user);
|
||||
service.deleteLocation(WarehouseResourceService.PUBLIC_RESOURCE_SCOPE, warehouseId, id);
|
||||
return ApiResponse.success(null);
|
||||
}
|
||||
|
||||
@PostMapping("/pallets")
|
||||
@PreAuthorize("hasAuthority('" + OverseasWarehousePermissions.PALLET_CREATE + "')")
|
||||
@Operation(summary = "Create a warehouse pallet", description = "Required authority: " + OverseasWarehousePermissions.PALLET_CREATE)
|
||||
public ApiResponse<Long> createPallet(@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@RequestParam @NotNull Long customerId,
|
||||
@PathVariable long warehouseId,
|
||||
@Valid @RequestBody PalletRequests.SaveRequest request) {
|
||||
requirePlatform(user, customerId);
|
||||
return ApiResponse.success(service.createPallet(customerId, warehouseId, request));
|
||||
requirePlatform(user);
|
||||
return ApiResponse.success(service.createPallet(WarehouseResourceService.PUBLIC_RESOURCE_SCOPE, warehouseId, request));
|
||||
}
|
||||
|
||||
@PutMapping("/pallets/{id}")
|
||||
@PreAuthorize("hasAuthority('" + OverseasWarehousePermissions.PALLET_EDIT + "')")
|
||||
@Operation(summary = "Update a warehouse pallet", description = "Required authority: " + OverseasWarehousePermissions.PALLET_EDIT)
|
||||
public ApiResponse<Void> updatePallet(@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@RequestParam @NotNull Long customerId,
|
||||
@PathVariable long warehouseId, @PathVariable long id,
|
||||
@Valid @RequestBody PalletRequests.SaveRequest request) {
|
||||
requirePlatform(user, customerId);
|
||||
service.updatePallet(customerId, warehouseId, id, request);
|
||||
requirePlatform(user);
|
||||
service.updatePallet(WarehouseResourceService.PUBLIC_RESOURCE_SCOPE, warehouseId, id, request);
|
||||
return ApiResponse.success(null);
|
||||
}
|
||||
|
||||
@GetMapping("/pallets")
|
||||
@PreAuthorize("hasAuthority('" + OverseasWarehousePermissions.PALLET_LIST + "')")
|
||||
@Operation(summary = "Page warehouse pallets", description = "Required authority: " + OverseasWarehousePermissions.PALLET_LIST)
|
||||
public ApiResponse<PageResult<WarehousePalletEntity>> pallets(
|
||||
@AuthenticationPrincipal AuthenticatedUser user, @RequestParam @NotNull Long customerId,
|
||||
@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@PathVariable long warehouseId, @Valid PalletRequests.QueryRequest query) {
|
||||
requirePlatform(user, customerId);
|
||||
return ApiResponse.success(service.pallets(customerId, warehouseId, query));
|
||||
requirePlatform(user);
|
||||
return ApiResponse.success(service.pallets(WarehouseResourceService.PUBLIC_RESOURCE_SCOPE, warehouseId, query));
|
||||
}
|
||||
|
||||
@GetMapping("/pallets/{id}")
|
||||
@PreAuthorize("hasAuthority('" + OverseasWarehousePermissions.PALLET_LIST + "')")
|
||||
@Operation(summary = "Get a warehouse pallet", description = "Required authority: " + OverseasWarehousePermissions.PALLET_LIST)
|
||||
public ApiResponse<WarehousePalletEntity> pallet(@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@RequestParam @NotNull Long customerId,
|
||||
@PathVariable long warehouseId, @PathVariable long id) {
|
||||
requirePlatform(user, customerId);
|
||||
return ApiResponse.success(service.pallet(customerId, warehouseId, id));
|
||||
requirePlatform(user);
|
||||
return ApiResponse.success(service.pallet(WarehouseResourceService.PUBLIC_RESOURCE_SCOPE, warehouseId, id));
|
||||
}
|
||||
|
||||
@DeleteMapping("/pallets/{id}")
|
||||
@PreAuthorize("hasAuthority('" + OverseasWarehousePermissions.PALLET_DELETE + "')")
|
||||
@Operation(summary = "Delete a warehouse pallet", description = "Required authority: " + OverseasWarehousePermissions.PALLET_DELETE)
|
||||
public ApiResponse<Void> deletePallet(@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@RequestParam @NotNull Long customerId,
|
||||
@PathVariable long warehouseId, @PathVariable long id) {
|
||||
requirePlatform(user, customerId);
|
||||
service.deletePallet(customerId, warehouseId, id);
|
||||
requirePlatform(user);
|
||||
service.deletePallet(WarehouseResourceService.PUBLIC_RESOURCE_SCOPE, warehouseId, id);
|
||||
return ApiResponse.success(null);
|
||||
}
|
||||
|
||||
private static void requirePlatform(AuthenticatedUser user, Long customerId) {
|
||||
if (user == null || !"PLATFORM".equals(user.appCode())) {
|
||||
private static void requirePlatform(AuthenticatedUser user) {
|
||||
if (user == null || !"PLATFORM".equals(user.appCode()) || user.tenantId() == null || user.tenantId() != 0L) {
|
||||
throw new BizException(ResultCode.FORBIDDEN, "仅允许平台端访问");
|
||||
}
|
||||
if (customerId == null || customerId <= 0) {
|
||||
throw new BizException(ResultCode.BAD_REQUEST, "必须指定有效目标租户");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+13
-11
@@ -7,11 +7,13 @@ import com.baiyue.warehouse.entity.WarehouseResourceLockEntity;
|
||||
import com.baiyue.warehouse.mapper.WarehouseLocationMapper;
|
||||
import com.baiyue.warehouse.mapper.WarehousePalletMapper;
|
||||
import com.baiyue.warehouse.mapper.WarehouseResourceLockMapper;
|
||||
import com.baiyue.warehouse.service.WarehouseResourceService;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
@Repository
|
||||
public class WarehouseResourceLockRepository {
|
||||
private static final long PUBLIC_RESOURCE_SCOPE = WarehouseResourceService.PUBLIC_RESOURCE_SCOPE;
|
||||
@Resource private WarehouseResourceLockMapper locks;
|
||||
@Resource private WarehousePalletMapper pallets;
|
||||
@Resource private WarehouseLocationMapper locations;
|
||||
@@ -32,58 +34,58 @@ public class WarehouseResourceLockRepository {
|
||||
|
||||
public WarehousePalletEntity findPallet(long customerId, long palletId) {
|
||||
return pallets.selectOne(new LambdaQueryWrapper<WarehousePalletEntity>()
|
||||
.eq(WarehousePalletEntity::getCustomerId, customerId)
|
||||
.eq(WarehousePalletEntity::getCustomerId, PUBLIC_RESOURCE_SCOPE)
|
||||
.eq(WarehousePalletEntity::getId, palletId));
|
||||
}
|
||||
|
||||
public WarehousePalletEntity findPallet(long customerId, long warehouseId, long palletId) {
|
||||
return pallets.selectOne(new LambdaQueryWrapper<WarehousePalletEntity>()
|
||||
.eq(WarehousePalletEntity::getCustomerId, customerId)
|
||||
.eq(WarehousePalletEntity::getCustomerId, PUBLIC_RESOURCE_SCOPE)
|
||||
.eq(WarehousePalletEntity::getWarehouseId, warehouseId)
|
||||
.eq(WarehousePalletEntity::getId, palletId));
|
||||
}
|
||||
|
||||
public WarehouseLocationEntity findLocation(long customerId, long warehouseId, long locationId) {
|
||||
return locations.selectOne(new LambdaQueryWrapper<WarehouseLocationEntity>()
|
||||
.eq(WarehouseLocationEntity::getCustomerId, customerId)
|
||||
.eq(WarehouseLocationEntity::getCustomerId, PUBLIC_RESOURCE_SCOPE)
|
||||
.eq(WarehouseLocationEntity::getWarehouseId, warehouseId)
|
||||
.eq(WarehouseLocationEntity::getId, locationId));
|
||||
}
|
||||
|
||||
public int occupyPallet(long customerId, long warehouseId, long palletId, long locationId) {
|
||||
return locks.occupyPallet(customerId, warehouseId, palletId, locationId);
|
||||
return locks.occupyPallet(PUBLIC_RESOURCE_SCOPE, warehouseId, palletId, locationId);
|
||||
}
|
||||
|
||||
public int occupyLocation(long customerId, long warehouseId, long locationId) {
|
||||
return locks.occupyLocation(customerId, warehouseId, locationId);
|
||||
return locks.occupyLocation(PUBLIC_RESOURCE_SCOPE, warehouseId, locationId);
|
||||
}
|
||||
|
||||
public void insert(WarehouseResourceLockEntity lock) { locks.insert(lock); }
|
||||
|
||||
public int releasePallet(WarehouseResourceLockEntity lock) {
|
||||
return locks.releasePallet(lock.getCustomerId(), lock.getWarehouseId(), lock.getPalletId(), lock.getLocationId());
|
||||
return locks.releasePallet(PUBLIC_RESOURCE_SCOPE, lock.getWarehouseId(), lock.getPalletId(), lock.getLocationId());
|
||||
}
|
||||
|
||||
public int releasePalletAtVirtualLocation(WarehouseResourceLockEntity lock) {
|
||||
return locks.releasePalletAtVirtualLocation(lock.getCustomerId(), lock.getWarehouseId(),
|
||||
return locks.releasePalletAtVirtualLocation(PUBLIC_RESOURCE_SCOPE, lock.getWarehouseId(),
|
||||
lock.getPalletId(), lock.getLocationId());
|
||||
}
|
||||
|
||||
public int scrapPallet(WarehouseResourceLockEntity lock) {
|
||||
return locks.scrapPallet(lock.getCustomerId(), lock.getWarehouseId(), lock.getPalletId(), lock.getLocationId());
|
||||
return locks.scrapPallet(PUBLIC_RESOURCE_SCOPE, lock.getWarehouseId(), lock.getPalletId(), lock.getLocationId());
|
||||
}
|
||||
|
||||
public int scrapPalletWithoutLock(long customerId, long palletId) {
|
||||
return locks.scrapPalletWithoutLock(customerId, palletId);
|
||||
return locks.scrapPalletWithoutLock(PUBLIC_RESOURCE_SCOPE, palletId);
|
||||
}
|
||||
|
||||
public int scrapPalletAtVirtualLocation(WarehouseResourceLockEntity lock) {
|
||||
return locks.scrapPalletAtVirtualLocation(lock.getCustomerId(), lock.getWarehouseId(),
|
||||
return locks.scrapPalletAtVirtualLocation(PUBLIC_RESOURCE_SCOPE, lock.getWarehouseId(),
|
||||
lock.getPalletId(), lock.getLocationId());
|
||||
}
|
||||
|
||||
public int releaseLocation(WarehouseResourceLockEntity lock) {
|
||||
return locks.releaseLocation(lock.getCustomerId(), lock.getWarehouseId(), lock.getLocationId());
|
||||
return locks.releaseLocation(PUBLIC_RESOURCE_SCOPE, lock.getWarehouseId(), lock.getLocationId());
|
||||
}
|
||||
|
||||
public int close(WarehouseResourceLockEntity lock, String status) { return locks.closeLock(lock.getId(), status); }
|
||||
|
||||
+4
@@ -45,6 +45,10 @@ public class WarehouseResourceRepository {
|
||||
.eq(WarehouseEntity::getId, warehouseId));
|
||||
}
|
||||
|
||||
public WarehouseEntity findWarehouseById(long warehouseId) {
|
||||
return warehouses.selectById(warehouseId);
|
||||
}
|
||||
|
||||
public WarehouseLocationEntity findDefaultVirtualLocation(long customerId, long warehouseId) {
|
||||
return locations.selectOne(new LambdaQueryWrapper<WarehouseLocationEntity>()
|
||||
.eq(WarehouseLocationEntity::getCustomerId, customerId)
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package com.baiyue.warehouse.security;
|
||||
|
||||
/** Canonical Admin authorities for overseas warehouse resources. */
|
||||
public final class OverseasWarehousePermissions {
|
||||
public static final String WAREHOUSE_LIST = "platform:overseas-warehouse:warehouse:list";
|
||||
public static final String WAREHOUSE_CREATE = "platform:overseas-warehouse:warehouse:create";
|
||||
public static final String WAREHOUSE_EDIT = "platform:overseas-warehouse:warehouse:edit";
|
||||
public static final String WAREHOUSE_STATUS = "platform:overseas-warehouse:warehouse:status";
|
||||
public static final String LOCATION_LIST = "platform:overseas-warehouse:location:list";
|
||||
public static final String LOCATION_CREATE = "platform:overseas-warehouse:location:create";
|
||||
public static final String LOCATION_EDIT = "platform:overseas-warehouse:location:edit";
|
||||
public static final String LOCATION_DELETE = "platform:overseas-warehouse:location:delete";
|
||||
public static final String PALLET_LIST = "platform:overseas-warehouse:pallet:list";
|
||||
public static final String PALLET_CREATE = "platform:overseas-warehouse:pallet:create";
|
||||
public static final String PALLET_EDIT = "platform:overseas-warehouse:pallet:edit";
|
||||
public static final String PALLET_DELETE = "platform:overseas-warehouse:pallet:delete";
|
||||
|
||||
private OverseasWarehousePermissions() { }
|
||||
}
|
||||
+9
-1
@@ -22,6 +22,7 @@ import org.springframework.util.StringUtils;
|
||||
|
||||
@Service
|
||||
public class WarehouseResourceService {
|
||||
public static final long PUBLIC_RESOURCE_SCOPE = 0L;
|
||||
private static final Set<String> LOCATION_STATUSES = Set.of("ACTIVE", "IDLE", "OCCUPIED", "INACTIVE");
|
||||
private static final Set<String> PALLET_STATUSES = Set.of("IDLE", "OCCUPIED", "SCRAPPED");
|
||||
|
||||
@@ -187,13 +188,20 @@ public class WarehouseResourceService {
|
||||
}
|
||||
|
||||
private void requireWarehouse(long customerId, long warehouseId) {
|
||||
if (customerId == PUBLIC_RESOURCE_SCOPE) {
|
||||
if (repository.findWarehouseById(warehouseId) == null) {
|
||||
throw new BizException(ResultCode.NOT_FOUND, "Warehouse not found");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!repository.warehouseOwned(customerId, warehouseId)) {
|
||||
throw new BizException(ResultCode.NOT_FOUND, "当前租户下仓库不存在");
|
||||
}
|
||||
}
|
||||
|
||||
private WarehouseEntity requireWarehouseEntity(long customerId, long warehouseId) {
|
||||
WarehouseEntity warehouse = repository.findWarehouse(customerId, warehouseId);
|
||||
WarehouseEntity warehouse = customerId == PUBLIC_RESOURCE_SCOPE
|
||||
? repository.findWarehouseById(warehouseId) : repository.findWarehouse(customerId, warehouseId);
|
||||
if (warehouse == null) {
|
||||
throw new BizException(ResultCode.NOT_FOUND, "Tenant warehouse not found");
|
||||
}
|
||||
|
||||
@@ -18,17 +18,17 @@ spring:
|
||||
- optional:nacos:${spring.application.name}.yml?group=BAIYUE&refreshEnabled=true
|
||||
cloud:
|
||||
nacos:
|
||||
server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8858}
|
||||
server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848}
|
||||
username: ${NACOS_USERNAME:nacos}
|
||||
password: ${NACOS_PASSWORD:nacos}
|
||||
discovery:
|
||||
server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8858}
|
||||
server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848}
|
||||
enabled: ${NACOS_DISCOVERY_ENABLED:true}
|
||||
register-enabled: ${NACOS_REGISTER_ENABLED:true}
|
||||
group: ${NACOS_GROUP:BAIYUE}
|
||||
namespace: ${NACOS_NAMESPACE:public}
|
||||
config:
|
||||
server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8858}
|
||||
server-addr: ${NACOS_SERVER_ADDR:127.0.0.1:8848}
|
||||
namespace: ${NACOS_NAMESPACE:public}
|
||||
datasource:
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
|
||||
+14
-5
@@ -34,20 +34,29 @@ class WarehouseResourceControllerTest {
|
||||
PlatformWarehouseResourceController controller = platformController();
|
||||
|
||||
assertThatThrownBy(() -> controller.location(user(10001L, "MERCHANT"),
|
||||
10002L, 20001L, 30001L))
|
||||
20001L, 30001L))
|
||||
.isInstanceOf(BizException.class)
|
||||
.hasMessageContaining("平台端");
|
||||
}
|
||||
|
||||
@Test
|
||||
void platformApiUsesExplicitTargetTenant() {
|
||||
void platformApiUsesPublicResourceScope() {
|
||||
PlatformWarehouseResourceController controller = platformController();
|
||||
WarehouseLocationEntity expected = new WarehouseLocationEntity();
|
||||
when(service.location(10002L, 20001L, 30001L)).thenReturn(expected);
|
||||
when(service.location(0L, 20001L, 30001L)).thenReturn(expected);
|
||||
|
||||
controller.location(user(1L, "PLATFORM"), 10002L, 20001L, 30001L);
|
||||
controller.location(user(0L, "PLATFORM"), 20001L, 30001L);
|
||||
|
||||
verify(service).location(10002L, 20001L, 30001L);
|
||||
verify(service).location(0L, 20001L, 30001L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void platformApiRejectsPlatformAppWithCustomerScope() {
|
||||
PlatformWarehouseResourceController controller = platformController();
|
||||
|
||||
assertThatThrownBy(() -> controller.location(user(10001L, "PLATFORM"), 20001L, 30001L))
|
||||
.isInstanceOf(BizException.class)
|
||||
.hasMessageContaining("平台端");
|
||||
}
|
||||
|
||||
private static AuthenticatedUser user(long customerId, String appCode) {
|
||||
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package com.baiyue.warehouse.controller;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
class WarehouseResourcePermissionContractTest {
|
||||
private static final String PREFIX = "platform:overseas-warehouse:";
|
||||
|
||||
@Test
|
||||
void locationAndPalletEndpointsUseOnlyCanonicalAuthorities() {
|
||||
Map<String, Method> methods = Arrays.stream(PlatformWarehouseResourceController.class.getDeclaredMethods())
|
||||
.filter(method -> method.isAnnotationPresent(PreAuthorize.class))
|
||||
.collect(Collectors.toMap(Method::getName, method -> method));
|
||||
|
||||
assertPermission(methods.get("locations"), PREFIX + "location:list");
|
||||
assertPermission(methods.get("location"), PREFIX + "location:list");
|
||||
assertPermission(methods.get("createLocation"), PREFIX + "location:create");
|
||||
assertPermission(methods.get("updateLocation"), PREFIX + "location:edit");
|
||||
assertPermission(methods.get("deleteLocation"), PREFIX + "location:delete");
|
||||
assertPermission(methods.get("pallets"), PREFIX + "pallet:list");
|
||||
assertPermission(methods.get("pallet"), PREFIX + "pallet:list");
|
||||
assertPermission(methods.get("createPallet"), PREFIX + "pallet:create");
|
||||
assertPermission(methods.get("updatePallet"), PREFIX + "pallet:edit");
|
||||
assertPermission(methods.get("deletePallet"), PREFIX + "pallet:delete");
|
||||
}
|
||||
|
||||
private static void assertPermission(Method method, String authority) {
|
||||
PreAuthorize preAuthorize = method.getAnnotation(PreAuthorize.class);
|
||||
Operation operation = method.getAnnotation(Operation.class);
|
||||
assertEquals("hasAuthority('" + authority + "')", preAuthorize.value());
|
||||
assertEquals("Required authority: " + authority, operation.description());
|
||||
}
|
||||
}
|
||||
+17
@@ -67,6 +67,23 @@ class WarehouseResourceServiceTest {
|
||||
assertThat(captor.getValue().getWarehouseId()).isEqualTo(WAREHOUSE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void platformPalletUsesPublicScopeAgainstAnyExistingWarehouse() {
|
||||
WarehouseEntity warehouse = warehouse();
|
||||
when(repository.findWarehouseById(WAREHOUSE)).thenReturn(warehouse);
|
||||
WarehouseLocationEntity location = new WarehouseLocationEntity();
|
||||
location.setId(30001L);
|
||||
when(repository.findLocation(0L, WAREHOUSE, 30001L)).thenReturn(location);
|
||||
|
||||
service.createPallet(0L, WAREHOUSE, new PalletRequests.SaveRequest(
|
||||
"PLT-PUBLIC", "STANDARD", null, BigDecimal.ONE, "IDLE", 30001L, null));
|
||||
|
||||
ArgumentCaptor<WarehousePalletEntity> captor = ArgumentCaptor.forClass(WarehousePalletEntity.class);
|
||||
verify(repository).insertPallet(captor.capture());
|
||||
assertThat(captor.getValue().getCustomerId()).isZero();
|
||||
assertThat(captor.getValue().getWarehouseId()).isEqualTo(WAREHOUSE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void rejectsResourceAccessWhenWarehouseDoesNotBelongToTenant() {
|
||||
when(repository.warehouseOwned(TENANT, WAREHOUSE)).thenReturn(false);
|
||||
|
||||
Reference in New Issue
Block a user