优化
This commit is contained in:
@@ -22,15 +22,18 @@ public final class PalletRequests {
|
||||
@NotNull @Min(1)
|
||||
@Schema(description = "所属仓库ID", example = "190000000000000002", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
Long warehouseId,
|
||||
@NotBlank @Size(max = 50)
|
||||
@Schema(description = "仓库内唯一托盘编码", example = "TP-001", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
String palletCode,
|
||||
@NotBlank @Size(max = 32)
|
||||
@Schema(description = "托盘类型", example = "木托盘", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
String palletType,
|
||||
@NotNull @DecimalMin(value = "0", inclusive = false) @Digits(integer = 12, fraction = 6)
|
||||
@Schema(description = "托盘容积,单位m³", example = "1.200000", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
BigDecimal capacityCbm,
|
||||
@NotNull @DecimalMin(value = "0", inclusive = false) @Digits(integer = 12, fraction = 3)
|
||||
@Schema(description = "托盘重量,单位kg", example = "8.000", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
BigDecimal weightKg,
|
||||
@NotBlank @Size(max = 32)
|
||||
@Schema(description = "托盘颜色", example = "黄色", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
String color,
|
||||
@Size(max = 500)
|
||||
@Schema(description = "备注", example = "标准川字托盘")
|
||||
String remark
|
||||
@@ -64,6 +67,8 @@ public final class PalletRequests {
|
||||
String palletCode,
|
||||
String palletType,
|
||||
BigDecimal capacityCbm,
|
||||
BigDecimal weightKg,
|
||||
String color,
|
||||
String remark,
|
||||
LocalDateTime createdAt,
|
||||
LocalDateTime updatedAt
|
||||
|
||||
@@ -11,7 +11,7 @@ import lombok.Setter;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 托盘主数据实体。状态同时承载可用、预占、占用和停用四种资源状态。
|
||||
* 托盘主数据实体。状态仅供内部预占、占用流程使用,不属于平台维护字段。
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@@ -37,6 +37,12 @@ public class PalletEntity extends BaseEntity {
|
||||
@Schema(description = "托盘容积,单位m³", example = "1.200000")
|
||||
private BigDecimal capacityCbm;
|
||||
|
||||
@Schema(description = "托盘重量,单位kg", example = "8.000")
|
||||
private BigDecimal weightKg;
|
||||
|
||||
@Schema(description = "托盘颜色", example = "黄色")
|
||||
private String color;
|
||||
|
||||
@Schema(description = "资源状态", allowableValues = {"AVAILABLE", "RESERVED", "OCCUPIED", "DISABLED"})
|
||||
private String status;
|
||||
|
||||
|
||||
@@ -13,16 +13,21 @@ import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** 托盘持久化仓储;平台分页支持跨租户筛选,资源操作始终包含租户和仓库边界。 */
|
||||
@Repository
|
||||
public class PalletRepository {
|
||||
private static final Pattern PALLET_CODE = Pattern.compile("TP-(\\d+)");
|
||||
|
||||
@Resource
|
||||
private PalletMapper mapper;
|
||||
|
||||
public PageResult<PalletEntity> page(Long tenantId, PalletRequests.PageQuery query) {
|
||||
LambdaQueryWrapper<PalletEntity> wrapper = new LambdaQueryWrapper<PalletEntity>()
|
||||
.eq(tenantId != null, PalletEntity::getTenantId, tenantId)
|
||||
.eq(PalletEntity::getDeleted, false)
|
||||
.eq(query.warehouseId() != null, PalletEntity::getWarehouseId, query.warehouseId())
|
||||
.like(StringUtils.hasText(query.palletCode()), PalletEntity::getPalletCode, query.palletCode())
|
||||
.eq(StringUtils.hasText(query.palletType()), PalletEntity::getPalletType, query.palletType())
|
||||
@@ -36,6 +41,7 @@ public class PalletRepository {
|
||||
return mapper.selectOne(new LambdaQueryWrapper<PalletEntity>()
|
||||
.eq(PalletEntity::getTenantId, tenantId)
|
||||
.eq(PalletEntity::getWarehouseId, warehouseId)
|
||||
.eq(PalletEntity::getDeleted, false)
|
||||
.eq(PalletEntity::getId, id));
|
||||
}
|
||||
|
||||
@@ -44,6 +50,7 @@ public class PalletRepository {
|
||||
.eq(PalletEntity::getTenantId, tenantId)
|
||||
.eq(PalletEntity::getWarehouseId, warehouseId)
|
||||
.eq(PalletEntity::getPalletCode, code)
|
||||
.eq(PalletEntity::getDeleted, false)
|
||||
.ne(excludedId != null, PalletEntity::getId, excludedId)) > 0;
|
||||
}
|
||||
|
||||
@@ -52,6 +59,7 @@ public class PalletRepository {
|
||||
return mapper.selectList(new LambdaQueryWrapper<PalletEntity>()
|
||||
.eq(PalletEntity::getTenantId, tenantId)
|
||||
.eq(PalletEntity::getWarehouseId, warehouseId)
|
||||
.eq(PalletEntity::getDeleted, false)
|
||||
.eq(PalletEntity::getStatus, "AVAILABLE")
|
||||
.eq(StringUtils.hasText(palletType), PalletEntity::getPalletType, palletType)
|
||||
.eq(capacityCbm != null, PalletEntity::getCapacityCbm, capacityCbm)
|
||||
@@ -59,6 +67,23 @@ public class PalletRepository {
|
||||
.last("LIMIT " + limit));
|
||||
}
|
||||
|
||||
public String nextCode(long tenantId, long warehouseId) {
|
||||
int maxSequence = mapper.selectList(new LambdaQueryWrapper<PalletEntity>()
|
||||
.select(PalletEntity::getPalletCode)
|
||||
.eq(PalletEntity::getTenantId, tenantId)
|
||||
.eq(PalletEntity::getWarehouseId, warehouseId)
|
||||
.likeRight(PalletEntity::getPalletCode, "TP-")
|
||||
.eq(PalletEntity::getDeleted, false))
|
||||
.stream()
|
||||
.map(PalletEntity::getPalletCode)
|
||||
.map(PALLET_CODE::matcher)
|
||||
.filter(Matcher::matches)
|
||||
.mapToInt(matcher -> Integer.parseInt(matcher.group(1)))
|
||||
.max()
|
||||
.orElse(0);
|
||||
return "TP-%03d".formatted(maxSequence + 1);
|
||||
}
|
||||
|
||||
public void insert(PalletEntity entity) {
|
||||
mapper.insert(entity);
|
||||
}
|
||||
|
||||
@@ -35,10 +35,10 @@ public class PalletApplicationService {
|
||||
@BusinessAudit(event = "PALLET_CREATE", resourceType = "PALLET", description = "新增托盘", captureBefore = false)
|
||||
public Long create(long tenantId, PalletRequests.SaveRequest request) {
|
||||
requireWarehouse(tenantId, request.warehouseId());
|
||||
ensureCodeUnique(tenantId, request.warehouseId(), request.palletCode(), null);
|
||||
PalletEntity entity = new PalletEntity();
|
||||
entity.setTenantId(tenantId);
|
||||
entity.setWarehouseId(request.warehouseId());
|
||||
entity.setPalletCode(repository.nextCode(tenantId, request.warehouseId()));
|
||||
copy(entity, request);
|
||||
entity.setStatus("AVAILABLE");
|
||||
try {
|
||||
@@ -56,7 +56,6 @@ public class PalletApplicationService {
|
||||
throw new BizException(ResultCode.FORBIDDEN, "请求仓库与托盘所属仓库不一致");
|
||||
}
|
||||
PalletEntity entity = owned(tenantId, warehouseId, id);
|
||||
ensureCodeUnique(tenantId, warehouseId, request.palletCode(), id);
|
||||
copy(entity, request);
|
||||
try {
|
||||
if (repository.save(entity) != 1) {
|
||||
@@ -90,22 +89,18 @@ public class PalletApplicationService {
|
||||
}
|
||||
}
|
||||
|
||||
private void ensureCodeUnique(long tenantId, long warehouseId, String code, Long excludedId) {
|
||||
if (repository.existsCode(tenantId, warehouseId, code, excludedId)) {
|
||||
throw new BizException(ResultCode.CONFLICT, "托盘编码已存在");
|
||||
}
|
||||
}
|
||||
|
||||
private static void copy(PalletEntity entity, PalletRequests.SaveRequest request) {
|
||||
entity.setPalletCode(request.palletCode());
|
||||
entity.setPalletType(request.palletType());
|
||||
entity.setCapacityCbm(request.capacityCbm());
|
||||
entity.setWeightKg(request.weightKg());
|
||||
entity.setColor(request.color());
|
||||
entity.setRemark(request.remark());
|
||||
}
|
||||
|
||||
private static PalletRequests.View view(PalletEntity entity) {
|
||||
return new PalletRequests.View(entity.getId(), entity.getTenantId(), entity.getWarehouseId(),
|
||||
entity.getPalletCode(), entity.getPalletType(), entity.getCapacityCbm(), entity.getRemark(),
|
||||
entity.getPalletCode(), entity.getPalletType(), entity.getCapacityCbm(), entity.getWeightKg(),
|
||||
entity.getColor(), entity.getRemark(),
|
||||
entity.getCreatedAt(), entity.getUpdatedAt());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,18 @@
|
||||
SET NAMES utf8mb4;
|
||||
USE baiyue_warehouse;
|
||||
|
||||
-- 托盘展示字段增量:重量、颜色;平台接口不暴露内部状态。
|
||||
SET @sql = IF((SELECT COUNT(*) FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE() AND table_name = 'wh_pallet' AND column_name = 'weight_kg') = 0,
|
||||
'ALTER TABLE wh_pallet ADD COLUMN weight_kg DECIMAL(18,3) NOT NULL DEFAULT 0 COMMENT ''托盘重量kg'' AFTER capacity_cbm',
|
||||
'SELECT 1');
|
||||
PREPARE statement FROM @sql; EXECUTE statement; DEALLOCATE PREPARE statement;
|
||||
SET @sql = IF((SELECT COUNT(*) FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE() AND table_name = 'wh_pallet' AND column_name = 'color') = 0,
|
||||
'ALTER TABLE wh_pallet ADD COLUMN color VARCHAR(32) NOT NULL DEFAULT '''' COMMENT ''托盘颜色'' AFTER weight_kg',
|
||||
'SELECT 1');
|
||||
PREPARE statement FROM @sql; EXECUTE statement; DEALLOCATE PREPARE statement;
|
||||
|
||||
-- 活动预占必须同时保证“一托一位”;A0 共享只放宽库位,不放宽托盘唯一性。
|
||||
SET @schema_name = DATABASE();
|
||||
DROP PROCEDURE IF EXISTS add_pallet_reservation_column_if_missing;
|
||||
|
||||
@@ -15,6 +15,8 @@ CREATE TABLE IF NOT EXISTS wh_pallet (
|
||||
pallet_type VARCHAR(32) NOT NULL COMMENT '托盘类型',
|
||||
pallet_name VARCHAR(100) NULL COMMENT '托盘名称',
|
||||
capacity_cbm DECIMAL(18,6) NOT NULL COMMENT '托盘可用容积CBM',
|
||||
weight_kg DECIMAL(18,3) NOT NULL DEFAULT 0 COMMENT '托盘重量kg',
|
||||
color VARCHAR(32) NOT NULL DEFAULT '' COMMENT '托盘颜色',
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'AVAILABLE' COMMENT '内部状态:AVAILABLE、RESERVED或OCCUPIED',
|
||||
remark VARCHAR(500) NULL COMMENT '备注',
|
||||
created_by BIGINT UNSIGNED NOT NULL COMMENT '创建人ID',
|
||||
|
||||
@@ -11,6 +11,13 @@ INSERT INTO wh_service_capability(id,tenant_id,warehouse_id,capability_code,capa
|
||||
VALUES(190000000000000021,0,190000000000000001,'RECEIVING','头程收货',1,'16:00:00','工作日16点前预约可当日收货')
|
||||
ON DUPLICATE KEY UPDATE tenant_id=0,enabled=1,cutoff_time=VALUES(cutoff_time);
|
||||
|
||||
-- 二期托盘初始化数据。编码由平台维护接口自动生成,种子固定为 TP-001、TP-002。
|
||||
INSERT INTO wh_pallet(id,tenant_id,warehouse_id,pallet_code,pallet_type,capacity_cbm,weight_kg,color,status,remark,created_by,updated_by)
|
||||
VALUES
|
||||
(190000000000000101,0,190000000000000001,'TP-001','木托盘',1.200000,8.000,'黄色','AVAILABLE','无备注',0,0),
|
||||
(190000000000000102,0,190000000000000001,'TP-002','胶托盘',2.400000,12.000,'黑色','AVAILABLE','无备注',0,0)
|
||||
ON DUPLICATE KEY UPDATE tenant_id=0,warehouse_id=VALUES(warehouse_id),pallet_type=VALUES(pallet_type),capacity_cbm=VALUES(capacity_cbm),weight_kg=VALUES(weight_kg),color=VALUES(color),remark=VALUES(remark);
|
||||
|
||||
-- 一期联调快递公司主数据,供平台维护和订单履约回显验证。
|
||||
INSERT INTO wh_express_company(id,tenant_id,company_code,company_name,service_phone,website,tracking_url_template,status,remark)
|
||||
VALUES(192000000000000001,0,'SF','顺丰速运','95338','https://www.sf-express.com','https://www.sf-express.com/chn/sc/dynamic_function/waybill/#search/bill-number/{trackingNo}','ACTIVE','平台公共快递公司样本')
|
||||
|
||||
Reference in New Issue
Block a user