From 45f44d8adafe447231a6e8e51bf8cb8d487a2ec3 Mon Sep 17 00:00:00 2001 From: Joshi <3040996759@qq.com> Date: Tue, 19 Aug 2025 13:53:30 +0800 Subject: [PATCH] =?UTF-8?q?feat(oa):=20=E6=96=B0=E5=A2=9E=20BOM=20?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E3=80=81=E4=BA=A7=E5=93=81=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E5=92=8C=E5=88=86=E7=B1=BB=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加 BOM 头和 BOM 明细相关实体、控制器、服务和 Mapper - 实现 BOM 头和 BOM 明细的增删查改功能 - 添加产品和产品分类相关实体、控制器、服务和 Mapper - 实现产品和产品分类的增删查改功能- 为所有新增功能添加相应的 Excel 导出功能 --- .../gear/oa/controller/GearBomController.java | 102 ++++++++ .../oa/controller/GearBomItemController.java | 102 ++++++++ .../GearProductCategoryController.java | 102 ++++++++ .../oa/controller/GearProductController.java | 112 +++++++++ .../main/java/com/gear/oa/domain/GearBom.java | 52 ++++ .../java/com/gear/oa/domain/GearBomItem.java | 56 +++++ .../java/com/gear/oa/domain/GearProduct.java | 71 ++++++ .../gear/oa/domain/GearProductCategory.java | 52 ++++ .../java/com/gear/oa/domain/bo/GearBomBo.java | 50 ++++ .../com/gear/oa/domain/bo/GearBomItemBo.java | 55 +++++ .../com/gear/oa/domain/bo/GearProductBo.java | 75 ++++++ .../oa/domain/bo/GearProductCategoryBo.java | 50 ++++ .../com/gear/oa/domain/vo/GearBomItemVo.java | 62 +++++ .../java/com/gear/oa/domain/vo/GearBomVo.java | 58 +++++ .../oa/domain/vo/GearProductCategoryVo.java | 65 +++++ .../com/gear/oa/domain/vo/GearProductVo.java | 85 +++++++ .../dashboard/MaterialRecommendationVO.java | 54 +++++ .../vo/dashboard/OrderCountStatisticsVO.java | 43 ++++ .../dashboard/OrderProductStatisticsVO.java | 43 ++++ .../vo/dashboard/OrderRecommendationVO.java | 49 ++++ .../vo/dashboard/ProductDashboardVO.java | 54 +++++ .../ProductMaterialRequirementVO.java | 53 ++++ .../dashboard/ProductSalesPerformanceVO.java | 43 ++++ .../vo/dashboard/RawMaterialInventoryVO.java | 53 ++++ .../dashboard/SalesPersonPerformanceVO.java | 38 +++ .../com/gear/oa/mapper/GearBomItemMapper.java | 15 ++ .../com/gear/oa/mapper/GearBomMapper.java | 15 ++ .../oa/mapper/GearProductCategoryMapper.java | 15 ++ .../com/gear/oa/mapper/GearProductMapper.java | 205 ++++++++++++++++ .../gear/oa/service/IGearBomItemService.java | 49 ++++ .../com/gear/oa/service/IGearBomService.java | 49 ++++ .../service/IGearProductCategoryService.java | 43 ++++ .../gear/oa/service/IGearProductService.java | 94 ++++++++ .../service/impl/GearBomItemServiceImpl.java | 112 +++++++++ .../oa/service/impl/GearBomServiceImpl.java | 111 +++++++++ .../impl/GearProductCategoryServiceImpl.java | 101 ++++++++ .../service/impl/GearProductServiceImpl.java | 228 ++++++++++++++++++ .../resources/mapper/oa/GearBomItemMapper.xml | 22 ++ .../resources/mapper/oa/GearBomMapper.xml | 21 ++ .../mapper/oa/GearProductCategoryMapper.xml | 22 ++ .../resources/mapper/oa/GearProductMapper.xml | 49 ++++ 41 files changed, 2730 insertions(+) create mode 100644 gear-oa/src/main/java/com/gear/oa/controller/GearBomController.java create mode 100644 gear-oa/src/main/java/com/gear/oa/controller/GearBomItemController.java create mode 100644 gear-oa/src/main/java/com/gear/oa/controller/GearProductCategoryController.java create mode 100644 gear-oa/src/main/java/com/gear/oa/controller/GearProductController.java create mode 100644 gear-oa/src/main/java/com/gear/oa/domain/GearBom.java create mode 100644 gear-oa/src/main/java/com/gear/oa/domain/GearBomItem.java create mode 100644 gear-oa/src/main/java/com/gear/oa/domain/GearProduct.java create mode 100644 gear-oa/src/main/java/com/gear/oa/domain/GearProductCategory.java create mode 100644 gear-oa/src/main/java/com/gear/oa/domain/bo/GearBomBo.java create mode 100644 gear-oa/src/main/java/com/gear/oa/domain/bo/GearBomItemBo.java create mode 100644 gear-oa/src/main/java/com/gear/oa/domain/bo/GearProductBo.java create mode 100644 gear-oa/src/main/java/com/gear/oa/domain/bo/GearProductCategoryBo.java create mode 100644 gear-oa/src/main/java/com/gear/oa/domain/vo/GearBomItemVo.java create mode 100644 gear-oa/src/main/java/com/gear/oa/domain/vo/GearBomVo.java create mode 100644 gear-oa/src/main/java/com/gear/oa/domain/vo/GearProductCategoryVo.java create mode 100644 gear-oa/src/main/java/com/gear/oa/domain/vo/GearProductVo.java create mode 100644 gear-oa/src/main/java/com/gear/oa/domain/vo/dashboard/MaterialRecommendationVO.java create mode 100644 gear-oa/src/main/java/com/gear/oa/domain/vo/dashboard/OrderCountStatisticsVO.java create mode 100644 gear-oa/src/main/java/com/gear/oa/domain/vo/dashboard/OrderProductStatisticsVO.java create mode 100644 gear-oa/src/main/java/com/gear/oa/domain/vo/dashboard/OrderRecommendationVO.java create mode 100644 gear-oa/src/main/java/com/gear/oa/domain/vo/dashboard/ProductDashboardVO.java create mode 100644 gear-oa/src/main/java/com/gear/oa/domain/vo/dashboard/ProductMaterialRequirementVO.java create mode 100644 gear-oa/src/main/java/com/gear/oa/domain/vo/dashboard/ProductSalesPerformanceVO.java create mode 100644 gear-oa/src/main/java/com/gear/oa/domain/vo/dashboard/RawMaterialInventoryVO.java create mode 100644 gear-oa/src/main/java/com/gear/oa/domain/vo/dashboard/SalesPersonPerformanceVO.java create mode 100644 gear-oa/src/main/java/com/gear/oa/mapper/GearBomItemMapper.java create mode 100644 gear-oa/src/main/java/com/gear/oa/mapper/GearBomMapper.java create mode 100644 gear-oa/src/main/java/com/gear/oa/mapper/GearProductCategoryMapper.java create mode 100644 gear-oa/src/main/java/com/gear/oa/mapper/GearProductMapper.java create mode 100644 gear-oa/src/main/java/com/gear/oa/service/IGearBomItemService.java create mode 100644 gear-oa/src/main/java/com/gear/oa/service/IGearBomService.java create mode 100644 gear-oa/src/main/java/com/gear/oa/service/IGearProductCategoryService.java create mode 100644 gear-oa/src/main/java/com/gear/oa/service/IGearProductService.java create mode 100644 gear-oa/src/main/java/com/gear/oa/service/impl/GearBomItemServiceImpl.java create mode 100644 gear-oa/src/main/java/com/gear/oa/service/impl/GearBomServiceImpl.java create mode 100644 gear-oa/src/main/java/com/gear/oa/service/impl/GearProductCategoryServiceImpl.java create mode 100644 gear-oa/src/main/java/com/gear/oa/service/impl/GearProductServiceImpl.java create mode 100644 gear-oa/src/main/resources/mapper/oa/GearBomItemMapper.xml create mode 100644 gear-oa/src/main/resources/mapper/oa/GearBomMapper.xml create mode 100644 gear-oa/src/main/resources/mapper/oa/GearProductCategoryMapper.xml create mode 100644 gear-oa/src/main/resources/mapper/oa/GearProductMapper.xml diff --git a/gear-oa/src/main/java/com/gear/oa/controller/GearBomController.java b/gear-oa/src/main/java/com/gear/oa/controller/GearBomController.java new file mode 100644 index 0000000..32db00d --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/controller/GearBomController.java @@ -0,0 +1,102 @@ +package com.gear.oa.controller; + +import java.util.List; +import java.util.Arrays; +import java.util.concurrent.TimeUnit; + +import lombok.RequiredArgsConstructor; +import javax.servlet.http.HttpServletResponse; +import javax.validation.constraints.*; +import cn.dev33.satoken.annotation.SaCheckPermission; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +import com.gear.common.annotation.RepeatSubmit; +import com.gear.common.annotation.Log; +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.validate.AddGroup; +import com.gear.common.core.validate.EditGroup; +import com.gear.common.core.validate.QueryGroup; +import com.gear.common.enums.BusinessType; +import com.gear.common.utils.poi.ExcelUtil; +import com.gear.oa.domain.vo.GearBomVo; +import com.gear.oa.domain.bo.GearBomBo; +import com.gear.oa.service.IGearBomService; +import com.gear.common.core.page.TableDataInfo; + +/** + * BOM 头,关联产品或原材料 + * + * @author Joshi + * @date 2025-08-19 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/oa/bom") +public class GearBomController extends BaseController { + + private final IGearBomService iGearBomService; + + /** + * 查询BOM 头,关联产品或原材料列表 + */ + @GetMapping("/list") + public TableDataInfo list(GearBomBo bo, PageQuery pageQuery) { + return iGearBomService.queryPageList(bo, pageQuery); + } + + /** + * 导出BOM 头,关联产品或原材料列表 + */ + @Log(title = "BOM 头,关联产品或原材料", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(GearBomBo bo, HttpServletResponse response) { + List list = iGearBomService.queryList(bo); + ExcelUtil.exportExcel(list, "BOM 头,关联产品或原材料", GearBomVo.class, response); + } + + /** + * 获取BOM 头,关联产品或原材料详细信息 + * + * @param bomId 主键 + */ + @GetMapping("/{bomId}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long bomId) { + return R.ok(iGearBomService.queryById(bomId)); + } + + /** + * 新增BOM 头,关联产品或原材料 + */ + @Log(title = "BOM 头,关联产品或原材料", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody GearBomBo bo) { + return toAjax(iGearBomService.insertByBo(bo)); + } + + /** + * 修改BOM 头,关联产品或原材料 + */ + @Log(title = "BOM 头,关联产品或原材料", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody GearBomBo bo) { + return toAjax(iGearBomService.updateByBo(bo)); + } + + /** + * 删除BOM 头,关联产品或原材料 + * + * @param bomIds 主键串 + */ + @Log(title = "BOM 头,关联产品或原材料", businessType = BusinessType.DELETE) + @DeleteMapping("/{bomIds}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] bomIds) { + return toAjax(iGearBomService.deleteWithValidByIds(Arrays.asList(bomIds), true)); + } +} diff --git a/gear-oa/src/main/java/com/gear/oa/controller/GearBomItemController.java b/gear-oa/src/main/java/com/gear/oa/controller/GearBomItemController.java new file mode 100644 index 0000000..d255d34 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/controller/GearBomItemController.java @@ -0,0 +1,102 @@ +package com.gear.oa.controller; + +import java.util.List; +import java.util.Arrays; +import java.util.concurrent.TimeUnit; + +import lombok.RequiredArgsConstructor; +import javax.servlet.http.HttpServletResponse; +import javax.validation.constraints.*; +import cn.dev33.satoken.annotation.SaCheckPermission; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +import com.gear.common.annotation.RepeatSubmit; +import com.gear.common.annotation.Log; +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.validate.AddGroup; +import com.gear.common.core.validate.EditGroup; +import com.gear.common.core.validate.QueryGroup; +import com.gear.common.enums.BusinessType; +import com.gear.common.utils.poi.ExcelUtil; +import com.gear.oa.domain.vo.GearBomItemVo; +import com.gear.oa.domain.bo.GearBomItemBo; +import com.gear.oa.service.IGearBomItemService; +import com.gear.common.core.page.TableDataInfo; + +/** + * BOM 明细,存放属性–值 + * + * @author Joshi + * @date 2025-08-19 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/oa/bomItem") +public class GearBomItemController extends BaseController { + + private final IGearBomItemService iGearBomItemService; + + /** + * 查询BOM 明细,存放属性–值列表 + */ + @GetMapping("/list") + public TableDataInfo list(GearBomItemBo bo, PageQuery pageQuery) { + return iGearBomItemService.queryPageList(bo, pageQuery); + } + + /** + * 导出BOM 明细,存放属性–值列表 + */ + @Log(title = "BOM 明细,存放属性–值", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(GearBomItemBo bo, HttpServletResponse response) { + List list = iGearBomItemService.queryList(bo); + ExcelUtil.exportExcel(list, "BOM 明细,存放属性–值", GearBomItemVo.class, response); + } + + /** + * 获取BOM 明细,存放属性–值详细信息 + * + * @param itemId 主键 + */ + @GetMapping("/{itemId}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long itemId) { + return R.ok(iGearBomItemService.queryById(itemId)); + } + + /** + * 新增BOM 明细,存放属性–值 + */ + @Log(title = "BOM 明细,存放属性–值", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody GearBomItemBo bo) { + return toAjax(iGearBomItemService.insertByBo(bo)); + } + + /** + * 修改BOM 明细,存放属性–值 + */ + @Log(title = "BOM 明细,存放属性–值", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody GearBomItemBo bo) { + return toAjax(iGearBomItemService.updateByBo(bo)); + } + + /** + * 删除BOM 明细,存放属性–值 + * + * @param itemIds 主键串 + */ + @Log(title = "BOM 明细,存放属性–值", businessType = BusinessType.DELETE) + @DeleteMapping("/{itemIds}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] itemIds) { + return toAjax(iGearBomItemService.deleteWithValidByIds(Arrays.asList(itemIds), true)); + } +} diff --git a/gear-oa/src/main/java/com/gear/oa/controller/GearProductCategoryController.java b/gear-oa/src/main/java/com/gear/oa/controller/GearProductCategoryController.java new file mode 100644 index 0000000..73da308 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/controller/GearProductCategoryController.java @@ -0,0 +1,102 @@ +package com.gear.oa.controller; + +import java.util.List; +import java.util.Arrays; +import java.util.concurrent.TimeUnit; + +import lombok.RequiredArgsConstructor; +import javax.servlet.http.HttpServletResponse; +import javax.validation.constraints.*; +import cn.dev33.satoken.annotation.SaCheckPermission; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +import com.gear.common.annotation.RepeatSubmit; +import com.gear.common.annotation.Log; +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.validate.AddGroup; +import com.gear.common.core.validate.EditGroup; +import com.gear.common.core.validate.QueryGroup; +import com.gear.common.enums.BusinessType; +import com.gear.common.utils.poi.ExcelUtil; +import com.gear.oa.domain.vo.GearProductCategoryVo; +import com.gear.oa.domain.bo.GearProductCategoryBo; +import com.gear.oa.service.IGearProductCategoryService; + +/** + * 产品分类树 + * + * @author Joshi + * @date 2025-08-19 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/oa/productCategory") +public class GearProductCategoryController extends BaseController { + + private final IGearProductCategoryService iGearProductCategoryService; + + /** + * 查询产品分类树列表 + */ + @GetMapping("/list") + public R> list(GearProductCategoryBo bo) { + List list = iGearProductCategoryService.queryList(bo); + return R.ok(list); + } + + /** + * 导出产品分类树列表 + */ + @Log(title = "产品分类树", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(GearProductCategoryBo bo, HttpServletResponse response) { + List list = iGearProductCategoryService.queryList(bo); + ExcelUtil.exportExcel(list, "产品分类树", GearProductCategoryVo.class, response); + } + + /** + * 获取产品分类树详细信息 + * + * @param categoryId 主键 + */ + @GetMapping("/{categoryId}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long categoryId) { + return R.ok(iGearProductCategoryService.queryById(categoryId)); + } + + /** + * 新增产品分类树 + */ + @Log(title = "产品分类树", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody GearProductCategoryBo bo) { + return toAjax(iGearProductCategoryService.insertByBo(bo)); + } + + /** + * 修改产品分类树 + */ + @Log(title = "产品分类树", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody GearProductCategoryBo bo) { + return toAjax(iGearProductCategoryService.updateByBo(bo)); + } + + /** + * 删除产品分类树 + * + * @param categoryIds 主键串 + */ + @Log(title = "产品分类树", businessType = BusinessType.DELETE) + @DeleteMapping("/{categoryIds}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] categoryIds) { + return toAjax(iGearProductCategoryService.deleteWithValidByIds(Arrays.asList(categoryIds), true)); + } +} diff --git a/gear-oa/src/main/java/com/gear/oa/controller/GearProductController.java b/gear-oa/src/main/java/com/gear/oa/controller/GearProductController.java new file mode 100644 index 0000000..be03b98 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/controller/GearProductController.java @@ -0,0 +1,112 @@ +package com.gear.oa.controller; + +import java.util.List; +import java.util.Arrays; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import lombok.RequiredArgsConstructor; +import javax.servlet.http.HttpServletResponse; +import javax.validation.constraints.*; +import cn.dev33.satoken.annotation.SaCheckPermission; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +import com.gear.common.annotation.RepeatSubmit; +import com.gear.common.annotation.Log; +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.validate.AddGroup; +import com.gear.common.core.validate.EditGroup; +import com.gear.common.core.validate.QueryGroup; +import com.gear.common.enums.BusinessType; +import com.gear.common.utils.poi.ExcelUtil; +import com.gear.oa.domain.vo.GearProductVo; +import com.gear.oa.domain.bo.GearProductBo; +import com.gear.oa.domain.vo.dashboard.*; +import com.gear.oa.service.IGearProductService; +import com.gear.common.core.page.TableDataInfo; + +/** + * 产品 + * + * @author Joshi + * @date 2025-08-19 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/oa/product") +public class GearProductController extends BaseController { + + private final IGearProductService iGearProductService; + + /** + * 查询产品列表 + */ + @GetMapping("/list") + public TableDataInfo list(GearProductBo bo, PageQuery pageQuery) { + return iGearProductService.queryPageList(bo, pageQuery); + } + + /** + * 导出产品列表 + */ + @Log(title = "产品", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(GearProductBo bo, HttpServletResponse response) { + List list = iGearProductService.queryList(bo); + ExcelUtil.exportExcel(list, "产品", GearProductVo.class, response); + } + + /** + * 获取产品详细信息 + * + * @param productId 主键 + */ + @GetMapping("/{productId}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long productId) { + return R.ok(iGearProductService.queryById(productId)); + } + + /** + * 新增产品 + */ + @Log(title = "产品", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody GearProductBo bo) { + return toAjax(iGearProductService.insertByBo(bo)); + } + + /** + * 修改产品 + */ + @Log(title = "产品", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody GearProductBo bo) { + return toAjax(iGearProductService.updateByBo(bo)); + } + + /** + * 删除产品 + * + * @param productIds 主键串 + */ + @Log(title = "产品", businessType = BusinessType.DELETE) + @DeleteMapping("/{productIds}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] productIds) { + return toAjax(iGearProductService.deleteWithValidByIds(Arrays.asList(productIds), true)); + } + +// /** +// * 数据看板 - 获取所有数据 +// */ +// @GetMapping("/dashboard") +// public R getDashboard() { +// return R.ok(iGearProductService.getDashboard()); +// } +} diff --git a/gear-oa/src/main/java/com/gear/oa/domain/GearBom.java b/gear-oa/src/main/java/com/gear/oa/domain/GearBom.java new file mode 100644 index 0000000..4a3bccc --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/GearBom.java @@ -0,0 +1,52 @@ +package com.gear.oa.domain; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; +import java.io.Serializable; +import java.util.Date; +import java.math.BigDecimal; + +import com.gear.common.core.domain.BaseEntity; + +/** + * BOM 头,关联产品或原材料对象 gear_bom + * + * @author Joshi + * @date 2025-08-19 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("gear_bom") +public class GearBom extends BaseEntity { + + private static final long serialVersionUID=1L; + + /** + * BOM 主键ID + */ + @TableId(value = "bom_id") + private Long bomId; + /** + * BOM 编码(可选) + */ + private String bomCode; + /** + * BOM 名称(可选) + */ + private String bomName; + /** + * 是否启用(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/GearBomItem.java b/gear-oa/src/main/java/com/gear/oa/domain/GearBomItem.java new file mode 100644 index 0000000..c72eeb9 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/GearBomItem.java @@ -0,0 +1,56 @@ +package com.gear.oa.domain; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; +import java.io.Serializable; +import java.util.Date; +import java.math.BigDecimal; + +import com.gear.common.core.domain.BaseEntity; + +/** + * BOM 明细,存放属性–值对象 gear_bom_item + * + * @author Joshi + * @date 2025-08-19 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("gear_bom_item") +public class GearBomItem extends BaseEntity { + + private static final long serialVersionUID=1L; + + /** + * BOM 明细ID + */ + @TableId(value = "item_id") + private Long itemId; + /** + * 关联 wms_bom.bom_id + */ + private Long bomId; + /** + * 属性名称 + */ + private String attrKey; + /** + * 属性值 + */ + private String attrValue; + /** + * 是否启用(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/GearProduct.java b/gear-oa/src/main/java/com/gear/oa/domain/GearProduct.java new file mode 100644 index 0000000..26325f9 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/GearProduct.java @@ -0,0 +1,71 @@ +package com.gear.oa.domain; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; +import java.io.Serializable; +import java.util.Date; +import java.math.BigDecimal; + +import com.gear.common.core.domain.BaseEntity; + +/** + * 产品对象 gear_product + * + * @author Joshi + * @date 2025-08-19 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("gear_product") +public class GearProduct extends BaseEntity { + + private static final long serialVersionUID=1L; + + /** + * 主键ID + */ + @TableId(value = "product_id") + private Long productId; + /** + * 产品编号 + */ + private String productCode; + /** + * 产品名称 + */ + private String productName; + /** + * 负责人 + */ + private String owner; + /** + * 单位 + */ + private String unit; + /** + * BOM 表头ID + */ + private Long bomId; + /** + * 产品类型(product=产品,semi=半成品,raw=原料) + */ + private String type; + /** + * 是否启用(0=否,1=是) + */ + private Integer isEnabled; + /** + * 删除标志(0=正常,1=已删除) + */ + @TableLogic + private Integer delFlag; + /** + * 备注 + */ + private String remark; + + //分类id + private Long categoryId; + +} diff --git a/gear-oa/src/main/java/com/gear/oa/domain/GearProductCategory.java b/gear-oa/src/main/java/com/gear/oa/domain/GearProductCategory.java new file mode 100644 index 0000000..5d63853 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/GearProductCategory.java @@ -0,0 +1,52 @@ +package com.gear.oa.domain; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; +import java.io.Serializable; +import java.util.Date; +import java.math.BigDecimal; + +import com.gear.common.core.domain.TreeEntity; + +/** + * 产品分类树对象 gear_product_category + * + * @author Joshi + * @date 2025-08-19 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("gear_product_category") +public class GearProductCategory extends TreeEntity { + + private static final long serialVersionUID=1L; + + /** + * 树节点唯一标识(根节点用固定值) + */ + @TableId(value = "category_id") + private Long categoryId; + /** + * 节点名称(根节点为类型名,产品节点为product_name) + */ + private String categoryName; + /** + * 节点类型(root=根节点、product=产品节点) + */ + private String categoryType; + /** + * 同级排序号 + */ + private Long sortNo; + /** + * 删除标志(0=正常,1=删除) + */ + @TableLogic + private Integer delFlag; + /** + * 备注 + */ + private String remark; + +} diff --git a/gear-oa/src/main/java/com/gear/oa/domain/bo/GearBomBo.java b/gear-oa/src/main/java/com/gear/oa/domain/bo/GearBomBo.java new file mode 100644 index 0000000..6d39880 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/bo/GearBomBo.java @@ -0,0 +1,50 @@ +package com.gear.oa.domain.bo; + +import com.gear.common.core.validate.AddGroup; +import com.gear.common.core.validate.EditGroup; +import lombok.Data; +import lombok.EqualsAndHashCode; +import javax.validation.constraints.*; + +import java.util.Date; + +import com.gear.common.core.domain.BaseEntity; + +/** + * BOM 头,关联产品或原材料业务对象 gear_bom + * + * @author Joshi + * @date 2025-08-19 + */ + +@Data +@EqualsAndHashCode(callSuper = true) +public class GearBomBo extends BaseEntity { + + /** + * BOM 主键ID + */ + private Long bomId; + + /** + * BOM 编码(可选) + */ + private String bomCode; + + /** + * BOM 名称(可选) + */ + private String bomName; + + /** + * 是否启用(0=否,1=是) + */ + private Integer isEnabled; + + /** + * 备注 + */ + private String remark; + + +} diff --git a/gear-oa/src/main/java/com/gear/oa/domain/bo/GearBomItemBo.java b/gear-oa/src/main/java/com/gear/oa/domain/bo/GearBomItemBo.java new file mode 100644 index 0000000..ba56be5 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/bo/GearBomItemBo.java @@ -0,0 +1,55 @@ +package com.gear.oa.domain.bo; + +import com.gear.common.core.validate.AddGroup; +import com.gear.common.core.validate.EditGroup; +import lombok.Data; +import lombok.EqualsAndHashCode; +import javax.validation.constraints.*; + +import java.util.Date; + +import com.gear.common.core.domain.BaseEntity; + +/** + * BOM 明细,存放属性–值业务对象 gear_bom_item + * + * @author Joshi + * @date 2025-08-19 + */ + +@Data +@EqualsAndHashCode(callSuper = true) +public class GearBomItemBo extends BaseEntity { + + /** + * BOM 明细ID + */ + private Long itemId; + + /** + * 关联 wms_bom.bom_id + */ + private Long bomId; + + /** + * 属性名称 + */ + private String attrKey; + + /** + * 属性值 + */ + private String attrValue; + + /** + * 是否启用(0=否,1=是) + */ + private Integer isEnabled; + + /** + * 备注 + */ + private String remark; + + +} diff --git a/gear-oa/src/main/java/com/gear/oa/domain/bo/GearProductBo.java b/gear-oa/src/main/java/com/gear/oa/domain/bo/GearProductBo.java new file mode 100644 index 0000000..aad88e8 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/bo/GearProductBo.java @@ -0,0 +1,75 @@ +package com.gear.oa.domain.bo; + +import com.gear.common.core.validate.AddGroup; +import com.gear.common.core.validate.EditGroup; +import lombok.Data; +import lombok.EqualsAndHashCode; +import javax.validation.constraints.*; + +import java.util.Date; + +import com.gear.common.core.domain.BaseEntity; + +/** + * 产品业务对象 gear_product + * + * @author Joshi + * @date 2025-08-19 + */ + +@Data +@EqualsAndHashCode(callSuper = true) +public class GearProductBo extends BaseEntity { + + /** + * 主键ID + */ + private Long productId; + + /** + * 产品编号 + */ + private String productCode; + + /** + * 产品名称 + */ + private String productName; + + /** + * 负责人 + */ + private String owner; + + /** + * 单位 + */ + private String unit; + + /** + * BOM 表头ID + */ + private Long bomId; + + /** + * 产品类型(product=产品,semi=半成品,raw=原料) + */ + private String type; + + /** + * 是否启用(0=否,1=是) + */ + private Integer isEnabled; + + /** + * 备注 + */ + private String remark; + + /** + * 分类ID + */ + private Long categoryId; + + +} diff --git a/gear-oa/src/main/java/com/gear/oa/domain/bo/GearProductCategoryBo.java b/gear-oa/src/main/java/com/gear/oa/domain/bo/GearProductCategoryBo.java new file mode 100644 index 0000000..d8d24d5 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/bo/GearProductCategoryBo.java @@ -0,0 +1,50 @@ +package com.gear.oa.domain.bo; + +import com.gear.common.core.validate.AddGroup; +import com.gear.common.core.validate.EditGroup; +import lombok.Data; +import lombok.EqualsAndHashCode; +import javax.validation.constraints.*; + +import java.util.Date; + +import com.gear.common.core.domain.TreeEntity; + +/** + * 产品分类树业务对象 gear_product_category + * + * @author Joshi + * @date 2025-08-19 + */ + +@Data +@EqualsAndHashCode(callSuper = true) +public class GearProductCategoryBo extends TreeEntity { + + /** + * 树节点唯一标识(根节点用固定值) + */ + private Long categoryId; + + /** + * 节点名称(根节点为类型名,产品节点为product_name) + */ + private String categoryName; + + /** + * 节点类型(root=根节点、product=产品节点) + */ + private String categoryType; + + /** + * 同级排序号 + */ + private Long sortNo; + + /** + * 备注 + */ + private String remark; + + +} diff --git a/gear-oa/src/main/java/com/gear/oa/domain/vo/GearBomItemVo.java b/gear-oa/src/main/java/com/gear/oa/domain/vo/GearBomItemVo.java new file mode 100644 index 0000000..b96c599 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/vo/GearBomItemVo.java @@ -0,0 +1,62 @@ +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.util.Date; + + + +/** + * BOM 明细,存放属性–值视图对象 gear_bom_item + * + * @author Joshi + * @date 2025-08-19 + */ +@Data +@ExcelIgnoreUnannotated +public class GearBomItemVo { + + private static final long serialVersionUID = 1L; + + /** + * BOM 明细ID + */ + @ExcelProperty(value = "BOM 明细ID") + private Long itemId; + + /** + * 关联 wms_bom.bom_id + */ + @ExcelProperty(value = "关联 wms_bom.bom_id") + private Long bomId; + + /** + * 属性名称 + */ + @ExcelProperty(value = "属性名称") + private String attrKey; + + /** + * 属性值 + */ + @ExcelProperty(value = "属性值") + private String attrValue; + + /** + * 是否启用(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/domain/vo/GearBomVo.java b/gear-oa/src/main/java/com/gear/oa/domain/vo/GearBomVo.java new file mode 100644 index 0000000..72b3c16 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/vo/GearBomVo.java @@ -0,0 +1,58 @@ +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.util.Date; + + + +/** + * BOM 头,关联产品或原材料视图对象 gear_bom + * + * @author Joshi + * @date 2025-08-19 + */ +@Data +@ExcelIgnoreUnannotated +public class GearBomVo { + + private static final long serialVersionUID = 1L; + + /** + * BOM 主键ID + */ + @ExcelProperty(value = "BOM 主键ID") + private Long bomId; + + /** + * BOM 编码(可选) + */ + @ExcelProperty(value = "BOM 编码", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "可=选") + private String bomCode; + + /** + * BOM 名称(可选) + */ + @ExcelProperty(value = "BOM 名称", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "可=选") + private String bomName; + + /** + * 是否启用(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/domain/vo/GearProductCategoryVo.java b/gear-oa/src/main/java/com/gear/oa/domain/vo/GearProductCategoryVo.java new file mode 100644 index 0000000..8a0ae4b --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/vo/GearProductCategoryVo.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 lombok.Data; +import java.util.Date; + + + +/** + * 产品分类树视图对象 gear_product_category + * + * @author Joshi + * @date 2025-08-19 + */ +@Data +@ExcelIgnoreUnannotated +public class GearProductCategoryVo { + + private static final long serialVersionUID = 1L; + + /** + * 树节点唯一标识(根节点用固定值) + */ + @ExcelProperty(value = "树节点唯一标识", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "根=节点用固定值") + private Long categoryId; + + /** + * 父节点tree_id(根节点的父节点为null) + */ + @ExcelProperty(value = "父节点tree_id", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "根=节点的父节点为null") + private Long parentId; + + /** + * 节点名称(根节点为类型名,产品节点为product_name) + */ + @ExcelProperty(value = "节点名称", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "根=节点为类型名,产品节点为product_name") + private String categoryName; + + /** + * 节点类型(root=根节点、product=产品节点) + */ + @ExcelProperty(value = "节点类型", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "r=oot=根节点、product=产品节点") + private String categoryType; + + /** + * 同级排序号 + */ + @ExcelProperty(value = "同级排序号") + private Long sortNo; + + /** + * 备注 + */ + @ExcelProperty(value = "备注") + private String remark; + + +} diff --git a/gear-oa/src/main/java/com/gear/oa/domain/vo/GearProductVo.java b/gear-oa/src/main/java/com/gear/oa/domain/vo/GearProductVo.java new file mode 100644 index 0000000..c85c31e --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/vo/GearProductVo.java @@ -0,0 +1,85 @@ +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.util.Date; + + + +/** + * 产品视图对象 gear_product + * + * @author Joshi + * @date 2025-08-19 + */ +@Data +@ExcelIgnoreUnannotated +public class GearProductVo { + + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @ExcelProperty(value = "主键ID") + private Long productId; + + /** + * 产品编号 + */ + @ExcelProperty(value = "产品编号") + private String productCode; + + /** + * 产品名称 + */ + @ExcelProperty(value = "产品名称") + private String productName; + + /** + * 负责人 + */ + @ExcelProperty(value = "负责人") + private String owner; + + /** + * 单位 + */ + @ExcelProperty(value = "单位") + private String unit; + + /** + * BOM 表头ID + */ + @ExcelProperty(value = "BOM 表头ID") + private Long bomId; + + /** + * 产品类型(product=产品,semi=半成品,raw=原料) + */ + @ExcelProperty(value = "产品类型", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "p=roduct=产品,semi=半成品,raw=原料") + private String type; + + /** + * 是否启用(0=否,1=是) + */ + @ExcelProperty(value = "是否启用", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "0==否,1=是") + private Integer isEnabled; + + /** + * 备注 + */ + @ExcelProperty(value = "备注") + private String remark; + /** + * 分类ID + */ + @ExcelProperty(value = "分类ID") + private Long categoryId; + +} diff --git a/gear-oa/src/main/java/com/gear/oa/domain/vo/dashboard/MaterialRecommendationVO.java b/gear-oa/src/main/java/com/gear/oa/domain/vo/dashboard/MaterialRecommendationVO.java new file mode 100644 index 0000000..4ced78d --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/vo/dashboard/MaterialRecommendationVO.java @@ -0,0 +1,54 @@ +package com.gear.oa.domain.vo.dashboard; + +import lombok.Data; +import java.util.Date; + +/** + * 原料维度推荐VO + * + * @author Joshi + * @date 2025-08-19 + */ +@Data +public class MaterialRecommendationVO { + + /** + * 原料名称 + */ + private String materialName; + + /** + * 原料编码 + */ + private String materialCode; + + /** + * 推荐采购数量 + */ + private Integer recommendedPurchaseQuantity; + + /** + * 推荐供应商 + */ + private String recommendedSupplier; + + /** + * 推荐原因 + */ + private String recommendationReason; + + /** + * 紧急程度 + */ + private String urgencyLevel; + + /** + * 预计到货时间 + */ + private Date estimatedArrivalTime; + + /** + * 建议操作 + */ + private String suggestedAction; +} \ No newline at end of file diff --git a/gear-oa/src/main/java/com/gear/oa/domain/vo/dashboard/OrderCountStatisticsVO.java b/gear-oa/src/main/java/com/gear/oa/domain/vo/dashboard/OrderCountStatisticsVO.java new file mode 100644 index 0000000..f3baae8 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/vo/dashboard/OrderCountStatisticsVO.java @@ -0,0 +1,43 @@ +package com.gear.oa.domain.vo.dashboard; + +import lombok.Data; + +/** + * 订单数量统计VO + * + * @author Joshi + * @date 2025-08-19 + */ +@Data +public class OrderCountStatisticsVO { + + /** + * 总订单数量 + */ + private Integer totalOrderCount; + + /** + * 已完成订单数量 + */ + private Integer completedOrderCount; + + /** + * 进行中订单数量 + */ + private Integer inProgressOrderCount; + + /** + * 待处理订单数量 + */ + private Integer pendingOrderCount; + + /** + * 本月新增订单数量 + */ + private Integer monthlyNewOrderCount; + + /** + * 完成率 + */ + private Double completionRate; +} \ No newline at end of file diff --git a/gear-oa/src/main/java/com/gear/oa/domain/vo/dashboard/OrderProductStatisticsVO.java b/gear-oa/src/main/java/com/gear/oa/domain/vo/dashboard/OrderProductStatisticsVO.java new file mode 100644 index 0000000..be98204 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/vo/dashboard/OrderProductStatisticsVO.java @@ -0,0 +1,43 @@ +package com.gear.oa.domain.vo.dashboard; + +import lombok.Data; + +/** + * 订单所需产品统计VO + * + * @author Joshi + * @date 2025-08-19 + */ +@Data +public class OrderProductStatisticsVO { + + /** + * 产品名称 + */ + private String productName; + + /** + * 产品编码 + */ + private String productCode; + + /** + * 订单需求数量 + */ + private Integer orderDemandQuantity; + + /** + * 当前库存数量 + */ + private Integer currentStockQuantity; + + /** + * 库存缺口 + */ + private Integer stockGap; + + /** + * 相关订单数量 + */ + private Integer relatedOrderCount; +} \ No newline at end of file diff --git a/gear-oa/src/main/java/com/gear/oa/domain/vo/dashboard/OrderRecommendationVO.java b/gear-oa/src/main/java/com/gear/oa/domain/vo/dashboard/OrderRecommendationVO.java new file mode 100644 index 0000000..99b067d --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/vo/dashboard/OrderRecommendationVO.java @@ -0,0 +1,49 @@ +package com.gear.oa.domain.vo.dashboard; + +import lombok.Data; +import java.util.Date; + +/** + * 订单维度推荐VO + * + * @author Joshi + * @date 2025-08-19 + */ +@Data +public class OrderRecommendationVO { + + /** + * 订单编码 + */ + private String orderCode; + + /** + * 客户名称 + */ + private String customerName; + + /** + * 订单状态 + */ + private String orderStatus; + + /** + * 优先级 + */ + private String priority; + + /** + * 推荐原因 + */ + private String recommendationReason; + + /** + * 建议操作 + */ + private String suggestedAction; + + /** + * 预计完成时间 + */ + private Date estimatedCompletionTime; +} \ No newline at end of file diff --git a/gear-oa/src/main/java/com/gear/oa/domain/vo/dashboard/ProductDashboardVO.java b/gear-oa/src/main/java/com/gear/oa/domain/vo/dashboard/ProductDashboardVO.java new file mode 100644 index 0000000..0d09e7d --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/vo/dashboard/ProductDashboardVO.java @@ -0,0 +1,54 @@ +package com.gear.oa.domain.vo.dashboard; + +import lombok.Data; +import java.util.List; + +/** + * 产品数据看板综合VO + * + * @author Joshi + * @date 2025-08-19 + */ +@Data +public class ProductDashboardVO { + + /** + * 产品销售情况 + */ + private List productSalesPerformance; + + /** + * 销售人员业绩 + */ + private List salesPersonPerformance; + + /** + * 总订单数量统计 + */ + private OrderCountStatisticsVO orderCountStatistics; + + /** + * 订单所需的产品统计 + */ + private List orderProductStatistics; + + /** + * 根据BOM计算的原料需求 + */ + private List productMaterialRequirements; + + /** + * 原料库存和需求情况 + */ + private List rawMaterialInventory; + + /** + * 订单维度推荐 + */ + private List orderRecommendations; + + /** + * 原料维度推荐 + */ + private List materialRecommendations; +} \ No newline at end of file diff --git a/gear-oa/src/main/java/com/gear/oa/domain/vo/dashboard/ProductMaterialRequirementVO.java b/gear-oa/src/main/java/com/gear/oa/domain/vo/dashboard/ProductMaterialRequirementVO.java new file mode 100644 index 0000000..1fe4437 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/vo/dashboard/ProductMaterialRequirementVO.java @@ -0,0 +1,53 @@ +package com.gear.oa.domain.vo.dashboard; + +import lombok.Data; + +/** + * 产品原料需求VO + * + * @author Joshi + * @date 2025-08-19 + */ +@Data +public class ProductMaterialRequirementVO { + + /** + * 产品名称 + */ + private String productName; + + /** + * 产品编码 + */ + private String productCode; + + /** + * 原料名称 + */ + private String materialName; + + /** + * 原料编码 + */ + private String materialCode; + + /** + * 需求数量 + */ + private Integer requiredQuantity; + + /** + * 当前库存数量 + */ + private Integer currentStockQuantity; + + /** + * 在途数量 + */ + private Integer inTransitQuantity; + + /** + * 库存缺口 + */ + private Integer stockGap; +} \ No newline at end of file diff --git a/gear-oa/src/main/java/com/gear/oa/domain/vo/dashboard/ProductSalesPerformanceVO.java b/gear-oa/src/main/java/com/gear/oa/domain/vo/dashboard/ProductSalesPerformanceVO.java new file mode 100644 index 0000000..e7f6dc5 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/vo/dashboard/ProductSalesPerformanceVO.java @@ -0,0 +1,43 @@ +package com.gear.oa.domain.vo.dashboard; + +import lombok.Data; + +/** + * 产品销售情况VO + * + * @author Joshi + * @date 2025-08-19 + */ +@Data +public class ProductSalesPerformanceVO { + + /** + * 产品名称 + */ + private String productName; + + /** + * 产品编码 + */ + private String productCode; + + /** + * 销售数量 + */ + private Integer salesQuantity; + + /** + * 销售金额 + */ + private Double salesAmount; + + /** + * 增长率 + */ + private Double growthRate; + + /** + * 销售排名 + */ + private Integer salesRank; +} \ No newline at end of file diff --git a/gear-oa/src/main/java/com/gear/oa/domain/vo/dashboard/RawMaterialInventoryVO.java b/gear-oa/src/main/java/com/gear/oa/domain/vo/dashboard/RawMaterialInventoryVO.java new file mode 100644 index 0000000..51464c7 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/vo/dashboard/RawMaterialInventoryVO.java @@ -0,0 +1,53 @@ +package com.gear.oa.domain.vo.dashboard; + +import lombok.Data; + +/** + * 原料库存和需求情况VO + * + * @author Joshi + * @date 2025-08-19 + */ +@Data +public class RawMaterialInventoryVO { + + /** + * 原料名称 + */ + private String materialName; + + /** + * 原料编码 + */ + private String materialCode; + + /** + * 当前库存数量 + */ + private Integer currentStockQuantity; + + /** + * 在途数量 + */ + private Integer inTransitQuantity; + + /** + * 总需求数量 + */ + private Integer totalRequiredQuantity; + + /** + * 库存缺口 + */ + private Integer stockGap; + + /** + * 安全库存 + */ + private Integer safetyStock; + + /** + * 库存状态(充足/不足/紧急) + */ + private String stockStatus; +} \ No newline at end of file diff --git a/gear-oa/src/main/java/com/gear/oa/domain/vo/dashboard/SalesPersonPerformanceVO.java b/gear-oa/src/main/java/com/gear/oa/domain/vo/dashboard/SalesPersonPerformanceVO.java new file mode 100644 index 0000000..e4296bc --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/vo/dashboard/SalesPersonPerformanceVO.java @@ -0,0 +1,38 @@ +package com.gear.oa.domain.vo.dashboard; + +import lombok.Data; + +/** + * 销售人员业绩VO + * + * @author Joshi + * @date 2025-08-19 + */ +@Data +public class SalesPersonPerformanceVO { + + /** + * 销售人员姓名 + */ + private String salesPersonName; + + /** + * 订单数量 + */ + private Integer orderCount; + + /** + * 销售金额 + */ + private Double salesAmount; + + /** + * 完成率 + */ + private Double completionRate; + + /** + * 业绩排名 + */ + private Integer performanceRank; +} \ No newline at end of file diff --git a/gear-oa/src/main/java/com/gear/oa/mapper/GearBomItemMapper.java b/gear-oa/src/main/java/com/gear/oa/mapper/GearBomItemMapper.java new file mode 100644 index 0000000..4b708dd --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/mapper/GearBomItemMapper.java @@ -0,0 +1,15 @@ +package com.gear.oa.mapper; + +import com.gear.oa.domain.GearBomItem; +import com.gear.oa.domain.vo.GearBomItemVo; +import com.gear.common.core.mapper.BaseMapperPlus; + +/** + * BOM 明细,存放属性–值Mapper接口 + * + * @author Joshi + * @date 2025-08-19 + */ +public interface GearBomItemMapper extends BaseMapperPlus { + +} diff --git a/gear-oa/src/main/java/com/gear/oa/mapper/GearBomMapper.java b/gear-oa/src/main/java/com/gear/oa/mapper/GearBomMapper.java new file mode 100644 index 0000000..68a379f --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/mapper/GearBomMapper.java @@ -0,0 +1,15 @@ +package com.gear.oa.mapper; + +import com.gear.oa.domain.GearBom; +import com.gear.oa.domain.vo.GearBomVo; +import com.gear.common.core.mapper.BaseMapperPlus; + +/** + * BOM 头,关联产品或原材料Mapper接口 + * + * @author Joshi + * @date 2025-08-19 + */ +public interface GearBomMapper extends BaseMapperPlus { + +} diff --git a/gear-oa/src/main/java/com/gear/oa/mapper/GearProductCategoryMapper.java b/gear-oa/src/main/java/com/gear/oa/mapper/GearProductCategoryMapper.java new file mode 100644 index 0000000..c699088 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/mapper/GearProductCategoryMapper.java @@ -0,0 +1,15 @@ +package com.gear.oa.mapper; + +import com.gear.oa.domain.GearProductCategory; +import com.gear.oa.domain.vo.GearProductCategoryVo; +import com.gear.common.core.mapper.BaseMapperPlus; + +/** + * 产品分类树Mapper接口 + * + * @author Joshi + * @date 2025-08-19 + */ +public interface GearProductCategoryMapper extends BaseMapperPlus { + +} diff --git a/gear-oa/src/main/java/com/gear/oa/mapper/GearProductMapper.java b/gear-oa/src/main/java/com/gear/oa/mapper/GearProductMapper.java new file mode 100644 index 0000000..e8655cd --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/mapper/GearProductMapper.java @@ -0,0 +1,205 @@ +package com.gear.oa.mapper; + +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.oa.domain.GearProduct; +import com.gear.oa.domain.vo.GearProductVo; +import com.gear.common.core.mapper.BaseMapperPlus; +import com.gear.oa.domain.vo.dashboard.*; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import java.util.List; + +/** + * 产品Mapper接口 + * + * @author Joshi + * @date 2025-08-19 + */ +public interface GearProductMapper extends BaseMapperPlus { + + /** + * 数据看板 - 产品销售情况 + */ + @Select("SELECT p.product_name, p.product_code, " + + "SUM(od.quantity) AS salesQuantity, " + + "SUM(od.quantity) AS salesAmount, " + + "0 AS growthRate, " + + "RANK() OVER (ORDER BY SUM(od.quantity) DESC) AS salesRank " + + "FROM gear_order_detail od " + + "JOIN gear_product p ON od.product_id = p.product_id " + + "JOIN gear_order o ON od.order_id = o.order_id " + + "WHERE o.order_status = 2 AND o.del_flag = 0 " + + "GROUP BY p.product_id, p.product_name, p.product_code " + + "ORDER BY salesQuantity DESC LIMIT 10") + List selectProductSalesPerformance(); + + /** + * 数据看板 - 销售人员业绩 + */ + @Select("SELECT o.sales_manager AS salesPersonName, " + + "COUNT(DISTINCT o.order_id) AS orderCount, " + + "SUM(od.quantity) AS salesAmount, " + + "ROUND(SUM(CASE WHEN o.order_status = 2 THEN 1 ELSE 0 END) / COUNT(*), 4) AS completionRate, " + + "RANK() OVER (ORDER BY SUM(od.quantity) DESC) AS performanceRank " + + "FROM gear_order o " + + "JOIN gear_order_detail od ON o.order_id = od.order_id " + + "WHERE o.del_flag = 0 " + + "GROUP BY o.sales_manager " + + "ORDER BY salesAmount DESC") + List selectSalesPersonPerformance(); + + /** + * 数据看板 - 总订单数量统计 + */ + @Select("SELECT " + + "COUNT(*) AS totalOrderCount, " + + "SUM(CASE WHEN order_status = 2 THEN 1 ELSE 0 END) AS completedOrderCount, " + + "SUM(CASE WHEN order_status = 1 THEN 1 ELSE 0 END) AS inProgressOrderCount, " + + "SUM(CASE WHEN order_status = 0 THEN 1 ELSE 0 END) AS pendingOrderCount, " + + "SUM(CASE WHEN DATE_FORMAT(create_time, '%Y-%m') = DATE_FORMAT(NOW(), '%Y-%m') THEN 1 ELSE 0 END) AS monthlyNewOrderCount, " + + "ROUND(SUM(CASE WHEN order_status = 2 THEN 1 ELSE 0 END) / COUNT(*), 4) AS completionRate " + + "FROM gear_order WHERE del_flag = 0") + OrderCountStatisticsVO selectOrderCountStatistics(); + + /** + * 数据看板 - 订单所需的产品统计 + */ + @Select("SELECT p.product_name, p.product_code, " + + "SUM(od.quantity) AS orderDemandQuantity, " + + "IFNULL(s.stockQuantity, 0) AS currentStockQuantity, " + + "SUM(od.quantity) - IFNULL(s.stockQuantity, 0) AS stockGap, " + + "COUNT(DISTINCT o.order_id) AS relatedOrderCount " + + "FROM gear_order_detail od " + + "JOIN gear_product p ON od.product_id = p.product_id " + + "JOIN gear_order o ON od.order_id = o.order_id " + + "LEFT JOIN (SELECT item_id, SUM(quantity) AS stockQuantity FROM gear_stock WHERE item_type = 'product' AND del_flag = 0 GROUP BY item_id) s ON p.product_id = s.item_id " + + "WHERE o.order_status IN (0, 1) AND o.del_flag = 0 " + + "GROUP BY p.product_id, p.product_name, p.product_code " + + "ORDER BY stockGap DESC") + List selectOrderProductStatistics(); + + /** + * 数据看板 - 根据BOM计算的原料需求 + */ + @Select("SELECT p.product_name, p.product_code, " + + "rm.material_name AS materialName, " + + "rm.material_code AS materialCode, " + + "SUM(od.quantity * bi.attr_value) AS requiredQuantity, " + + "IFNULL(s.stockQuantity, 0) AS currentStockQuantity, " + + "IFNULL(it.inTransitQuantity, 0) AS inTransitQuantity, " + + "SUM(od.quantity * bi.attr_value) - IFNULL(s.stockQuantity, 0) - IFNULL(it.inTransitQuantity, 0) AS stockGap " + + "FROM gear_order_detail od " + + "JOIN gear_product p ON od.product_id = p.product_id " + + "JOIN gear_bom b ON p.bom_id = b.bom_id " + + "JOIN gear_bom_item bi ON b.bom_id = bi.bom_id " + + "JOIN gear_material rm ON bi.attr_key = rm.material_code " + + "JOIN gear_order o ON od.order_id = o.order_id " + + "LEFT JOIN (SELECT item_id, SUM(quantity) AS stockQuantity FROM gear_stock WHERE item_type = 'material' AND del_flag = 0 GROUP BY item_id) s ON rm.material_id = s.item_id " + + "LEFT JOIN (SELECT material_id, SUM(quantity) AS inTransitQuantity FROM gear_purchase_plan_detail WHERE status = 1 GROUP BY material_id) it ON rm.material_id = it.material_id " + + "WHERE o.order_status IN (0, 1) AND o.del_flag = 0 " + + "GROUP BY p.product_id, p.product_name, p.product_code, rm.material_id, rm.material_name, rm.material_code " + + "ORDER BY stockGap DESC") + List selectProductMaterialRequirements(); + + /** + * 数据看板 - 原料库存和需求情况 + */ + @Select("SELECT rm.material_name AS materialName, " + + "rm.material_code AS materialCode, " + + "IFNULL(s.stockQuantity, 0) AS currentStockQuantity, " + + "IFNULL(it.inTransitQuantity, 0) AS inTransitQuantity, " + + "IFNULL(req.requiredQuantity, 0) AS totalRequiredQuantity, " + + "IFNULL(req.requiredQuantity, 0) - IFNULL(s.stockQuantity, 0) - IFNULL(it.inTransitQuantity, 0) AS stockGap, " + + "0 AS safetyStock, " + + "CASE " + + " WHEN IFNULL(req.requiredQuantity, 0) <= IFNULL(s.stockQuantity, 0) + IFNULL(it.inTransitQuantity, 0) THEN '充足' " + + " WHEN IFNULL(req.requiredQuantity, 0) <= IFNULL(s.stockQuantity, 0) + IFNULL(it.inTransitQuantity, 0) + 0 THEN '不足' " + + " ELSE '紧急' " + + "END AS stockStatus " + + "FROM gear_material rm " + + "LEFT JOIN (SELECT item_id, SUM(quantity) AS stockQuantity FROM gear_stock WHERE item_type = 'material' AND del_flag = 0 GROUP BY item_id) s ON rm.material_id = s.item_id " + + "LEFT JOIN (SELECT material_id, SUM(quantity) AS inTransitQuantity FROM gear_purchase_plan_detail WHERE status = 1 GROUP BY material_id) it ON rm.material_id = it.material_id " + + "LEFT JOIN (SELECT bi.attr_key AS material_code, SUM(od.quantity * bi.attr_value) AS requiredQuantity " + + " FROM gear_order_detail od " + + " JOIN gear_order o ON od.order_id = o.order_id " + + " JOIN gear_product p ON od.product_id = p.product_id " + + " JOIN gear_bom b ON p.bom_id = b.bom_id " + + " JOIN gear_bom_item bi ON b.bom_id = bi.bom_id " + + " WHERE o.order_status IN (0, 1) AND o.del_flag = 0 " + + " GROUP BY bi.attr_key) req ON rm.material_code = req.material_code " + + "ORDER BY stockGap DESC") + List selectRawMaterialInventory(); + + /** + * 数据看板 - 订单维度推荐 + */ + @Select("SELECT o.order_code, o.customer_name, " + + "CASE o.order_status " + + " WHEN 0 THEN '新建' " + + " WHEN 1 THEN '生产中' " + + " WHEN 2 THEN '已完成' " + + " WHEN 3 THEN '已取消' " + + "END AS orderStatus, " + + "CASE " + + " WHEN o.order_status = 0 THEN '高' " + + " WHEN o.order_status = 1 THEN '中' " + + " ELSE '低' " + + "END AS priority, " + + "CASE " + + " WHEN o.order_status = 0 THEN '新订单需要及时处理' " + + " WHEN o.order_status = 1 THEN '生产中的订单需要关注进度' " + + " ELSE '订单已完成或已取消' " + + "END AS recommendationReason, " + + "CASE " + + " WHEN o.order_status = 0 THEN '开始生产' " + + " WHEN o.order_status = 1 THEN '检查生产进度' " + + " ELSE '无需操作' " + + "END AS suggestedAction, " + + "DATE_ADD(o.create_time, INTERVAL 30 DAY) AS estimatedCompletionTime " + + "FROM gear_order o " + + "WHERE o.order_status IN (0, 1) AND o.del_flag = 0 " + + "ORDER BY o.create_time ASC LIMIT 10") + List selectOrderRecommendations(); + + /** + * 数据看板 - 原料维度推荐 + */ + @Select("SELECT rm.material_name AS materialName, " + + "rm.material_code AS materialCode, " + + "GREATEST(0, IFNULL(req.requiredQuantity, 0) - IFNULL(s.stockQuantity, 0) - IFNULL(it.inTransitQuantity, 0)) AS recommendedPurchaseQuantity, " + + "'默认供应商' AS recommendedSupplier, " + + "CASE " + + " WHEN IFNULL(req.requiredQuantity, 0) > IFNULL(s.stockQuantity, 0) + IFNULL(it.inTransitQuantity, 0) + 0 THEN '库存不足,需要紧急采购' " + + " WHEN IFNULL(req.requiredQuantity, 0) > IFNULL(s.stockQuantity, 0) + IFNULL(it.inTransitQuantity, 0) THEN '库存不足,建议采购' " + + " ELSE '库存充足' " + + "END AS recommendationReason, " + + "CASE " + + " WHEN IFNULL(req.requiredQuantity, 0) > IFNULL(s.stockQuantity, 0) + IFNULL(it.inTransitQuantity, 0) + 0 THEN '紧急' " + + " WHEN IFNULL(req.requiredQuantity, 0) > IFNULL(s.stockQuantity, 0) + IFNULL(it.inTransitQuantity, 0) THEN '一般' " + + " ELSE '低' " + + "END AS urgencyLevel, " + + "DATE_ADD(NOW(), INTERVAL 7 DAY) AS estimatedArrivalTime, " + + "CASE " + + " WHEN IFNULL(req.requiredQuantity, 0) > IFNULL(s.stockQuantity, 0) + IFNULL(it.inTransitQuantity, 0) + 0 THEN '立即采购' " + + " WHEN IFNULL(req.requiredQuantity, 0) > IFNULL(s.stockQuantity, 0) + IFNULL(it.inTransitQuantity, 0) THEN '计划采购' " + + " ELSE '无需采购' " + + "END AS suggestedAction " + + "FROM gear_material rm " + + "LEFT JOIN (SELECT item_id, SUM(quantity) AS stockQuantity FROM gear_stock WHERE item_type = 'material' AND del_flag = 0 GROUP BY item_id) s ON rm.material_id = s.item_id " + + "LEFT JOIN (SELECT material_id, SUM(quantity) AS inTransitQuantity FROM gear_purchase_plan_detail WHERE status = 1 GROUP BY material_id) it ON rm.material_id = it.material_id " + + "LEFT JOIN (SELECT bi.attr_key AS material_code, SUM(od.quantity * bi.attr_value) AS requiredQuantity " + + " FROM gear_order_detail od " + + " JOIN gear_order o ON od.order_id = o.order_id " + + " JOIN gear_product p ON od.product_id = p.product_id " + + " JOIN gear_bom b ON p.bom_id = b.bom_id " + + " JOIN gear_bom_item bi ON b.bom_id = bi.bom_id " + + " WHERE o.order_status IN (0, 1) AND o.del_flag = 0 " + + " GROUP BY bi.attr_key) req ON rm.material_code = req.material_code " + + "WHERE IFNULL(req.requiredQuantity, 0) > IFNULL(s.stockQuantity, 0) + IFNULL(it.inTransitQuantity, 0) " + + "ORDER BY (IFNULL(req.requiredQuantity, 0) - IFNULL(s.stockQuantity, 0) - IFNULL(it.inTransitQuantity, 0)) DESC LIMIT 10") + List selectMaterialRecommendations(); + + Page selectVoPagePlus(Page build, @Param("ew") QueryWrapper lqw); +} diff --git a/gear-oa/src/main/java/com/gear/oa/service/IGearBomItemService.java b/gear-oa/src/main/java/com/gear/oa/service/IGearBomItemService.java new file mode 100644 index 0000000..3fc557a --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/service/IGearBomItemService.java @@ -0,0 +1,49 @@ +package com.gear.oa.service; + +import com.gear.oa.domain.GearBomItem; +import com.gear.oa.domain.vo.GearBomItemVo; +import com.gear.oa.domain.bo.GearBomItemBo; +import com.gear.common.core.page.TableDataInfo; +import com.gear.common.core.domain.PageQuery; + +import java.util.Collection; +import java.util.List; + +/** + * BOM 明细,存放属性–值Service接口 + * + * @author Joshi + * @date 2025-08-19 + */ +public interface IGearBomItemService { + + /** + * 查询BOM 明细,存放属性–值 + */ + GearBomItemVo queryById(Long itemId); + + /** + * 查询BOM 明细,存放属性–值列表 + */ + TableDataInfo queryPageList(GearBomItemBo bo, PageQuery pageQuery); + + /** + * 查询BOM 明细,存放属性–值列表 + */ + List queryList(GearBomItemBo bo); + + /** + * 新增BOM 明细,存放属性–值 + */ + Boolean insertByBo(GearBomItemBo bo); + + /** + * 修改BOM 明细,存放属性–值 + */ + Boolean updateByBo(GearBomItemBo bo); + + /** + * 校验并批量删除BOM 明细,存放属性–值信息 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); +} diff --git a/gear-oa/src/main/java/com/gear/oa/service/IGearBomService.java b/gear-oa/src/main/java/com/gear/oa/service/IGearBomService.java new file mode 100644 index 0000000..a44e95a --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/service/IGearBomService.java @@ -0,0 +1,49 @@ +package com.gear.oa.service; + +import com.gear.oa.domain.GearBom; +import com.gear.oa.domain.vo.GearBomVo; +import com.gear.oa.domain.bo.GearBomBo; +import com.gear.common.core.page.TableDataInfo; +import com.gear.common.core.domain.PageQuery; + +import java.util.Collection; +import java.util.List; + +/** + * BOM 头,关联产品或原材料Service接口 + * + * @author Joshi + * @date 2025-08-19 + */ +public interface IGearBomService { + + /** + * 查询BOM 头,关联产品或原材料 + */ + GearBomVo queryById(Long bomId); + + /** + * 查询BOM 头,关联产品或原材料列表 + */ + TableDataInfo queryPageList(GearBomBo bo, PageQuery pageQuery); + + /** + * 查询BOM 头,关联产品或原材料列表 + */ + List queryList(GearBomBo bo); + + /** + * 新增BOM 头,关联产品或原材料 + */ + Boolean insertByBo(GearBomBo bo); + + /** + * 修改BOM 头,关联产品或原材料 + */ + Boolean updateByBo(GearBomBo bo); + + /** + * 校验并批量删除BOM 头,关联产品或原材料信息 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); +} diff --git a/gear-oa/src/main/java/com/gear/oa/service/IGearProductCategoryService.java b/gear-oa/src/main/java/com/gear/oa/service/IGearProductCategoryService.java new file mode 100644 index 0000000..c8311df --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/service/IGearProductCategoryService.java @@ -0,0 +1,43 @@ +package com.gear.oa.service; + +import com.gear.oa.domain.GearProductCategory; +import com.gear.oa.domain.vo.GearProductCategoryVo; +import com.gear.oa.domain.bo.GearProductCategoryBo; + +import java.util.Collection; +import java.util.List; + +/** + * 产品分类树Service接口 + * + * @author Joshi + * @date 2025-08-19 + */ +public interface IGearProductCategoryService { + + /** + * 查询产品分类树 + */ + GearProductCategoryVo queryById(Long categoryId); + + + /** + * 查询产品分类树列表 + */ + List queryList(GearProductCategoryBo bo); + + /** + * 新增产品分类树 + */ + Boolean insertByBo(GearProductCategoryBo bo); + + /** + * 修改产品分类树 + */ + Boolean updateByBo(GearProductCategoryBo bo); + + /** + * 校验并批量删除产品分类树信息 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); +} 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 new file mode 100644 index 0000000..d34161a --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/service/IGearProductService.java @@ -0,0 +1,94 @@ +package com.gear.oa.service; + +import java.util.Collection; +import java.util.List; + +import com.gear.oa.domain.vo.GearProductVo; +import com.gear.oa.domain.bo.GearProductBo; +import com.gear.common.core.page.TableDataInfo; +import com.gear.common.core.domain.PageQuery; +import com.gear.oa.domain.vo.dashboard.*; + +/** + * 产品Service接口 + * + * @author Joshi + * @date 2025-08-19 + */ +public interface IGearProductService { + + /** + * 查询产品 + */ + GearProductVo queryById(Long productId); + + /** + * 查询产品列表 + */ + TableDataInfo queryPageList(GearProductBo bo, PageQuery pageQuery); + + /** + * 查询产品列表 + */ + List queryList(GearProductBo bo); + + /** + * 新增产品 + */ + Boolean insertByBo(GearProductBo bo); + + /** + * 修改产品 + */ + Boolean updateByBo(GearProductBo bo); + + /** + * 校验并批量删除产品信息 + */ + 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/impl/GearBomItemServiceImpl.java b/gear-oa/src/main/java/com/gear/oa/service/impl/GearBomItemServiceImpl.java new file mode 100644 index 0000000..aa2941b --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/service/impl/GearBomItemServiceImpl.java @@ -0,0 +1,112 @@ +package com.gear.oa.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import com.gear.common.utils.StringUtils; +import com.gear.common.core.page.TableDataInfo; +import com.gear.common.core.domain.PageQuery; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import com.gear.oa.domain.bo.GearBomItemBo; +import com.gear.oa.domain.vo.GearBomItemVo; +import com.gear.oa.domain.GearBomItem; +import com.gear.oa.mapper.GearBomItemMapper; +import com.gear.oa.service.IGearBomItemService; + +import java.util.List; +import java.util.Map; +import java.util.Collection; + +/** + * BOM 明细,存放属性–值Service业务层处理 + * + * @author Joshi + * @date 2025-08-19 + */ +@RequiredArgsConstructor +@Service +public class GearBomItemServiceImpl implements IGearBomItemService { + + private final GearBomItemMapper baseMapper; + + /** + * 查询BOM 明细,存放属性–值 + */ + @Override + public GearBomItemVo queryById(Long itemId){ + return baseMapper.selectVoById(itemId); + } + + /** + * 查询BOM 明细,存放属性–值列表 + */ + @Override + public TableDataInfo queryPageList(GearBomItemBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询BOM 明细,存放属性–值列表 + */ + @Override + public List queryList(GearBomItemBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(GearBomItemBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(bo.getBomId() != null, GearBomItem::getBomId, bo.getBomId()); + lqw.eq(StringUtils.isNotBlank(bo.getAttrKey()), GearBomItem::getAttrKey, bo.getAttrKey()); + lqw.eq(StringUtils.isNotBlank(bo.getAttrValue()), GearBomItem::getAttrValue, bo.getAttrValue()); + lqw.eq(bo.getIsEnabled() != null, GearBomItem::getIsEnabled, bo.getIsEnabled()); + return lqw; + } + + /** + * 新增BOM 明细,存放属性–值 + */ + @Override + public Boolean insertByBo(GearBomItemBo bo) { + GearBomItem add = BeanUtil.toBean(bo, GearBomItem.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setItemId(add.getItemId()); + } + return flag; + } + + /** + * 修改BOM 明细,存放属性–值 + */ + @Override + public Boolean updateByBo(GearBomItemBo bo) { + GearBomItem update = BeanUtil.toBean(bo, GearBomItem.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(GearBomItem entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 批量删除BOM 明细,存放属性–值 + */ + @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/GearBomServiceImpl.java b/gear-oa/src/main/java/com/gear/oa/service/impl/GearBomServiceImpl.java new file mode 100644 index 0000000..e04676f --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/service/impl/GearBomServiceImpl.java @@ -0,0 +1,111 @@ +package com.gear.oa.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import com.gear.common.utils.StringUtils; +import com.gear.common.core.page.TableDataInfo; +import com.gear.common.core.domain.PageQuery; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import com.gear.oa.domain.bo.GearBomBo; +import com.gear.oa.domain.vo.GearBomVo; +import com.gear.oa.domain.GearBom; +import com.gear.oa.mapper.GearBomMapper; +import com.gear.oa.service.IGearBomService; + +import java.util.List; +import java.util.Map; +import java.util.Collection; + +/** + * BOM 头,关联产品或原材料Service业务层处理 + * + * @author Joshi + * @date 2025-08-19 + */ +@RequiredArgsConstructor +@Service +public class GearBomServiceImpl implements IGearBomService { + + private final GearBomMapper baseMapper; + + /** + * 查询BOM 头,关联产品或原材料 + */ + @Override + public GearBomVo queryById(Long bomId){ + return baseMapper.selectVoById(bomId); + } + + /** + * 查询BOM 头,关联产品或原材料列表 + */ + @Override + public TableDataInfo queryPageList(GearBomBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询BOM 头,关联产品或原材料列表 + */ + @Override + public List queryList(GearBomBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(GearBomBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(StringUtils.isNotBlank(bo.getBomCode()), GearBom::getBomCode, bo.getBomCode()); + lqw.like(StringUtils.isNotBlank(bo.getBomName()), GearBom::getBomName, bo.getBomName()); + lqw.eq(bo.getIsEnabled() != null, GearBom::getIsEnabled, bo.getIsEnabled()); + return lqw; + } + + /** + * 新增BOM 头,关联产品或原材料 + */ + @Override + public Boolean insertByBo(GearBomBo bo) { + GearBom add = BeanUtil.toBean(bo, GearBom.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setBomId(add.getBomId()); + } + return flag; + } + + /** + * 修改BOM 头,关联产品或原材料 + */ + @Override + public Boolean updateByBo(GearBomBo bo) { + GearBom update = BeanUtil.toBean(bo, GearBom.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(GearBom entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 批量删除BOM 头,关联产品或原材料 + */ + @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/GearProductCategoryServiceImpl.java b/gear-oa/src/main/java/com/gear/oa/service/impl/GearProductCategoryServiceImpl.java new file mode 100644 index 0000000..182f1c2 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/service/impl/GearProductCategoryServiceImpl.java @@ -0,0 +1,101 @@ +package com.gear.oa.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import com.gear.common.utils.StringUtils; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import com.gear.oa.domain.bo.GearProductCategoryBo; +import com.gear.oa.domain.vo.GearProductCategoryVo; +import com.gear.oa.domain.GearProductCategory; +import com.gear.oa.mapper.GearProductCategoryMapper; +import com.gear.oa.service.IGearProductCategoryService; + +import java.util.List; +import java.util.Map; +import java.util.Collection; + +/** + * 产品分类树Service业务层处理 + * + * @author Joshi + * @date 2025-08-19 + */ +@RequiredArgsConstructor +@Service +public class GearProductCategoryServiceImpl implements IGearProductCategoryService { + + private final GearProductCategoryMapper baseMapper; + + /** + * 查询产品分类树 + */ + @Override + public GearProductCategoryVo queryById(Long categoryId){ + return baseMapper.selectVoById(categoryId); + } + + + /** + * 查询产品分类树列表 + */ + @Override + public List queryList(GearProductCategoryBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(GearProductCategoryBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(bo.getParentId() != null, GearProductCategory::getParentId, bo.getParentId()); + lqw.like(StringUtils.isNotBlank(bo.getCategoryName()), GearProductCategory::getCategoryName, bo.getCategoryName()); + lqw.eq(StringUtils.isNotBlank(bo.getCategoryType()), GearProductCategory::getCategoryType, bo.getCategoryType()); + //同级排序号需要order by asc + lqw.orderByAsc(GearProductCategory::getSortNo); + return lqw; + } + + /** + * 新增产品分类树 + */ + @Override + public Boolean insertByBo(GearProductCategoryBo bo) { + GearProductCategory add = BeanUtil.toBean(bo, GearProductCategory.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setCategoryId(add.getCategoryId()); + } + return flag; + } + + /** + * 修改产品分类树 + */ + @Override + public Boolean updateByBo(GearProductCategoryBo bo) { + GearProductCategory update = BeanUtil.toBean(bo, GearProductCategory.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(GearProductCategory 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/GearProductServiceImpl.java b/gear-oa/src/main/java/com/gear/oa/service/impl/GearProductServiceImpl.java new file mode 100644 index 0000000..399dbe3 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/service/impl/GearProductServiceImpl.java @@ -0,0 +1,228 @@ +package com.gear.oa.service.impl; + +import java.util.List; +import java.util.Map; +import java.util.Collection; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import org.springframework.stereotype.Service; +import com.gear.common.utils.StringUtils; +import com.gear.common.core.page.TableDataInfo; +import com.gear.common.core.domain.PageQuery; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import com.gear.oa.domain.bo.GearProductBo; +import com.gear.oa.domain.vo.GearProductVo; +import com.gear.oa.domain.vo.dashboard.*; +import com.gear.oa.domain.GearProduct; +import com.gear.oa.mapper.GearProductMapper; +import com.gear.oa.service.IGearProductService; + +/** + * 产品Service业务层处理 + * + * @author Joshi + * @date 2025-08-19 + */ +@RequiredArgsConstructor +@Service +public class GearProductServiceImpl implements IGearProductService { + + private final GearProductMapper baseMapper; + + /** + * 查询产品 + */ + @Override + public GearProductVo queryById(Long productId) { + return baseMapper.selectVoById(productId); + } + + /** + * 查询产品列表 + */ + @Override + public TableDataInfo queryPageList(GearProductBo bo, PageQuery pageQuery) { + QueryWrapper qw = buildQueryWrapperPlus(bo); + Page result = baseMapper.selectVoPagePlus(pageQuery.build(), qw); + return TableDataInfo.build(result); + } + public QueryWrapper buildQueryWrapperPlus(GearProductBo bo) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + // 构建查询条件 + if (bo.getProductId() != null) { + queryWrapper.eq("p.product_id", bo.getProductId()); + } + if (bo.getCategoryId() != null) { + queryWrapper.eq("p.category_id", bo.getCategoryId()); + } + if (StringUtils.isNotBlank(bo.getProductCode())) { + queryWrapper.like("p.product_code", bo.getProductCode()); + } + if (StringUtils.isNotBlank(bo.getProductName())) { + queryWrapper.like("p.product_name", bo.getProductName()); + } + if (StringUtils.isNotBlank(bo.getOwner())) { + queryWrapper.eq("p.owner", bo.getOwner()); + } + if (StringUtils.isNotBlank(bo.getUnit())) { + queryWrapper.eq("p.unit", bo.getUnit()); + } + if (bo.getBomId() != null) { + queryWrapper.eq("p.bom_id", bo.getBomId()); + } + if (StringUtils.isNotBlank(bo.getType())) { + queryWrapper.eq("p.type", bo.getType()); + } + if (bo.getIsEnabled() != null) { + queryWrapper.eq("p.is_enabled", bo.getIsEnabled()); + } + return queryWrapper; + } + + + + /** + * 查询产品列表 + */ + @Override + public List queryList(GearProductBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(GearProductBo bo) { + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(bo.getProductId() != null, GearProduct::getProductId, bo.getProductId()); + lqw.eq(bo.getCategoryId()!= null, GearProduct::getCategoryId, bo.getCategoryId()); + lqw.like(StringUtils.isNotBlank(bo.getProductCode()), GearProduct::getProductCode, bo.getProductCode()); + lqw.like(StringUtils.isNotBlank(bo.getProductName()), GearProduct::getProductName, bo.getProductName()); + lqw.eq(StringUtils.isNotBlank(bo.getOwner()), GearProduct::getOwner, bo.getOwner()); + lqw.eq(StringUtils.isNotBlank(bo.getUnit()), GearProduct::getUnit, bo.getUnit()); + lqw.eq(bo.getBomId() != null, GearProduct::getBomId, bo.getBomId()); + lqw.eq(StringUtils.isNotBlank(bo.getType()), GearProduct::getType, bo.getType()); + lqw.eq(bo.getIsEnabled() != null, GearProduct::getIsEnabled, bo.getIsEnabled()); + return lqw; + } + + /** + * 新增产品 + */ + @Override + public Boolean insertByBo(GearProductBo bo) { + GearProduct add = new GearProduct(); + // 设置属性 + // ... + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setProductId(add.getProductId()); + } + return flag; + } + + /** + * 修改产品 + */ + @Override + public Boolean updateByBo(GearProductBo bo) { + GearProduct update = new GearProduct(); + // 设置属性 + // ... + return baseMapper.updateById(update) > 0; + } + + /** + * 批量删除产品 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if (isValid) { + // 做一些校验 + } + return baseMapper.deleteBatchIds(ids) > 0; + } + + /** + * 数据看板 - 获取所有数据 + */ + @Override + public ProductDashboardVO getDashboard() { + ProductDashboardVO dashboard = new ProductDashboardVO(); + dashboard.setProductSalesPerformance(selectProductSalesPerformance()); + dashboard.setSalesPersonPerformance(selectSalesPersonPerformance()); + dashboard.setOrderCountStatistics(selectOrderCountStatistics()); + dashboard.setOrderProductStatistics(selectOrderProductStatistics()); + dashboard.setProductMaterialRequirements(selectProductMaterialRequirements()); + dashboard.setRawMaterialInventory(selectRawMaterialInventory()); + dashboard.setOrderRecommendations(selectOrderRecommendations()); + dashboard.setMaterialRecommendations(selectMaterialRecommendations()); + return dashboard; + } + + /** + * 数据看板 - 产品销售情况 + */ + @Override + public List selectProductSalesPerformance() { + return baseMapper.selectProductSalesPerformance(); + } + + /** + * 数据看板 - 销售人员业绩 + */ + @Override + public List selectSalesPersonPerformance() { + return baseMapper.selectSalesPersonPerformance(); + } + + /** + * 数据看板 - 总订单数量统计 + */ + @Override + public OrderCountStatisticsVO selectOrderCountStatistics() { + return baseMapper.selectOrderCountStatistics(); + } + + /** + * 数据看板 - 订单所需的产品统计 + */ + @Override + public List selectOrderProductStatistics() { + return baseMapper.selectOrderProductStatistics(); + } + + /** + * 数据看板 - 根据BOM计算的原料需求 + */ + @Override + public List selectProductMaterialRequirements() { + return baseMapper.selectProductMaterialRequirements(); + } + + /** + * 数据看板 - 原料库存和需求情况 + */ + @Override + public List selectRawMaterialInventory() { + return baseMapper.selectRawMaterialInventory(); + } + + /** + * 数据看板 - 订单维度推荐 + */ + @Override + public List selectOrderRecommendations() { + return baseMapper.selectOrderRecommendations(); + } + + /** + * 数据看板 - 原料维度推荐 + */ + @Override + public List selectMaterialRecommendations() { + return baseMapper.selectMaterialRecommendations(); + } +} diff --git a/gear-oa/src/main/resources/mapper/oa/GearBomItemMapper.xml b/gear-oa/src/main/resources/mapper/oa/GearBomItemMapper.xml new file mode 100644 index 0000000..2b2f039 --- /dev/null +++ b/gear-oa/src/main/resources/mapper/oa/GearBomItemMapper.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/gear-oa/src/main/resources/mapper/oa/GearBomMapper.xml b/gear-oa/src/main/resources/mapper/oa/GearBomMapper.xml new file mode 100644 index 0000000..f78c213 --- /dev/null +++ b/gear-oa/src/main/resources/mapper/oa/GearBomMapper.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + diff --git a/gear-oa/src/main/resources/mapper/oa/GearProductCategoryMapper.xml b/gear-oa/src/main/resources/mapper/oa/GearProductCategoryMapper.xml new file mode 100644 index 0000000..9202f97 --- /dev/null +++ b/gear-oa/src/main/resources/mapper/oa/GearProductCategoryMapper.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/gear-oa/src/main/resources/mapper/oa/GearProductMapper.xml b/gear-oa/src/main/resources/mapper/oa/GearProductMapper.xml new file mode 100644 index 0000000..3383f91 --- /dev/null +++ b/gear-oa/src/main/resources/mapper/oa/GearProductMapper.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + +