diff --git a/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/WmsItemSkuController.java b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/WmsItemSkuController.java new file mode 100644 index 0000000..5ece6f3 --- /dev/null +++ b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/WmsItemSkuController.java @@ -0,0 +1,89 @@ +package cn.iocoder.yudao.module.wms.controller.admin.md.item; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.MapUtils; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.wms.controller.admin.md.item.vo.sku.WmsItemSkuPageReqVO; +import cn.iocoder.yudao.module.wms.controller.admin.md.item.vo.sku.WmsItemSkuRespVO; +import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemBrandDO; +import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemCategoryDO; +import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemDO; +import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemSkuDO; +import cn.iocoder.yudao.module.wms.service.md.item.WmsItemBrandService; +import cn.iocoder.yudao.module.wms.service.md.item.WmsItemCategoryService; +import cn.iocoder.yudao.module.wms.service.md.item.WmsItemService; +import cn.iocoder.yudao.module.wms.service.md.item.WmsItemSkuService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; + +/** + * WMS 商品 SKU Controller。 + * + *

SKU 维度的查询入口:弹窗 / 选择器场景使用,按 SKU 一行展开,支持商品 / 品牌 / 分类多表联查筛选。 + * 复用商品权限 {@code wms:item:query},不单独建权限点(lite 也是商品/SKU 共用 {@code wms:item:list})。 + * + *

SKU 的新增 / 修改 / 删除仍随商品弹窗一并维护,不在本 Controller 暴露。 + */ +@Tag(name = "管理后台 - WMS 商品 SKU") +@RestController +@RequestMapping("/wms/item-sku") +@Validated +public class WmsItemSkuController { + + @Resource + private WmsItemSkuService itemSkuService; + @Resource + private WmsItemService itemService; + @Resource + private WmsItemCategoryService categoryService; + @Resource + private WmsItemBrandService brandService; + + @GetMapping("/page") + @Operation(summary = "获得商品 SKU 分页", description = "按 SKU 维度分页,支持商品 / 品牌 / 分类多表联查筛选") + @PreAuthorize("@ss.hasPermission('wms:item:query')") + public CommonResult> getItemSkuPage(@Valid WmsItemSkuPageReqVO pageReqVO) { + PageResult pageResult = itemSkuService.getItemSkuPage(pageReqVO); + return success(new PageResult<>(buildItemSkuRespVOList(pageResult.getList()), pageResult.getTotal())); + } + + // ==================== 拼接 VO ==================== + + private List buildItemSkuRespVOList(List list) { + if (CollUtil.isEmpty(list)) { + return Collections.emptyList(); + } + // 查询关联数据 + Map itemMap = itemService.getItemMap(convertSet(list, WmsItemSkuDO::getItemId)); + Map categoryMap = categoryService.getItemCategoryMap( + convertSet(itemMap.values(), WmsItemDO::getCategoryId)); + Map brandMap = brandService.getItemBrandMap( + convertSet(itemMap.values(), WmsItemDO::getBrandId)); + // 拼接 VO + return BeanUtils.toBean(list, WmsItemSkuRespVO.class, vo -> MapUtils.findAndThen(itemMap, vo.getItemId(), item -> { + vo.setItemCode(item.getCode()).setItemName(item.getName()).setUnit(item.getUnit()) + .setCategoryId(item.getCategoryId()).setBrandId(item.getBrandId()); + MapUtils.findAndThen(categoryMap, item.getCategoryId(), category -> + vo.setCategoryName(category.getName())); + MapUtils.findAndThen(brandMap, item.getBrandId(), brand -> + vo.setBrandName(brand.getName())); + })); + } + +} diff --git a/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/sku/WmsItemSkuPageReqVO.java b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/sku/WmsItemSkuPageReqVO.java new file mode 100644 index 0000000..c091ea8 --- /dev/null +++ b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/md/item/vo/sku/WmsItemSkuPageReqVO.java @@ -0,0 +1,36 @@ +package cn.iocoder.yudao.module.wms.controller.admin.md.item.vo.sku; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Schema(description = "管理后台 - WMS 商品 SKU 分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class WmsItemSkuPageReqVO extends PageParam { + + @Schema(description = "商品编号", example = "I00000001") + private String itemCode; + + @Schema(description = "商品名称", example = "华为 nova flip") + private String itemName; + + @Schema(description = "商品分类编号", example = "1") + private Long categoryId; + + @Schema(description = "商品品牌编号", example = "1") + private Long brandId; + + @Schema(description = "规格编号", example = "S00000001") + private String code; + + @Schema(description = "规格名称", example = "黑色") + private String name; + + @Schema(description = "条码", example = "12345678") + private String barCode; + +} diff --git a/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/mysql/md/item/WmsItemSkuMapper.java b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/mysql/md/item/WmsItemSkuMapper.java index eeae0e2..1a0d528 100644 --- a/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/mysql/md/item/WmsItemSkuMapper.java +++ b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/mysql/md/item/WmsItemSkuMapper.java @@ -1,8 +1,12 @@ package cn.iocoder.yudao.module.wms.dal.mysql.md.item; import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; +import cn.iocoder.yudao.module.wms.controller.admin.md.item.vo.sku.WmsItemSkuPageReqVO; +import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemDO; import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemSkuDO; import org.apache.ibatis.annotations.Mapper; @@ -18,6 +22,27 @@ import java.util.List; @Mapper public interface WmsItemSkuMapper extends BaseMapperX { + /** + * 按 SKU 维度分页查询,支持商品 / 品牌 / 分类多表联查筛选。 + * + * 使用 {@link MPJLambdaWrapperX} 替代 lite 的手写 XML JOIN(见 lite + * {@code ItemSkuMapper.selectByBo}),范式参照本模块 {@code WmsInventoryMapper.selectPage}。 + */ + default PageResult selectPage(WmsItemSkuPageReqVO reqVO) { + MPJLambdaWrapperX query = new MPJLambdaWrapperX() + .selectAll(WmsItemSkuDO.class) + .innerJoin(WmsItemDO.class, WmsItemDO::getId, WmsItemSkuDO::getItemId) + .likeIfPresent(WmsItemDO::getCode, reqVO.getItemCode()) + .likeIfPresent(WmsItemDO::getName, reqVO.getItemName()) + .eqIfPresent(WmsItemDO::getCategoryId, reqVO.getCategoryId()) + .eqIfPresent(WmsItemDO::getBrandId, reqVO.getBrandId()) + .likeIfPresent(WmsItemSkuDO::getCode, reqVO.getCode()) + .likeIfPresent(WmsItemSkuDO::getName, reqVO.getName()) + .likeIfPresent(WmsItemSkuDO::getBarCode, reqVO.getBarCode()) + .orderByDesc(WmsItemSkuDO::getId); + return selectJoinPage(reqVO, WmsItemSkuDO.class, query); + } + default List selectListByItemId(Long itemId) { return selectList(new LambdaQueryWrapperX() .eq(WmsItemSkuDO::getItemId, itemId) diff --git a/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/inventory/dto/WmsInventoryCheckReqDTO.java b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/inventory/dto/WmsInventoryCheckReqDTO.java new file mode 100644 index 0000000..f7a93e2 --- /dev/null +++ b/yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/inventory/dto/WmsInventoryCheckReqDTO.java @@ -0,0 +1,77 @@ +package cn.iocoder.yudao.module.wms.service.inventory.dto; + +import cn.iocoder.yudao.module.wms.enums.order.WmsOrderTypeEnum; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +/** + * WMS 库存盘点请求 DTO + * + * @author 芋道源码 + */ +@Data +public class WmsInventoryCheckReqDTO { + + /** + * 单据编号 + */ + private Long orderId; + /** + * 单据号 + */ + private String orderNo; + /** + * 单据类型 + * + * 枚举 {@link WmsOrderTypeEnum#getType()} + */ + private Integer orderType; + + /** + * 库存盘点明细 + */ + private List items; + + /** + * WMS 库存盘点明细 + */ + @Data + public static class Item { + + /** + * 库存编号 + */ + private Long inventoryId; + /** + * SKU 编号 + */ + private Long skuId; + /** + * 仓库编号 + */ + private Long warehouseId; + /** + * 账面数量 + */ + private BigDecimal quantity; + /** + * 实盘数量 + */ + private BigDecimal checkQuantity; + + // ========= 单价备注相关字段 ========= + + /** + * 单价 + */ + private BigDecimal price; + /** + * 备注 + */ + private String remark; + + } + +}