package cn.iocoder.yudao.module.yavwarehouse.controller.admin.iomanagementmain;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApiImpl;
import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
import cn.iocoder.yudao.module.marketing.controller.admin.aftersalesmanagement.vo.AftersalesManagementSaveReqVO;
import cn.iocoder.yudao.module.yavwarehouse.controller.admin.iomanagementmain.vo.IoManagementMainPageReqVO;
import cn.iocoder.yudao.module.yavwarehouse.controller.admin.iomanagementmain.vo.IoManagementMainRespVO;
import cn.iocoder.yudao.module.yavwarehouse.controller.admin.iomanagementmain.vo.IoManagementMainSaveReqVO;
import cn.iocoder.yudao.module.yavwarehouse.controller.admin.iomanagementmain.vo.IoManagementMainStartFlowReqVO;
import cn.iocoder.yudao.module.yavwarehouse.dal.dataobject.iomanagementmain.IoManagementMainDO;
import cn.iocoder.yudao.module.yavwarehouse.service.iomanagementdetail.IoManagementDetailService;
import cn.iocoder.yudao.module.yavwarehouse.service.iomanagementmain.IoManagementMainService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
@Tag(name = "管理后台 - 出入库管理")
@RestController
@RequestMapping("/yavwarehouse/io-management-main")
@Validated
public class IoManagementMainController {
@Resource
private IoManagementMainService ioManagementMainService;
@Resource
private IoManagementDetailService ioManagementDetailService;
@Resource
private BpmProcessInstanceApiImpl bpmProcessInstanceApi;
// 变更说明:
// 1) 参数校验、鉴权保持不变;业务逻辑仍在 Service 层,控制器保持薄。
@PostMapping("/create")
@Operation(summary = "创建出入库主")
@PreAuthorize("@ss.hasPermission('yavwarehouse:io-management-main:create')")
public CommonResult<Long> createIoManagementMain(@Valid @RequestBody IoManagementMainSaveReqVO createReqVO) {
return success(ioManagementMainService.createIoManagementMain(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新出入库主")
@PreAuthorize("@ss.hasPermission('yavwarehouse:io-management-main:update')")
public CommonResult<Boolean> updateIoManagementMain(@Valid @RequestBody IoManagementMainSaveReqVO updateReqVO) {
ioManagementMainService.updateIoManagementMain(updateReqVO);
return success(true);
}
@PostMapping("/approval")
@Operation(summary = "审批出入库主")
@PreAuthorize("@ss.hasPermission('yavwarehouse:io-management-main:approval')")
public CommonResult<Boolean> approvalIoManagementMain(@Valid @RequestBody IoManagementMainSaveReqVO updateReqVO) {
ioManagementMainService.approvalIoManagementMain(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除出入库主")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('yavwarehouse:io-management-main:delete')")
public CommonResult<Boolean> deleteIoManagementMain(@RequestParam("id") Long id) {
ioManagementMainService.deleteIoManagementMain(id);
return success(true);
}
@DeleteMapping("/delete-list")
@Parameter(name = "ids", description = "编号", required = true)
@Operation(summary = "批量删除出入库主")
@PreAuthorize("@ss.hasPermission('yavwarehouse:io-management-main:delete')")
public CommonResult<Boolean> deleteIoManagementMainList(@RequestParam("ids") List<Long> ids) {
ioManagementMainService.deleteIoManagementMainListByIds(ids);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得出入库主")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('yavwarehouse:io-management-main:query')")
public CommonResult<IoManagementMainRespVO> getIoManagementMain(@RequestParam("id") Long id,
@RequestParam(value = "withItems", required = false, defaultValue = "false") boolean withItems) {
// 变更:将“查明细与组装”下沉到 Service;Controller 只透传参数
return success(ioManagementMainService.getIoManagementMainWithItems(id, withItems));
}
@GetMapping("/page")
@Operation(summary = "获得出入库主分页")
@PreAuthorize("@ss.hasPermission('yavwarehouse:io-management-main:query')")
public CommonResult<PageResult<IoManagementMainRespVO>> getIoManagementMainPage(@Valid IoManagementMainPageReqVO pageReqVO) {
return success(ioManagementMainService.getIoManagementMainPages(pageReqVO));
}
@GetMapping("/export-excel")
@Operation(summary = "导出出入库主 Excel")
@PreAuthorize("@ss.hasPermission('yavwarehouse:io-management-main:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportIoManagementMainExcel(@Valid IoManagementMainPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<IoManagementMainDO> list = ioManagementMainService.getIoManagementMainPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "出入库主.xls", "数据", IoManagementMainRespVO.class,
BeanUtils.toBean(list, IoManagementMainRespVO.class));
}
@GetMapping("/getOrderPage")
@Operation(summary = "根据业务类型查询单据")
@PreAuthorize("@ss.hasPermission('yavwarehouse:io-management-main:query')")
public CommonResult getOrderPage(@RequestParam String businessType, @RequestParam String businessTypeValue, @RequestParam String applyType, PageParam pageParam) {
return success(ioManagementMainService.getOrderPage(businessType, businessTypeValue, applyType, pageParam));
}
@PutMapping("/startFlow")
@Operation(summary = "发起出入库流程")
@PreAuthorize("@ss.hasPermission('yavwarehouse:io-management-main:update')")
public CommonResult<Boolean> startFlow(@Valid @RequestBody IoManagementMainStartFlowReqVO reqVO) {
Map<String, Object> variables = new HashMap<>();
variables.put("ioId", reqVO.getId());
String processInstanceId = bpmProcessInstanceApi.createProcessInstance(getLoginUserId(),
new BpmProcessInstanceCreateReqDTO()
.setProcessDefinitionKey("inbound")
.setVariables(variables)
.setBusinessKey(String.valueOf(reqVO.getId()))
.setStartUserSelectAssignees(reqVO.getNextAssignees()));
ioManagementMainService.updateProcessInfo(reqVO.getId(), processInstanceId, "RUNNING");
return success(true);
}
}
package cn.iocoder.yudao.module.yavwarehouse.service.iomanagementmain;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.enums.AuditStateEnum;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.marketing.controller.admin.profilesalesorder.vo.ProfileSalesOrderPageReqVO;
import cn.iocoder.yudao.module.marketing.controller.admin.projectsalesorder.vo.ProjectSalesOrderPageReqVO;
import cn.iocoder.yudao.module.marketing.controller.admin.salesorder.vo.KreSalesOrderPageReqVO;
import cn.iocoder.yudao.module.marketing.dal.dataobject.profilesalesorder.ProfileSalesOrderDO;
import cn.iocoder.yudao.module.marketing.dal.dataobject.projectsalesorder.ProjectSalesOrderDO;
import cn.iocoder.yudao.module.marketing.dal.dataobject.salesorder.KreSalesOrderDO;
import cn.iocoder.yudao.module.marketing.dal.mysql.profilesalesorder.ProfileSalesOrderMapper;
import cn.iocoder.yudao.module.marketing.dal.mysql.projectsalesorder.ProjectSalesOrderMapper;
import cn.iocoder.yudao.module.marketing.dal.mysql.salesorder.KreSalesOrderMapper;
import cn.iocoder.yudao.module.plan.controller.admin.factorymaterials.vo.FactoryMaterialsPageReqVO;
import cn.iocoder.yudao.module.plan.controller.admin.fenestrationmanagement.vo.FenestrationManagementPageReqVO;
import cn.iocoder.yudao.module.plan.controller.admin.profilecheck.vo.ProfileCheckPageReqVO;
import cn.iocoder.yudao.module.plan.dal.dataobject.factorymaterials.FactoryMaterialsDO;
import cn.iocoder.yudao.module.plan.dal.dataobject.fenestrationmanagement.FenestrationManagementDO;
import cn.iocoder.yudao.module.plan.dal.dataobject.profilecheck.ProfileCheckDO;
import cn.iocoder.yudao.module.plan.dal.mysql.factorymaterials.FactoryMaterialsMapper;
import cn.iocoder.yudao.module.plan.dal.mysql.fenestrationmanagement.FenestrationManagementMapper;
import cn.iocoder.yudao.module.plan.dal.mysql.profilecheck.ProfileCheckMapper;
import cn.iocoder.yudao.module.purchase.controller.admin.receipt.vo.ReceiptPageReqVO;
import cn.iocoder.yudao.module.purchase.dal.dataobject.material.MaterialDO;
import cn.iocoder.yudao.module.purchase.dal.dataobject.materialinventory.MaterialInventoryDO;
import cn.iocoder.yudao.module.purchase.dal.dataobject.receipt.ReceiptDO;
import cn.iocoder.yudao.module.purchase.dal.mysql.material.MaterialMapper;
import cn.iocoder.yudao.module.purchase.dal.mysql.materialinventory.MaterialInventoryMapper;
import cn.iocoder.yudao.module.purchase.dal.mysql.receipt.ReceiptMapper;
import cn.iocoder.yudao.module.purchase.utils.OrderNoGeneratorUtil;
import cn.iocoder.yudao.module.yavwarehouse.controller.admin.inventorydetails.vo.InventoryDetailsSaveReqVO;
import cn.iocoder.yudao.module.yavwarehouse.controller.admin.iomanagementdetail.vo.IoManagementDetailRespVO;
import cn.iocoder.yudao.module.yavwarehouse.controller.admin.iomanagementdetail.vo.IoManagementDetailSaveReqVO;
import cn.iocoder.yudao.module.yavwarehouse.controller.admin.iomanagementmain.vo.IoManagementMainPageReqVO;
import cn.iocoder.yudao.module.yavwarehouse.controller.admin.iomanagementmain.vo.IoManagementMainRespVO;
import cn.iocoder.yudao.module.yavwarehouse.controller.admin.iomanagementmain.vo.IoManagementMainSaveReqVO;
import cn.iocoder.yudao.module.yavwarehouse.dal.dataobject.inventorydetails.InventoryDetailsDO;
import cn.iocoder.yudao.module.yavwarehouse.dal.dataobject.iomanagementdetail.IoManagementDetailDO;
import cn.iocoder.yudao.module.yavwarehouse.dal.dataobject.iomanagementmain.IoManagementMainDO;
import cn.iocoder.yudao.module.yavwarehouse.dal.dataobject.yavwarehouse.YavWarehouseDO;
import cn.iocoder.yudao.module.yavwarehouse.dal.mysql.iomanagementdetail.IoManagementDetailMapper;
import cn.iocoder.yudao.module.yavwarehouse.dal.mysql.iomanagementmain.IoManagementMainMapper;
import cn.iocoder.yudao.module.yavwarehouse.dal.mysql.yavwarehouse.YavWarehouseMapper;
import cn.iocoder.yudao.module.yavwarehouse.enums.BILL_TYPE;
import cn.iocoder.yudao.module.yavwarehouse.enums.CostStrategyType;
import cn.iocoder.yudao.module.yavwarehouse.enums.YavConstants;
import cn.iocoder.yudao.module.yavwarehouse.service.inventorydetails.InventoryDetailsService;
import cn.iocoder.yudao.module.yavwarehouse.service.iomanagementdetail.IoManagementDetailService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.datical.liquibase.ext.checks.config.IFileAccessor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.yavwarehouse.enums.ErrorCodeConstants.*;
/**
* 出入库主 Service 实现类
*/
@Service
@Validated
@Slf4j
public class IoManagementMainServiceImpl implements IoManagementMainService {
@Resource
private IoManagementMainMapper ioManagementMainMapper;
@Resource
private IoManagementDetailService ioManagementDetailService;
@Resource
private InventoryDetailsService inventoryDetailsService;
@Resource
private IoManagementDetailMapper ioManagementDetailMapper;
@Resource
private ProfileCheckMapper profileCheckMapper;
@Resource
private FenestrationManagementMapper fenestrationManagementMapper;
@Resource
private FactoryMaterialsMapper factoryMaterialsMapper;
@Resource
private ReceiptMapper receiptMapper;
@Resource
private KreSalesOrderMapper kreSalesOrderMapper;
@Resource
private ProjectSalesOrderMapper projectSalesOrderMapper;
@Resource
private ProfileSalesOrderMapper profileSalesOrderMapper;
@Resource
private MaterialInventoryMapper materialInventoryMapper;
@Resource
private MaterialMapper materialMapper;
@Resource
private YavWarehouseMapper warehouseMapper;
@Override
@Transactional(rollbackFor = Exception.class)
public Long createIoManagementMain(IoManagementMainSaveReqVO createReqVO) {
// 插入主表记录
if (StringUtils.isBlank(createReqVO.getIoBillNo())) {
String next = OrderNoGeneratorUtil.next();
if (createReqVO.getIoBillType().equals(BILL_TYPE.OUTBOUND)) {
createReqVO.setIoBillNo(BILL_TYPE.CK + "_" + next);
} else {
createReqVO.setIoBillNo(BILL_TYPE.RK + "_" + next);
}
}
IoManagementMainDO ioManagementMain = BeanUtils.toBean(createReqVO, IoManagementMainDO.class);
if (ObjectUtil.equals(createReqVO.getAuditState(), AuditStateEnum.NO.getStatus())) {
checkSave(createReqVO);
ioManagementMain.setAuditState(AuditStateEnum.NO.getStatus());
}
if (ObjectUtil.equals(createReqVO.getAuditState(), AuditStateEnum.NOT_PASS.getStatus())) {
checkAuditState(createReqVO);
ioManagementMain.setAuditState(AuditStateEnum.NOT_PASS.getStatus());
}
ioManagementMainMapper.insert(ioManagementMain);
// 根据 ioBillType 判断入库/出库,影响库存增减方向与校验
boolean isInbound = BILL_TYPE.INBOUND.equals(createReqVO.getIoBillType());
// 默认策略:FIFO(保持现有行为不变)。如需切换策略,仅需改此处。
final CostStrategyType costStrategy = CostStrategyType.FIFO;
// 明细持久化:先统一补主表关联字段,再调用明细创建(可后续优化为批量)
List<IoManagementDetailDO> ioManagementDetailDOS = BeanUtils.toBean(createReqVO.getItems(), IoManagementDetailDO.class);
ioManagementDetailDOS.forEach(item -> {
item.setMainId(ioManagementMain.getId());
item.setIoBillNo(ioManagementMain.getIoBillNo());
if (!isInbound)
item.setIoMainUnitQty(item.getIoMainUnitQty().negate());
Long detailId = ioManagementDetailService.createIoManagementDetail(item);
Long warehouseId = item.getIoWarehouseId();
if (!isInbound) {
if (costStrategy == CostStrategyType.FIFO) {
// FIFO:按入库明细顺序分摊并写回成本
updateInboundDetail(warehouseId, item.getIoMaterialId(), detailId, item.getIoMainUnitQty().negate());
} else {
// 其他策略:计算并写回成本(不改变入库明细的已出库数量)
computeAndWriteOutboundCostByStrategy(warehouseId, item.getIoMaterialId(), detailId, item.getIoMainUnitQty().negate(), costStrategy);
}
}
});
if (CollectionUtils.isNotEmpty(ioManagementDetailDOS)) {
ioManagementDetailDOS.stream().map(p -> p.getIoWarehouseId()).distinct().forEach(warehouseId -> {
// 合并明细:按物料ID汇总数量;使用已带方向(出库为负、入库为正)的明细集合
Map<Long, BigDecimal> materialIdToDelta = ioManagementDetailDOS.stream()
.filter(p -> Objects.equals(p.getIoWarehouseId(), warehouseId))
.collect(Collectors.toMap(
IoManagementDetailDO::getIoMaterialId,
IoManagementDetailDO::getIoMainUnitQty,
BigDecimal::add));
// 一次性查询所有涉及物料的现存库存,返回以 materialId 为 key 的 Map
Map<Long, InventoryDetailsDO> materialIdToInv = inventoryDetailsService
.listByWarehouseIdAndMaterialIds(warehouseId, materialIdToDelta.keySet());
// 分流创建/更新:出库校验库存存在与不为负
for (Map.Entry<Long, BigDecimal> entry : materialIdToDelta.entrySet()) {
Long materialId = entry.getKey();
BigDecimal delta = entry.getValue(); // 已包含方向(入库+,出库-)
InventoryDetailsDO inv = materialIdToInv.get(materialId);
if (inv == null) {
if (!isInbound) {
// 出库:库存不存在,直接拒绝
throw exception(INVENTORY_REFUSE_OUTBOUND);
}
// 入库:不存在则创建
YavWarehouseDO warehouseDO = warehouseMapper.selectById(warehouseId);
List<MaterialInventoryDO> materialInventoryDOS = materialInventoryMapper.selectList(new LambdaQueryWrapper<MaterialInventoryDO>().eq(Objects.nonNull(warehouseDO) && StringUtils.isNotBlank(warehouseDO.getWhName()), MaterialInventoryDO::getMWarehouse, warehouseDO.getWhName()));
String position = "";
String unit = "";
String ioCustomOrder = "";
if (CollectionUtils.isNotEmpty(materialInventoryDOS)) {
MaterialInventoryDO materialInventoryDO = materialInventoryDOS.get(0);
position = materialInventoryDO.getMWarehouseShelf() + "-" + materialInventoryDO.getMWarehouseColumn() + "-" + materialInventoryDO.getMWarehouseNum();
}
MaterialDO materialDO = materialMapper.selectById(materialId);
List<IoManagementDetailDO> detailDOS = ioManagementDetailDOS.stream()
.filter(p -> Objects.equals(p.getIoWarehouseId(), warehouseId) && Objects.equals(p.getIoMaterialCode(), Objects.nonNull(materialDO) ? materialDO.getMCode() : null))
.collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(detailDOS)) {
position = detailDOS.get(0).getIoWarehouseLocation();
unit = detailDOS.get(0).getIoMainUnit();
ioCustomOrder = detailDOS.get(0).getIoCustomOrder();
}
inventoryDetailsService.createInventoryDetails(InventoryDetailsSaveReqVO.builder()
.idWhId(warehouseId)
.idMaterialId(materialId)
.idMaterialName(materialDO.getMName())
.idMaterialCode(materialDO.getMCode())
.idAvailableQuantity(delta)
.idStockQuantity(delta)
.idInventoryUnit(unit)
.idCustomOrder(StringUtils.isNotBlank(ioCustomOrder) ? Integer.valueOf(ioCustomOrder) : null)
.idMaterialPosition(position)
.idWhName(Objects.nonNull(warehouseDO) ? warehouseDO.getWhName() : "")
.idWhCode(Objects.nonNull(warehouseDO) ? warehouseDO.getWhNumber() : "")
.build());
} else {
BigDecimal newAvailable = inv.getIdAvailableQuantity().add(delta);
BigDecimal newStock = inv.getIdStockQuantity().add(delta);
if (!isInbound && newStock.compareTo(BigDecimal.ZERO) < 0) {
// 出库:扣减后为负,拒绝
throw exception(BOUND_RUN_OUT);
}
YavWarehouseDO warehouseDO = warehouseMapper.selectById(warehouseId);
List<MaterialInventoryDO> materialInventoryDOS = materialInventoryMapper.selectList(new LambdaQueryWrapper<MaterialInventoryDO>().eq(Objects.nonNull(warehouseDO) && StringUtils.isNotBlank(warehouseDO.getWhName()), MaterialInventoryDO::getMWarehouse, warehouseDO.getWhName()));
String position = "";
String unit = "";
String ioCustomOrder = "";
if (CollectionUtils.isNotEmpty(materialInventoryDOS)) {
MaterialInventoryDO materialInventoryDO = materialInventoryDOS.get(0);
position = materialInventoryDO.getMWarehouseShelf() + "-" + materialInventoryDO.getMWarehouseColumn() + "-" + materialInventoryDO.getMWarehouseNum();
}
MaterialDO materialDO = materialMapper.selectById(materialId);
List<IoManagementDetailDO> detailDOS = ioManagementDetailDOS.stream()
.filter(p -> Objects.equals(p.getIoWarehouseId(), warehouseId) && Objects.equals(p.getIoMaterialCode(), Objects.nonNull(materialDO) ? materialDO.getMCode() : null))
.collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(detailDOS)) {
position = detailDOS.get(0).getIoWarehouseLocation();
unit = detailDOS.get(0).getIoMainUnit();
ioCustomOrder = detailDOS.get(0).getIoCustomOrder();
}
inventoryDetailsService.updateInventoryDetails(InventoryDetailsSaveReqVO.builder()
.id(inv.getId())
.idWhId(warehouseId)
.idMaterialId(materialId)
.idMaterialName(Objects.nonNull(materialDO) ? materialDO.getMName() : "")
.idMaterialCode(Objects.nonNull(materialDO) ? materialDO.getMCode() : "")
.idAvailableQuantity(newAvailable)
.idStockQuantity(newStock)
.idInventoryUnit(unit)
.idCustomOrder(StringUtils.isNotBlank(ioCustomOrder) ? Integer.valueOf(ioCustomOrder) : null)
.idMaterialPosition(position)
.idMaterialPosition(position)
.idWhName(Objects.nonNull(warehouseDO) ? warehouseDO.getWhName() : "")
.idWhCode(Objects.nonNull(warehouseDO) ? warehouseDO.getWhNumber() : "")
.build());
}
}
});
}
//更改对应单据来源表出入库状态
if (Objects.nonNull(createReqVO.getIoRelateNum())) {
updateSourceBillStatus(createReqVO, createReqVO.getIoBillType());
}
return ioManagementMain.getId();
}
private void checkSave(IoManagementMainSaveReqVO createReqVO) {
}
private void checkAuditState(IoManagementMainSaveReqVO createReqVO) {
//入库类型、入库时间、应用类型、入库总成本、关联单号、入库用途、选择物料、仓库、仓库类型、入库数量、单位
if (StringUtils.isBlank(createReqVO.getIoBillType())) {
throw new ServiceException(GlobalErrorCodeConstants.BAD_REQUEST_PARAM.getCode(), "入库/出库类型不能为空");
}
String name = createReqVO.getIoBillType().equals(BILL_TYPE.INBOUND) ? "入库" : "出库";
if (ObjectUtil.isEmpty(createReqVO.getIoBillDate())) {
throw new ServiceException(GlobalErrorCodeConstants.BAD_REQUEST_PARAM.getCode(), name + "时间不能为空");
}
if (StringUtils.isBlank(createReqVO.getIoApplyType())) {
throw new ServiceException(GlobalErrorCodeConstants.BAD_REQUEST_PARAM.getCode(), "应用类型不能为空");
}
if (ObjectUtil.isEmpty(createReqVO.getIoTotalCost())) {
throw new ServiceException(GlobalErrorCodeConstants.BAD_REQUEST_PARAM.getCode(), name + "总成本不能为空");
}
if (ObjectUtil.isEmpty(createReqVO.getIoRelateNum())) {
throw new ServiceException(GlobalErrorCodeConstants.BAD_REQUEST_PARAM.getCode(), "关联单号不能为空");
}
if (StringUtils.isBlank(createReqVO.getIoPurpose())) {
throw new ServiceException(GlobalErrorCodeConstants.BAD_REQUEST_PARAM.getCode(), name + "用途不能为空");
}
List<IoManagementDetailSaveReqVO> items = createReqVO.getItems();
if (CollectionUtils.isEmpty(items)) {
throw new ServiceException(GlobalErrorCodeConstants.BAD_REQUEST_PARAM.getCode(), "选择物料不能为空");
}
if (items.stream().anyMatch(item -> StringUtils.isBlank(item.getIoWarehouse()))) {
throw new ServiceException(GlobalErrorCodeConstants.BAD_REQUEST_PARAM.getCode(), "仓库名字不能为空");
}
if (items.stream().anyMatch(item -> StringUtils.isBlank(item.getIoWarehouseType()))) {
throw new ServiceException(GlobalErrorCodeConstants.BAD_REQUEST_PARAM.getCode(), "仓库类型不能为空");
}
if (items.stream().anyMatch(item -> ObjectUtil.isEmpty(item.getIoMainUnitQty()))) {
throw new ServiceException(GlobalErrorCodeConstants.BAD_REQUEST_PARAM.getCode(), name + "数量不能为空");
}
if (items.stream().anyMatch(item -> ObjectUtil.isEmpty(item.getIoMainUnit()))) {
throw new ServiceException(GlobalErrorCodeConstants.BAD_REQUEST_PARAM.getCode(), "主单位不能为空");
}
}
/**
* 更新源单据状态
*/
private void updateSourceBillStatus(IoManagementMainSaveReqVO createReqVO, String ioBillType) {
Long ioRelateNum = createReqVO.getIoRelateNum();
if (ioRelateNum == null) {
log.warn("关联单据ID为空,无法更新源单据状态");
return;
}
String ioApplyType = createReqVO.getIoApplyType();
String ioBusinessType = createReqVO.getIoBusinessType();
try {
if (BILL_TYPE.INBOUND.equals(ioBillType)) {
updateInboundSourceStatus(ioBusinessType, ioRelateNum);
} else {
updateOutboundSourceStatus(ioBusinessType, ioApplyType, ioRelateNum);
}
} catch (Exception e) {
log.error("更新源单据状态失败: billType={}, businessType={}, applyType={}, relateNum={}",
ioBillType, ioBusinessType, ioApplyType, ioRelateNum, e);
}
}
/**
* 更新入库源单据状态
*/
private void updateInboundSourceStatus(String ioBusinessType, Long ioRelateNum) {
if (YavConstants.ONE_STR.equals(ioBusinessType)) {
// 采购入库(收料通知单表)
receiptMapper.update(new LambdaUpdateWrapper<ReceiptDO>()
.eq(ReceiptDO::getId, ioRelateNum)
.set(ReceiptDO::getRWareStatus, YavConstants.ONE_STR));
}
// 可以在这里添加其他入库类型的处理
}
/**
* 更新出库源单据状态
*/
private void updateOutboundSourceStatus(String ioBusinessType, String ioApplyType, Long ioRelateNum) {
if (YavConstants.ONE_STR.equals(ioBusinessType)) {
switch (ioApplyType) {
case YavConstants.ONE_STR:
// 型材配置
profileCheckMapper.update(new LambdaUpdateWrapper<ProfileCheckDO>()
.eq(ProfileCheckDO::getId, ioRelateNum)
.set(ProfileCheckDO::getRWareStatus, YavConstants.ONE_STR));
break;
case YavConstants.TWO_STR:
// 门窗原料
fenestrationManagementMapper.update(new LambdaUpdateWrapper<FenestrationManagementDO>()
.eq(FenestrationManagementDO::getId, ioRelateNum)
.set(FenestrationManagementDO::getRWareStatus, YavConstants.ONE_STR));
break;
case YavConstants.THREE_STR:
// 门窗工厂
factoryMaterialsMapper.update(new LambdaUpdateWrapper<FactoryMaterialsDO>()
.eq(FactoryMaterialsDO::getId, ioRelateNum)
.set(FactoryMaterialsDO::getRWareStatus, YavConstants.ONE_STR));
break;
default:
log.warn("未知的出库应用类型: {}", ioApplyType);
}
} else {
//出库-销售订单
switch (ioApplyType) {
case YavConstants.ONE_STR:
// 型材配置
profileSalesOrderMapper.update(new LambdaUpdateWrapper<ProfileSalesOrderDO>()
.eq(ProfileSalesOrderDO::getId, ioRelateNum)
.set(ProfileSalesOrderDO::getPsShipper, YavConstants.ONE));
break;
case YavConstants.TWO_STR:
// 家装销售订单
kreSalesOrderMapper.update(new LambdaUpdateWrapper<KreSalesOrderDO>()
.eq(KreSalesOrderDO::getId, ioRelateNum)
.set(KreSalesOrderDO::getSoShipper, YavConstants.ONE));
break;
case YavConstants.THREE_STR:
// 工程销售订单
projectSalesOrderMapper.update(new LambdaUpdateWrapper<ProjectSalesOrderDO>()
.eq(ProjectSalesOrderDO::getId, ioRelateNum)
.set(ProjectSalesOrderDO::getEsShipper, YavConstants.ONE));
break;
default:
log.warn("未知的出库应用类型: {}", ioApplyType);
}
return;
}
}
// 计算除 FIFO 以外策略下的出库成本并写回当前出库明细(不改变入库明细)
private void computeAndWriteOutboundCostByStrategy(Long warehouseId, Long ioMaterialId, Long outboundDetailId, BigDecimal outboundQty, CostStrategyType strategy) {
if (outboundQty == null || outboundQty.compareTo(BigDecimal.ZERO) <= 0) {
return;
}
BigDecimal unitCost;
switch (strategy) {
case AVERAGE:
unitCost = computeAverageUnitCost(warehouseId, ioMaterialId);
break;
case WEIGHTED:
unitCost = computeWeightedUnitCost(warehouseId, ioMaterialId);
break;
case MOVING_AVERAGE:
unitCost = computeMovingAverageUnitCost(warehouseId, ioMaterialId);
break;
default:
unitCost = BigDecimal.ZERO;
}
writeOutboundCost(outboundDetailId, unitCost, outboundQty);
}
// 简单平均:历史“可消耗入库明细”的单价算术平均(不考虑数量)
private BigDecimal computeAverageUnitCost(Long warehouseId, Long materialId) {
List<IoManagementDetailDO> inboundList = ioManagementDetailMapper.selectConsumableInbound(warehouseId, materialId);
if (inboundList == null || inboundList.isEmpty()) return BigDecimal.ZERO;
BigDecimal sum = BigDecimal.ZERO;
int count = 0;
for (IoManagementDetailDO d : inboundList) {
if (d.getIoCostPrice() != null) {
sum = sum.add(d.getIoCostPrice());
count++;
}
}
if (count == 0) return BigDecimal.ZERO;
return sum.divide(new BigDecimal(count), 6, RoundingMode.HALF_UP);
}
// 加权平均:按“剩余可用数量”加权
private BigDecimal computeWeightedUnitCost(Long warehouseId, Long materialId) {
List<IoManagementDetailDO> inboundList = ioManagementDetailMapper.selectConsumableInbound(warehouseId, materialId);
if (inboundList == null || inboundList.isEmpty()) return BigDecimal.ZERO;
BigDecimal weightedSum = BigDecimal.ZERO;
BigDecimal totalQty = BigDecimal.ZERO;
for (IoManagementDetailDO d : inboundList) {
BigDecimal inQty = d.getIoMainUnitQty();
BigDecimal used = d.getIoOutboundQuantity() == null ? BigDecimal.ZERO : d.getIoOutboundQuantity();
BigDecimal remain = inQty.subtract(used);
if (remain.compareTo(BigDecimal.ZERO) <= 0) continue;
BigDecimal unit = d.getIoCostPrice() == null ? BigDecimal.ZERO : d.getIoCostPrice();
weightedSum = weightedSum.add(unit.multiply(remain));
totalQty = totalQty.add(remain);
}
if (totalQty.compareTo(BigDecimal.ZERO) == 0) return BigDecimal.ZERO;
return weightedSum.divide(totalQty, 6, RoundingMode.HALF_UP);
}
// 移动加权平均:优先使用主表平均成本;没有则回退为当前加权平均
private BigDecimal computeMovingAverageUnitCost(Long warehouseId, Long materialId) {
// 主表暂未保存 avgCost 字段,先回退到加权平均
return computeWeightedUnitCost(warehouseId, materialId);
}
private void writeOutboundCost(Long outboundDetailId, BigDecimal unitCost, BigDecimal qty) {
if (outboundDetailId == null || unitCost == null || qty == null) return;
BigDecimal line = unitCost.multiply(qty);
IoManagementDetailDO update = new IoManagementDetailDO();
update.setId(outboundDetailId);
update.setIoCostPrice(unitCost);
update.setIoLineCost(line);
ioManagementDetailMapper.updateById(update);
}
// FIFO:按时间顺序(先进先出)累计入库明细的已出库数量,并计算本次出库成本
private void updateInboundDetail(Long warehouseId, Long ioMaterialId, Long outboundDetailId, BigDecimal outboundQty) {
if (outboundQty == null || outboundQty.compareTo(BigDecimal.ZERO) <= 0) {
return;
}
BigDecimal need = outboundQty;
BigDecimal costSum = BigDecimal.ZERO;
List<IoManagementDetailDO> inboundList = ioManagementDetailMapper.selectConsumableInbound(warehouseId, ioMaterialId);
for (IoManagementDetailDO inbound : inboundList) {
if (need.compareTo(BigDecimal.ZERO) <= 0) {
break;
}
BigDecimal inQty = inbound.getIoMainUnitQty();
BigDecimal used = inbound.getIoOutboundQuantity() == null ? BigDecimal.ZERO : inbound.getIoOutboundQuantity();
BigDecimal remain = inQty.subtract(used);
if (remain.compareTo(BigDecimal.ZERO) <= 0) {
continue;
}
BigDecimal alloc = need.min(remain);
int affected = ioManagementDetailMapper.increaseOutboundQuantity(inbound.getId(), alloc);
if (affected != 1) {
inboundList = ioManagementDetailMapper.selectConsumableInbound(warehouseId, ioMaterialId);
continue;
}
BigDecimal unitCost = inbound.getIoCostPrice() == null ? BigDecimal.ZERO : inbound.getIoCostPrice();
costSum = costSum.add(unitCost.multiply(alloc));
need = need.subtract(alloc);
if (need.compareTo(BigDecimal.ZERO) > 0) {
throw exception(BOUND_RUN_OUT);
}
}
if (outboundDetailId != null) {
IoManagementDetailDO update = new IoManagementDetailDO();
update.setId(outboundDetailId);
update.setIoLineCost(costSum);
BigDecimal unit = costSum.divide(outboundQty, 6, RoundingMode.HALF_UP);
update.setIoCostPrice(unit);
ioManagementDetailMapper.updateById(update);
}
}
@Override
@Transactional(readOnly = true)
public IoManagementMainRespVO getIoManagementMainWithItems(Long id, boolean withItems) {
IoManagementMainDO main = ioManagementMainMapper.selectById(id);
if (main == null) {
throw exception(IO_MANAGEMENT_MAIN_NOT_EXISTS);
}
IoManagementMainRespVO vo = BeanUtils.toBean(main, IoManagementMainRespVO.class);
List<IoManagementDetailDO> details = ioManagementDetailService.listByMainId(id);
vo.setItems(BeanUtils.toBean(details, IoManagementDetailRespVO.class));
vo.setIoApplyType(CollectionUtils.isNotEmpty(details) ? details.get(0).getIoApplyType() : "");
return vo;
}
@Transactional(rollbackFor = Exception.class)
@Override
public void updateIoManagementMain(IoManagementMainSaveReqVO updateReqVO) {
// 校验存在
validateIoManagementMainExists(updateReqVO.getId());
// 更新
IoManagementMainDO updateObj = BeanUtils.toBean(updateReqVO, IoManagementMainDO.class);
if (ObjectUtil.equals(updateReqVO.getAuditState(), AuditStateEnum.NO.getStatus())) {
checkSave(updateReqVO);
updateObj.setAuditState(AuditStateEnum.NO.getStatus());
}
if (ObjectUtil.equals(updateReqVO.getAuditState(), AuditStateEnum.NOT_PASS.getStatus())) {
checkAuditState(updateReqVO);
updateObj.setAuditState(AuditStateEnum.NOT_PASS.getStatus());
//更新明细
if (CollectionUtils.isNotEmpty(updateReqVO.getItems())) {
updateReqVO.getItems().forEach(updateItem -> {
IoManagementDetailDO newUpdateItem = BeanUtils.toBean(updateItem, IoManagementDetailDO.class);
ioManagementDetailMapper.insertOrUpdate(newUpdateItem);
});
}
}
ioManagementMainMapper.updateById(updateObj);
}
@Override
public void approvalIoManagementMain(IoManagementMainSaveReqVO updateReqVO) {
Long id = updateReqVO.getId();
IoManagementMainDO ioManagementMainDO = ioManagementMainMapper.selectById(id);
// 状态校验 审批不通过,数据状态变为保存
if (ObjectUtil.equals(updateReqVO.getAuditState(), AuditStateEnum.NO.getStatus())) {
ioManagementMainDO.setAuditState(AuditStateEnum.NO.getStatus());
}
ioManagementMainDO.setAuditState(updateReqVO.getAuditState());
ioManagementMainMapper.updateById(ioManagementMainDO);
}
@Override
public void deleteIoManagementMain(Long id) {
// 校验存在
validateIoManagementMainExists(id);
// 删除
ioManagementMainMapper.deleteById(id);
}
@Transactional(rollbackFor = Exception.class)
@Override
public void deleteIoManagementMainListByIds(List<Long> ids) {
// 删除
ioManagementMainMapper.deleteByIds(ids);
//删除出入库明细
ioManagementDetailMapper.delete(new LambdaUpdateWrapper<IoManagementDetailDO>().in(CollectionUtils.isNotEmpty(ids), IoManagementDetailDO::getMainId, ids));
}
private void validateIoManagementMainExists(Long id) {
if (ioManagementMainMapper.selectById(id) == null) {
throw exception(IO_MANAGEMENT_MAIN_NOT_EXISTS);
}
}
@Override
public IoManagementMainDO getIoManagementMain(Long id) {
return ioManagementMainMapper.selectById(id);
}
@Override
public PageResult<IoManagementMainDO> getIoManagementMainPage(IoManagementMainPageReqVO pageReqVO) {
return ioManagementMainMapper.selectPage(pageReqVO);
}
//@Override
//public PageResult<IoManagementMainRespVO> getIoManagementMainPages(IoManagementMainPageReqVO pageReqVO) {
// PageResult<IoManagementMainDO> pageResult = ioManagementMainMapper.selectPage(pageReqVO);
// PageResult<IoManagementMainRespVO> result = BeanUtils.toBean(pageResult, IoManagementMainRespVO.class);
// if (CollectionUtils.isEmpty(result.getList())) {
// return result;
// }
// List<Long> ids = result.getList().stream().map(p -> p.getId()).collect(Collectors.toList());
// List<IoManagementDetailDO> detailDOS = ioManagementDetailMapper.selectList(new LambdaQueryWrapper<IoManagementDetailDO>().in(IoManagementDetailDO::getMainId, ids));
// // 5. 将明细数据按mainId分组
// Map<Long, List<IoManagementDetailDO>> detailMap = detailDOS.stream()
// .collect(Collectors.groupingBy(IoManagementDetailDO::getMainId));
// result.getList().forEach(p -> {
// List<IoManagementDetailDO> details = detailMap.get(p.getId());
// p.setIoApplyType(details.get(0).getIoApplyType());
// });
// return result;
//}
@Override
public PageResult<IoManagementMainRespVO> getIoManagementMainPages(IoManagementMainPageReqVO pageReqVO) {
PageResult<IoManagementMainDO> pageResult = ioManagementMainMapper.selectPage(pageReqVO);
PageResult<IoManagementMainRespVO> result = BeanUtils.toBean(pageResult, IoManagementMainRespVO.class);
if (CollectionUtils.isEmpty(result.getList())) {
return result;
}
List<Long> ids = result.getList().stream().map(p -> p.getId()).collect(Collectors.toList());
List<IoManagementDetailDO> detailDOS = ioManagementDetailMapper.selectList(
new LambdaQueryWrapper<IoManagementDetailDO>().in(IoManagementDetailDO::getMainId, ids)
);
Map<Long, List<IoManagementDetailDO>> detailMap = detailDOS.stream()
.collect(Collectors.groupingBy(IoManagementDetailDO::getMainId));
// 修复:增加非空判断,避免空指针
result.getList().forEach(p -> {
List<IoManagementDetailDO> details = detailMap.get(p.getId());
if (CollectionUtils.isNotEmpty(details)) { // 只有明细数据存在时才赋值
p.setIoApplyType(details.get(0).getIoApplyType());
} else {
p.setIoApplyType(null); // 无明细时设为null或默认值
}
});
return result;
}
/**
* @Description:根据业务类型查询单据列表
* @Author: hjs
* @Date 2025/9/3
**/
@Override
public PageResult<?> getOrderPage(String businessType, String businessTypeValue, String applyType, PageParam pageParam) {
log.info("根据业务类型查询单据列表入参,businessType={},businessTypeValue={},applyType={}", businessType, businessTypeValue, applyType);
if (BILL_TYPE.CK_BUSINESS_TYPE.equals(businessType)) {
if (businessTypeValue.equals(YavConstants.ONE_STR)) {
//出库-生产领料(字典出库明细应用类型 ck_apply_type)
if (applyType.equals(YavConstants.ONE_STR)) {
//型材配置
ProfileCheckPageReqVO pageReqVO = new ProfileCheckPageReqVO();
pageReqVO.setPageSize(pageParam.getPageSize());
pageReqVO.setPageNo(pageParam.getPageNo());
pageReqVO.setRWareStatus(YavConstants.TWO_STR);
return profileCheckMapper.selectPage(pageReqVO);
} else if (applyType.equals(YavConstants.TWO_STR)) {
//门窗原料-家装
FenestrationManagementPageReqVO pageReqVO = new FenestrationManagementPageReqVO();
pageReqVO.setPageSize(pageParam.getPageSize());
pageReqVO.setPageNo(pageParam.getPageNo());
pageReqVO.setRWareStatus(YavConstants.TWO_STR);
return fenestrationManagementMapper.selectPage(pageReqVO);
} else if (applyType.equals(YavConstants.THREE_STR)) {
//门窗工厂
FactoryMaterialsPageReqVO pageReqVO = new FactoryMaterialsPageReqVO();
pageReqVO.setPageSize(pageParam.getPageSize());
pageReqVO.setPageNo(pageParam.getPageNo());
pageReqVO.setRWareStatus(YavConstants.TWO_STR);
return factoryMaterialsMapper.selectPage(pageReqVO);
}
} else if (businessTypeValue.equals(YavConstants.TWO_STR)) {
//出库-销售出库(字典出库明细应用类型 xs_ck_apply_type)
if (applyType.equals(YavConstants.ONE_STR)) {
//型材销售订单
ProfileSalesOrderPageReqVO pageReqVO = new ProfileSalesOrderPageReqVO();
pageReqVO.setPageSize(pageParam.getPageSize());
pageReqVO.setPageNo(pageParam.getPageNo());
pageReqVO.setPsShipper(YavConstants.ZERO);
return profileSalesOrderMapper.selectPage(pageReqVO);
} else if (applyType.equals(YavConstants.TWO_STR)) {
//家装销售订单
KreSalesOrderPageReqVO pageReqVO = new KreSalesOrderPageReqVO();
pageReqVO.setPageSize(pageParam.getPageSize());
pageReqVO.setPageNo(pageParam.getPageNo());
pageReqVO.setSoShipper(YavConstants.ZERO);
return kreSalesOrderMapper.selectPage(pageReqVO);
} else if (applyType.equals(YavConstants.THREE_STR)) {
//工程销售订单
ProjectSalesOrderPageReqVO pageReqVO = new ProjectSalesOrderPageReqVO();
pageReqVO.setPageSize(pageParam.getPageSize());
pageReqVO.setPageNo(pageParam.getPageNo());
pageReqVO.setEsShipper(YavConstants.ZERO);
return projectSalesOrderMapper.selectPage(pageReqVO);
}
}
} else {
if (businessTypeValue.equals(YavConstants.ONE_STR)) {
//入库-采购入库(收料通知单表)
ReceiptPageReqVO pageReqVO = new ReceiptPageReqVO();
pageReqVO.setPageNo(pageParam.getPageNo());
pageReqVO.setPageSize(pageParam.getPageSize());
pageReqVO.setRWareStatus(YavConstants.TWO_STR);
return receiptMapper.selectPage(pageReqVO);
} else if (businessTypeValue.equals(YavConstants.TWO_STR)) {
//入库-生产入库(来源生产订单,目前还没有)
return null;
}
}
return null;
}
@Override
public void updateProcessInfo(Long id, String processInstanceId, String status) {
validateIoManagementMainExists(id);
IoManagementMainDO updateObj = new IoManagementMainDO();
updateObj.setId(id);
updateObj.setProcessInstanceId(processInstanceId);
updateObj.setStatus(status);
ioManagementMainMapper.updateById(updateObj);
}
@Override
public void updateProcessStatus(Long id, String status) {
validateIoManagementMainExists(id);
IoManagementMainDO updateObj = new IoManagementMainDO();
updateObj.setId(id);
updateObj.setStatus(status);
ioManagementMainMapper.updateById(updateObj);
}
}
package cn.iocoder.yudao.module.yavwarehouse.dal.mysql.iomanagementmain;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.yavwarehouse.dal.dataobject.iomanagementmain.IoManagementMainDO;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.yavwarehouse.controller.admin.iomanagementmain.vo.*;
/**
* 出入库主 Mapper
*
* @author YAVII
*/
@Mapper
public interface IoManagementMainMapper extends BaseMapperX<IoManagementMainDO> {
default PageResult<IoManagementMainDO> selectPage(IoManagementMainPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<IoManagementMainDO>()
.eqIfPresent(IoManagementMainDO::getIoBillNo, reqVO.getIoBillNo())
.eqIfPresent(IoManagementMainDO::getIoBillType, reqVO.getIoBillType())
.eqIfPresent(IoManagementMainDO::getIoBusinessType, reqVO.getIoBusinessType())
.betweenIfPresent(IoManagementMainDO::getIoBillDate, reqVO.getIoBillDate())
.eqIfPresent(IoManagementMainDO::getIoWarehouseId, reqVO.getIoWarehouseId())
.eqIfPresent(IoManagementMainDO::getIoWarehouse, reqVO.getIoWarehouse())
.eqIfPresent(IoManagementMainDO::getIoWarehouseCode, reqVO.getIoWarehouseCode())
.eqIfPresent(IoManagementMainDO::getIoTotalCost, reqVO.getIoTotalCost())
.eqIfPresent(IoManagementMainDO::getIoReferenceTotalCost, reqVO.getIoReferenceTotalCost())
.eqIfPresent(IoManagementMainDO::getIoRemark, reqVO.getIoRemark())
.eqIfPresent(IoManagementMainDO::getReserve1, reqVO.getReserve1())
.eqIfPresent(IoManagementMainDO::getReserve2, reqVO.getReserve2())
.eqIfPresent(IoManagementMainDO::getReserve3, reqVO.getReserve3())
.eqIfPresent(IoManagementMainDO::getReserve4, reqVO.getReserve4())
.eqIfPresent(IoManagementMainDO::getReserve5, reqVO.getReserve5())
.eqIfPresent(IoManagementMainDO::getState, reqVO.getState())
.eqIfPresent(IoManagementMainDO::getIoRelateNum, reqVO.getIoRelateNum())
.eqIfPresent(IoManagementMainDO::getIoOwnership, reqVO.getIoOwnership())
.eqIfPresent(IoManagementMainDO::getIoPurpose, reqVO.getIoPurpose())
.eqIfPresent(IoManagementMainDO::getStatus, reqVO.getStatus())
.eqIfPresent(IoManagementMainDO::getAuditState, reqVO.getAuditState())
.betweenIfPresent(IoManagementMainDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(IoManagementMainDO::getId));
}
}分页查询不显示
最新发布