1. 修复主数据的物料信息ZT前缀时,存在层级判断错误的问题

This commit is contained in:
chenbowen
2025-12-15 14:26:03 +08:00
parent ac27409776
commit 8d0175a13d
13 changed files with 393 additions and 14 deletions

View File

@@ -0,0 +1,146 @@
package com.zt.plat.module.base.service.materialhasproperties;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zt.plat.framework.test.core.ut.BaseDbUnitTest;
import com.zt.plat.module.base.controller.admin.materialhasproperties.vo.MaterialHasPropertiesBatchItemReqVO;
import com.zt.plat.module.base.controller.admin.materialhasproperties.vo.MaterialHasPropertiesBatchSaveReqVO;
import com.zt.plat.module.base.controller.admin.materialhasproperties.vo.MaterialHasPropertiesBatchSaveRespVO;
import com.zt.plat.module.base.controller.admin.materialhasproperties.vo.RowValidationErrorVO;
import com.zt.plat.module.base.dal.dao.materialhasproperties.MaterialHasPropertiesMapper;
import com.zt.plat.module.base.dal.dataobject.materialhasproperties.MaterialHasPropertiesDO;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.Import;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import static com.zt.plat.framework.test.core.util.RandomUtils.randomLongId;
import static org.assertj.core.api.Assertions.assertThat;
/**
* {@link MaterialHasPropertiesServiceImpl} 单元测试
*/
@Import(MaterialHasPropertiesServiceImpl.class)
class MaterialHasPropertiesServiceImplTest extends BaseDbUnitTest {
@Resource
private MaterialHasPropertiesServiceImpl materialHasPropertiesService;
@Resource
private MaterialHasPropertiesMapper materialHasPropertiesMapper;
private MaterialHasPropertiesDO insertRelation(Long infoId, Long propId, String value, Long sort) {
MaterialHasPropertiesDO entity = MaterialHasPropertiesDO.builder()
.id(randomLongId())
.infomationId(infoId)
.propertiesId(propId)
.value(value)
.sort(sort)
.build();
materialHasPropertiesMapper.insert(entity);
return entity;
}
@Test
void batchSave_shouldReplaceAndDedup() {
Long infoId = 1001L;
// 旧数据:同一个物料下的旧记录 + 其他物料记录
insertRelation(infoId, 9L, "old", 1L);
insertRelation(2002L, 99L, "other", 1L);
MaterialHasPropertiesBatchItemReqVO item1 = new MaterialHasPropertiesBatchItemReqVO();
item1.setPropertiesId(9L);
item1.setValue("new-val");
item1.setIsKey(1);
MaterialHasPropertiesBatchItemReqVO item2 = new MaterialHasPropertiesBatchItemReqVO();
item2.setPropertiesId(10L);
item2.setValue("v10");
item2.setSort(5L);
// 重复属性,应该被去重跳过
MaterialHasPropertiesBatchItemReqVO itemDuplicate = new MaterialHasPropertiesBatchItemReqVO();
itemDuplicate.setPropertiesId(9L);
itemDuplicate.setValue("dup");
MaterialHasPropertiesBatchSaveReqVO req = new MaterialHasPropertiesBatchSaveReqVO();
req.setInfomationId(infoId);
req.setProperties(CollUtil.newArrayList(item1, item2, itemDuplicate));
MaterialHasPropertiesBatchSaveRespVO resp = materialHasPropertiesService.batchSave(req);
assertThat(resp.getRowErrors()).isEmpty();
List<MaterialHasPropertiesDO> result = materialHasPropertiesMapper.selectList();
// 只应保留当前物料的新两条 + 另一物料的 1 条
assertThat(result).hasSize(3);
List<MaterialHasPropertiesDO> current = result.stream()
.filter(item -> infoId.equals(item.getInfomationId()))
.toList();
assertThat(current).hasSize(2);
Set<Long> propIds = current.stream().map(MaterialHasPropertiesDO::getPropertiesId).collect(Collectors.toSet());
assertThat(propIds).containsExactlyInAnyOrder(9L, 10L);
MaterialHasPropertiesDO updated = current.stream()
.filter(item -> item.getPropertiesId().equals(9L)).findFirst().orElseThrow();
assertThat(updated.getValue()).isEqualTo("new-val");
}
@Test
void batchSave_missingInfoId_shouldReturnErrorAndSkipInsert() {
MaterialHasPropertiesBatchSaveReqVO req = new MaterialHasPropertiesBatchSaveReqVO();
MaterialHasPropertiesBatchSaveRespVO resp = materialHasPropertiesService.batchSave(req);
assertThat(resp.getRowErrors()).hasSize(1);
RowValidationErrorVO error = resp.getRowErrors().get(0);
assertThat(error.getMessage()).contains("物料信息 ID 不能为空");
assertThat(materialHasPropertiesMapper.selectList()).isEmpty();
}
@Test
void batchSave_emptyList_shouldDeleteExisting() {
Long infoId = 3003L;
insertRelation(infoId, 77L, "keep", 1L);
MaterialHasPropertiesBatchSaveReqVO req = new MaterialHasPropertiesBatchSaveReqVO();
req.setInfomationId(infoId);
req.setProperties(List.of());
MaterialHasPropertiesBatchSaveRespVO resp = materialHasPropertiesService.batchSave(req);
assertThat(resp.getRowErrors()).isEmpty();
List<MaterialHasPropertiesDO> current = materialHasPropertiesMapper.selectList(new QueryWrapper<MaterialHasPropertiesDO>()
.eq("INF_ID", infoId));
assertThat(current).isEmpty();
}
@Test
void batchSave_blankValue_shouldCollectRowError() {
Long infoId = 4004L;
MaterialHasPropertiesBatchItemReqVO item = new MaterialHasPropertiesBatchItemReqVO();
item.setPropertiesId(55L);
item.setValue(" ");
MaterialHasPropertiesBatchSaveReqVO req = new MaterialHasPropertiesBatchSaveReqVO();
req.setInfomationId(infoId);
req.setProperties(List.of(item));
MaterialHasPropertiesBatchSaveRespVO resp = materialHasPropertiesService.batchSave(req);
assertThat(resp.getRowErrors()).hasSize(1);
RowValidationErrorVO error = resp.getRowErrors().get(0);
assertThat(error.getRowIndex()).isEqualTo(1);
assertThat(error.getMessage()).contains("属性值不能为空");
List<MaterialHasPropertiesDO> saved = materialHasPropertiesMapper.selectList(new QueryWrapper<MaterialHasPropertiesDO>()
.eq("INF_ID", infoId));
assertThat(saved).isEmpty();
}
}

View File

@@ -0,0 +1,39 @@
spring:
main:
lazy-initialization: true
banner-mode: off
--- #################### 数据库相关配置 ####################
spring:
datasource:
name: zt-base
url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value
driver-class-name: org.h2.Driver
username: sa
password:
druid:
async-init: true
initial-size: 1
sql:
init:
schema-locations: classpath:/sql/create_tables.sql
data:
redis:
host: 127.0.0.1
port: 16379
database: 0
mybatis-plus:
lazy-initialization: true
type-aliases-package: ${zt.info.base-package}.dal.dataobject
global-config:
db-config:
id-type: AUTO
zt:
info:
base-package: com.zt.plat.module.base
AES:
key: XDV71a+xqStEA3WH

View File

@@ -0,0 +1 @@
TRUNCATE TABLE bse_mtrl_hs_prps;

View File

@@ -0,0 +1,16 @@
CREATE TABLE IF NOT EXISTS bse_mtrl_hs_prps (
id BIGINT PRIMARY KEY,
INF_ID BIGINT NOT NULL,
PRPS_ID BIGINT NOT NULL,
UNT_ID BIGINT,
VAL VARCHAR(255),
IS_KY INT,
IS_MTNG INT,
SRT BIGINT,
creator VARCHAR(64) DEFAULT '',
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
updater VARCHAR(64) DEFAULT '',
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
deleted BIT DEFAULT FALSE NOT NULL,
tenant_id BIGINT DEFAULT 1 NOT NULL
);