Merge remote-tracking branch 'origin/dev' into test

This commit is contained in:
qianshijiang
2026-01-08 17:58:57 +08:00
7 changed files with 259 additions and 1 deletions

View File

@@ -59,6 +59,35 @@ public class DetailRespDTO {
@Schema(description = "长度")
private String length;
// 中文牌名
@Schema(description = "中文牌名")
private String chineseNo;
// 英文牌名
@Schema(description = "英文牌名")
private String englishNo;
// 技术规格
@Schema(description = "技术规格")
private String technicalSpecification;
// 技术标准1
@Schema(description = "技术标准1")
private String technicalStandard1;
// 技术标准2
@Schema(description = "技术标准2")
private String technicalStandard2;
// 线别
@Schema(description = "线别")
private String lineLevel;
// 包装
@Schema(description = "包装")
private String pack;
@Schema(description = "交货计划")
private List<PlanRespDTO> plans;
}

View File

@@ -1,5 +1,6 @@
package com.zt.plat.module.contractorder.api.vo.contract;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@@ -59,6 +60,36 @@ public class DetailRespVO {
@Schema(description = "长度")
private String length;
// 中文牌名
@Schema(description = "中文牌名")
private String chineseNo;
// 英文牌名
@Schema(description = "英文牌名")
private String englishNo;
// 技术规格
@Schema(description = "技术规格")
private String technicalSpecification;
// 技术标准1
@Schema(description = "技术标准1")
private String technicalStandard1;
// 技术标准2
@Schema(description = "技术标准2")
private String technicalStandard2;
// 线别
@Schema(description = "线别")
private String lineLevel;
// 包装
@Schema(description = "包装")
private String pack;
// 交货计划
@Schema(description = "交货计划")
private List<PlanRespVO> plans;
}

View File

@@ -55,6 +55,35 @@ public class DetailSaveReqVO {
@Schema(description = "长度")
private String length;
// 中文牌名
@Schema(description = "中文牌名")
private String chineseNo;
// 英文牌名
@Schema(description = "英文牌名")
private String englishNo;
// 技术规格
@Schema(description = "技术规格")
private String technicalSpecification;
// 技术标准1
@Schema(description = "技术标准1")
private String technicalStandard1;
// 技术标准2
@Schema(description = "技术标准2")
private String technicalStandard2;
// 线别
@Schema(description = "线别")
private String lineLevel;
// 包装
@Schema(description = "包装")
private String pack;
// 交货计划
private List<PlanSaveReqVO> plans;
}

View File

@@ -19,6 +19,7 @@ public interface ErrorCodeConstants {
ErrorCode CONTRACT_ID_NOT_EXISTS = new ErrorCode(1_027_000_004, "合同主键为空");
ErrorCode CONTRACT_STATUS_NOT_UPDATE = new ErrorCode(1_027_000_005, "{}状态合同不允许修改");
ErrorCode CONTRACT_DATA_NOT_EXISTS = new ErrorCode(1_027_000_006, "{}不存在");
ErrorCode CONTRACT_PARAMS_ERROR = new ErrorCode(1_027_000_100, "{}");
ErrorCode CONTRACT_STATUS_NOT_SUBMIT_APPROVAL = new ErrorCode(1_027_000_007, "{}状态合同不允许提交审核");
ErrorCode CONTRACT_STATUS_NOT_APPROVAL = new ErrorCode(1_027_000_008, "{}状态合同不允许审核");
ErrorCode CONTRACT_ERP_COMPANY_PLEASE_BIND = new ErrorCode(1_027_000_009, "请先绑定{}ERP公司信息");

View File

@@ -0,0 +1,131 @@
package com.zt.plat.module.contractorder.controller.admin.contract.util;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.zt.plat.module.contractorder.api.vo.contract.ContractReceiveSendSaveReqVO;
import io.swagger.v3.oas.annotations.media.Schema;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
// 补充项目自定义异常相关的import
import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.zt.plat.module.contractorder.enums.ErrorCodeConstants.CONTRACT_PARAMS_ERROR;
public class ContractReceiveSendValidator {
/**
* 校验收发货规则列表的合法性(无返回值,校验失败直接抛异常)
* 规则排除id和继承字段需校验字段要么全有值/全为空;报错显示@Schema的description
*/
public static void validateContractReceiveSend(List<ContractReceiveSendSaveReqVO> contractReceiveSends) {
// 列表为空时,无需校验,直接结束方法
if (CollectionUtils.isEmpty(contractReceiveSends)) {
return;
}
// 遍历列表逐个校验
for (int index = 0; index < contractReceiveSends.size(); index++) {
ContractReceiveSendSaveReqVO vo = contractReceiveSends.get(index);
validateSingleVO(vo, index);
}
}
/**
* 校验单个VO对象核心获取@Schema的description并替换字段名
*/
private static void validateSingleVO(ContractReceiveSendSaveReqVO vo, int index) {
if (vo == null) {
return; // 单个对象为null视为全空合法
}
Class<?> clazz = vo.getClass();
Field[] declaredFields = clazz.getDeclaredFields();
List<Field> targetFields = new ArrayList<>();
// 过滤排除id字段保留自有非id字段
for (Field field : declaredFields) {
if (!"id".equals(field.getName())) {
targetFields.add(field);
}
}
// 统计有值/空值的字段描述(@Schema的description
List<String> nonNullFieldDescs = new ArrayList<>(); // 有值字段的描述
List<String> nullFieldDescs = new ArrayList<>(); // 空值字段的描述
for (Field field : targetFields) {
field.setAccessible(true);
String fieldName = field.getName();
// 1. 获取字段@Schema注解的description
String fieldDesc = getFieldSchemaDescription(field);
try {
Object value = field.get(vo);
// 判断是否为“有值”
boolean hasValue = false;
if (value != null) {
if (value instanceof String) {
hasValue = !((String) value).trim().isEmpty();
} else {
hasValue = true;
}
}
// 2. 根据值是否为空,将描述加入对应列表
if (hasValue) {
nonNullFieldDescs.add(fieldDesc);
} else {
nullFieldDescs.add(fieldDesc);
}
} catch (IllegalAccessException e) {
throw new RuntimeException("反射获取字段[" + fieldName + "]值失败", e);
}
}
// 校验规则:有值字段数>0 且 <总校验字段数 → 不合法,抛自定义异常
int totalTargetCount = targetFields.size();
int nonNullCount = nonNullFieldDescs.size();
if (nonNullCount > 0 && nonNullCount < totalTargetCount) {
// 拼接错误提示信息
String errorMsg = String.format("列表中第%d个收发货规则对象不符合规则" +
"需校验字段中,有值字段:%s空值字段%s。" +
"规则要求:要么所有需校验字段都有值,要么都为空。",
index, nonNullFieldDescs, nullFieldDescs);
// 抛项目自定义异常
throw exception(CONTRACT_PARAMS_ERROR, errorMsg);
}
}
/**
* 获取字段上@Schema注解的description值无注解则返回字段名
*/
private static String getFieldSchemaDescription(Field field) {
// 检查字段是否有@Schema注解
if (field.isAnnotationPresent(Schema.class)) {
Schema schema = field.getAnnotation(Schema.class);
String description = schema.description();
// 若description为空如注解只写了example仍返回字段名
return description == null || description.trim().isEmpty() ? field.getName() : description;
}
// 无@Schema注解返回字段名兜底
return field.getName();
}
// 测试示例
public static void main(String[] args) {
// 测试:部分有值 → 抛自定义异常
List<ContractReceiveSendSaveReqVO> list = new ArrayList<>();
ContractReceiveSendSaveReqVO vo = new ContractReceiveSendSaveReqVO();
vo.setId(1L);
vo.setMaterialName("ZT"); // 物料名称有值
list.add(vo);
try {
validateContractReceiveSend(list); // 无返回值,仅执行校验
} catch (Exception e) {
// 输出报错信息
System.out.println(e.getMessage());
}
}
}

View File

@@ -98,4 +98,33 @@ public class ContractDetailDO extends BusinessBaseDO {
*/
@TableField("LEN")
private String length;
// 中文牌名
@TableField("CHS_NO")
private String chineseNo;
// 英文牌名
@TableField("EN_NO")
private String englishNo;
// 技术规格
@TableField("TCHI_SPEC")
private String technicalSpecification;
// 技术标准1
@TableField("TCHL_STD1")
private String technicalStandard1;
// 技术标准2
@TableField("TCHI_STD2")
private String technicalStandard2;
// 线别
@TableField("LINE_LVL")
private String lineLevel;
// 包装
@TableField("PACK")
private String pack;
}

View File

@@ -126,11 +126,19 @@ public class ContractServiceImpl implements ContractService {
public PageResult<ContractMainDO> getContractPage(ContractPageReqVO pageReqVO) {
return contractMainMapper.selectContractPage(pageReqVO);
}
boolean isContractReceiveSendValid(List<ContractReceiveSendSaveReqVO> contractReceiveSends){
if (CollectionUtils.isEmpty(contractReceiveSends)) {
return true;
}
return false;
}
@Transactional
@Override
public Long createContract(ContractSaveReqVO reqVO) {
//校验收发货的规则的合法性
isContractReceiveSendValid(reqVO.getContractReceiveSends());
// 校验合同名称是否存在
ContractMainDO contract = contractMainMapper
.selectOne(TableFieldConstants.BSE_CTRT_MAIN_CTRT_NAME, reqVO.getContractName());