1. 修复主数据的物料信息ZT前缀时,存在层级判断错误的问题
This commit is contained in:
@@ -73,6 +73,20 @@
|
||||
<dependency>
|
||||
<groupId>com.zt.plat</groupId>
|
||||
<artifactId>zt-spring-boot-starter-mybatis</artifactId>
|
||||
<exclusions>
|
||||
<!-- 避免上游引入 com.mysql:mysql-connector-j 8/9 系列,与目标 MySQL 5.1 不兼容 -->
|
||||
<exclusion>
|
||||
<groupId>com.mysql</groupId>
|
||||
<artifactId>mysql-connector-j</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- 强制使用 MySQL 5.1 驱动,避免继承的高版本驱动与目标库不兼容 -->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>5.1.49</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
@@ -91,6 +91,14 @@ public class MaterialHasPropertiesController {
|
||||
return success(BeanUtils.toBean(pageResult, MaterialHasPropertiesRespVO.class));
|
||||
}
|
||||
|
||||
@PostMapping("/batch-save")
|
||||
@Operation(summary = "批量保存物料持有属性(全量替换)")
|
||||
@PreAuthorize("@ss.hasPermission('base:material-has-properties:update')")
|
||||
public CommonResult<MaterialHasPropertiesBatchSaveRespVO> batchSave(@Valid @RequestBody MaterialHasPropertiesBatchSaveReqVO reqVO) {
|
||||
MaterialHasPropertiesBatchSaveRespVO resp = materialHasPropertiesService.batchSave(reqVO);
|
||||
return success(resp);
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(summary = "导出物料持有属性 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('base:material-has-properties:export')")
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.zt.plat.module.base.controller.admin.materialhasproperties.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "物料持有属性批量保存单项 Request VO")
|
||||
@Data
|
||||
public class MaterialHasPropertiesBatchItemReqVO {
|
||||
|
||||
@Schema(description = "主键ID", example = "6800")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "属性ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "8607")
|
||||
@NotNull(message = "属性ID不能为空")
|
||||
private Long propertiesId;
|
||||
|
||||
@Schema(description = "计量单位ID-默认计量单位", example = "23731")
|
||||
private Long unitId;
|
||||
|
||||
@Schema(description = "属性值", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String value;
|
||||
|
||||
@Schema(description = "是否关键属性-关键属性表示物料唯一性")
|
||||
private Integer isKey;
|
||||
|
||||
@Schema(description = "是否计量定价")
|
||||
private Integer isMetering;
|
||||
|
||||
@Schema(description = "排序号")
|
||||
private Long sort;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.zt.plat.module.base.controller.admin.materialhasproperties.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 物料持有属性批量保存 Request VO")
|
||||
@Data
|
||||
public class MaterialHasPropertiesBatchSaveReqVO {
|
||||
|
||||
@Schema(description = "物料信息 ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "物料信息 ID 不能为空")
|
||||
private Long infomationId;
|
||||
|
||||
@Schema(description = "属性列表", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Valid
|
||||
private List<MaterialHasPropertiesBatchItemReqVO> properties = new ArrayList<>();
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.zt.plat.module.base.controller.admin.materialhasproperties.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 物料持有属性批量保存 Response VO")
|
||||
@Data
|
||||
public class MaterialHasPropertiesBatchSaveRespVO {
|
||||
|
||||
@Schema(description = "行级错误列表(为空表示全部成功)")
|
||||
private List<RowValidationErrorVO> rowErrors = new ArrayList<>();
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.zt.plat.module.base.controller.admin.materialhasproperties.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Schema(description = "行级校验错误信息")
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class RowValidationErrorVO {
|
||||
|
||||
@Schema(description = "错误所在行(1 开始)")
|
||||
private Integer rowIndex;
|
||||
|
||||
@Schema(description = "错误提示")
|
||||
private String message;
|
||||
}
|
||||
@@ -65,14 +65,7 @@ public class MaterialInfomationServiceImpl implements MaterialInfomationService
|
||||
validateMaterialClassForBinding(createReqVO.getClassesId());
|
||||
MaterialInfomationDO materialInfomation = BeanUtils.toBean(createReqVO, MaterialInfomationDO.class);
|
||||
materialInfomationMapper.insert(materialInfomation);
|
||||
if (createReqVO.getClassesId() != null) {
|
||||
MaterialHasClassesDO relation = MaterialHasClassesDO.builder()
|
||||
.classesId(createReqVO.getClassesId())
|
||||
.infomationId(materialInfomation.getId())
|
||||
.build();
|
||||
materialHasClassesMapper.insert(relation);
|
||||
materialInfomation.setClassesId(createReqVO.getClassesId());
|
||||
}
|
||||
bindMaterialClassIfAbsent(materialInfomation.getId(), createReqVO.getClassesId());
|
||||
return CollUtil.getFirst(buildRespList(Collections.singletonList(materialInfomation)));
|
||||
}
|
||||
|
||||
@@ -85,13 +78,27 @@ public class MaterialInfomationServiceImpl implements MaterialInfomationService
|
||||
materialInfomationMapper.updateById(updateObj);
|
||||
materialHasClassesMapper.delete(new LambdaUpdateWrapper<MaterialHasClassesDO>()
|
||||
.eq(MaterialHasClassesDO::getInfomationId, updateReqVO.getId()));
|
||||
if (updateReqVO.getClassesId() != null) {
|
||||
MaterialHasClassesDO relation = MaterialHasClassesDO.builder()
|
||||
.classesId(updateReqVO.getClassesId())
|
||||
.infomationId(updateReqVO.getId())
|
||||
.build();
|
||||
materialHasClassesMapper.insert(relation);
|
||||
bindMaterialClassIfAbsent(updateReqVO.getId(), updateReqVO.getClassesId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定物料与分类关系(若已存在则跳过),避免唯一索引冲突
|
||||
*/
|
||||
private void bindMaterialClassIfAbsent(Long materialId, Long classesId) {
|
||||
if (materialId == null || classesId == null) {
|
||||
return;
|
||||
}
|
||||
Long exists = materialHasClassesMapper.selectCount(new LambdaQueryWrapperX<MaterialHasClassesDO>()
|
||||
.eq(MaterialHasClassesDO::getInfomationId, materialId)
|
||||
.eq(MaterialHasClassesDO::getClassesId, classesId));
|
||||
if (exists != null && exists > 0) {
|
||||
return;
|
||||
}
|
||||
MaterialHasClassesDO relation = MaterialHasClassesDO.builder()
|
||||
.classesId(classesId)
|
||||
.infomationId(materialId)
|
||||
.build();
|
||||
materialHasClassesMapper.insert(relation);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -59,4 +59,11 @@ public interface MaterialHasPropertiesService {
|
||||
*/
|
||||
PageResult<MaterialHasPropertiesDO> getMaterialHasPropertiesPage(MaterialHasPropertiesPageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 批量保存物料属性(全量替换指定物料的属性关系)
|
||||
* @param batchReqVO 请求参数
|
||||
* @return 行级校验错误(为空表示成功)
|
||||
*/
|
||||
MaterialHasPropertiesBatchSaveRespVO batchSave(MaterialHasPropertiesBatchSaveReqVO batchReqVO);
|
||||
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.zt.plat.module.base.service.materialhasproperties;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import org.springframework.stereotype.Service;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
@@ -14,6 +15,7 @@ import com.zt.plat.framework.common.pojo.PageParam;
|
||||
import com.zt.plat.framework.common.util.object.BeanUtils;
|
||||
|
||||
import com.zt.plat.module.base.dal.dao.materialhasproperties.MaterialHasPropertiesMapper;
|
||||
import com.zt.plat.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
|
||||
import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static com.zt.plat.framework.common.util.collection.CollectionUtils.convertList;
|
||||
@@ -89,4 +91,55 @@ public class MaterialHasPropertiesServiceImpl implements MaterialHasPropertiesSe
|
||||
return materialHasPropertiesMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public MaterialHasPropertiesBatchSaveRespVO batchSave(MaterialHasPropertiesBatchSaveReqVO batchReqVO) {
|
||||
MaterialHasPropertiesBatchSaveRespVO resp = new MaterialHasPropertiesBatchSaveRespVO();
|
||||
Long infoId = batchReqVO.getInfomationId();
|
||||
if (infoId == null) {
|
||||
resp.getRowErrors().add(new RowValidationErrorVO(0, "物料信息 ID 不能为空"));
|
||||
return resp;
|
||||
}
|
||||
// 全量替换:先删除该物料的已有属性
|
||||
materialHasPropertiesMapper.delete(new LambdaQueryWrapperX<MaterialHasPropertiesDO>()
|
||||
.eq(MaterialHasPropertiesDO::getInfomationId, infoId));
|
||||
|
||||
List<MaterialHasPropertiesBatchItemReqVO> properties = batchReqVO.getProperties();
|
||||
if (CollUtil.isEmpty(properties)) {
|
||||
return resp;
|
||||
}
|
||||
|
||||
// 去重并按提交顺序插入
|
||||
Set<String> dedupKeys = new LinkedHashSet<>();
|
||||
for (int i = 0; i < properties.size(); i++) {
|
||||
MaterialHasPropertiesBatchItemReqVO item = properties.get(i);
|
||||
String propIdStr = item.getPropertiesId() == null ? null : String.valueOf(item.getPropertiesId());
|
||||
if (StrUtil.isBlank(propIdStr)) {
|
||||
resp.getRowErrors().add(new RowValidationErrorVO(i + 1, "属性 ID 不能为空"));
|
||||
continue;
|
||||
}
|
||||
if (StrUtil.isBlank(item.getValue())) {
|
||||
resp.getRowErrors().add(new RowValidationErrorVO(i + 1, "属性值不能为空"));
|
||||
continue;
|
||||
}
|
||||
String key = propIdStr;
|
||||
if (!dedupKeys.add(key)) {
|
||||
// 重复的属性直接跳过后续插入,避免唯一冲突
|
||||
continue;
|
||||
}
|
||||
MaterialHasPropertiesDO entity = MaterialHasPropertiesDO.builder()
|
||||
.infomationId(infoId)
|
||||
.propertiesId(item.getPropertiesId())
|
||||
.unitId(item.getUnitId())
|
||||
.value(item.getValue())
|
||||
.isKey(item.getIsKey())
|
||||
.isMetering(item.getIsMetering())
|
||||
.sort(item.getSort() == null ? (long) (i + 1) : item.getSort())
|
||||
.build();
|
||||
materialHasPropertiesMapper.insert(entity);
|
||||
}
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user