From 56749b305b987fca1c9090e64636df591f3f0189 Mon Sep 17 00:00:00 2001 From: zxy Date: Fri, 22 May 2026 16:46:04 +0800 Subject: [PATCH] =?UTF-8?q?fix(biz):=20=E4=BF=AE=E5=A4=8D=E9=87=87?= =?UTF-8?q?=E8=B4=AD=E5=85=A5=E5=BA=93=E5=8D=95=E5=8A=9F=E8=83=BD=E7=9A=84?= =?UTF-8?q?=E5=A4=9A=E4=B8=AA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 + .../mybatis/core/mapper/BaseMapperX.java | 6 +- .../vo/PurReceiptDetailRespVO.java | 9 ++ .../rawstoragelog/RawStorageLogDO.java | 4 +- .../mysql/purreceipt/PurReceiptMapper.java | 24 +++- .../PurReceiptDetailMapper.java | 17 ++- .../purreceipt/PurReceiptServiceImpl.java | 136 +++++++++++++----- .../src/views/biz/purorder/PurOrderForm.vue | 4 +- .../views/biz/purreceipt/PurReceiptForm.vue | 68 +++++++-- .../src/views/biz/purreceipt/index.vue | 12 ++ 10 files changed, 225 insertions(+), 57 deletions(-) diff --git a/.gitignore b/.gitignore index 167f26a..f790f50 100644 --- a/.gitignore +++ b/.gitignore @@ -52,3 +52,5 @@ application-my.yaml /mes-ui-app/unpackage/ +### Trae ### +/.trae/ diff --git a/mes-framework/mes-spring-boot-starter-mybatis/src/main/java/com/ningxia/yunxi/chemmes/framework/mybatis/core/mapper/BaseMapperX.java b/mes-framework/mes-spring-boot-starter-mybatis/src/main/java/com/ningxia/yunxi/chemmes/framework/mybatis/core/mapper/BaseMapperX.java index cc89481..25ef315 100644 --- a/mes-framework/mes-spring-boot-starter-mybatis/src/main/java/com/ningxia/yunxi/chemmes/framework/mybatis/core/mapper/BaseMapperX.java +++ b/mes-framework/mes-spring-boot-starter-mybatis/src/main/java/com/ningxia/yunxi/chemmes/framework/mybatis/core/mapper/BaseMapperX.java @@ -1,18 +1,20 @@ package com.ningxia.yunxi.chemmes.framework.mybatis.core.mapper; import cn.hutool.core.collection.CollUtil; +import com.baomidou.mybatisplus.annotation.InterceptorIgnore; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; import com.baomidou.mybatisplus.core.toolkit.support.SFunction; import com.baomidou.mybatisplus.extension.toolkit.Db; +import com.github.yulichang.base.MPJBaseMapper; +import com.github.yulichang.interfaces.MPJBaseJoin; import com.ningxia.yunxi.chemmes.framework.common.pojo.PageParam; import com.ningxia.yunxi.chemmes.framework.common.pojo.PageResult; import com.ningxia.yunxi.chemmes.framework.mybatis.core.util.MyBatisUtils; -import com.github.yulichang.base.MPJBaseMapper; -import com.github.yulichang.interfaces.MPJBaseJoin; import org.apache.ibatis.annotations.Param; import java.math.BigDecimal; diff --git a/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/controller/admin/purreceiptdetail/vo/PurReceiptDetailRespVO.java b/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/controller/admin/purreceiptdetail/vo/PurReceiptDetailRespVO.java index 9d0223b..fc81dc8 100644 --- a/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/controller/admin/purreceiptdetail/vo/PurReceiptDetailRespVO.java +++ b/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/controller/admin/purreceiptdetail/vo/PurReceiptDetailRespVO.java @@ -104,4 +104,13 @@ public class PurReceiptDetailRespVO { @ExcelProperty("已退料数量") private BigDecimal returnQty; + @Schema(description = "发货数量") + @ExcelProperty("发货数量") + private BigDecimal deliveryQty; + + @Schema(description = "采购数量") + @ExcelProperty("采购数量") + private BigDecimal purQty; + + } diff --git a/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/dal/dataobject/rawstoragelog/RawStorageLogDO.java b/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/dal/dataobject/rawstoragelog/RawStorageLogDO.java index 7e395ad..e6141a2 100644 --- a/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/dal/dataobject/rawstoragelog/RawStorageLogDO.java +++ b/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/dal/dataobject/rawstoragelog/RawStorageLogDO.java @@ -40,7 +40,7 @@ public class RawStorageLogDO extends BaseDO { /** * 状态:1为保存;2为提交;3为作废 */ - private Boolean status; + private String status; /** * 仓储id */ @@ -140,7 +140,7 @@ public class RawStorageLogDO extends BaseDO { /** * 操作人id */ - private Integer operatorId; + private Long operatorId; /** * 操作人 */ diff --git a/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/dal/mysql/purreceipt/PurReceiptMapper.java b/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/dal/mysql/purreceipt/PurReceiptMapper.java index 905890c..3890ffd 100644 --- a/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/dal/mysql/purreceipt/PurReceiptMapper.java +++ b/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/dal/mysql/purreceipt/PurReceiptMapper.java @@ -1,14 +1,15 @@ package com.ningxia.yunxi.chemmes.module.biz.dal.mysql.purreceipt; -import java.util.*; - +import com.baomidou.mybatisplus.annotation.InterceptorIgnore; import com.ningxia.yunxi.chemmes.framework.common.pojo.PageResult; -import com.ningxia.yunxi.chemmes.framework.mybatis.core.query.LambdaQueryWrapperX; import com.ningxia.yunxi.chemmes.framework.mybatis.core.mapper.BaseMapperX; +import com.ningxia.yunxi.chemmes.framework.mybatis.core.query.LambdaQueryWrapperX; +import com.ningxia.yunxi.chemmes.module.biz.controller.admin.purreceipt.vo.PurReceiptPageReqVO; import com.ningxia.yunxi.chemmes.module.biz.dal.dataobject.purreceipt.PurReceiptDO; +import org.apache.ibatis.annotations.Delete; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; -import com.ningxia.yunxi.chemmes.module.biz.controller.admin.purreceipt.vo.*; /** * 采购入库单主 Mapper @@ -20,12 +21,11 @@ public interface PurReceiptMapper extends BaseMapperX { default PageResult selectPage(PurReceiptPageReqVO reqVO) { return selectPage(reqVO, new LambdaQueryWrapperX() - .eqIfPresent(PurReceiptDO::getPurReceiptNo, reqVO.getPurReceiptNo()) + .likeIfPresent(PurReceiptDO::getPurReceiptNo, reqVO.getPurReceiptNo()) .betweenIfPresent(PurReceiptDO::getReceiptDate, reqVO.getReceiptDate()) .eqIfPresent(PurReceiptDO::getSupplierId, reqVO.getSupplierId()) .likeIfPresent(PurReceiptDO::getSupplierName, reqVO.getSupplierName()) .eqIfPresent(PurReceiptDO::getPurStatus, reqVO.getPurStatus()) - .eqIfPresent(PurReceiptDO::getRemark, reqVO.getRemark()) .eqIfPresent(PurReceiptDO::getPurOrdId, reqVO.getPurOrdId()) .eqIfPresent(PurReceiptDO::getPurOrdNo, reqVO.getPurOrdNo()) .eqIfPresent(PurReceiptDO::getBillType, reqVO.getBillType()) @@ -35,4 +35,14 @@ public interface PurReceiptMapper extends BaseMapperX { @Select("SELECT MAX(pur_receipt_no) FROM tsc_pur_receipt") String selectMaxPurReceiptNo(); -} \ No newline at end of file + /** + * 根据ID物理删除采购入库单 + * + * @param id 主键ID + * @return 删除的记录数 + */ + @Delete("DELETE FROM tsc_pur_receipt WHERE id = #{id}") + @InterceptorIgnore(tenantLine = "true") + int physicalDeleteById(@Param("id") Integer id); + +} diff --git a/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/dal/mysql/purreceiptdetail/PurReceiptDetailMapper.java b/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/dal/mysql/purreceiptdetail/PurReceiptDetailMapper.java index 0987e36..1466e93 100644 --- a/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/dal/mysql/purreceiptdetail/PurReceiptDetailMapper.java +++ b/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/dal/mysql/purreceiptdetail/PurReceiptDetailMapper.java @@ -1,11 +1,14 @@ package com.ningxia.yunxi.chemmes.module.biz.dal.mysql.purreceiptdetail; +import com.baomidou.mybatisplus.annotation.InterceptorIgnore; import com.ningxia.yunxi.chemmes.framework.common.pojo.PageResult; import com.ningxia.yunxi.chemmes.framework.mybatis.core.mapper.BaseMapperX; import com.ningxia.yunxi.chemmes.framework.mybatis.core.query.LambdaQueryWrapperX; import com.ningxia.yunxi.chemmes.module.biz.controller.admin.purreceiptdetail.vo.PurReceiptDetailPageReqVO; import com.ningxia.yunxi.chemmes.module.biz.dal.dataobject.purreceiptdetail.PurReceiptDetailDO; +import org.apache.ibatis.annotations.Delete; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; import java.util.List; @@ -48,9 +51,15 @@ public interface PurReceiptDetailMapper extends BaseMapperX .eq(PurReceiptDetailDO::getPurReceiptId, purReceiptId)); } - default void deleteByPurReceiptId(Integer purReceiptId) { - delete(new LambdaQueryWrapperX() - .eq(PurReceiptDetailDO::getPurReceiptId, purReceiptId)); - } + /** + * 根据采购入库单ID物理删除明细 + * 使用 @Delete 注解直接写 SQL, bypass 逻辑删除和多租户插件 + * + * @param purReceiptId 采购入库单ID + * @return 删除的记录数 + */ + @Delete("DELETE FROM tsc_pur_receipt_detail WHERE pur_receipt_id = #{purReceiptId}") + @InterceptorIgnore(tenantLine = "true") + int physicalDeleteByPurReceiptId(@Param("purReceiptId") Integer purReceiptId); } diff --git a/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/service/purreceipt/PurReceiptServiceImpl.java b/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/service/purreceipt/PurReceiptServiceImpl.java index adc6f95..f9537cb 100644 --- a/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/service/purreceipt/PurReceiptServiceImpl.java +++ b/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/service/purreceipt/PurReceiptServiceImpl.java @@ -7,9 +7,11 @@ import com.ningxia.yunxi.chemmes.module.biz.controller.admin.purreceipt.vo.PurRe import com.ningxia.yunxi.chemmes.module.biz.controller.admin.purreceipt.vo.PurReceiptSaveReqVO; import com.ningxia.yunxi.chemmes.module.biz.controller.admin.purreceiptdetail.vo.PurReceiptDetailRespVO; import com.ningxia.yunxi.chemmes.module.biz.controller.admin.purreceiptdetail.vo.PurReceiptDetailSaveReqVO; +import com.ningxia.yunxi.chemmes.module.biz.dal.dataobject.purorderitem.PurOrderItemDO; import com.ningxia.yunxi.chemmes.module.biz.dal.dataobject.purreceipt.PurReceiptDO; import com.ningxia.yunxi.chemmes.module.biz.dal.dataobject.purreceiptdetail.PurReceiptDetailDO; import com.ningxia.yunxi.chemmes.module.biz.dal.dataobject.rawstoragelog.RawStorageLogDO; +import com.ningxia.yunxi.chemmes.module.biz.dal.mysql.purorderitem.PurOrderItemMapper; import com.ningxia.yunxi.chemmes.module.biz.dal.mysql.purreceipt.PurReceiptMapper; import com.ningxia.yunxi.chemmes.module.biz.dal.mysql.purreceiptdetail.PurReceiptDetailMapper; import com.ningxia.yunxi.chemmes.module.biz.service.rawstoragelog.RawStorageLogService; @@ -48,6 +50,9 @@ public class PurReceiptServiceImpl implements PurReceiptService { @Resource private RawStorageLogService rawStorageLogService; + @Resource + private PurOrderItemMapper purOrderItemMapper; + @Override @Transactional(rollbackFor = Exception.class) @@ -65,23 +70,7 @@ public class PurReceiptServiceImpl implements PurReceiptService { purReceiptMapper.insert(purReceipt); // 插入子表 - if (createReqVO.getItems() != null && !createReqVO.getItems().isEmpty()) { - Integer purReceiptId = purReceipt.getId(); - for (PurReceiptDetailSaveReqVO item : createReqVO.getItems()) { - item.setPurReceiptId(purReceiptId); - PurReceiptDetailDO detail = BeanUtils.toBean(item, PurReceiptDetailDO.class); - detail.setTwmStorageDetailId(item.getTwmStorageDetailId()); - detail.setInventBillNo(item.getInventBillNo()); -// detail.setPurOrdDetailId(item.getPurOrdDetailId()); - detail.setOrdQty(item.getOrdQty()); - detail.setReceiptQty(item.getReceiptQty()); - detail.setId(null); - purReceiptDetailMapper.insert(detail); - if ("2".equals(createReqVO.getPurStatus())) { - saveRwaStorageLog(purReceipt, detail); - } - } - } + updatePurReceiptDetails(purReceipt.getId(), createReqVO.getItems(), purReceipt); // 返回 return purReceipt.getId(); @@ -94,23 +83,62 @@ public class PurReceiptServiceImpl implements PurReceiptService { validatePurReceiptExists(updateReqVO.getId()); // 更新主表 PurReceiptDO updateObj = BeanUtils.toBean(updateReqVO, PurReceiptDO.class); + Long userId = getLoginUserId(); + AdminUserDO adminUserDO = adminUserMapper.selectById(userId); + updateObj.setReceiptEmpName(adminUserDO.getNickname()); + updateObj.setReceiptEmpId(adminUserDO.getId()); purReceiptMapper.updateById(updateObj); - // 更新子表:先删除旧的,再插入新的 - Integer purReceiptId = updateReqVO.getId(); - purReceiptDetailMapper.deleteByPurReceiptId(purReceiptId); - if (updateReqVO.getItems() != null && !updateReqVO.getItems().isEmpty()) { - for (PurReceiptDetailSaveReqVO item : updateReqVO.getItems()) { + // 更新子表 + updatePurReceiptDetails(updateReqVO.getId(), updateReqVO.getItems(), updateObj); + } + + /** + * 更新采购入库单明细 + * 先删除所有旧明细,再插入新明细 + * + * @param purReceiptId 采购入库单ID + * @param items 明细列表 + * @param purReceipt 采购入库单主表对象 + */ + private void updatePurReceiptDetails(Integer purReceiptId, List items, PurReceiptDO purReceipt) { + // 物理删除旧明细 + purReceiptDetailMapper.physicalDeleteByPurReceiptId(purReceiptId); + + // 插入新明细 + if (items != null && !items.isEmpty()) { + for (PurReceiptDetailSaveReqVO item : items) { item.setPurReceiptId(purReceiptId); PurReceiptDetailDO detail = BeanUtils.toBean(item, PurReceiptDetailDO.class); - detail.setTwmStorageDetailId(item.getTwmStorageDetailId()); + + // 补全所有字段 +// detail.setTwmStorageDetailId(item.getId()); detail.setInventBillNo(item.getInventBillNo()); -// detail.setPurOrdDetailId(item.getPurOrdDetailId()); + detail.setPurOrdDetailId(item.getPurOrdDetailId()); detail.setOrdQty(item.getOrdQty()); detail.setReceiptQty(item.getReceiptQty()); + detail.setRemark(item.getRemark()); + detail.setLotNo(item.getLotNo()); + detail.setStoreAreaId(item.getStoreAreaId()); + detail.setStoreAreCd(item.getStoreAreCd()); + detail.setStoreAreaName(item.getStoreAreaName()); + detail.setReqDeliveryDate(item.getReqDeliveryDate()); + detail.setTotalPrice(item.getTotalPrice()); + detail.setMaterialId(item.getMaterialId()); + detail.setMaterialCode(item.getMaterialCode()); + detail.setMaterialName(item.getMaterialName()); + detail.setSpec(item.getSpec()); + detail.setUnit(item.getUnit()); + detail.setRemaimQty(item.getRemaimQty()); + detail.setReturnQty(item.getReturnQty()); + + // 新增明细(ID设为null) + detail.setId(null); purReceiptDetailMapper.insert(detail); - if ("2".equals(updateReqVO.getPurStatus())) { - saveRwaStorageLog(updateObj, detail); + + // 如果状态为已入库,生成入库日志 + if ("2".equals(purReceipt.getPurStatus())) { + saveRwaStorageLog(purReceipt, detail); } } } @@ -118,8 +146,44 @@ public class PurReceiptServiceImpl implements PurReceiptService { private void saveRwaStorageLog(PurReceiptDO purReceipt, PurReceiptDetailDO item) { RawStorageLogDO rawStorageLog = BeanUtils.toBean(item, RawStorageLogDO.class); + // 查询采购订单明细 + PurOrderItemDO purOrderItem = purOrderItemMapper.selectById(item.getPurOrdDetailId()); + rawStorageLog.setStockId(purReceipt.getId()); + rawStorageLog.setStatus("2"); + rawStorageLog.setStoreHouseId(purReceipt.getStoreHouseId()); + rawStorageLog.setStoreAreaId(item.getStoreAreaId()); + rawStorageLog.setStoreHouseCd(purReceipt.getStoreHouseCd()); + rawStorageLog.setStoreHouseName(purReceipt.getStoreHouseName()); + rawStorageLog.setStoreAreCd(item.getStoreAreCd()); + rawStorageLog.setStoreAreaName(item.getStoreAreaName()); + rawStorageLog.setOperatorType("1"); + rawStorageLog.setOperatorId(purReceipt.getReceiptEmpId()); + rawStorageLog.setOperatorName(purReceipt.getReceiptEmpName()); + + rawStorageLog.setMaterialId(item.getMaterialId()); + rawStorageLog.setMatCode(item.getMaterialCode()); + rawStorageLog.setMatName(item.getMaterialName()); + rawStorageLog.setRelarionId(purReceipt.getId()); rawStorageLog.setRelarionNo(purReceipt.getPurReceiptNo()); + rawStorageLog.setRelarionDetailId(item.getId()); + + // 补全所有字段set + rawStorageLog.setDescription(item.getRemark()); + rawStorageLog.setSpec(item.getSpec()); + rawStorageLog.setUnit(item.getUnit()); + rawStorageLog.setLotNo(item.getLotNo()); + rawStorageLog.setOperatorQty(item.getReceiptQty()); + rawStorageLog.setBusinessType("10"); + rawStorageLog.setStockItemId(item.getTwmStorageDetailId()); + rawStorageLog.setDpstNo(purReceipt.getPurReceiptNo()); +// rawStorageLog.setSupplierNo(purReceipt.getSupplierNo()); + rawStorageLog.setSupplierName(purReceipt.getSupplierName()); + rawStorageLog.setSupplierId(purReceipt.getSupplierId()); + rawStorageLog.setPurQty(purOrderItem.getPurQty()); + rawStorageLog.setBillDate(purReceipt.getReceiptDate()); + rawStorageLog.setStockItemId(item.getId()); + rawStorageLogService.saveRawStorageLog(rawStorageLog); } @@ -128,10 +192,10 @@ public class PurReceiptServiceImpl implements PurReceiptService { public void deletePurReceipt(Integer id) { // 校验存在 validatePurReceiptExists(id); - // 删除子表 - purReceiptDetailMapper.deleteByPurReceiptId(id); - // 删除主表 - purReceiptMapper.deleteById(id); + // 物理删除子表 + purReceiptDetailMapper.physicalDeleteByPurReceiptId(id); + // 物理删除主表 + purReceiptMapper.physicalDeleteById(id); } private void validatePurReceiptExists(Integer id) { @@ -155,9 +219,17 @@ public class PurReceiptServiceImpl implements PurReceiptService { List detailList = purReceiptDetailMapper.selectListByPurReceiptId(id); if (detailList != null && !detailList.isEmpty()) { List detailRespVOList = BeanUtils.toBean(detailList, PurReceiptDetailRespVO.class); - respVO.setItems(detailRespVOList); - } + for (PurReceiptDetailRespVO purReceiptDetailRespVO : detailRespVOList) { + PurOrderItemDO purOrderItem = purOrderItemMapper.selectById(purReceiptDetailRespVO.getPurOrdDetailId()); + if (purOrderItem != null) { + purReceiptDetailRespVO.setDeliveryQty(purOrderItem.getDeliveryQty()); + purReceiptDetailRespVO.setPurQty(purOrderItem.getPurQty()); + } + } + respVO.setItems(detailRespVOList); + + } return respVO; } diff --git a/mes-ui/mes-ui-admin-vue3/src/views/biz/purorder/PurOrderForm.vue b/mes-ui/mes-ui-admin-vue3/src/views/biz/purorder/PurOrderForm.vue index e49fd45..5919fc7 100644 --- a/mes-ui/mes-ui-admin-vue3/src/views/biz/purorder/PurOrderForm.vue +++ b/mes-ui/mes-ui-admin-vue3/src/views/biz/purorder/PurOrderForm.vue @@ -16,7 +16,7 @@ - + @@ -24,7 +24,7 @@ - + diff --git a/mes-ui/mes-ui-admin-vue3/src/views/biz/purreceipt/PurReceiptForm.vue b/mes-ui/mes-ui-admin-vue3/src/views/biz/purreceipt/PurReceiptForm.vue index 077856d..5974bdd 100644 --- a/mes-ui/mes-ui-admin-vue3/src/views/biz/purreceipt/PurReceiptForm.vue +++ b/mes-ui/mes-ui-admin-vue3/src/views/biz/purreceipt/PurReceiptForm.vue @@ -18,12 +18,12 @@ v-model="formData.billType" placeholder="请选择" class="!w-full" - :disabled="formType === 'detail'" + :disabled="formType === 'detail' || formType === 'update'" > - + @@ -71,7 +71,7 @@ v-model="formData.supplierId" placeholder="请选择" class="!w-full" - :disabled="formType === 'detail'" + :disabled="formType === 'detail' || formType === 'update'" @change="handleSupplierChange" > 保存 { Object.assign(formData, data) // 加载明细数据 detailList.value = data.items || [] + + // 如果已有仓储ID,加载库区列表用于回显(保持已选择的库区) + if (formData.storeHouseId) { + await handleStoreHouseChange(formData.storeHouseId, true) + } } finally { formLoading.value = false } @@ -357,7 +363,7 @@ const openPurOrderDialog = () => { } /** 处理采购订单选择 */ -const handlePurOrderSelect = (selectedData: any[]) => { +const handlePurOrderSelect = async (selectedData: any[]) => { if (selectedData && selectedData.length > 0) { // 取第一个订单的主信息 const firstItem = selectedData[0] @@ -388,6 +394,11 @@ const handlePurOrderSelect = (selectedData: any[]) => { deliveryQty: Number(item.deliveryQty) || 0, } }) + + // 如果已有仓储ID,重新加载库区列表 + if (formData.storeHouseId) { + await handleStoreHouseChange(formData.storeHouseId) + } } } @@ -408,7 +419,7 @@ const loadOrderDetail = async (orderId: number) => { const items = await PurOrderApi.getPurOrderDetail(orderId) if (items && items.length > 0) { detailList.value = items.map(item => ({ - id: item.id, + id: undefined, materialCode: item.materialCode, materialName: item.materialName, spec: item.spec, @@ -423,6 +434,7 @@ const loadOrderDetail = async (orderId: number) => { materialId: item.materialId, totalPrice: item.totalPrice, deliveryQty: item.deliveryQty || 0, + purOrdDetailId: item.id, })) } } catch (error) { @@ -431,15 +443,33 @@ const loadOrderDetail = async (orderId: number) => { } /** 仓储变更 */ -const handleStoreHouseChange = async (val: number) => { +const handleStoreHouseChange = async (val: number, keepSelection: boolean = false) => { const storeHouse = storeHouseList.value.find(item => item.id === val) if (storeHouse) { formData.storeHouseName = storeHouse.storeHouseName + formData.storeHouseCd = storeHouse.storeHouseCd + // 加载库区列表 const areas = await StoreAreaApi.getStoreAreaSelect(val) storeAreaList.value = areas || [] + + // 如果不是编辑时加载(即用户主动切换仓储),清空之前选择的库区 + // 因为切换仓储后旧的库区可能不存在于新仓储中 + if (!keepSelection) { + detailList.value.forEach(item => { + item.storeAreaId = undefined + item.storeAreaName = undefined + }) + } } else { storeAreaList.value = [] + // 清空明细中的库区选择 + if (!keepSelection) { + detailList.value.forEach(item => { + item.storeAreaId = undefined + item.storeAreaName = undefined + }) + } } } @@ -475,6 +505,7 @@ const addDetailItem = () => { materialId: undefined, totalPrice: 0, deliveryQty: 0, + purOrdDetailId: undefined, }) } @@ -494,11 +525,31 @@ const handleSave = async () => { return } + // 校验每个明细项的必填字段 + for (let i = 0; i < detailList.value.length; i++) { + const item = detailList.value[i] + if (!item.receiptQty || Number(item.receiptQty) <= 0) { + message.warning(`第${i + 1}行物料的收货数量不能为空且必须大于0`) + return + } + if (!item.storeAreaId) { + message.warning(`第${i + 1}行物料的库区名称不能为空`) + return + } + } + formLoading.value = true + // 准备明细数据 + // 新增时:item.id 是采购订单明细ID,需要映射为 purOrdDetailId + // 编辑时:后端返回的 items 中应该已有 purOrdDetailId 字段,保持不变 const data = { ...formData, - items: detailList.value, + items: detailList.value.map(item => ({ + ...item, + // 如果已经有 purOrdDetailId 则使用它(编辑场景),否则使用 item.id(新增场景) + purOrdDetailId: item.purOrdDetailId || item.id + })), } if (formType.value === 'create') { @@ -553,6 +604,7 @@ const resetForm = () => { formData.purOrdNo = undefined formData.storeHouseId = undefined formData.storeHouseName = undefined + formData.storeHouseCd = undefined formData.billType = undefined detailList.value = [] diff --git a/mes-ui/mes-ui-admin-vue3/src/views/biz/purreceipt/index.vue b/mes-ui/mes-ui-admin-vue3/src/views/biz/purreceipt/index.vue index ed26711..faebe07 100644 --- a/mes-ui/mes-ui-admin-vue3/src/views/biz/purreceipt/index.vue +++ b/mes-ui/mes-ui-admin-vue3/src/views/biz/purreceipt/index.vue @@ -116,6 +116,7 @@ type="primary" @click="openForm('update', scope.row.id)" v-hasPermi="['biz:pur-receipt:update']" + v-if="scope.row.purStatus === '1' " > 编辑 @@ -124,6 +125,7 @@ type="danger" @click="handleDelete(scope.row.id)" v-hasPermi="['biz:pur-receipt:delete']" + v-if="scope.row.purStatus === '1' " > 删除 @@ -196,6 +198,7 @@ const detailLoading = ref(false) // 详情列表的加载中 const list = ref([]) // 列表的数据 const total = ref(0) // 列表的总页数 const detailList = ref([]) // 入库物料信息列表 +const mainInfo = ref({}) // 主信息(包含仓储名称、库区名称等) const queryParams = reactive({ pageNo: 1, @@ -230,11 +233,20 @@ const getDetailList = async (id: number) => { try { // 根据入库单ID查询物料详情 const data = await PurReceiptApi.getPurReceipt(id) + // 保存主信息(仓储名称等) + mainInfo.value = { + storeHouseName: data.storeHouseName + } // 后端返回的数据中,明细在items字段中 detailList.value = data?.items || data || [] + // 将主信息中的仓储名称和库区名称填充到每个明细项中 + detailList.value.forEach(item => { + item.storeHouseName = mainInfo.value.storeHouseName + }) } catch (error) { console.error('获取入库物料详情失败:', error) detailList.value = [] + mainInfo.value = {} } finally { detailLoading.value = false }