明细计算,产品详情页

This commit is contained in:
朱昊天
2026-04-28 16:53:35 +08:00
parent 539889a346
commit fe13e952f2
18 changed files with 633 additions and 298 deletions

View File

@@ -8,6 +8,7 @@ import com.gear.common.core.controller.BaseController;
import com.gear.mat.domain.bo.MatProductAdditionBo;
import com.gear.mat.domain.vo.MatProductAdditionVo;
import com.gear.mat.service.IMatProductAdditionService;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@@ -69,4 +70,19 @@ public class MatProductAdditionController extends BaseController {
boolean result = productAdditionService.delProductAddition(addId);
return R.ok(result);
}
@Log(title = "产品属性附加表", businessType = BusinessType.UPDATE)
@PostMapping("/batchSave")
public R<Boolean> batchSave(@RequestBody BatchSaveRequest payload) {
if (payload == null) {
return R.ok(false);
}
return R.ok(productAdditionService.batchSaveProductAddition(payload.getProductId(), payload.getItems()));
}
@Data
public static class BatchSaveRequest {
private Long productId;
private List<MatProductAdditionBo> items;
}
}

View File

@@ -8,6 +8,7 @@ import com.gear.common.enums.BusinessType;
import com.gear.mat.domain.bo.MatProductLaborBo;
import com.gear.mat.domain.vo.MatProductLaborVo;
import com.gear.mat.service.IMatProductLaborService;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@@ -46,4 +47,19 @@ public class MatProductLaborController extends BaseController {
boolean result = productLaborService.delProductLabor(laborId);
return R.ok(result);
}
@Log(title = "产品手动工价", businessType = BusinessType.UPDATE)
@PostMapping("/batchSave")
public R<Boolean> batchSave(@RequestBody BatchSaveRequest payload) {
if (payload == null) {
return R.ok(false);
}
return R.ok(productLaborService.batchSaveProductLabor(payload.getProductId(), payload.getItems()));
}
@Data
public static class BatchSaveRequest {
private Long productId;
private List<MatProductLaborBo> items;
}
}

View File

@@ -71,6 +71,11 @@ public class MatMaterialVo {
@ExcelDictFormat(readConverterExp = "已=入库")
private BigDecimal currentStock;
/**
* 单价(用于成本测算:默认取最新入库单价,其次取最新采购单价)
*/
private BigDecimal unitPrice;
/**
* 备注
*/

View File

@@ -44,4 +44,6 @@ public interface IMatProductAdditionService extends IService<MatProductAddition>
* @return 删除结果
*/
boolean delProductAddition(Long addId);
boolean batchSaveProductAddition(Long productId, List<MatProductAdditionBo> items);
}

View File

@@ -16,4 +16,6 @@ public interface IMatProductLaborService extends IService<MatProductLabor> {
boolean updateProductLabor(MatProductLaborBo productLaborBo);
boolean delProductLabor(Long laborId);
boolean batchSaveProductLabor(Long productId, List<MatProductLaborBo> items);
}

View File

@@ -49,7 +49,41 @@ public class MatMaterialServiceImpl implements IMatMaterialService {
*/
@Override
public MatMaterialVo queryById(Long materialId){
return baseMapper.selectVoById(materialId);
MatMaterialVo vo = baseMapper.selectVoById(materialId);
if (vo == null) {
return null;
}
vo.setUnitPrice(resolveUnitPrice(materialId));
return vo;
}
private BigDecimal resolveUnitPrice(Long materialId) {
QueryWrapper<MatPurchaseInDetail> inDetailQw = new QueryWrapper<>();
inDetailQw.eq("material_id", materialId);
inDetailQw.eq("del_flag", 0);
inDetailQw.isNotNull("in_price");
inDetailQw.orderByDesc("in_time");
inDetailQw.orderByDesc("create_time");
inDetailQw.last("LIMIT 1");
MatPurchaseInDetail latestInDetail = matPurchaseInDetailMapper.selectOne(inDetailQw);
if (latestInDetail != null && latestInDetail.getInPrice() != null) {
return latestInDetail.getInPrice();
}
QueryWrapper<MatPurchase> purchaseQw = new QueryWrapper<>();
purchaseQw.eq("material_id", materialId);
purchaseQw.eq("del_flag", 0);
purchaseQw.ne("status", 3);
purchaseQw.isNotNull("purchase_price");
purchaseQw.orderByDesc("update_time");
purchaseQw.orderByDesc("create_time");
purchaseQw.last("LIMIT 1");
MatPurchase latestPurchase = matPurchaseMapper.selectOne(purchaseQw);
if (latestPurchase != null && latestPurchase.getPurchasePrice() != null) {
return latestPurchase.getPurchasePrice();
}
return null;
}
/**

View File

@@ -9,7 +9,10 @@ import com.gear.mat.mapper.MatProductAdditionMapper;
import com.gear.mat.service.IMatProductAdditionService;
import com.gear.common.utils.BeanCopyUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* 产品属性附加表Service实现类
@@ -51,4 +54,55 @@ public class MatProductAdditionServiceImpl extends ServiceImpl<MatProductAdditio
public boolean delProductAddition(Long addId) {
return removeById(addId);
}
@Transactional(rollbackFor = Exception.class)
@Override
public boolean batchSaveProductAddition(Long productId, List<MatProductAdditionBo> items) {
if (productId == null) {
return false;
}
List<MatProductAddition> exist = baseMapper.selectList(new LambdaQueryWrapper<MatProductAddition>()
.select(MatProductAddition::getAddId)
.eq(MatProductAddition::getProductId, productId)
.eq(MatProductAddition::getDelFlag, 0));
Set<Long> existIds = exist.stream()
.map(MatProductAddition::getAddId)
.filter(id -> id != null && id > 0)
.collect(Collectors.toSet());
Set<Long> incomingIds = items == null ? java.util.Collections.emptySet() : items.stream()
.map(MatProductAdditionBo::getAddId)
.filter(id -> id != null && id > 0)
.collect(Collectors.toSet());
List<Long> deleteIds = existIds.stream()
.filter(id -> !incomingIds.contains(id))
.collect(Collectors.toList());
if (!deleteIds.isEmpty()) {
removeByIds(deleteIds);
}
if (items == null || items.isEmpty()) {
return true;
}
for (MatProductAdditionBo item : items) {
if (item == null) {
continue;
}
MatProductAddition addition = BeanCopyUtils.copy(item, MatProductAddition.class);
if (addition == null) {
continue;
}
addition.setProductId(productId);
if (addition.getAddId() == null) {
save(addition);
} else {
updateById(addition);
}
}
return true;
}
}

View File

@@ -9,8 +9,11 @@ import com.gear.mat.domain.vo.MatProductLaborVo;
import com.gear.mat.mapper.MatProductLaborMapper;
import com.gear.mat.service.IMatProductLaborService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@Service
public class MatProductLaborServiceImpl extends ServiceImpl<MatProductLaborMapper, MatProductLabor> implements IMatProductLaborService {
@@ -42,4 +45,55 @@ public class MatProductLaborServiceImpl extends ServiceImpl<MatProductLaborMappe
public boolean delProductLabor(Long laborId) {
return removeById(laborId);
}
@Transactional(rollbackFor = Exception.class)
@Override
public boolean batchSaveProductLabor(Long productId, List<MatProductLaborBo> items) {
if (productId == null) {
return false;
}
List<MatProductLabor> exist = baseMapper.selectList(new LambdaQueryWrapper<MatProductLabor>()
.select(MatProductLabor::getLaborId)
.eq(MatProductLabor::getProductId, productId)
.eq(MatProductLabor::getDelFlag, 0));
Set<Long> existIds = exist.stream()
.map(MatProductLabor::getLaborId)
.filter(id -> id != null && id > 0)
.collect(Collectors.toSet());
Set<Long> incomingIds = items == null ? java.util.Collections.emptySet() : items.stream()
.map(MatProductLaborBo::getLaborId)
.filter(id -> id != null && id > 0)
.collect(Collectors.toSet());
List<Long> deleteIds = existIds.stream()
.filter(id -> !incomingIds.contains(id))
.collect(Collectors.toList());
if (!deleteIds.isEmpty()) {
removeByIds(deleteIds);
}
if (items == null || items.isEmpty()) {
return true;
}
for (MatProductLaborBo item : items) {
if (item == null) {
continue;
}
MatProductLabor labor = BeanCopyUtils.copy(item, MatProductLabor.class);
if (labor == null) {
continue;
}
labor.setProductId(productId);
if (labor.getLaborId() == null) {
save(labor);
} else {
updateById(labor);
}
}
return true;
}
}