package cn.iocoder.yudao.module.mes.service.pd.ctc; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi; import cn.iocoder.yudao.module.mes.controller.admin.pd.ctc.vo.*; import cn.iocoder.yudao.module.mes.dal.dataobject.pd.ctc.ProductCtcDO; import cn.iocoder.yudao.module.mes.dal.mysql.pd.ctc.ProductCtcMapper; import cn.iocoder.yudao.module.mes.service.pd.reel.ProductCtcReelService; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import java.math.BigDecimal; import java.math.RoundingMode; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.PD_CTC_CALC_PARAM_INVALID; import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.PD_CTC_ITEM_DUPLICATE; import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.PD_CTC_NOT_EXISTS; /** * MES 换位导线产品技术参数 Service 实现类 * * @author 超级管理员 */ @Service @Validated public class ProductCtcServiceImpl implements ProductCtcService { @Resource private ProductCtcMapper ctcMapper; @Resource private MdmItemApi mdmItemApi; @Resource private ProductCtcReelService reelService; @Override public Long createCtc(ProductCtcSaveReqVO createReqVO) { // 校验物料存在 mdmItemApi.validateItemExists(createReqVO.getItemId()); // 校验物料唯一 validateItemUnique(createReqVO.getItemId(), null); // 插入 ProductCtcDO ctc = BeanUtils.toBean(createReqVO, ProductCtcDO.class); ctcMapper.insert(ctc); return ctc.getId(); } @Override public void updateCtc(ProductCtcSaveReqVO updateReqVO) { // 校验存在 ProductCtcDO ctc = validateCtcExists(updateReqVO.getId()); // 校验物料存在 mdmItemApi.validateItemExists(updateReqVO.getItemId()); // 校验物料唯一(排除自身) validateItemUnique(updateReqVO.getItemId(), updateReqVO.getId()); // 更新 ProductCtcDO updateObj = BeanUtils.toBean(updateReqVO, ProductCtcDO.class); ctcMapper.updateById(updateObj); } @Override public void deleteCtc(Long id) { // 校验存在 validateCtcExists(id); // 删除关联盘具 reelService.deleteByCtcId(id); // 删除 ctcMapper.deleteById(id); } @Override public ProductCtcDO getCtc(Long id) { return ctcMapper.selectById(id); } @Override public PageResult getCtcPage(ProductCtcPageReqVO pageReqVO) { return ctcMapper.selectPage(pageReqVO); } @Override public ProductCtcAngleCalcRespVO calcAngle(ProductCtcAngleCalcReqVO reqVO) { double a = reqVO.getConductorThickness().doubleValue(); double b = reqVO.getConductorWidth().doubleValue(); double r = reqVO.getCornerRadius().doubleValue(); double t = reqVO.getInsulationThickness().doubleValue(); double w = reqVO.getTapeWidth().doubleValue(); double overlap = reqVO.getOverlapWidth().doubleValue(); // 导线周长:圆角矩形,厚度方向含绝缘,宽度方向不含 double circumference = 2 * (a + b + 2 * t) - (8 - 2 * Math.PI) * r; // 有效纸带宽度 = 纸带宽度 - 重叠宽度 double effectiveWidth = w - overlap; if (circumference <= 0 || effectiveWidth <= 0 || effectiveWidth > circumference) { throw exception(PD_CTC_CALC_PARAM_INVALID); } double angle = Math.asin(effectiveWidth / circumference); double angleDeg = Math.toDegrees(angle); double pitch = effectiveWidth / Math.cos(angle); ProductCtcAngleCalcRespVO respVO = new ProductCtcAngleCalcRespVO(); respVO.setCircumference(BigDecimal.valueOf(circumference).setScale(6, RoundingMode.HALF_UP)); respVO.setWrappingAngle(BigDecimal.valueOf(angleDeg).setScale(6, RoundingMode.HALF_UP)); respVO.setWrappingPitch(BigDecimal.valueOf(pitch).setScale(6, RoundingMode.HALF_UP)); return respVO; } @Override public ProductCtcResistanceCalcRespVO calcResistance(ProductCtcResistanceCalcReqVO reqVO) { double thickness = reqVO.getConductorThickness().doubleValue(); double width = reqVO.getConductorWidth().doubleValue(); double temp = reqVO.getTemperature().doubleValue(); // 材质参数:铜/铝(ρ20 单位 Ω·mm²/m,α 单位 1/℃) double rho20; double alpha; if ("aluminum".equalsIgnoreCase(reqVO.getMaterial())) { rho20 = 0.0283; alpha = 0.00403; } else { rho20 = 0.0175; alpha = 0.00393; } double area = thickness * width; if (area <= 0) { throw exception(PD_CTC_CALC_PARAM_INVALID); } // R20 = ρ20 / A(Ω/m) double r20 = rho20 / area; // Rt = R20 × (1 + α × (t - 20)) double rt = r20 * (1 + alpha * (temp - 20)); ProductCtcResistanceCalcRespVO respVO = new ProductCtcResistanceCalcRespVO(); respVO.setCrossSection(BigDecimal.valueOf(area).setScale(6, RoundingMode.HALF_UP)); respVO.setResistance20cKm(BigDecimal.valueOf(r20 * 1000).setScale(6, RoundingMode.HALF_UP)); respVO.setResistanceAtTemp(BigDecimal.valueOf(rt).setScale(6, RoundingMode.HALF_UP)); respVO.setResistanceAtTempKm(BigDecimal.valueOf(rt * 1000).setScale(6, RoundingMode.HALF_UP)); return respVO; } @Override public ProductCtcReelCalcRespVO calcReelCapacity(ProductCtcReelCalcReqVO reqVO) { double d1 = reqVO.getReelOuterDiameter().doubleValue(); double d2 = reqVO.getReelInnerDiameter().doubleValue(); double l2 = reqVO.getReelWidth().doubleValue(); double ct = reqVO.getCtcThickness().doubleValue(); double cw = reqVO.getCtcWidth().doubleValue(); if (d1 <= d2 || l2 <= 0 || ct <= 0 || cw <= 0) { throw exception(PD_CTC_CALC_PARAM_INVALID); } // 盘具容量公式(参照需求文档盘具计算 sheet): // ((d1-60)+(d2+10)) × INT(l2/(CTC宽+1)) × (d1-d2-70) / (CTC高+0.2) / 1274 double capacityM = ((d1 - 60) + (d2 + 10)) * Math.floor(l2 / (cw + 1)) * (d1 - d2 - 70) / (ct + 0.2) / 1274; ProductCtcReelCalcRespVO respVO = new ProductCtcReelCalcRespVO(); respVO.setCapacityMeter(BigDecimal.valueOf(capacityM).setScale(2, RoundingMode.HALF_UP)); respVO.setCapacityKm(BigDecimal.valueOf(capacityM / 1000).setScale(4, RoundingMode.HALF_UP)); return respVO; } private void validateItemUnique(Long itemId, Long excludeId) { ProductCtcDO ctc = ctcMapper.selectByItemId(itemId); if (ctc != null && !ctc.getId().equals(excludeId)) { throw exception(PD_CTC_ITEM_DUPLICATE); } } private ProductCtcDO validateCtcExists(Long id) { ProductCtcDO ctc = ctcMapper.selectById(id); if (ctc == null) { throw exception(PD_CTC_NOT_EXISTS); } return ctc; } }