diff --git a/gear-oa/src/main/java/com/gear/oa/controller/GearStockController.java b/gear-oa/src/main/java/com/gear/oa/controller/GearStockController.java new file mode 100644 index 0000000..2408c46 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/controller/GearStockController.java @@ -0,0 +1,112 @@ +package com.gear.oa.controller; + +import com.gear.common.annotation.Log; +import com.gear.common.annotation.RepeatSubmit; +import com.gear.common.core.controller.BaseController; +import com.gear.common.core.domain.PageQuery; +import com.gear.common.core.domain.R; +import com.gear.common.core.page.TableDataInfo; +import com.gear.common.core.validate.AddGroup; +import com.gear.common.core.validate.EditGroup; +import com.gear.common.enums.BusinessType; +import com.gear.common.utils.poi.ExcelUtil; +import com.gear.oa.domain.bo.GearStockBo; +import com.gear.oa.domain.vo.GearStockVo; +import com.gear.oa.service.IGearStockService; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.Arrays; +import java.util.List; + +/** + * 库存:原材料/产品与库区/库位的存放关系 + * + * @author Joshi + * @date 2025-07-18 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/gear/stock") +public class GearStockController extends BaseController { + + private final IGearStockService iGearStockService; + + /** + * 查询库存:原材料/产品与库区/库位的存放关系列表 + */ + @GetMapping("/list") + public TableDataInfo list(GearStockBo bo, PageQuery pageQuery) { + return iGearStockService.queryPageList(bo, pageQuery); + } + + /** + * 导出库存:原材料/产品与库区/库位的存放关系列表 + */ + @Log(title = "库存:原材料/产品与库区/库位的存放关系", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(GearStockBo bo, HttpServletResponse response) { + List list = iGearStockService.queryList(bo); + ExcelUtil.exportExcel(list, "库存:原材料-产品与库区-库位的存放关系", GearStockVo.class, response); + } + + /** + * 获取库存:原材料/产品与库区/库位的存放关系详细信息 + * + * @param stockId 主键 + */ + @GetMapping("/{stockId}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long stockId) { + return R.ok(iGearStockService.queryById(stockId)); + } + + /** + * 新增库存:原材料/产品与库区/库位的存放关系 + */ + @Log(title = "库存:原材料/产品与库区/库位的存放关系", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody GearStockBo bo) { + return toAjax(iGearStockService.insertByBo(bo)); + } + + /** + * 修改库存:原材料/产品与库区/库位的存放关系 + */ + @Log(title = "库存:原材料/产品与库区/库位的存放关系", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody GearStockBo bo) { + return toAjax(iGearStockService.updateByBo(bo)); + } + + /** + * 删除库存:原材料/产品与库区/库位的存放关系 + * + * @param stockIds 主键串 + */ + @Log(title = "库存:原材料/产品与库区/库位的存放关系", businessType = BusinessType.DELETE) + @DeleteMapping("/{stockIds}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] stockIds) { + return toAjax(iGearStockService.deleteWithValidByIds(Arrays.asList(stockIds), true)); + } + + /** + * 测试递归查询功能 + */ + @GetMapping("/test/warehouse/{warehouseId}") + public R testWarehouseQuery(@PathVariable Long warehouseId) { + GearStockBo bo = new GearStockBo(); + bo.setWarehouseId(warehouseId); + List list = iGearStockService.queryList(bo); + return R.ok("查询到 " + list.size() + " 条库存记录,仓库ID: " + warehouseId); + } + +} diff --git a/gear-oa/src/main/java/com/gear/oa/controller/GearStockIoController.java b/gear-oa/src/main/java/com/gear/oa/controller/GearStockIoController.java new file mode 100644 index 0000000..2ffbac8 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/controller/GearStockIoController.java @@ -0,0 +1,182 @@ +package com.gear.oa.controller; + +import com.gear.common.annotation.Log; +import com.gear.common.annotation.RepeatSubmit; +import com.gear.common.core.controller.BaseController; +import com.gear.common.core.domain.PageQuery; +import com.gear.common.core.domain.R; +import com.gear.common.core.page.TableDataInfo; +import com.gear.common.core.validate.AddGroup; +import com.gear.common.core.validate.EditGroup; +import com.gear.common.enums.BusinessType; +import com.gear.common.utils.poi.ExcelUtil; +import com.gear.oa.domain.bo.GearStockIoBo; +import com.gear.oa.domain.bo.GearStockIoDetailBo; +import com.gear.oa.domain.bo.GearStockIoWithDetailBo; +import com.gear.oa.domain.vo.GearStockIoDetailVo; +import com.gear.oa.domain.vo.GearStockIoVo; +import com.gear.oa.service.IGearStockIoService; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.Arrays; +import java.util.List; + +/** + * 出入库单主表 + * + * @author Joshi + * @date 2025-07-18 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/gear/stockIo") +public class GearStockIoController extends BaseController { + + private final IGearStockIoService iGearStockIoService; + + /** + * 查询出入库单主列表 + */ + @GetMapping("/list") + public TableDataInfo list(GearStockIoBo bo, PageQuery pageQuery) { + return iGearStockIoService.queryPageList(bo, pageQuery); + } + + /** + * 导出出入库单主列表 + */ + @Log(title = "出入库单主", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(GearStockIoBo bo, HttpServletResponse response) { + List list = iGearStockIoService.queryList(bo); + ExcelUtil.exportExcel(list, "出入库单主", GearStockIoVo.class, response); + } + + /** + * 获取出入库单主详细信息 + * + * @param stockIoId 主键 + */ + @GetMapping("/{stockIoId}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long stockIoId) { + return R.ok(iGearStockIoService.queryById(stockIoId)); + } + + /** + * 新增出入库单主 + */ + @Log(title = "出入库单主", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody GearStockIoBo bo) { + return toAjax(iGearStockIoService.insertByBo(bo)); + } + + /** + * 批量新增主表和明细 + */ + @PostMapping("/withDetail") + public R addWithDetail(@RequestBody GearStockIoWithDetailBo bo) { + iGearStockIoService.addWithDetail(bo); + return R.ok(); + } + + /** + * 修改出入库单主 + */ + @Log(title = "出入库单主", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody GearStockIoBo bo) { + return toAjax(iGearStockIoService.updateByBo(bo)); + } + + /** + * 删除出入库单主 + * + * @param stockIoIds 主键串 + */ + @Log(title = "出入库单主", businessType = BusinessType.DELETE) + @DeleteMapping("/{stockIoIds}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] stockIoIds) { + return toAjax(iGearStockIoService.deleteWithValidByIds(Arrays.asList(stockIoIds), true)); + } + + /** + * 审核出入库/移库单 + */ + @Log(title = "出入库单主", businessType = BusinessType.UPDATE) + @PostMapping("/audit/{stockIoId}") + public R audit(@NotNull(message = "主键不能为空") @PathVariable Long stockIoId) { + return toAjax(iGearStockIoService.auditStockIo(stockIoId)); + } + + /** + * 撤销出入库/移库单 + */ + + @Log(title = "出入库单主", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PostMapping("/cancel/{stockIoId}") + public R cancel(@NotNull(message = "主键不能为空") @PathVariable Long stockIoId) { + return toAjax(iGearStockIoService.cancelStockIo(stockIoId)); + } + + /** + * 根据ioType和stockIoId联查明细 + */ + @GetMapping("/detailByTypeAndId") + public R> detailByTypeAndId(@RequestParam String ioType, @RequestParam Long stockIoId) { + return R.ok(iGearStockIoService.detailByTypeAndId(ioType, stockIoId)); + } + + /** + * 更新出入库单状态 + */ + @Log(title = "出入库单主", businessType = BusinessType.UPDATE) + @PostMapping("/updateStatus/{stockIoId}") + public R updateStatus(@NotNull(message = "主键不能为空") @PathVariable Long stockIoId, + @RequestParam Integer status) { + return toAjax(iGearStockIoService.updateStatus(stockIoId, status)); + } + +// /** +// * 扫码枪专用:根据明细ID直接入库,无需审核整单 +// */ +// @PostMapping("/scanInStock") +// public R scanInStock(@RequestBody GearStockIoDetailBo bo) { +// try { +// boolean result = iGearStockIoService.scanInStockByBo(bo); +// return toAjax(result); +// } catch (Exception e) { +// return R.fail(e.getMessage()); +// } +// } +// @PostMapping("/scanOutStock") +// public R scanOutStock(@RequestBody GearStockIoDetailBo bo) { +// try { +// boolean result = iGearStockIoService.scanOutStockByBo(bo); +// return toAjax(result); +// } catch (Exception e) { +// return R.fail(e.getMessage()); +// } +// } +// //退库操作 +// @PostMapping("/returnStock") +// public R scanReturnStock(@RequestBody GearStockIoBo bo) { +// try { +// boolean result = iGearStockIoService.scanReturnStockByBo(bo); +// return toAjax(result); +// } catch (Exception e) { +// return R.fail(e.getMessage()); +// } +// } +} diff --git a/gear-oa/src/main/java/com/gear/oa/controller/GearStockIoDetailController.java b/gear-oa/src/main/java/com/gear/oa/controller/GearStockIoDetailController.java new file mode 100644 index 0000000..140ffd7 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/controller/GearStockIoDetailController.java @@ -0,0 +1,105 @@ +package com.gear.oa.controller; + +import com.gear.common.annotation.Log; +import com.gear.common.annotation.RepeatSubmit; +import com.gear.common.core.controller.BaseController; +import com.gear.common.core.domain.PageQuery; +import com.gear.common.core.domain.R; +import com.gear.common.core.page.TableDataInfo; +import com.gear.common.core.validate.AddGroup; +import com.gear.common.core.validate.EditGroup; +import com.gear.common.enums.BusinessType; +import com.gear.common.utils.poi.ExcelUtil; +import com.gear.oa.domain.bo.GearStockIoDetailBo; +import com.gear.oa.domain.vo.GearStockIoDetailVo; +import com.gear.oa.service.IGearStockIoDetailService; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.Arrays; +import java.util.List; + +/** + * 出入库单明细 + * + * @author Joshi + * @date 2025-07-18 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/gear/stockIoDetail") +public class GearStockIoDetailController extends BaseController { + + private final IGearStockIoDetailService iGearStockIoDetailService; + + /** + * 查询出入库单明细列表 + */ + @GetMapping("/list") + public TableDataInfo list(GearStockIoDetailBo bo, PageQuery pageQuery) { + return iGearStockIoDetailService.queryPageList(bo, pageQuery); + } + + /** + * 导出出入库单明细列表 + */ + @Log(title = "出入库单明细", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(GearStockIoDetailBo bo, HttpServletResponse response) { + List list = iGearStockIoDetailService.queryList(bo); + ExcelUtil.exportExcel(list, "出入库单明细", GearStockIoDetailVo.class, response); + } + + /** + * 获取出入库单明细详细信息 + * + * @param detailId 主键 + */ + @GetMapping("/{detailId}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long detailId) { + return R.ok(iGearStockIoDetailService.queryById(detailId)); + } + + /** + * 新增出入库单明细 + */ + @Log(title = "出入库单明细", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody GearStockIoDetailBo bo) { + return toAjax(iGearStockIoDetailService.insertByBo(bo)); + } + + /** + * 修改出入库单明细 + */ + @Log(title = "出入库单明细", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody GearStockIoDetailBo bo) { + return toAjax(iGearStockIoDetailService.updateByBo(bo)); + } + + /** + * 删除出入库单明细 + * + * @param detailIds 主键串 + */ + @Log(title = "出入库单明细", businessType = BusinessType.DELETE) + @DeleteMapping("/{detailIds}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] detailIds) { + return toAjax(iGearStockIoDetailService.deleteWithValidByIds(Arrays.asList(detailIds), true)); + } + //根据批次号联查出入库单主表以及明细表信息 + @PostMapping("/batch") + public R> batchQuery(@RequestBody GearStockIoDetailBo bo) { + return R.ok(iGearStockIoDetailService.batchQuery(bo)); + } +} diff --git a/gear-oa/src/main/java/com/gear/oa/controller/GearStockLogController.java b/gear-oa/src/main/java/com/gear/oa/controller/GearStockLogController.java new file mode 100644 index 0000000..d1e0a8b --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/controller/GearStockLogController.java @@ -0,0 +1,100 @@ +package com.gear.oa.controller; + +import com.gear.common.annotation.Log; +import com.gear.common.annotation.RepeatSubmit; +import com.gear.common.core.controller.BaseController; +import com.gear.common.core.domain.PageQuery; +import com.gear.common.core.domain.R; +import com.gear.common.core.page.TableDataInfo; +import com.gear.common.core.validate.AddGroup; +import com.gear.common.core.validate.EditGroup; +import com.gear.common.enums.BusinessType; +import com.gear.common.utils.poi.ExcelUtil; +import com.gear.oa.domain.bo.GearStockLogBo; +import com.gear.oa.domain.vo.GearStockLogVo; +import com.gear.oa.service.IGearStockLogService; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.Arrays; +import java.util.List; + +/** + * 库存流水 + * + * @author JR + * @date 2025-08-11 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/gear/stockLog") +public class GearStockLogController extends BaseController { + + private final IGearStockLogService iGearStockLogService; + + /** + * 查询库存流水列表 + */ + @GetMapping("/list") + public TableDataInfo list(GearStockLogBo bo, PageQuery pageQuery) { + return iGearStockLogService.queryPageList(bo, pageQuery); + } + + /** + * 导出库存流水列表 + */ + @Log(title = "库存流水", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(GearStockLogBo bo, HttpServletResponse response) { + List list = iGearStockLogService.queryList(bo); + ExcelUtil.exportExcel(list, "库存流水", GearStockLogVo.class, response); + } + + /** + * 获取库存流水详细信息 + * + * @param id 主键 + */ + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(iGearStockLogService.queryById(id)); + } + + /** + * 新增库存流水 + */ + @Log(title = "库存流水", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody GearStockLogBo bo) { + return toAjax(iGearStockLogService.insertByBo(bo)); + } + + /** + * 修改库存流水 + */ + @Log(title = "库存流水", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody GearStockLogBo bo) { + return toAjax(iGearStockLogService.updateByBo(bo)); + } + + /** + * 删除库存流水 + * + * @param ids 主键串 + */ + @Log(title = "库存流水", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { + return toAjax(iGearStockLogService.deleteWithValidByIds(Arrays.asList(ids), true)); + } +} diff --git a/gear-oa/src/main/java/com/gear/oa/controller/GearWarehouseController.java b/gear-oa/src/main/java/com/gear/oa/controller/GearWarehouseController.java new file mode 100644 index 0000000..2479c88 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/controller/GearWarehouseController.java @@ -0,0 +1,99 @@ +package com.gear.oa.controller; + +import com.gear.common.annotation.Log; +import com.gear.common.annotation.RepeatSubmit; +import com.gear.common.core.controller.BaseController; +import com.gear.common.core.domain.R; +import com.gear.common.core.validate.AddGroup; +import com.gear.common.core.validate.EditGroup; +import com.gear.common.enums.BusinessType; +import com.gear.common.utils.poi.ExcelUtil; +import com.gear.oa.domain.bo.GearWarehouseBo; +import com.gear.oa.domain.vo.GearWarehouseVo; +import com.gear.oa.service.IGearWarehouseService; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.Arrays; +import java.util.List; + +/** + * 仓库/库区/库位自关联 + * + * @author JR + * @date 2025-07-18 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/gear/warehouse") +public class GearWarehouseController extends BaseController { + + private final IGearWarehouseService iGearWarehouseService; + + /** + * 查询仓库/库区/库位自关联列表 + */ + @GetMapping("/list") + public R> list(GearWarehouseBo bo) { + List list = iGearWarehouseService.queryList(bo); + return R.ok(list); + } + + /** + * 导出仓库/库区/库位自关联列表 + */ + @Log(title = "仓库/库区/库位自关联", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(GearWarehouseBo bo, HttpServletResponse response) { + List list = iGearWarehouseService.queryList(bo); + ExcelUtil.exportExcel(list, "仓库/库区/库位自关联", GearWarehouseVo.class, response); + } + + /** + * 获取仓库/库区/库位自关联详细信息 + * + * @param warehouseId 主键 + */ + @GetMapping("/{warehouseId}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long warehouseId) { + return R.ok(iGearWarehouseService.queryById(warehouseId)); + } + + /** + * 新增仓库/库区/库位自关联 + */ + @Log(title = "仓库/库区/库位自关联", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody GearWarehouseBo bo) { + return toAjax(iGearWarehouseService.insertByBo(bo)); + } + + /** + * 修改仓库/库区/库位自关联 + */ + @Log(title = "仓库/库区/库位自关联", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody GearWarehouseBo bo) { + return toAjax(iGearWarehouseService.updateByBo(bo)); + } + + /** + * 删除仓库/库区/库位自关联 + * + * @param warehouseIds 主键串 + */ + @Log(title = "仓库/库区/库位自关联", businessType = BusinessType.DELETE) + @DeleteMapping("/{warehouseIds}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] warehouseIds) { + return toAjax(iGearWarehouseService.deleteWithValidByIds(Arrays.asList(warehouseIds), true)); + } +} diff --git a/gear-oa/src/main/java/com/gear/oa/domain/GearStock.java b/gear-oa/src/main/java/com/gear/oa/domain/GearStock.java new file mode 100644 index 0000000..3334735 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/GearStock.java @@ -0,0 +1,64 @@ +package com.gear.oa.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.TableName; +import com.gear.common.core.domain.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.math.BigDecimal; + +/** + * 库存:原材料/产品与库区/库位的存放关系对象 gear_stock + * + * @author Joshi + * @date 2025-07-18 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("gear_stock") +public class GearStock extends BaseEntity { + + private static final long serialVersionUID=1L; + + /** + * 主键ID + */ + @TableId(value = "stock_id") + private Long stockId; + /** + * 仓库/库区/库位ID + */ + private Long warehouseId; + /** + * 物品类型(raw_material/product) + */ + private String itemType; + /** + * 物品ID(指向原材料或产品主键) + */ + private Long itemId; + /** + * 库存数量 + */ + private BigDecimal quantity; + /** + * 单位 + */ + private String unit; + /** + * 批次号(可选) + */ + private String batchNo; + /** + * 备注 + */ + private String remark; + /** + * 删除标志(0=正常,1=已删除) + */ + @TableLogic + private Integer delFlag; + +} diff --git a/gear-oa/src/main/java/com/gear/oa/domain/GearStockIo.java b/gear-oa/src/main/java/com/gear/oa/domain/GearStockIo.java new file mode 100644 index 0000000..3a497bd --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/GearStockIo.java @@ -0,0 +1,57 @@ +package com.gear.oa.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.TableName; +import com.gear.common.core.domain.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + + +/** + * 出入库单主对象 gear_stock_io + * + * @author Joshi + * @date 2025-07-18 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("gear_stock_io") +public class GearStockIo extends BaseEntity { + + private static final long serialVersionUID=1L; + + /** + * 出入库单ID + */ + @TableId(value = "stock_io_id") + private Long stockIoId; + /** + * 出入库单号 + */ + private String stockIoCode; + /** + * 类型(in=入库,out=出库) + */ + private String ioType; + /** + * 业务类型(采购、销售、退货、调拨等) + */ + private String bizType; + /** + * 单据状态(0=草稿,1=已提交,2=已审核,3=已完成) + */ + private Integer status; + /** + * 备注 + */ + private String remark; + // + private Long parentId; + /** + * 删除标志(0=正常,1=已删除) + */ + @TableLogic + private Integer delFlag; + +} diff --git a/gear-oa/src/main/java/com/gear/oa/domain/GearStockIoDetail.java b/gear-oa/src/main/java/com/gear/oa/domain/GearStockIoDetail.java new file mode 100644 index 0000000..1ebd9e7 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/GearStockIoDetail.java @@ -0,0 +1,76 @@ +package com.gear.oa.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.TableName; +import com.gear.common.core.domain.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.math.BigDecimal; + +/** + * 出入库单明细对象 gear_stock_io_detail + * + * @author Joshi + * @date 2025-07-18 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("gear_stock_io_detail") +public class GearStockIoDetail extends BaseEntity { + + private static final long serialVersionUID=1L; + + /** + * 明细ID + */ + @TableId(value = "detail_id") + private Long detailId; + /** + * 出入库单ID + */ + private Long stockIoId; + /** + * 库区/库位ID + */ + private Long warehouseId; + /** + * 物品类型(raw_material/product) + */ + private String itemType; + /** + * 物品ID + */ + private Long itemId; + /** + * 数量 + */ + private BigDecimal quantity; + /** + * 单位 + */ + private String unit; + /** + * 批次号 + */ + private String batchNo; + /** + * 备注 + */ + private String remark; + /** + * 删除标志(0=正常,1=已删除) + */ + @TableLogic + private Integer delFlag; + /** + * 源库位ID(移库时使用) + */ + private Long fromWarehouseId; + /** + * 记录类型,0:详情,1:扫码枪记录 + */ + private Integer recordType; + +} diff --git a/gear-oa/src/main/java/com/gear/oa/domain/GearStockLog.java b/gear-oa/src/main/java/com/gear/oa/domain/GearStockLog.java new file mode 100644 index 0000000..e665b10 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/GearStockLog.java @@ -0,0 +1,72 @@ +package com.gear.oa.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.TableName; +import com.gear.common.core.domain.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 库存流水对象 gear_stock_log + * + * @author JR + * @date 2025-08-11 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("gear_stock_log") +public class GearStockLog extends BaseEntity { + + private static final long serialVersionUID=1L; + + /** + * 主键ID + */ + @TableId(value = "id") + private Long id; + /** + * 仓库/库区/库位ID + */ + private Long warehouseId; + /** + * 物品ID(指向原材料或产品主键) + */ + private Long itemId; + /** + * 物品类型(raw_material/product) + */ + private String itemType; + /** + * 变动数量(正=入库,负=出库) + */ + private BigDecimal changeQty; + /** + * 变动后的库存数量 + */ + private BigDecimal afterQty; + /** + * 变动类型(入库/出库等) + */ + private String changeType; + /** + * 实际库存变动时间 + */ + private Date changeTime; + /** + * 备注 + */ + private String remark; + /** + * 删除标志(0=正常,1=删除) + */ + @TableLogic + private Long delFlag; + + //批次号 + private String batchNo; + +} diff --git a/gear-oa/src/main/java/com/gear/oa/domain/GearWarehouse.java b/gear-oa/src/main/java/com/gear/oa/domain/GearWarehouse.java new file mode 100644 index 0000000..81244f5 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/GearWarehouse.java @@ -0,0 +1,58 @@ +package com.gear.oa.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.TableName; +import com.gear.common.core.domain.TreeEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 仓库/库区/库位自关联对象 gear_warehouse + * + * @author JR + * @date 2025-07-18 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("gear_warehouse") +public class GearWarehouse extends TreeEntity { + + private static final long serialVersionUID=1L; + + /** + * 主键ID + */ + @TableId(value = "warehouse_id") + private Long warehouseId; + /** + * 仓库/库区编码 + */ + private String warehouseCode; + /** + * 仓库/库区名称 + */ + private String warehouseName; + /** + * 类型:0=仓库,1=库区,2=库位,… + */ + private Long warehouseType; + /** + * 同级排序号 + */ + private Long sortNo; + /** + * 是否启用(0=否,1=是) + */ + private Integer isEnabled; + /** + * 删除标志(0=正常,1=已删除) + */ + @TableLogic + private Integer delFlag; + /** + * 备注 + */ + private String remark; + +} diff --git a/gear-oa/src/main/java/com/gear/oa/domain/bo/GearStockBo.java b/gear-oa/src/main/java/com/gear/oa/domain/bo/GearStockBo.java new file mode 100644 index 0000000..d39d41e --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/bo/GearStockBo.java @@ -0,0 +1,71 @@ +package com.gear.oa.domain.bo; + +import com.gear.common.core.domain.BaseEntity; +import com.gear.common.core.validate.AddGroup; +import com.gear.common.core.validate.EditGroup; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.math.BigDecimal; + +/** + * 库存:原材料/产品与库区/库位的存放关系业务对象 gear_stock + * + * @author Joshi + * @date 2025-07-18 + */ + +@Data +@EqualsAndHashCode(callSuper = true) +public class GearStockBo extends BaseEntity { + + /** + * 主键ID + */ + private Long stockId; + + /** + * 仓库/库区/库位ID + */ + @NotNull(message = "仓库/库区/库位ID不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long warehouseId; + + /** + * 物品类型(raw_material/product) + */ + @NotBlank(message = "物品类型(raw_material/product)不能为空", groups = { AddGroup.class, EditGroup.class }) + private String itemType; + + /** + * 物品ID(指向原材料或产品主键) + */ + @NotNull(message = "物品ID(指向原材料或产品主键)不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long itemId; + + /** + * 库存数量 + */ + @NotNull(message = "库存数量不能为空", groups = { AddGroup.class, EditGroup.class }) + private BigDecimal quantity; + + /** + * 单位 + */ + @NotBlank(message = "单位不能为空", groups = { AddGroup.class, EditGroup.class }) + private String unit; + + /** + * 批次号(可选) + */ + @NotBlank(message = "批次号(可选)不能为空", groups = { AddGroup.class, EditGroup.class }) + private String batchNo; + + /** + * 备注 + */ + private String remark; + + +} diff --git a/gear-oa/src/main/java/com/gear/oa/domain/bo/GearStockIoBo.java b/gear-oa/src/main/java/com/gear/oa/domain/bo/GearStockIoBo.java new file mode 100644 index 0000000..fb9885b --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/bo/GearStockIoBo.java @@ -0,0 +1,63 @@ +package com.gear.oa.domain.bo; + +import com.gear.common.core.domain.BaseEntity; +import com.gear.common.core.validate.AddGroup; +import com.gear.common.core.validate.EditGroup; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + + +/** + * 出入库单主业务对象 gear_stock_io + * + * @author Joshi + * @date 2025-07-18 + */ + +@Data +@EqualsAndHashCode(callSuper = true) +public class GearStockIoBo extends BaseEntity { + + /** + * 出入库单ID + */ + private Long stockIoId; + + /** + * 出入库单号 + */ + @NotBlank(message = "出入库单号不能为空", groups = { AddGroup.class, EditGroup.class }) + private String stockIoCode; + + /** + * 类型(in=入库,out=出库) + */ + @NotBlank(message = "类型(in=入库,out=出库)不能为空", groups = { AddGroup.class, EditGroup.class }) + private String ioType; + + /** + * 业务类型(采购、销售、退货、调拨等) + */ + @NotBlank(message = "业务类型(采购、销售、退货、调拨等)不能为空", groups = { AddGroup.class, EditGroup.class }) + private String bizType; + + /** + * 单据状态(0=草稿,1=已提交,2=已审核,3=已完成) + */ + @NotNull(message = "单据状态(0=草稿,1=已提交,2=已审核,3=已完成)不能为空", groups = { AddGroup.class, EditGroup.class }) + private Integer status; + + /** + * 备注 + */ + private String remark; + + /** + * 父级ID(用于退库时关联原出库单) + */ + private Long parentId; + +} diff --git a/gear-oa/src/main/java/com/gear/oa/domain/bo/GearStockIoDetailBo.java b/gear-oa/src/main/java/com/gear/oa/domain/bo/GearStockIoDetailBo.java new file mode 100644 index 0000000..1228a06 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/bo/GearStockIoDetailBo.java @@ -0,0 +1,86 @@ +package com.gear.oa.domain.bo; + +import com.gear.common.core.domain.BaseEntity; +import com.gear.common.core.validate.AddGroup; +import com.gear.common.core.validate.EditGroup; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.math.BigDecimal; + +/** + * 出入库单明细业务对象 gear_stock_io_detail + * + * @author Joshi + * @date 2025-07-18 + */ + +@Data +@EqualsAndHashCode(callSuper = true) +public class GearStockIoDetailBo extends BaseEntity { + + /** + * 明细ID + */ + private Long detailId; + + /** + * 出入库单ID + */ + @NotNull(message = "出入库单ID不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long stockIoId; + + /** + * 库区/库位ID + */ + @NotNull(message = "库区/库位ID不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long warehouseId; + + /** + * 物品类型(raw_material/product) + */ + @NotBlank(message = "物品类型(raw_material/product)不能为空", groups = { AddGroup.class, EditGroup.class }) + private String itemType; + + /** + * 物品ID + */ + @NotNull(message = "物品ID不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long itemId; + + /** + * 数量 + */ + @NotNull(message = "数量不能为空", groups = { AddGroup.class, EditGroup.class }) + private BigDecimal quantity; + + /** + * 单位 + */ + private String unit; + + /** + * 批次号 + */ + @NotBlank(message = "批次号不能为空", groups = { AddGroup.class, EditGroup.class }) + private String batchNo; + + /** + * 备注 + */ + private String remark; + + /** + * 源库位ID(移库时使用) + */ + private Long fromWarehouseId; + + /** + * 记录类型,0:详情,1:扫码枪记录 + */ + private Integer recordType; + + +} diff --git a/gear-oa/src/main/java/com/gear/oa/domain/bo/GearStockIoWithDetailBo.java b/gear-oa/src/main/java/com/gear/oa/domain/bo/GearStockIoWithDetailBo.java new file mode 100644 index 0000000..4d8c9c0 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/bo/GearStockIoWithDetailBo.java @@ -0,0 +1,56 @@ +package com.gear.oa.domain.bo; + +import com.gear.common.core.validate.AddGroup; +import com.gear.common.core.validate.EditGroup; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 出入库单主+明细批量插入业务对象 + */ +@Data +public class GearStockIoWithDetailBo { + // 主表字段 + /** + * 出入库单ID + */ + private Long stockIoId; + + /** + * 出入库单号 + */ + @NotBlank(message = "出入库单号不能为空", groups = { AddGroup.class, EditGroup.class }) + private String stockIoCode; + + /** + * 类型(in=入库,out=出库) + */ + @NotBlank(message = "类型(in=入库,out=出库)不能为空", groups = { AddGroup.class, EditGroup.class }) + private String ioType; + + /** + * 业务类型(采购、销售、退货、调拨等) + */ + @NotBlank(message = "业务类型(采购、销售、退货、调拨等)不能为空", groups = { AddGroup.class, EditGroup.class }) + private String bizType; + + /** + * 单据状态(0=草稿,1=已提交,2=已审核,3=已完成) + */ + @NotNull(message = "单据状态(0=草稿,1=已提交,2=已审核,3=已完成)不能为空", groups = { AddGroup.class, EditGroup.class }) + private Integer status; + + /** + * 备注 + */ + private String remark; + // ...如有其他主表字段可补充 + + // 明细列表 + private List details; + + private Long parentId; +} diff --git a/gear-oa/src/main/java/com/gear/oa/domain/bo/GearStockLogBo.java b/gear-oa/src/main/java/com/gear/oa/domain/bo/GearStockLogBo.java new file mode 100644 index 0000000..2f0a2e2 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/bo/GearStockLogBo.java @@ -0,0 +1,85 @@ +package com.gear.oa.domain.bo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.gear.common.core.domain.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.springframework.format.annotation.DateTimeFormat; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 库存流水业务对象 gear_stock_log + * + * @author JR + * @date 2025-08-11 + */ + +@Data +@EqualsAndHashCode(callSuper = true) +public class GearStockLogBo extends BaseEntity { + + /** + * 主键ID + */ + private Long id; + + /** + * 仓库/库区/库位ID + */ + private Long warehouseId; + + /** + * 物品ID(指向原材料或产品主键) + */ + private Long itemId; + + /** + * 物品类型(raw_material/product) + */ + private String itemType; + + /** + * 变动数量(正=入库,负=出库) + */ + private BigDecimal changeQty; + + /** + * 变动后的库存数量 + */ + private BigDecimal afterQty; + + /** + * 变动类型(入库/出库等) + */ + private String changeType; + + /** + * 实际库存变动时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date changeTime; + + /** + * 备注 + */ + private String remark; + + /** + * 开始时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date startTime; + + /** + * 结束时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date endTime; + + //批次号 + private String batchNo; +} diff --git a/gear-oa/src/main/java/com/gear/oa/domain/bo/GearWarehouseBo.java b/gear-oa/src/main/java/com/gear/oa/domain/bo/GearWarehouseBo.java new file mode 100644 index 0000000..9ceccff --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/bo/GearWarehouseBo.java @@ -0,0 +1,62 @@ +package com.gear.oa.domain.bo; + +import com.gear.common.core.domain.TreeEntity; +import com.gear.common.core.validate.AddGroup; +import com.gear.common.core.validate.EditGroup; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 仓库/库区/库位自关联业务对象 gear_warehouse + * + * @author JR + * @date 2025-07-18 + */ + +@Data +@EqualsAndHashCode(callSuper = true) +public class GearWarehouseBo extends TreeEntity { + + /** + * 主键ID + */ + private Long warehouseId; + + /** + * 仓库/库区编码 + */ + @NotBlank(message = "仓库/库区编码不能为空", groups = { AddGroup.class, EditGroup.class }) + private String warehouseCode; + + /** + * 仓库/库区名称 + */ + @NotBlank(message = "仓库/库区名称不能为空", groups = { AddGroup.class, EditGroup.class }) + private String warehouseName; + + /** + * 类型:0=仓库,1=库区,2=库位,… + */ + @NotNull(message = "类型:0=仓库,1=库区,2=库位,…不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long warehouseType; + + /** + * 同级排序号 + */ + private Long sortNo; + + /** + * 是否启用(0=否,1=是) + */ + private Integer isEnabled; + + /** + * 备注 + */ + private String remark; + + +} diff --git a/gear-oa/src/main/java/com/gear/oa/domain/vo/GearStockIoDetailVo.java b/gear-oa/src/main/java/com/gear/oa/domain/vo/GearStockIoDetailVo.java new file mode 100644 index 0000000..f2d746a --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/vo/GearStockIoDetailVo.java @@ -0,0 +1,104 @@ +package com.gear.oa.domain.vo; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import com.gear.common.annotation.ExcelDictFormat; +import com.gear.common.convert.ExcelDictConvert; +import lombok.Data; + +import java.math.BigDecimal; + + +/** + * 出入库单明细视图对象 gear_stock_io_detail + * + * @author Joshi + * @date 2025-07-18 + */ +@Data +@ExcelIgnoreUnannotated +public class GearStockIoDetailVo { + + private static final long serialVersionUID = 1L; + + /** + * 明细ID + */ + @ExcelProperty(value = "明细ID") + private Long detailId; + + /** + * 出入库单ID + */ + @ExcelProperty(value = "出入库单ID") + private Long stockIoId; + + /** + * 库区/库位ID + */ + @ExcelProperty(value = "库区/库位ID") + private Long warehouseId; + + /** + * 物品类型(raw_material/product) + */ + @ExcelProperty(value = "物品类型", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "r=aw_material/product") + private String itemType; + + /** + * 物品ID + */ + @ExcelProperty(value = "物品ID") + private Long itemId; + + /** + * 数量 + */ + @ExcelProperty(value = "数量") + private BigDecimal quantity; + + /** + * 单位 + */ + @ExcelProperty(value = "单位") + private String unit; + + /** + * 批次号 + */ + @ExcelProperty(value = "批次号") + private String batchNo; + + /** + * 备注 + */ + @ExcelProperty(value = "备注") + private String remark; + + /** + * 记录类型,0:详情,1:扫码枪记录 + */ + private Integer recordType; + + /** + * 库区/库位名称 + */ + private String warehouseName; + /** + * 源库区/库位名称(移库用) + */ + private String fromWarehouseName; + + /** + * 源库位ID(移库时使用) + */ + private Long fromWarehouseId; + + //主表的 数据号 类型以及业务类型 + private String stockIoCode; + private String ioType; + private String bizType; + + +} diff --git a/gear-oa/src/main/java/com/gear/oa/domain/vo/GearStockIoVo.java b/gear-oa/src/main/java/com/gear/oa/domain/vo/GearStockIoVo.java new file mode 100644 index 0000000..e44fbdf --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/vo/GearStockIoVo.java @@ -0,0 +1,65 @@ +package com.gear.oa.domain.vo; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import com.gear.common.annotation.ExcelDictFormat; +import com.gear.common.convert.ExcelDictConvert; +import com.gear.common.core.domain.BaseEntity; +import lombok.Data; + + +/** + * 出入库单主视图对象 gear_stock_io + * + * @author Joshi + * @date 2025-07-18 + */ +@Data +@ExcelIgnoreUnannotated +public class GearStockIoVo extends BaseEntity { + + private static final long serialVersionUID = 1L; + + /** + * 出入库单ID + */ + @ExcelProperty(value = "出入库单ID") + private Long stockIoId; + + /** + * 出入库单号 + */ + @ExcelProperty(value = "出入库单号") + private String stockIoCode; + + /** + * 类型(in=入库,out=出库) + */ + @ExcelProperty(value = "类型", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "i=n=入库,out=出库") + private String ioType; + + /** + * 业务类型(采购、销售、退货、调拨等) + */ + @ExcelProperty(value = "业务类型", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "采=购、销售、退货、调拨等") + private String bizType; + + /** + * 单据状态(0=草稿,1=已提交,2=已审核,3=已完成) + */ + @ExcelProperty(value = "单据状态", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "0==草稿,1=已提交,2=已审核,3=已完成") + private Integer status; + + /** + * 备注 + */ + @ExcelProperty(value = "备注") + private String remark; + + private Long parentId; + + +} diff --git a/gear-oa/src/main/java/com/gear/oa/domain/vo/GearStockLogVo.java b/gear-oa/src/main/java/com/gear/oa/domain/vo/GearStockLogVo.java new file mode 100644 index 0000000..ede6060 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/vo/GearStockLogVo.java @@ -0,0 +1,93 @@ +package com.gear.oa.domain.vo; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.gear.common.annotation.ExcelDictFormat; +import com.gear.common.convert.ExcelDictConvert; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + + +/** + * 库存流水视图对象 gear_stock_log + * + * @author JR + * @date 2025-08-11 + */ +@Data +@ExcelIgnoreUnannotated +public class GearStockLogVo { + + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @ExcelProperty(value = "主键ID") + private Long id; + + /** + * 仓库/库区/库位ID + */ + @ExcelProperty(value = "仓库/库区/库位ID") + private Long warehouseId; + + /** + * 物品ID(指向原材料或产品主键) + */ + @ExcelProperty(value = "物品ID", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "指=向原材料或产品主键") + private Long itemId; + + /** + * 物品类型(raw_material/product) + */ + @ExcelProperty(value = "物品类型", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "r=aw_material/product") + private String itemType; + + /** + * 变动数量(正=入库,负=出库) + */ + @ExcelProperty(value = "变动数量", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "正==入库,负=出库") + private BigDecimal changeQty; + + /** + * 变动后的库存数量 + */ + @ExcelProperty(value = "变动后的库存数量") + private BigDecimal afterQty; + + /** + * 变动类型(入库/出库等) + */ + @ExcelProperty(value = "变动类型", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "入=库/出库等") + private String changeType; + + /** + * 实际库存变动时间 + */ + @ExcelProperty(value = "实际库存变动时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date changeTime; + + /** + * 备注 + */ + @ExcelProperty(value = "备注") + private String remark; + + /** + * 仓库/库区名称 + */ + @ExcelProperty(value = "仓库/库区名称") + private String warehouseName; + + //批次号 + private String batchNo; +} diff --git a/gear-oa/src/main/java/com/gear/oa/domain/vo/GearStockVo.java b/gear-oa/src/main/java/com/gear/oa/domain/vo/GearStockVo.java new file mode 100644 index 0000000..8d3d54a --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/vo/GearStockVo.java @@ -0,0 +1,96 @@ +package com.gear.oa.domain.vo; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import com.gear.common.annotation.ExcelDictFormat; +import com.gear.common.convert.ExcelDictConvert; +import lombok.Data; + +import java.math.BigDecimal; + + +/** + * 库存:原材料/产品与库区/库位的存放关系视图对象 gear_stock + * + * @author Joshi + * @date 2025-07-18 + */ +@Data +@ExcelIgnoreUnannotated +public class GearStockVo { + + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @ExcelProperty(value = "主键ID") + private Long stockId; + + /** + * 仓库/库区/库位ID + */ + @ExcelProperty(value = "仓库/库区/库位ID") + private Long warehouseId; + + /** + * 物品类型(raw_material/product) + */ + @ExcelProperty(value = "物品类型", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "raw_material/product") + private String itemType; + + /** + * 物品ID(指向原材料或产品主键) + */ + @ExcelProperty(value = "物品ID", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "指向原材料或产品主键") + private Long itemId; + + /** + * 物品名称(动态:产品或原材料) + */ + private String itemName; + /** + * 物品编码(动态:产品或原材料) + */ + private String itemCode; + + /** + * 库存数量 + */ + @ExcelProperty(value = "库存数量") + private BigDecimal quantity; + + /** + * 单位 + */ + @ExcelProperty(value = "单位") + private String unit; + + /** + * 批次号(可选) + */ + @ExcelProperty(value = "批次号", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "可=选") + private String batchNo; + + /** + * 备注 + */ + @ExcelProperty(value = "备注") + private String remark; + + /** + * 仓库/库区名称 + */ + @ExcelProperty(value = "仓库/库区名称") + private String warehouseName; + + /** + * 在途量 + */ + @ExcelProperty(value = "在途量") + private BigDecimal onTheWay; + +} diff --git a/gear-oa/src/main/java/com/gear/oa/domain/vo/GearWarehouseVo.java b/gear-oa/src/main/java/com/gear/oa/domain/vo/GearWarehouseVo.java new file mode 100644 index 0000000..9e8b9d6 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/vo/GearWarehouseVo.java @@ -0,0 +1,73 @@ +package com.gear.oa.domain.vo; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import com.gear.common.annotation.ExcelDictFormat; +import com.gear.common.convert.ExcelDictConvert; +import lombok.Data; + + +/** + * 仓库/库区/库位自关联视图对象 gear_warehouse + * + * @author JR + * @date 2025-07-18 + */ +@Data +@ExcelIgnoreUnannotated +public class GearWarehouseVo { + + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @ExcelProperty(value = "主键ID") + private Long warehouseId; + + /** + * 父节点ID(指向同表 warehouse_id) + */ + @ExcelProperty(value = "父节点ID", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "指=向同表,w=arehouse_id") + private Long parentId; + + /** + * 仓库/库区编码 + */ + @ExcelProperty(value = "仓库/库区编码") + private String warehouseCode; + + /** + * 仓库/库区名称 + */ + @ExcelProperty(value = "仓库/库区名称") + private String warehouseName; + + /** + * 类型:0=仓库,1=库区,2=库位,… + */ + @ExcelProperty(value = "类型:0=仓库,1=库区,2=库位,…") + private Long warehouseType; + + /** + * 同级排序号 + */ + @ExcelProperty(value = "同级排序号") + private Long sortNo; + + /** + * 是否启用(0=否,1=是) + */ + @ExcelProperty(value = "是否启用", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "0==否,1=是") + private Integer isEnabled; + + /** + * 备注 + */ + @ExcelProperty(value = "备注") + private String remark; + + +} diff --git a/gear-oa/src/main/java/com/gear/oa/mapper/GearStockIoDetailMapper.java b/gear-oa/src/main/java/com/gear/oa/mapper/GearStockIoDetailMapper.java new file mode 100644 index 0000000..192e19a --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/mapper/GearStockIoDetailMapper.java @@ -0,0 +1,34 @@ +package com.gear.oa.mapper; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.gear.common.core.mapper.BaseMapperPlus; +import com.gear.oa.domain.GearStockIoDetail; +import com.gear.oa.domain.vo.GearStockIoDetailVo; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * 出入库单明细Mapper接口 + * + * VO带有库区/库位名称和源库区/库位名称 + * + * @author Joshi + * @date 2025-07-18 + */ +public interface GearStockIoDetailMapper extends BaseMapperPlus { + + /** + * 联查库区/库位名称的明细列表,返回Map + */ + List> selectDetailWithWarehouseName(@Param("stockIoId") Long stockIoId); + + /** + * 分页联查库区/库位名称的明细列表,支持Wrapper动态条件,返回Page + */ + Page selectVoPagePlus(Page page, @Param("ew") Wrapper wrapper); + + List batchQuery(@Param("batchNo") String batchNo); +} diff --git a/gear-oa/src/main/java/com/gear/oa/mapper/GearStockIoMapper.java b/gear-oa/src/main/java/com/gear/oa/mapper/GearStockIoMapper.java new file mode 100644 index 0000000..630f53b --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/mapper/GearStockIoMapper.java @@ -0,0 +1,15 @@ +package com.gear.oa.mapper; + +import com.gear.common.core.mapper.BaseMapperPlus; +import com.gear.oa.domain.GearStockIo; +import com.gear.oa.domain.vo.GearStockIoVo; + +/** + * 出入库单主Mapper接口 + * + * @author Joshi + * @date 2025-07-18 + */ +public interface GearStockIoMapper extends BaseMapperPlus { + +} diff --git a/gear-oa/src/main/java/com/gear/oa/mapper/GearStockLogMapper.java b/gear-oa/src/main/java/com/gear/oa/mapper/GearStockLogMapper.java new file mode 100644 index 0000000..58633d6 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/mapper/GearStockLogMapper.java @@ -0,0 +1,19 @@ +package com.gear.oa.mapper; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.gear.common.core.mapper.BaseMapperPlus; +import com.gear.oa.domain.GearStockLog; +import com.gear.oa.domain.vo.GearStockLogVo; +import org.apache.ibatis.annotations.Param; + +/** + * 库存流水Mapper接口 + * + * @author JR + * @date 2025-08-11 + */ +public interface GearStockLogMapper extends BaseMapperPlus { + + Page selectVoPagePlus(Page page, @Param("ew") Wrapper wrapper); +} diff --git a/gear-oa/src/main/java/com/gear/oa/mapper/GearStockMapper.java b/gear-oa/src/main/java/com/gear/oa/mapper/GearStockMapper.java new file mode 100644 index 0000000..3e60f78 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/mapper/GearStockMapper.java @@ -0,0 +1,27 @@ +package com.gear.oa.mapper; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.gear.common.core.mapper.BaseMapperPlus; +import com.gear.oa.domain.GearStock; +import com.gear.oa.domain.vo.GearStockVo; +import org.apache.ibatis.annotations.Param; + +import java.math.BigDecimal; + +/** + * 库存:原材料/产品与库区/库位的存放关系Mapper接口 + * + * @author Joshi + * @date 2025-07-18 + */ +public interface GearStockMapper extends BaseMapperPlus { + + BigDecimal getStockByItemId(Long rawMaterialId); + + /** + * 分页联查物品名称和编码,支持Wrapper动态条件,返回Page + */ + Page selectVoPagePlus(Page page, @Param("ew") Wrapper wrapper); + +} diff --git a/gear-oa/src/main/java/com/gear/oa/mapper/GearWarehouseMapper.java b/gear-oa/src/main/java/com/gear/oa/mapper/GearWarehouseMapper.java new file mode 100644 index 0000000..d501c20 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/mapper/GearWarehouseMapper.java @@ -0,0 +1,15 @@ +package com.gear.oa.mapper; + +import com.gear.common.core.mapper.BaseMapperPlus; +import com.gear.oa.domain.GearWarehouse; +import com.gear.oa.domain.vo.GearWarehouseVo; + +/** + * 仓库/库区/库位自关联Mapper接口 + * + * @author JR + * @date 2025-07-18 + */ +public interface GearWarehouseMapper extends BaseMapperPlus { + +} diff --git a/gear-oa/src/main/java/com/gear/oa/service/IGearProductService.java b/gear-oa/src/main/java/com/gear/oa/service/IGearProductService.java index d34161a..51cd9a6 100644 --- a/gear-oa/src/main/java/com/gear/oa/service/IGearProductService.java +++ b/gear-oa/src/main/java/com/gear/oa/service/IGearProductService.java @@ -46,49 +46,49 @@ public interface IGearProductService { * 校验并批量删除产品信息 */ Boolean deleteWithValidByIds(Collection ids, Boolean isValid); - + /** * 数据看板 - 获取所有数据 */ ProductDashboardVO getDashboard(); - + /** * 数据看板 - 产品销售情况 */ List selectProductSalesPerformance(); - + /** * 数据看板 - 销售人员业绩 */ List selectSalesPersonPerformance(); - + /** * 数据看板 - 总订单数量统计 */ OrderCountStatisticsVO selectOrderCountStatistics(); - + /** * 数据看板 - 订单所需的产品统计 */ List selectOrderProductStatistics(); - + /** * 数据看板 - 根据BOM计算的原料需求 */ List selectProductMaterialRequirements(); - + /** * 数据看板 - 原料库存和需求情况 */ List selectRawMaterialInventory(); - + /** * 数据看板 - 订单维度推荐 */ List selectOrderRecommendations(); - + /** * 数据看板 - 原料维度推荐 */ List selectMaterialRecommendations(); -} \ No newline at end of file +} diff --git a/gear-oa/src/main/java/com/gear/oa/service/IGearStockIoDetailService.java b/gear-oa/src/main/java/com/gear/oa/service/IGearStockIoDetailService.java new file mode 100644 index 0000000..436adb4 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/service/IGearStockIoDetailService.java @@ -0,0 +1,50 @@ +package com.gear.oa.service; + +import com.gear.common.core.domain.PageQuery; +import com.gear.common.core.page.TableDataInfo; +import com.gear.oa.domain.bo.GearStockIoDetailBo; +import com.gear.oa.domain.vo.GearStockIoDetailVo; + +import java.util.Collection; +import java.util.List; + +/** + * 出入库单明细Service接口 + * + * @author Joshi + * @date 2025-07-18 + */ +public interface IGearStockIoDetailService { + + /** + * 查询出入库单明细 + */ + GearStockIoDetailVo queryById(Long detailId); + + /** + * 查询出入库单明细列表 + */ + TableDataInfo queryPageList(GearStockIoDetailBo bo, PageQuery pageQuery); + + /** + * 查询出入库单明细列表 + */ + List queryList(GearStockIoDetailBo bo); + + /** + * 新增出入库单明细 + */ + Boolean insertByBo(GearStockIoDetailBo bo); + + /** + * 修改出入库单明细 + */ + Boolean updateByBo(GearStockIoDetailBo bo); + + /** + * 校验并批量删除出入库单明细信息 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + List batchQuery(GearStockIoDetailBo bo); +} diff --git a/gear-oa/src/main/java/com/gear/oa/service/IGearStockIoService.java b/gear-oa/src/main/java/com/gear/oa/service/IGearStockIoService.java new file mode 100644 index 0000000..c5dae01 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/service/IGearStockIoService.java @@ -0,0 +1,83 @@ +package com.gear.oa.service; + +import com.gear.common.core.domain.PageQuery; +import com.gear.common.core.page.TableDataInfo; +import com.gear.oa.domain.bo.GearStockIoBo; +import com.gear.oa.domain.bo.GearStockIoDetailBo; +import com.gear.oa.domain.bo.GearStockIoWithDetailBo; +import com.gear.oa.domain.vo.GearStockIoDetailVo; +import com.gear.oa.domain.vo.GearStockIoVo; + +import java.util.Collection; +import java.util.List; + +/** + * 出入库单主Service接口 + * + * @author Joshi + * @date 2025-07-18 + */ +public interface IGearStockIoService { + + /** + * 查询出入库单主 + */ + GearStockIoVo queryById(Long stockIoId); + + /** + * 查询出入库单主列表 + */ + TableDataInfo queryPageList(GearStockIoBo bo, PageQuery pageQuery); + + /** + * 查询出入库单主列表 + */ + List queryList(GearStockIoBo bo); + + /** + * 新增出入库单主 + */ + Boolean insertByBo(GearStockIoBo bo); + + /** + * 修改出入库单主 + */ + Boolean updateByBo(GearStockIoBo bo); + + /** + * 校验并批量删除出入库单主信息 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 审核出入库/移库单,变更库存,含库存校验 + */ + Boolean auditStockIo(Long stockIoId); + + /** + * 撤销出入库/移库单,库存回滚 + */ + Boolean cancelStockIo(Long stockIoId); + + /** + * 根据ioType和stockIoId联查明细 + */ + List detailByTypeAndId(String ioType, Long stockIoId); + + /** + * 更新出入库单状态 + */ + Boolean updateStatus(Long stockIoId, Integer status); + + /** + * 批量新增主表和明细 + */ + void addWithDetail(GearStockIoWithDetailBo bo); + + +// boolean scanInStockByBo(GearStockIoDetailBo bo); +// +// boolean scanOutStockByBo(GearStockIoDetailBo bo); +// +// boolean scanReturnStockByBo(GearStockIoBo bo); +} diff --git a/gear-oa/src/main/java/com/gear/oa/service/IGearStockLogService.java b/gear-oa/src/main/java/com/gear/oa/service/IGearStockLogService.java new file mode 100644 index 0000000..7cc51fd --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/service/IGearStockLogService.java @@ -0,0 +1,48 @@ +package com.gear.oa.service; + +import com.gear.common.core.domain.PageQuery; +import com.gear.common.core.page.TableDataInfo; +import com.gear.oa.domain.bo.GearStockLogBo; +import com.gear.oa.domain.vo.GearStockLogVo; + +import java.util.Collection; +import java.util.List; + +/** + * 库存流水Service接口 + * + * @author JR + * @date 2025-08-11 + */ +public interface IGearStockLogService { + + /** + * 查询库存流水 + */ + GearStockLogVo queryById(Long id); + + /** + * 查询库存流水列表 + */ + TableDataInfo queryPageList(GearStockLogBo bo, PageQuery pageQuery); + + /** + * 查询库存流水列表 + */ + List queryList(GearStockLogBo bo); + + /** + * 新增库存流水 + */ + Boolean insertByBo(GearStockLogBo bo); + + /** + * 修改库存流水 + */ + Boolean updateByBo(GearStockLogBo bo); + + /** + * 校验并批量删除库存流水信息 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); +} diff --git a/gear-oa/src/main/java/com/gear/oa/service/IGearStockService.java b/gear-oa/src/main/java/com/gear/oa/service/IGearStockService.java new file mode 100644 index 0000000..5693340 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/service/IGearStockService.java @@ -0,0 +1,56 @@ +package com.gear.oa.service; + +import com.gear.common.core.domain.PageQuery; +import com.gear.common.core.page.TableDataInfo; +import com.gear.oa.domain.bo.GearStockBo; +import com.gear.oa.domain.vo.GearStockVo; + +import java.math.BigDecimal; +import java.util.Collection; +import java.util.List; + +/** + * 库存:原材料/产品与库区/库位的存放关系Service接口 + * + * @author Joshi + * @date 2025-07-18 + */ +public interface IGearStockService { + + /** + * 查询库存:原材料/产品与库区/库位的存放关系 + */ + GearStockVo queryById(Long stockId); + + /** + * 查询库存:原材料/产品与库区/库位的存放关系列表 + */ + TableDataInfo queryPageList(GearStockBo bo, PageQuery pageQuery); + + /** + * 查询库存:原材料/产品与库区/库位的存放关系列表 + */ + List queryList(GearStockBo bo); + + /** + * 新增库存:原材料/产品与库区/库位的存放关系 + */ + Boolean insertByBo(GearStockBo bo); + + /** + * 修改库存:原材料/产品与库区/库位的存放关系 + */ + Boolean updateByBo(GearStockBo bo); + + /** + * 校验并批量删除库存:原材料/产品与库区/库位的存放关系信息 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + +// /** +// * 根据原材料ID获取库存数量 (用于生成推荐采购计划) +// */ +// BigDecimal getStockByItemId(Long rawMaterialId); + + +} diff --git a/gear-oa/src/main/java/com/gear/oa/service/IGearWarehouseService.java b/gear-oa/src/main/java/com/gear/oa/service/IGearWarehouseService.java new file mode 100644 index 0000000..2507af4 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/service/IGearWarehouseService.java @@ -0,0 +1,42 @@ +package com.gear.oa.service; + +import com.gear.oa.domain.bo.GearWarehouseBo; +import com.gear.oa.domain.vo.GearWarehouseVo; + +import java.util.Collection; +import java.util.List; + +/** + * 仓库/库区/库位自关联Service接口 + * + * @author JR + * @date 2025-07-18 + */ +public interface IGearWarehouseService { + + /** + * 查询仓库/库区/库位自关联 + */ + GearWarehouseVo queryById(Long warehouseId); + + + /** + * 查询仓库/库区/库位自关联列表 + */ + List queryList(GearWarehouseBo bo); + + /** + * 新增仓库/库区/库位自关联 + */ + Boolean insertByBo(GearWarehouseBo bo); + + /** + * 修改仓库/库区/库位自关联 + */ + Boolean updateByBo(GearWarehouseBo bo); + + /** + * 校验并批量删除仓库/库区/库位自关联信息 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); +} diff --git a/gear-oa/src/main/java/com/gear/oa/service/impl/GearAttendanceSummaryServiceImpl.java b/gear-oa/src/main/java/com/gear/oa/service/impl/GearAttendanceSummaryServiceImpl.java index f9b05c9..66c5105 100644 --- a/gear-oa/src/main/java/com/gear/oa/service/impl/GearAttendanceSummaryServiceImpl.java +++ b/gear-oa/src/main/java/com/gear/oa/service/impl/GearAttendanceSummaryServiceImpl.java @@ -144,17 +144,17 @@ public class GearAttendanceSummaryServiceImpl implements IGearAttendanceSummaryS // 按userId和recordType分组,确保每个用户每种类型正确统计 Map> groupedRecords = records.stream() .collect(Collectors.groupingBy(r -> r.getUserId() + "_" + r.getRecordType())); - + // 为每个用户创建汇总明细 Map summaryDetails = new HashMap<>(); - + for (List recordList : groupedRecords.values()) { if (recordList.isEmpty()) continue; - + GearAttendanceRecord firstRecord = recordList.get(0); Long userId = firstRecord.getUserId(); String recordType = firstRecord.getRecordType(); - + // 获取或创建用户的汇总明细 GearAttendanceSummaryDetailVo detail = summaryDetails.computeIfAbsent(userId, k -> { GearAttendanceSummaryDetailVo newDetail = new GearAttendanceSummaryDetailVo(); @@ -164,12 +164,12 @@ public class GearAttendanceSummaryServiceImpl implements IGearAttendanceSummaryS newDetail.setTravelHours(BigDecimal.ZERO); return newDetail; }); - + // 计算该类型的小时数总和 long totalHours = recordList.stream() .mapToLong(GearAttendanceRecord::getDurationHour) .sum(); - + // 根据记录类型设置对应的小时数 switch (recordType) { case "attendance": diff --git a/gear-oa/src/main/java/com/gear/oa/service/impl/GearStockIoDetailServiceImpl.java b/gear-oa/src/main/java/com/gear/oa/service/impl/GearStockIoDetailServiceImpl.java new file mode 100644 index 0000000..27bcd3e --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/service/impl/GearStockIoDetailServiceImpl.java @@ -0,0 +1,222 @@ +package com.gear.oa.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.gear.common.core.domain.PageQuery; +import com.gear.common.core.page.TableDataInfo; +import com.gear.common.exception.ServiceException; +import com.gear.common.utils.StringUtils; +import com.gear.oa.domain.GearProduct; +import com.gear.oa.domain.GearStockIo; +import com.gear.oa.domain.GearStockIoDetail; +import com.gear.oa.domain.bo.GearStockIoDetailBo; +import com.gear.oa.domain.vo.GearStockIoDetailVo; +import com.gear.oa.mapper.GearProductMapper; +import com.gear.oa.mapper.GearStockIoDetailMapper; +import com.gear.oa.mapper.GearStockIoMapper; +import com.gear.oa.service.IGearStockIoDetailService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * 出入库单明细Service业务层处理 + * + * @author Joshi + * @date 2025-07-18 + */ +@RequiredArgsConstructor +@Service +public class GearStockIoDetailServiceImpl implements IGearStockIoDetailService { + + private final GearStockIoDetailMapper baseMapper; + private final GearStockIoMapper stockIoMapper; + private final GearProductMapper productMapper; + + /** + * 查询出入库单明细 + */ + @Override + public GearStockIoDetailVo queryById(Long detailId){ + return baseMapper.selectVoById(detailId); + } + + /** + * 查询出入库单明细列表 + */ + @Override + public TableDataInfo queryPageList(GearStockIoDetailBo bo, PageQuery pageQuery) { + QueryWrapper qw = buildQueryWrapperPlus(bo); + Page result = baseMapper.selectVoPagePlus(pageQuery.build(), qw); + return TableDataInfo.build(result); + } + + /** + * 查询出入库单明细列表 + */ + @Override + public List queryList(GearStockIoDetailBo bo) { + LambdaQueryWrapper qw = buildQueryWrapper(bo); + return baseMapper.selectVoList(qw); + } + private LambdaQueryWrapper buildQueryWrapper(GearStockIoDetailBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.eq(bo.getStockIoId() != null, GearStockIoDetail::getStockIoId, bo.getStockIoId()); + lqw.eq(bo.getWarehouseId() != null, GearStockIoDetail::getWarehouseId, bo.getWarehouseId()); + lqw.eq(StringUtils.isNotBlank(bo.getItemType()), GearStockIoDetail::getItemType, bo.getItemType()); + lqw.eq(bo.getItemId() != null, GearStockIoDetail::getItemId, bo.getItemId()); + lqw.eq(bo.getQuantity() != null, GearStockIoDetail::getQuantity, bo.getQuantity()); + lqw.eq(StringUtils.isNotBlank(bo.getUnit()), GearStockIoDetail::getUnit, bo.getUnit()); + lqw.eq(StringUtils.isNotBlank(bo.getBatchNo()), GearStockIoDetail::getBatchNo, bo.getBatchNo()); + return lqw; + } + + private QueryWrapper buildQueryWrapperPlus(GearStockIoDetailBo bo) { + Map params = bo.getParams(); + QueryWrapper qw = new QueryWrapper<>(); + qw.eq("d.del_flag", 0); // 手动添加逻辑删除条件 + qw.eq(bo.getStockIoId() != null, "d.stock_io_id", bo.getStockIoId()); + qw.eq(bo.getWarehouseId() != null, "d.warehouse_id", bo.getWarehouseId()); + qw.eq(StringUtils.isNotBlank(bo.getItemType()), "d.item_type", bo.getItemType()); + qw.eq(bo.getItemId() != null, "d.item_id", bo.getItemId()); + qw.eq(bo.getQuantity() != null, "d.quantity", bo.getQuantity()); + qw.eq(StringUtils.isNotBlank(bo.getUnit()), "d.unit", bo.getUnit()); + qw.eq(StringUtils.isNotBlank(bo.getBatchNo()), "d.batch_no", bo.getBatchNo()); + return qw; + } + + /** + * 新增出入库单明细 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean insertByBo(GearStockIoDetailBo bo) { + // 检查主表状态,已审核的单据不能添加明细 + GearStockIo stockIo = stockIoMapper.selectById(bo.getStockIoId()); + if (stockIo != null && stockIo.getStatus() >= 2) { + throw new ServiceException("已审核的单据不能修改明细"); + } + // 如果unit为空,自动查item表补全(新增逻辑) + String unit = bo.getUnit(); + if (unit == null || unit.trim().isEmpty()) { + if ("product".equals(bo.getItemType())) { + GearProduct p = productMapper.selectById(bo.getItemId()); + unit = p != null ? p.getUnit() : null; + } + } + // 将获取到的unit设置回bo对象 + bo.setUnit(unit); + GearStockIoDetail add = BeanUtil.toBean(bo, GearStockIoDetail.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setDetailId(add.getDetailId()); + + // 检查主表状态,如果有明细且状态为草稿,则自动变为待审核 + if (stockIo != null && stockIo.getStatus() == 0) { + // 检查是否有明细 + Long detailCount = baseMapper.selectCount( + new LambdaQueryWrapper() + .eq(GearStockIoDetail::getStockIoId, bo.getStockIoId()) + ); + + if (detailCount > 0) { + // 自动更新状态为待审核 + stockIo.setStatus(1); + stockIo.setUpdateTime(new Date()); + stockIoMapper.updateById(stockIo); + } + } + } + return flag; + } + + /** + * 修改出入库单明细 + */ + @Override + public Boolean updateByBo(GearStockIoDetailBo bo) { + // 检查主表状态,已审核的单据不能修改明细 + GearStockIo stockIo = stockIoMapper.selectById(bo.getStockIoId()); + if (stockIo != null && stockIo.getStatus() >= 2) { + throw new ServiceException("已审核的单据不能修改明细"); + } + + GearStockIoDetail update = BeanUtil.toBean(bo, GearStockIoDetail.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(GearStockIoDetail entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 批量删除出入库单明细 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + + // 获取要删除的明细对应的主表ID,检查状态 + List details = baseMapper.selectBatchIds(ids); + if (details != null && !details.isEmpty()) { + // 检查主表状态,已审核的单据不能删除明细 + for (GearStockIoDetail detail : details) { + GearStockIo stockIo = stockIoMapper.selectById(detail.getStockIoId()); + if (stockIo != null && stockIo.getStatus() >= 2) { + throw new ServiceException("已审核的单据不能修改明细"); + } + } + // 按主表ID分组 + Map> stockIoIdMap = details.stream() + .collect(java.util.stream.Collectors.groupingBy(GearStockIoDetail::getStockIoId)); + + boolean flag = baseMapper.deleteBatchIds(ids) > 0; + + if (flag) { + // 检查每个主表是否还有其他明细 + for (Long stockIoId : stockIoIdMap.keySet()) { + Long remainingCount = baseMapper.selectCount( + new LambdaQueryWrapper() + .eq(GearStockIoDetail::getStockIoId, stockIoId) + ); + + // 如果没有明细了,状态回退为草稿 + if (remainingCount == 0) { + GearStockIo stockIo = stockIoMapper.selectById(stockIoId); + if (stockIo != null && stockIo.getStatus() == 1) { + stockIo.setStatus(0); + stockIo.setUpdateTime(new Date()); + stockIoMapper.updateById(stockIo); + } + } + } + } + + return flag; + } + + return baseMapper.deleteBatchIds(ids) > 0; + } + + @Override + public List batchQuery(GearStockIoDetailBo bo) { + //根据这个bo.getBatchNo()拿到这个批次号对应明细表的信息在根据明细表带的stockIoId拿到库存表信息 + return baseMapper.batchQuery(bo.getBatchNo()); + } +} diff --git a/gear-oa/src/main/java/com/gear/oa/service/impl/GearStockIoServiceImpl.java b/gear-oa/src/main/java/com/gear/oa/service/impl/GearStockIoServiceImpl.java new file mode 100644 index 0000000..36245d6 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/service/impl/GearStockIoServiceImpl.java @@ -0,0 +1,491 @@ +package com.gear.oa.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.gear.common.core.domain.PageQuery; +import com.gear.common.core.page.TableDataInfo; +import com.gear.common.exception.ServiceException; +import com.gear.common.utils.StringUtils; +import com.gear.oa.domain.*; +import com.gear.oa.domain.bo.GearStockIoBo; +import com.gear.oa.domain.bo.GearStockIoDetailBo; +import com.gear.oa.domain.bo.GearStockIoWithDetailBo; +import com.gear.oa.domain.vo.GearStockIoDetailVo; +import com.gear.oa.domain.vo.GearStockIoVo; +import com.gear.oa.mapper.*; +import com.gear.oa.service.IGearStockIoService; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.util.*; + +/** + * 出入库单主Service业务层处理 + * + * @author Joshi + * @date 2025-07-18 + */ +@RequiredArgsConstructor +@Service +public class GearStockIoServiceImpl implements IGearStockIoService { + + private final GearStockIoMapper baseMapper; + private final GearStockIoDetailMapper stockIoDetailMapper; + private final GearStockMapper stockMapper; + private final GearProductMapper productMapper; +// private final GearRawMaterialMapper rawMaterialMapper; + private final GearWarehouseMapper warehouseMapper; + @Resource + private GearStockLogMapper stockLogMapper; + + /** + * 查询出入库单主 + */ + @Override + public GearStockIoVo queryById(Long stockIoId){ + return baseMapper.selectVoById(stockIoId); + } + + /** + * 查询出入库单主列表 + */ + @Override + public TableDataInfo queryPageList(GearStockIoBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询出入库单主列表 + */ + @Override + public List queryList(GearStockIoBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(GearStockIoBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(StringUtils.isNotBlank(bo.getStockIoCode()), GearStockIo::getStockIoCode, bo.getStockIoCode()); + lqw.eq(StringUtils.isNotBlank(bo.getIoType()), GearStockIo::getIoType, bo.getIoType()); + lqw.eq(StringUtils.isNotBlank(bo.getBizType()), GearStockIo::getBizType, bo.getBizType()); + lqw.eq(bo.getStatus() != null, GearStockIo::getStatus, bo.getStatus()); + return lqw; + } + + /** + * 新增出入库单主 + */ + @Override + public Boolean insertByBo(GearStockIoBo bo) { + GearStockIo add = BeanUtil.toBean(bo, GearStockIo.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setStockIoId(add.getStockIoId()); + } + return flag; + } + + /** + * 修改出入库单主 + */ + @Override + public Boolean updateByBo(GearStockIoBo bo) { + GearStockIo update = BeanUtil.toBean(bo, GearStockIo.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(GearStockIo entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 批量删除出入库单主 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteBatchIds(ids) > 0; + } + + /** + * 批量新增主表和明细 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void addWithDetail(GearStockIoWithDetailBo bo) { + // 插入主表 + GearStockIo stockIo = BeanUtil.toBean(bo, GearStockIo.class); + stockIo.setParentId(bo.getParentId()); + baseMapper.insert(stockIo); + // 插入明细 + if (bo.getDetails() != null && !bo.getDetails().isEmpty()) { + for (GearStockIoDetailBo detailBo : bo.getDetails()) { + GearStockIoDetail detail = BeanUtil.toBean(detailBo, GearStockIoDetail.class); + detail.setStockIoId(stockIo.getStockIoId()); + stockIoDetailMapper.insert(detail); + } + } + } + +// @Override +// @Transactional(rollbackFor = Exception.class) +// public boolean scanInStockByBo(GearStockIoDetailBo bo) { +// String unit = bo.getUnit(); +// // 如果unit为空,自动查item表补全 +// if (unit == null || unit.trim().isEmpty()) { +// if ("product".equals(bo.getItemType())) { +// GearProduct p = productMapper.selectById(bo.getItemId()); +// unit = p != null ? p.getUnit() : null; +// } else if ("raw_material".equals(bo.getItemType())) { +// GearRawMaterial r = rawMaterialMapper.selectById(bo.getItemId()); +// unit = r != null ? r.getUnit() : null; +// } +// } +// if (unit == null || unit.trim().isEmpty()) { +// throw new RuntimeException("未能获取到单位"); +// } +// // 入库操作 +// changeStock(bo.getWarehouseId(), bo.getItemType(), bo.getItemId(), bo.getBatchNo(), bo.getQuantity(), true, unit); +// return true; +// } +// @Override +// @Transactional(rollbackFor = Exception.class) +// public boolean scanOutStockByBo(GearStockIoDetailBo bo) { +// String unit = bo.getUnit(); +// // 如果unit为空,自动查item表补全 +// if (unit == null || unit.trim().isEmpty()) { +// if ("product".equals(bo.getItemType())) { +// GearProduct p = productMapper.selectById(bo.getItemId()); +// unit = p != null ? p.getUnit() : null; +// } else if ("raw_material".equals(bo.getItemType())) { +// GearRawMaterial r = rawMaterialMapper.selectById(bo.getItemId()); +// unit = r != null ? r.getUnit() : null; +// } +// } +// if (unit == null || unit.trim().isEmpty()) { +// throw new RuntimeException("未能获取到单位"); +// } +// // 出库操作 +// changeStock(bo.getWarehouseId(), bo.getItemType(), bo.getItemId(), bo.getBatchNo(), bo.getQuantity(), false, unit); +// return true; +// } + +// @Override +// @Transactional(rollbackFor = Exception.class) +// public boolean scanReturnStockByBo(GearStockIoBo bo) { +// // 退库操作:根据主表ID查询明细列表,验证退库数量,执行退库 +// if (bo.getStockIoId() == null) { +// throw new ServiceException("退库单ID不能为空"); +// } +// +// // 1. 获取退库单主表信息 +// GearStockIo returnStockIo = baseMapper.selectById(bo.getStockIoId()); +// if (returnStockIo == null || returnStockIo.getParentId() == null) { +// throw new ServiceException("退库单不存在或未关联原出库单"); +// } +// +// // 2. 获取退库单明细列表 +// List returnDetails = stockIoDetailMapper.selectList( +// Wrappers.lambdaQuery().eq(GearStockIoDetail::getStockIoId, bo.getStockIoId()) +// ); +// +// if (returnDetails == null || returnDetails.isEmpty()) { +// throw new ServiceException("退库单明细不能为空"); +// } +// +// // 3. 获取原出库单明细列表 +// List originalOutDetails = stockIoDetailMapper.selectList( +// Wrappers.lambdaQuery().eq(GearStockIoDetail::getStockIoId, returnStockIo.getParentId()) +// ); +// +// if (originalOutDetails == null || originalOutDetails.isEmpty()) { +// throw new ServiceException("原出库单明细不存在"); +// } +// +// // 4. 遍历退库明细,验证数量并执行退库 +// for (GearStockIoDetail returnDetail : returnDetails) { +// // 查找对应的原出库明细 +// GearStockIoDetail originalOutDetail = originalOutDetails.stream() +// .filter(detail -> detail.getItemType().equals(returnDetail.getItemType()) && +// detail.getItemId().equals(returnDetail.getItemId()) && +// detail.getWarehouseId().equals(returnDetail.getWarehouseId())) +// .findFirst() +// .orElse(null); +// +// if (originalOutDetail == null) { +// throw new ServiceException("未找到对应的原出库明细:" + returnDetail.getItemType() + "-" + returnDetail.getItemId()); +// } +// +// // 验证退库数量不能超过原出库数量 +// BigDecimal totalReturnedQty = baseMapper.selectList( +// Wrappers.lambdaQuery() +// .eq(GearStockIo::getParentId, returnStockIo.getParentId()) +// .eq(GearStockIo::getIoType, "withdraw") +// .ne(GearStockIo::getStockIoId, returnStockIo.getStockIoId()) +// ).stream() +// .flatMap(returnStockIoItem -> stockIoDetailMapper.selectList( +// Wrappers.lambdaQuery() +// .eq(GearStockIoDetail::getStockIoId, returnStockIoItem.getStockIoId()) +// .eq(GearStockIoDetail::getItemType, returnDetail.getItemType()) +// .eq(GearStockIoDetail::getItemId, returnDetail.getItemId()) +// .eq(GearStockIoDetail::getWarehouseId, returnDetail.getWarehouseId()) +// ).stream()) +// .map(GearStockIoDetail::getQuantity) +// .reduce(BigDecimal.ZERO, BigDecimal::add); +// +// BigDecimal remainingQty = originalOutDetail.getQuantity().subtract(totalReturnedQty); +// if (returnDetail.getQuantity().compareTo(remainingQty) > 0) { +// throw new ServiceException("退库数量超过原出库数量,物品:" + returnDetail.getItemType() + "-" + returnDetail.getItemId() + +// ",原出库数量:" + originalOutDetail.getQuantity() + ",已退库数量:" + totalReturnedQty + +// ",剩余可退数量:" + remainingQty + ",本次退库数量:" + returnDetail.getQuantity()); +// } +// +// // 执行退库操作(增加库存) +// String unit = returnDetail.getUnit(); +// if (unit == null || unit.trim().isEmpty()) { +// if ("product".equals(returnDetail.getItemType())) { +// GearProduct p = productMapper.selectById(returnDetail.getItemId()); +// unit = p != null ? p.getUnit() : "个"; +// } else if ("raw_material".equals(returnDetail.getItemType())) { +// GearRawMaterial r = rawMaterialMapper.selectById(returnDetail.getItemId()); +// unit = r != null ? r.getUnit() : "个"; +// } +// } +// +// // 执行入库操作(退库就是入库) +// changeStock(returnDetail.getWarehouseId(), returnDetail.getItemType(), +// returnDetail.getItemId(), returnDetail.getBatchNo(), returnDetail.getQuantity(), true, unit); +// } +// // 更新单据状态为已审核(2) +// returnStockIo.setStatus(2); +// return baseMapper.updateById(returnStockIo) > 0; +// } + + + /** + * 审核出入库/移库单,变更库存,含库存校验 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean auditStockIo(Long stockIoId) { + GearStockIo stockIo = baseMapper.selectById(stockIoId); + if (stockIo == null || stockIo.getStatus() == null || stockIo.getStatus() != 1) { + // 只允许审核“已提交”状态的单据 + throw new RuntimeException("单据不存在或状态不允许审核"); + } + List details = stockIoDetailMapper.selectList( + Wrappers.lambdaQuery().eq(GearStockIoDetail::getStockIoId, stockIoId) + ); + if (details == null || details.isEmpty()) { + throw new RuntimeException("单据明细不能为空"); + } + //如果details.batchNo不相等则需要去stock表新建一条批次号不同的记录 + for (GearStockIoDetail detail : details) { + String ioType = stockIo.getIoType(); + if ("in".equals(ioType)) { + // 入库:目标库位库存增加 + changeStock(detail.getWarehouseId(), detail.getItemType(), detail.getItemId(), detail.getBatchNo(), detail.getQuantity(), true, detail.getUnit()); + } else if ("out".equals(ioType)) { + // 出库:目标库位库存减少 + changeStock(detail.getWarehouseId(), detail.getItemType(), detail.getItemId(), detail.getBatchNo(), detail.getQuantity(), false, detail.getUnit()); + } else if ("transfer".equals(ioType)) { + // 移库:fromWarehouseId减少,warehouseId增加 + if (detail.getFromWarehouseId() == null) { + throw new RuntimeException("移库明细缺少源库位ID"); + } + // 先减少源库位 + changeStock(detail.getFromWarehouseId(), detail.getItemType(), detail.getItemId(), detail.getBatchNo(), detail.getQuantity(), false, detail.getUnit()); + // 再增加目标库位 + changeStock(detail.getWarehouseId(), detail.getItemType(), detail.getItemId(), detail.getBatchNo(), detail.getQuantity(), true, detail.getUnit()); + } else { + throw new RuntimeException("未知的出入库类型"); + } + } + // 更新单据状态为已审核(2) + stockIo.setStatus(2); + return baseMapper.updateById(stockIo) > 0; + } + + /** + * 撤销出入库/移库单,库存回滚 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean cancelStockIo(Long stockIoId) { + GearStockIo stockIo = baseMapper.selectById(stockIoId); + if (stockIo == null || stockIo.getStatus() == null || stockIo.getStatus() != 2) { + throw new ServiceException("只能撤销已审核的单据"); + } + List details = stockIoDetailMapper.selectList( + Wrappers.lambdaQuery().eq(GearStockIoDetail::getStockIoId, stockIoId) + ); + if (details == null || details.isEmpty()) { + throw new ServiceException("单据明细不能为空"); + } + for (GearStockIoDetail detail : details) { + String ioType = stockIo.getIoType(); + if ("in".equals(ioType)) { + // 入库撤销:目标库位库存减少 + changeStock(detail.getWarehouseId(), detail.getItemType(), detail.getItemId(), detail.getBatchNo(), detail.getQuantity(), false, detail.getUnit()); + } else if ("out".equals(ioType)) { + // 出库撤销:目标库位库存增加 + changeStock(detail.getWarehouseId(), detail.getItemType(), detail.getItemId(), detail.getBatchNo(), detail.getQuantity(), true, detail.getUnit()); + } else if ("transfer".equals(ioType)) { + if (detail.getFromWarehouseId() == null) { + throw new ServiceException("移库明细缺少源库位ID"); + } + // 源库位库存增加 + changeStock(detail.getFromWarehouseId(), detail.getItemType(), detail.getItemId(), detail.getBatchNo(), detail.getQuantity(), true, detail.getUnit()); + // 目标库位库存减少 + changeStock(detail.getWarehouseId(), detail.getItemType(), detail.getItemId(), detail.getBatchNo(), detail.getQuantity(), false, detail.getUnit()); + } else { + throw new ServiceException("未知的出入库类型"); + } + } + // 更新单据状态为待审核(1) + stockIo.setStatus(1); + baseMapper.updateById(stockIo); + return true; + } + + /** + * 根据ioType和stockIoId联查明细 + */ + @Override + public List detailByTypeAndId(String ioType, Long stockIoId) { + GearStockIo stockIo = baseMapper.selectById(stockIoId); + if (stockIo == null) { + throw new ServiceException("单据不存在"); + } + if (!ioType.equals(stockIo.getIoType())) { + throw new ServiceException("单据类型不匹配"); + } + List details = stockIoDetailMapper.selectList( + Wrappers.lambdaQuery().eq(GearStockIoDetail::getStockIoId, stockIoId) + ); + if (details == null || details.isEmpty()) { + return Collections.emptyList(); + } + // 转VO + List voList = new ArrayList<>(); + for (GearStockIoDetail detail : details) { + GearStockIoDetailVo vo = new GearStockIoDetailVo(); + BeanUtils.copyProperties(detail, vo); + voList.add(vo); + } + return voList; + } + + /** + * 更新出入库单状态 + */ + @Override + public Boolean updateStatus(Long stockIoId, Integer status) { + GearStockIo stockIo = baseMapper.selectById(stockIoId); + if (stockIo == null) { + throw new ServiceException("单据不存在"); + } + + // 状态流转验证 + if (stockIo.getStatus() == 0 && status == 1) { + // 草稿 -> 已提交:需要检查是否有明细 + List details = stockIoDetailMapper.selectList( + Wrappers.lambdaQuery().eq(GearStockIoDetail::getStockIoId, stockIoId) + ); + if (details == null || details.isEmpty()) { + throw new ServiceException("单据明细不能为空,无法提交"); + } + } else if (stockIo.getStatus() == 1 && status == 0) { + // 已提交 -> 草稿:允许回退 + } else { + throw new ServiceException("状态流转不允许"); + } + + stockIo.setStatus(status); + return baseMapper.updateById(stockIo) > 0; + } + + /** + * 库存增减,isAdd=true为增加,false为减少,减少时校验库存是否足够 + */ + private void changeStock(Long warehouseId, String itemType, Long itemId, BigDecimal quantity, boolean isAdd, String unit) { + changeStock(warehouseId, itemType, itemId, null, quantity, isAdd, unit); + } + + /** + * 库存增减(支持批次号),isAdd=true为增加,false为减少,减少时校验库存是否足够 + */ + private void changeStock(Long warehouseId, String itemType, Long itemId, String batchNo, BigDecimal quantity, boolean isAdd, String unit) { + GearStock stock = null; + + if (StringUtils.isNotBlank(batchNo)) { + // 如果指定了批次号,按批次号查找(应该是唯一的) + stock = stockMapper.selectOne(Wrappers.lambdaQuery() + .eq(GearStock::getWarehouseId, warehouseId) + .eq(GearStock::getItemType, itemType) + .eq(GearStock::getItemId, itemId) + .eq(GearStock::getBatchNo, batchNo)); + } else { + // 如果没有指定批次号,查找任意一个批次(按创建时间排序取第一个) + stock = stockMapper.selectOne(Wrappers.lambdaQuery() + .eq(GearStock::getWarehouseId, warehouseId) + .eq(GearStock::getItemType, itemType) + .eq(GearStock::getItemId, itemId) + .orderByAsc(GearStock::getCreateTime) + .last("limit 1")); + } + + if (stock == null) { + if (!isAdd) { + throw new RuntimeException("库存不足,无法出库/移库"); + } + // 新增库存记录 + stock = new GearStock(); + stock.setWarehouseId(warehouseId); + stock.setItemType(itemType); + stock.setItemId(itemId); + stock.setBatchNo(StringUtils.isNotBlank(batchNo) ? batchNo : "B-100"); + stock.setQuantity(quantity); + stock.setUnit(unit); + stockMapper.insert(stock); + } else { + // 更新现有库存 + BigDecimal newQty = isAdd ? stock.getQuantity().add(quantity) : stock.getQuantity().subtract(quantity); + if (newQty.compareTo(BigDecimal.ZERO) < 0) { + throw new RuntimeException("库存不足,无法出库/移库"); + } + stock.setQuantity(newQty); + stockMapper.updateById(stock); + } + // 记录库存变更日志 + GearStockLog log = new GearStockLog(); + log.setWarehouseId(warehouseId); + log.setItemType(itemType); + log.setItemId(itemId); + // 变动数量(正=入库,负=出库) + log.setChangeQty(isAdd ? quantity : quantity.negate()); + // 变动后的库存数量 + log.setAfterQty(stock.getQuantity()); + // 变动类型(入库/出库等) + log.setChangeType(isAdd ? "入库" : "出库"); + log.setChangeTime(new Date()); + log.setBatchNo(batchNo); + stockLogMapper.insert(log); + } +} diff --git a/gear-oa/src/main/java/com/gear/oa/service/impl/GearStockLogServiceImpl.java b/gear-oa/src/main/java/com/gear/oa/service/impl/GearStockLogServiceImpl.java new file mode 100644 index 0000000..33fab3d --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/service/impl/GearStockLogServiceImpl.java @@ -0,0 +1,183 @@ +package com.gear.oa.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.gear.common.core.domain.PageQuery; +import com.gear.common.core.page.TableDataInfo; +import com.gear.common.utils.StringUtils; +import com.gear.oa.domain.GearStockLog; +import com.gear.oa.domain.GearWarehouse; +import com.gear.oa.domain.bo.GearStockLogBo; +import com.gear.oa.domain.vo.GearStockLogVo; +import com.gear.oa.mapper.GearStockLogMapper; +import com.gear.oa.mapper.GearWarehouseMapper; +import com.gear.oa.service.IGearStockLogService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * 库存流水Service业务层处理 + * + * @author JR + * @date 2025-08-11 + */ +@RequiredArgsConstructor +@Service +public class GearStockLogServiceImpl implements IGearStockLogService { + + private final GearStockLogMapper baseMapper; + @Resource + private GearWarehouseMapper warehouseMapper; + + /** + * 查询库存流水 + */ + @Override + public GearStockLogVo queryById(Long id){ + return baseMapper.selectVoById(id); + } + + /** + * 查询库存流水列表 + */ + @Override + public TableDataInfo queryPageList(GearStockLogBo bo, PageQuery pageQuery) { + QueryWrapper lqw = buildQueryWrapperPlus(bo); + Page result = baseMapper.selectVoPagePlus(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询库存流水列表 + */ + @Override + public List queryList(GearStockLogBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private QueryWrapper buildQueryWrapperPlus(GearStockLogBo bo) { + QueryWrapper lqw = Wrappers.query(); + lqw.eq("sl.del_flag", 0); + // 处理仓库ID查询,支持递归查询子节点 + if (bo.getWarehouseId() != null) { + List warehouseIds = getWarehouseIdsWithChildren(bo.getWarehouseId()); + if (warehouseIds.size() == 1) { + lqw.eq("sl.warehouse_id", warehouseIds.get(0)); + } else { + lqw.in("sl.warehouse_id", warehouseIds); + } + } + lqw.eq(bo.getItemId() != null, "sl.item_id", bo.getItemId()); + lqw.eq(StringUtils.isNotBlank(bo.getItemType()), "sl.item_type", bo.getItemType()); + lqw.eq(bo.getChangeQty() != null, "sl.change_qty", bo.getChangeQty()); + lqw.eq(bo.getAfterQty() != null, "sl.after_qty", bo.getAfterQty()); + lqw.eq(StringUtils.isNotBlank(bo.getChangeType()), "sl.change_type", bo.getChangeType()); + // 根据时间区间查询 + lqw.ge(bo.getStartTime() != null, "sl.change_time", bo.getStartTime()); + lqw.le(bo.getEndTime() != null, "sl.change_time", bo.getEndTime()); + lqw.eq(StringUtils.isNotBlank(bo.getBatchNo()), "sl.batch_no", bo.getBatchNo()); + return lqw; + } + + private LambdaQueryWrapper buildQueryWrapper(GearStockLogBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(bo.getWarehouseId() != null, GearStockLog::getWarehouseId, bo.getWarehouseId()); + lqw.eq(bo.getItemId() != null, GearStockLog::getItemId, bo.getItemId()); + lqw.eq(StringUtils.isNotBlank(bo.getItemType()), GearStockLog::getItemType, bo.getItemType()); + lqw.eq(bo.getChangeQty() != null, GearStockLog::getChangeQty, bo.getChangeQty()); + lqw.eq(bo.getAfterQty() != null, GearStockLog::getAfterQty, bo.getAfterQty()); + lqw.eq(StringUtils.isNotBlank(bo.getChangeType()), GearStockLog::getChangeType, bo.getChangeType()); + lqw.eq(StringUtils.isNotBlank(bo.getBatchNo()), GearStockLog::getBatchNo, bo.getBatchNo()); + // 根据时间区间查询 + lqw.ge(bo.getStartTime() != null, GearStockLog::getChangeTime, bo.getStartTime()); + lqw.le(bo.getEndTime() != null, GearStockLog::getChangeTime, bo.getEndTime()); + return lqw; + } + + /** + * 新增库存流水 + */ + @Override + public Boolean insertByBo(GearStockLogBo bo) { + GearStockLog add = BeanUtil.toBean(bo, GearStockLog.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setId(add.getId()); + } + return flag; + } + + /** + * 修改库存流水 + */ + @Override + public Boolean updateByBo(GearStockLogBo bo) { + GearStockLog update = BeanUtil.toBean(bo, GearStockLog.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(GearStockLog entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 批量删除库存流水 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteBatchIds(ids) > 0; + } + + /** + * 获取指定仓库ID及其所有子仓库ID + * @param warehouseId 仓库ID + * @return 包含当前仓库ID和所有子仓库ID的列表 + */ + private List getWarehouseIdsWithChildren(Long warehouseId) { + List warehouseIds = new ArrayList<>(); + warehouseIds.add(warehouseId); // 添加当前仓库ID + + // 递归获取所有子仓库ID + getChildWarehouseIds(warehouseId, warehouseIds); + + return warehouseIds; + } + + /** + * 递归获取子仓库ID + * @param parentId 父仓库ID + * @param warehouseIds 仓库ID列表(用于收集结果) + */ + private void getChildWarehouseIds(Long parentId, List warehouseIds) { + // 查询直接子仓库 + List children = warehouseMapper.selectList( + Wrappers.lambdaQuery() + .eq(GearWarehouse::getParentId, parentId) + .eq(GearWarehouse::getDelFlag, 0) + ); + // 递归处理每个子仓库 + for (GearWarehouse child : children) { + warehouseIds.add(child.getWarehouseId()); + getChildWarehouseIds(child.getWarehouseId(), warehouseIds); + } + } +} diff --git a/gear-oa/src/main/java/com/gear/oa/service/impl/GearStockServiceImpl.java b/gear-oa/src/main/java/com/gear/oa/service/impl/GearStockServiceImpl.java new file mode 100644 index 0000000..ee6862a --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/service/impl/GearStockServiceImpl.java @@ -0,0 +1,220 @@ +package com.gear.oa.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.gear.common.core.domain.PageQuery; +import com.gear.common.core.page.TableDataInfo; +import com.gear.common.utils.StringUtils; +import com.gear.oa.domain.GearStock; +import com.gear.oa.domain.GearWarehouse; +import com.gear.oa.domain.bo.GearPurchasePlanDetailBo; +import com.gear.oa.domain.bo.GearStockBo; +import com.gear.oa.domain.vo.GearPurchasePlanDetailVo; +import com.gear.oa.domain.vo.GearStockVo; +import com.gear.oa.mapper.GearStockMapper; +import com.gear.oa.mapper.GearWarehouseMapper; +import com.gear.oa.service.IGearPurchasePlanDetailService; +import com.gear.oa.service.IGearStockService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * 库存:原材料/产品与库区/库位的存放关系Service业务层处理 + * + * @author Joshi + * @date 2025-07-18 + */ +@RequiredArgsConstructor +@Service +public class GearStockServiceImpl implements IGearStockService { + + private final GearStockMapper baseMapper; + private final GearWarehouseMapper warehouseMapper; +// private final IGearPurchasePlanDetailService purchasePlanDetailService; + + + /** + * 查询库存:原材料/产品与库区/库位的存放关系 + */ + @Override + public GearStockVo queryById(Long stockId){ + return baseMapper.selectVoById(stockId); + } + + /** + * 查询库存:原材料/产品与库区/库位的存放关系列表 + */ + @Override + public TableDataInfo queryPageList(GearStockBo bo, PageQuery pageQuery) { + QueryWrapper lqw = buildQueryWrapperPlus(bo); + Page result = baseMapper.selectVoPagePlus(pageQuery.build(), lqw); +// fillDemandInfo(result.getRecords()); + return TableDataInfo.build(result); + } + +// /** +// * 填充原材料在途信息 +// */ +// private void fillDemandInfo(List rawMaterialList) { +// if (rawMaterialList == null || rawMaterialList.isEmpty()) { +// return; +// } +// // 为每个原材料填充信息 +// for (GearStockVo vo : rawMaterialList) { +// Long rawMaterialId = vo.getItemId(); +// // 查询在途量(采购计划明细) +// BigDecimal onTheWay = getOnTheWayQuantity(rawMaterialId); +// vo.setOnTheWay(onTheWay); +// } +// } + +// /** +// * 获取在途量 +// */ +// private BigDecimal getOnTheWayQuantity(Long rawMaterialId) { +// GearPurchasePlanDetailBo bo = new GearPurchasePlanDetailBo(); +// bo.setRawMaterialId(rawMaterialId); +// List list = purchasePlanDetailService.queryList(bo); +// return list.stream() +// .filter(item -> item.getStatus() != null && item.getStatus() == 1) // 在途状态 +// .map(GearPurchasePlanDetailVo::getQuantity) +// .filter(qty -> qty != null) +// .reduce(BigDecimal.ZERO, BigDecimal::add); +// } + + /** + * 查询库存:原材料/产品与库区/库位的存放关系列表 + */ + @Override + public List queryList(GearStockBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + private LambdaQueryWrapper buildQueryWrapper(GearStockBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.eq(StringUtils.isNotBlank(bo.getItemType()), GearStock::getItemType, bo.getItemType()); + lqw.eq(bo.getItemId() != null, GearStock::getItemId, bo.getItemId()); + lqw.eq(bo.getQuantity() != null, GearStock::getQuantity, bo.getQuantity()); + lqw.eq(StringUtils.isNotBlank(bo.getUnit()), GearStock::getUnit, bo.getUnit()); + lqw.eq(StringUtils.isNotBlank(bo.getBatchNo()), GearStock::getBatchNo, bo.getBatchNo()); + return lqw; + } + + private QueryWrapper buildQueryWrapperPlus(GearStockBo bo) { // 注意:这里改用 QueryWrapper 而非 LambdaQueryWrapper + Map params = bo.getParams(); + QueryWrapper qw = Wrappers.query(); // 使用普通 QueryWrapper + qw.eq("s.del_flag", 0); // 手动添加逻辑删除条件 + + // 处理仓库ID查询,支持递归查询子节点 + if (bo.getWarehouseId() != null) { + List warehouseIds = getWarehouseIdsWithChildren(bo.getWarehouseId()); + if (warehouseIds.size() == 1) { + qw.eq("s.warehouse_id", warehouseIds.get(0)); + } else { + qw.in("s.warehouse_id", warehouseIds); + } + } + + qw.eq(StringUtils.isNotBlank(bo.getItemType()), "s.item_type", bo.getItemType()); + qw.eq(bo.getItemId() != null, "s.item_id", bo.getItemId()); + qw.eq(bo.getQuantity() != null, "s.quantity", bo.getQuantity()); + qw.eq(StringUtils.isNotBlank(bo.getUnit()), "s.unit", bo.getUnit()); + qw.eq(StringUtils.isNotBlank(bo.getBatchNo()), "s.batch_no", bo.getBatchNo()); + + return qw; + } + + /** + * 新增库存:原材料/产品与库区/库位的存放关系 + */ + @Override + public Boolean insertByBo(GearStockBo bo) { + GearStock add = BeanUtil.toBean(bo, GearStock.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setStockId(add.getStockId()); + } + return flag; + } + + /** + * 修改库存:原材料/产品与库区/库位的存放关系 + */ + @Override + public Boolean updateByBo(GearStockBo bo) { + GearStock update = BeanUtil.toBean(bo, GearStock.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(GearStock entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 批量删除库存:原材料/产品与库区/库位的存放关系 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteBatchIds(ids) > 0; + } + +// @Override +// public BigDecimal getStockByItemId(Long rawMaterialId) { +// return baseMapper.getStockByItemId(rawMaterialId); +// } + + + + /** + * 获取指定仓库ID及其所有子仓库ID + * @param warehouseId 仓库ID + * @return 包含当前仓库ID和所有子仓库ID的列表 + */ + private List getWarehouseIdsWithChildren(Long warehouseId) { + List warehouseIds = new ArrayList<>(); + warehouseIds.add(warehouseId); // 添加当前仓库ID + + // 递归获取所有子仓库ID + getChildWarehouseIds(warehouseId, warehouseIds); + + return warehouseIds; + } + + /** + * 递归获取子仓库ID + * @param parentId 父仓库ID + * @param warehouseIds 仓库ID列表(用于收集结果) + */ + private void getChildWarehouseIds(Long parentId, List warehouseIds) { + // 查询直接子仓库 + List children = warehouseMapper.selectList( + Wrappers.lambdaQuery() + .eq(GearWarehouse::getParentId, parentId) + .eq(GearWarehouse::getDelFlag, 0) + ); + + // 递归处理每个子仓库 + for (GearWarehouse child : children) { + warehouseIds.add(child.getWarehouseId()); + getChildWarehouseIds(child.getWarehouseId(), warehouseIds); + } + } +} diff --git a/gear-oa/src/main/java/com/gear/oa/service/impl/GearWarehouseServiceImpl.java b/gear-oa/src/main/java/com/gear/oa/service/impl/GearWarehouseServiceImpl.java new file mode 100644 index 0000000..d7412ed --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/service/impl/GearWarehouseServiceImpl.java @@ -0,0 +1,104 @@ +package com.gear.oa.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.gear.common.utils.StringUtils; +import com.gear.oa.domain.GearWarehouse; +import com.gear.oa.domain.bo.GearWarehouseBo; +import com.gear.oa.domain.vo.GearWarehouseVo; +import com.gear.oa.mapper.GearWarehouseMapper; +import com.gear.oa.service.IGearWarehouseService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * 仓库/库区/库位自关联Service业务层处理 + * + * @author JR + * @date 2025-07-18 + */ +@RequiredArgsConstructor +@Service +public class GearWarehouseServiceImpl implements IGearWarehouseService { + + private final GearWarehouseMapper baseMapper; + + /** + * 查询仓库/库区/库位自关联 + */ + @Override + public GearWarehouseVo queryById(Long warehouseId){ + return baseMapper.selectVoById(warehouseId); + } + + + /** + * 查询仓库/库区/库位自关联列表 + */ + @Override + public List queryList(GearWarehouseBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(GearWarehouseBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(bo.getParentId() != null, GearWarehouse::getParentId, bo.getParentId()); + lqw.eq(StringUtils.isNotBlank(bo.getWarehouseCode()), GearWarehouse::getWarehouseCode, bo.getWarehouseCode()); + lqw.like(StringUtils.isNotBlank(bo.getWarehouseName()), GearWarehouse::getWarehouseName, bo.getWarehouseName()); + lqw.eq(bo.getWarehouseType() != null, GearWarehouse::getWarehouseType, bo.getWarehouseType()); + lqw.eq(bo.getSortNo() != null, GearWarehouse::getSortNo, bo.getSortNo()); + lqw.eq(bo.getIsEnabled() != null, GearWarehouse::getIsEnabled, bo.getIsEnabled()); + // 新增排序(SortNo升序) + lqw.orderByAsc(GearWarehouse::getSortNo); + return lqw; + } + + /** + * 新增仓库/库区/库位自关联 + */ + @Override + public Boolean insertByBo(GearWarehouseBo bo) { + GearWarehouse add = BeanUtil.toBean(bo, GearWarehouse.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setWarehouseId(add.getWarehouseId()); + } + return flag; + } + + /** + * 修改仓库/库区/库位自关联 + */ + @Override + public Boolean updateByBo(GearWarehouseBo bo) { + GearWarehouse update = BeanUtil.toBean(bo, GearWarehouse.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(GearWarehouse entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 批量删除仓库/库区/库位自关联 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteBatchIds(ids) > 0; + } +} diff --git a/gear-oa/src/main/java/com/gear/oa/service/impl/OaExpressServiceImpl.java b/gear-oa/src/main/java/com/gear/oa/service/impl/OaExpressServiceImpl.java index 9766e90..32605fb 100644 --- a/gear-oa/src/main/java/com/gear/oa/service/impl/OaExpressServiceImpl.java +++ b/gear-oa/src/main/java/com/gear/oa/service/impl/OaExpressServiceImpl.java @@ -213,8 +213,8 @@ public class OaExpressServiceImpl implements IOaExpressService { } if (expressType.equals("YD") && oaExpressVo.getStatus() == 1L) { // 韵达快递轨迹查询 - String result = com.gear.oa.utils.YdRouteQueryUtil.queryRoute(oaExpressVo.getExpressCode()); - OaExpressVo ydVo = YdRouteQueryUtil.parseData(result); + String result =YdRouteQueryUtil.queryRoute(oaExpressVo.getExpressCode()); + OaExpressVo ydVo =YdRouteQueryUtil.parseData(result); if (ydVo != null) { oaExpressVo.setLastUpdateTime(ydVo.getLastUpdateTime()); oaExpressVo.setLastStatus(ydVo.getLastStatus()); @@ -222,7 +222,7 @@ public class OaExpressServiceImpl implements IOaExpressService { } if (expressType.equals("YT") && oaExpressVo.getStatus() == 1L) { // 圆通快递轨迹查询 - String result = com.gear.oa.utils.YtRouteQueryUtil.queryRoute(oaExpressVo.getExpressCode()); + String result = YtRouteQueryUtil.queryRoute(oaExpressVo.getExpressCode()); OaExpressVo ytVo = YtRouteQueryUtil.parseData(result); if (ytVo != null) { oaExpressVo.setLastUpdateTime(ytVo.getLastUpdateTime()); diff --git a/gear-oa/src/main/resources/mapper/oa/GearStockIoDetailMapper.xml b/gear-oa/src/main/resources/mapper/oa/GearStockIoDetailMapper.xml new file mode 100644 index 0000000..78c0bda --- /dev/null +++ b/gear-oa/src/main/resources/mapper/oa/GearStockIoDetailMapper.xml @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gear-oa/src/main/resources/mapper/oa/GearStockIoMapper.xml b/gear-oa/src/main/resources/mapper/oa/GearStockIoMapper.xml new file mode 100644 index 0000000..50e73d8 --- /dev/null +++ b/gear-oa/src/main/resources/mapper/oa/GearStockIoMapper.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/gear-oa/src/main/resources/mapper/oa/GearStockLogMapper.xml b/gear-oa/src/main/resources/mapper/oa/GearStockLogMapper.xml new file mode 100644 index 0000000..e4280e2 --- /dev/null +++ b/gear-oa/src/main/resources/mapper/oa/GearStockLogMapper.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gear-oa/src/main/resources/mapper/oa/GearStockMapper.xml b/gear-oa/src/main/resources/mapper/oa/GearStockMapper.xml new file mode 100644 index 0000000..368c171 --- /dev/null +++ b/gear-oa/src/main/resources/mapper/oa/GearStockMapper.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gear-oa/src/main/resources/mapper/oa/GearWarehouseMapper.xml b/gear-oa/src/main/resources/mapper/oa/GearWarehouseMapper.xml new file mode 100644 index 0000000..a9d84c3 --- /dev/null +++ b/gear-oa/src/main/resources/mapper/oa/GearWarehouseMapper.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + +