From 264ca0e407346117d039d060ea593081ebc3cc57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E6=98=8A=E5=A4=A9?= <15984976+n2319_0@user.noreply.gitee.com> Date: Mon, 18 May 2026 17:48:43 +0800 Subject: [PATCH] =?UTF-8?q?=E9=94=80=E5=94=AE=E5=8F=91=E8=B4=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GearOrderProductionController.java | 64 + .../oa/controller/GearSalesmanController.java | 102 + .../GearShippingOrderController.java | 104 + .../GearShippingPlanController.java | 100 + .../oa/controller/GearStockController.java | 8 + .../java/com/gear/oa/domain/GearOrder.java | 12 + .../gear/oa/domain/GearOrderProduction.java | 44 + .../java/com/gear/oa/domain/GearSalesman.java | 52 + .../com/gear/oa/domain/GearShippingOrder.java | 117 + .../com/gear/oa/domain/GearShippingPlan.java | 55 + .../com/gear/oa/domain/bo/GearOrderBo.java | 9 + .../oa/domain/bo/GearOrderProductionBo.java | 37 + .../com/gear/oa/domain/bo/GearSalesmanBo.java | 39 + .../oa/domain/bo/GearShippingOrderBo.java | 138 ++ .../gear/oa/domain/bo/GearShippingPlanBo.java | 50 + .../gear/oa/domain/vo/GearOrderDetailVo.java | 21 + .../oa/domain/vo/GearOrderProductionVo.java | 46 + .../com/gear/oa/domain/vo/GearOrderVo.java | 21 +- .../com/gear/oa/domain/vo/GearSalesmanVo.java | 31 + .../oa/domain/vo/GearShippingOrderVo.java | 69 + .../gear/oa/domain/vo/GearShippingPlanVo.java | 37 + .../oa/mapper/GearOrderProductionMapper.java | 20 + .../gear/oa/mapper/GearSalesmanMapper.java | 12 + .../oa/mapper/GearShippingOrderMapper.java | 12 + .../oa/mapper/GearShippingPlanMapper.java | 50 + .../com/gear/oa/mapper/GearStockMapper.java | 4 + .../service/IGearOrderProductionService.java | 31 + .../gear/oa/service/IGearSalesmanService.java | 34 + .../oa/service/IGearShippingOrderService.java | 51 + .../oa/service/IGearShippingPlanService.java | 30 + .../gear/oa/service/IGearStockService.java | 3 + .../impl/GearOrderProductionServiceImpl.java | 150 ++ .../oa/service/impl/GearOrderServiceImpl.java | 48 +- .../service/impl/GearSalesmanServiceImpl.java | 131 ++ .../impl/GearShippingOrderServiceImpl.java | 195 ++ .../impl/GearShippingPlanServiceImpl.java | 111 + .../oa/service/impl/GearStockServiceImpl.java | 44 + .../mapper/oa/GearOrderDetailMapper.xml | 22 +- .../resources/mapper/oa/GearOrderMapper.xml | 80 +- .../mapper/oa/GearOrderProductionMapper.xml | 54 + .../resources/mapper/oa/GearStockMapper.xml | 12 + gear-ui3/package.json | 3 + gear-ui3/src/api/mat/product.js | 12 + gear-ui3/src/api/mat/productAddition.js | 5 +- gear-ui3/src/api/oms/orderProduction.js | 27 + gear-ui3/src/api/oms/salesman.js | 54 + gear-ui3/src/api/oms/shippingOrder.js | 111 + gear-ui3/src/api/wms/stock.js | 14 + .../dashboard/components/ProductSalesRank.vue | 6 +- gear-ui3/src/views/mat/sales/order/index.vue | 626 +++++ gear-ui3/src/views/oms/customer/index.vue | 1109 ++++++--- gear-ui3/src/views/oms/dashboard/index.vue | 57 +- .../src/views/oms/order/panels/detail.vue | 47 - .../src/views/oms/order/panels/orderPage.vue | 2060 +++++++++++++++-- .../src/views/oms/order/panels/receive.vue | 65 +- gear-ui3/src/views/oms/salesman/index.vue | 761 ++++++ gear-ui3/src/views/shipping/order/index.vue | 1479 ++++++++++++ .../sql/mysql/item/gear_order_production.sql | 30 + script/sql/mysql/item/gear_shipping_order.sql | 68 + 59 files changed, 8181 insertions(+), 603 deletions(-) create mode 100644 gear-oa/src/main/java/com/gear/oa/controller/GearOrderProductionController.java create mode 100644 gear-oa/src/main/java/com/gear/oa/controller/GearSalesmanController.java create mode 100644 gear-oa/src/main/java/com/gear/oa/controller/GearShippingOrderController.java create mode 100644 gear-oa/src/main/java/com/gear/oa/controller/GearShippingPlanController.java create mode 100644 gear-oa/src/main/java/com/gear/oa/domain/GearOrderProduction.java create mode 100644 gear-oa/src/main/java/com/gear/oa/domain/GearSalesman.java create mode 100644 gear-oa/src/main/java/com/gear/oa/domain/GearShippingOrder.java create mode 100644 gear-oa/src/main/java/com/gear/oa/domain/GearShippingPlan.java create mode 100644 gear-oa/src/main/java/com/gear/oa/domain/bo/GearOrderProductionBo.java create mode 100644 gear-oa/src/main/java/com/gear/oa/domain/bo/GearSalesmanBo.java create mode 100644 gear-oa/src/main/java/com/gear/oa/domain/bo/GearShippingOrderBo.java create mode 100644 gear-oa/src/main/java/com/gear/oa/domain/bo/GearShippingPlanBo.java create mode 100644 gear-oa/src/main/java/com/gear/oa/domain/vo/GearOrderProductionVo.java create mode 100644 gear-oa/src/main/java/com/gear/oa/domain/vo/GearSalesmanVo.java create mode 100644 gear-oa/src/main/java/com/gear/oa/domain/vo/GearShippingOrderVo.java create mode 100644 gear-oa/src/main/java/com/gear/oa/domain/vo/GearShippingPlanVo.java create mode 100644 gear-oa/src/main/java/com/gear/oa/mapper/GearOrderProductionMapper.java create mode 100644 gear-oa/src/main/java/com/gear/oa/mapper/GearSalesmanMapper.java create mode 100644 gear-oa/src/main/java/com/gear/oa/mapper/GearShippingOrderMapper.java create mode 100644 gear-oa/src/main/java/com/gear/oa/mapper/GearShippingPlanMapper.java create mode 100644 gear-oa/src/main/java/com/gear/oa/service/IGearOrderProductionService.java create mode 100644 gear-oa/src/main/java/com/gear/oa/service/IGearSalesmanService.java create mode 100644 gear-oa/src/main/java/com/gear/oa/service/IGearShippingOrderService.java create mode 100644 gear-oa/src/main/java/com/gear/oa/service/IGearShippingPlanService.java create mode 100644 gear-oa/src/main/java/com/gear/oa/service/impl/GearOrderProductionServiceImpl.java create mode 100644 gear-oa/src/main/java/com/gear/oa/service/impl/GearSalesmanServiceImpl.java create mode 100644 gear-oa/src/main/java/com/gear/oa/service/impl/GearShippingOrderServiceImpl.java create mode 100644 gear-oa/src/main/java/com/gear/oa/service/impl/GearShippingPlanServiceImpl.java create mode 100644 gear-oa/src/main/resources/mapper/oa/GearOrderProductionMapper.xml create mode 100644 gear-ui3/src/api/oms/orderProduction.js create mode 100644 gear-ui3/src/api/oms/salesman.js create mode 100644 gear-ui3/src/api/oms/shippingOrder.js create mode 100644 gear-ui3/src/views/mat/sales/order/index.vue create mode 100644 gear-ui3/src/views/oms/salesman/index.vue create mode 100644 gear-ui3/src/views/shipping/order/index.vue create mode 100644 script/sql/mysql/item/gear_order_production.sql create mode 100644 script/sql/mysql/item/gear_shipping_order.sql diff --git a/gear-oa/src/main/java/com/gear/oa/controller/GearOrderProductionController.java b/gear-oa/src/main/java/com/gear/oa/controller/GearOrderProductionController.java new file mode 100644 index 0000000..ced7b2d --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/controller/GearOrderProductionController.java @@ -0,0 +1,64 @@ +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.EditGroup; +import com.gear.common.enums.BusinessType; +import com.gear.oa.domain.bo.GearOrderProductionBo; +import com.gear.oa.domain.vo.GearOrderProductionVo; +import com.gear.oa.service.IGearOrderProductionService; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.Arrays; +import java.util.List; + +/** + * 订单生产记录 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/oa/orderProduction") +public class GearOrderProductionController extends BaseController { + + private final IGearOrderProductionService iGearOrderProductionService; + + @GetMapping("/list") + public TableDataInfo list(GearOrderProductionBo bo, PageQuery pageQuery) { + return iGearOrderProductionService.queryPageList(bo, pageQuery); + } + + @GetMapping("/{productionId}") + public R getInfo(@NotNull(message = "主键不能为空") @PathVariable Long productionId) { + return R.ok(iGearOrderProductionService.queryById(productionId)); + } + + @Log(title = "订单生产记录", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody GearOrderProductionBo bo) { + return toAjax(iGearOrderProductionService.updateByBo(bo)); + } + + @Log(title = "订单生产记录", businessType = BusinessType.DELETE) + @DeleteMapping("/{productionIds}") + public R remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] productionIds) { + return toAjax(iGearOrderProductionService.deleteWithValidByIds(Arrays.asList(productionIds), true)); + } + + @Log(title = "订单生产记录", businessType = BusinessType.OTHER) + @RepeatSubmit() + @PostMapping("/init/{orderId}") + public R init(@NotNull(message = "订单ID不能为空") @PathVariable Long orderId) { + return toAjax(iGearOrderProductionService.initByOrderId(orderId)); + } +} + diff --git a/gear-oa/src/main/java/com/gear/oa/controller/GearSalesmanController.java b/gear-oa/src/main/java/com/gear/oa/controller/GearSalesmanController.java new file mode 100644 index 0000000..f0f583a --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/controller/GearSalesmanController.java @@ -0,0 +1,102 @@ +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.GearSalesmanBo; +import com.gear.oa.domain.vo.GearCustomerVo; +import com.gear.oa.domain.vo.GearSalesmanVo; +import com.gear.oa.service.IGearSalesmanService; +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; + +/** + * 销售员管理 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/oa/salesman") +public class GearSalesmanController extends BaseController { + + private final IGearSalesmanService iGearSalesmanService; + + /** + * 查询销售员列表 + */ + @GetMapping("/list") + public TableDataInfo list(GearSalesmanBo bo, PageQuery pageQuery) { + return iGearSalesmanService.queryPageList(bo, pageQuery); + } + + /** + * 导出销售员列表 + */ + @Log(title = "销售员", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(GearSalesmanBo bo, HttpServletResponse response) { + List list = iGearSalesmanService.queryList(bo); + ExcelUtil.exportExcel(list, "销售员", GearSalesmanVo.class, response); + } + + /** + * 获取销售员详情 + */ + @GetMapping("/{salesmanId}") + public R getInfo(@NotNull(message = "主键不能为空") @PathVariable Long salesmanId) { + return R.ok(iGearSalesmanService.queryById(salesmanId)); + } + + /** + * 新增销售员 + */ + @Log(title = "销售员", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody GearSalesmanBo bo) { + return toAjax(iGearSalesmanService.insertByBo(bo)); + } + + /** + * 修改销售员 + */ + @Log(title = "销售员", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody GearSalesmanBo bo) { + return toAjax(iGearSalesmanService.updateByBo(bo)); + } + + /** + * 删除销售员 + */ + @Log(title = "销售员", businessType = BusinessType.DELETE) + @DeleteMapping("/{salesmanIds}") + public R remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] salesmanIds) { + return toAjax(iGearSalesmanService.deleteWithValidByIds(Arrays.asList(salesmanIds), true)); + } + + /** + * 跟进客户:按销售员反查客户列表 + */ + @GetMapping("/{salesmanId}/customers") + public TableDataInfo customers(@NotNull(message = "主键不能为空") @PathVariable Long salesmanId, + PageQuery pageQuery) { + return iGearSalesmanService.queryFollowCustomers(salesmanId, pageQuery); + } +} + diff --git a/gear-oa/src/main/java/com/gear/oa/controller/GearShippingOrderController.java b/gear-oa/src/main/java/com/gear/oa/controller/GearShippingOrderController.java new file mode 100644 index 0000000..d055bc3 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/controller/GearShippingOrderController.java @@ -0,0 +1,104 @@ +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.GearShippingOrderBo; +import com.gear.oa.domain.vo.GearShippingOrderVo; +import com.gear.oa.service.IGearShippingOrderService; +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; + +/** + * 发货单据 + * + * 说明: + * - 本模块写入 gear_shipping_order(独立表) + * - 用于订单发货/物流信息记录,不与出入库/WMS 绑定 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/oa/shippingOrder") +public class GearShippingOrderController extends BaseController { + + private final IGearShippingOrderService iGearShippingOrderService; + + /** + * 查询发货单据列表 + */ + @GetMapping("/list") + public TableDataInfo list(GearShippingOrderBo bo, PageQuery pageQuery) { + return iGearShippingOrderService.queryPageList(bo, pageQuery); + } + + /** + * 根据订单ID查询发货单据列表 + */ + @GetMapping("/listByOrderId/{orderId}") + public R> listByOrderId(@PathVariable Long orderId) { + return R.ok(iGearShippingOrderService.queryListByOrderId(orderId)); + } + + /** + * 导出发货单据列表 + */ + @Log(title = "发货单据", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(GearShippingOrderBo bo, HttpServletResponse response) { + List list = iGearShippingOrderService.queryList(bo); + ExcelUtil.exportExcel(list, "发货单据", GearShippingOrderVo.class, response); + } + + /** + * 获取发货单据详细信息 + */ + @GetMapping("/{shippingId}") + public R getInfo(@NotNull(message = "主键不能为空") @PathVariable Long shippingId) { + return R.ok(iGearShippingOrderService.queryById(shippingId)); + } + + /** + * 新增发货单据 + */ + @Log(title = "发货单据", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody GearShippingOrderBo bo) { + return toAjax(iGearShippingOrderService.insertByBo(bo)); + } + + /** + * 修改发货单据 + */ + @Log(title = "发货单据", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody GearShippingOrderBo bo) { + return toAjax(iGearShippingOrderService.updateByBo(bo)); + } + + /** + * 删除发货单据 + */ + @Log(title = "发货单据", businessType = BusinessType.DELETE) + @DeleteMapping("/{shippingIds}") + public R remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] shippingIds) { + return toAjax(iGearShippingOrderService.deleteWithValidByIds(Arrays.asList(shippingIds), true)); + } +} + diff --git a/gear-oa/src/main/java/com/gear/oa/controller/GearShippingPlanController.java b/gear-oa/src/main/java/com/gear/oa/controller/GearShippingPlanController.java new file mode 100644 index 0000000..47b0f4b --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/controller/GearShippingPlanController.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.GearShippingPlanBo; +import com.gear.oa.domain.vo.GearShippingPlanVo; +import com.gear.oa.service.IGearShippingPlanService; +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; + +/** + * 发货计划 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/oa/shippingPlan") +public class GearShippingPlanController extends BaseController { + + private final IGearShippingPlanService iGearShippingPlanService; + + /** + * 查询发货计划列表 + */ + @GetMapping("/list") + public TableDataInfo list(GearShippingPlanBo bo, PageQuery pageQuery) { + return iGearShippingPlanService.queryPageList(bo, pageQuery); + } + + /** + * 查询发货计划列表(带单据数) + */ + @GetMapping("/listWithCount") + public R> listWithCount(GearShippingPlanBo bo) { + return R.ok(iGearShippingPlanService.queryListWithCount(bo)); + } + + /** + * 导出发货计划列表 + */ + @Log(title = "发货计划", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(GearShippingPlanBo bo, HttpServletResponse response) { + List list = iGearShippingPlanService.queryList(bo); + ExcelUtil.exportExcel(list, "发货计划", GearShippingPlanVo.class, response); + } + + /** + * 获取发货计划详细信息 + */ + @GetMapping("/{planId}") + public R getInfo(@NotNull(message = "主键不能为空") @PathVariable Long planId) { + return R.ok(iGearShippingPlanService.queryById(planId)); + } + + /** + * 新增发货计划 + */ + @Log(title = "发货计划", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody GearShippingPlanBo bo) { + return toAjax(iGearShippingPlanService.insertByBo(bo)); + } + + /** + * 修改发货计划 + */ + @Log(title = "发货计划", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody GearShippingPlanBo bo) { + return toAjax(iGearShippingPlanService.updateByBo(bo)); + } + + /** + * 删除发货计划 + */ + @Log(title = "发货计划", businessType = BusinessType.DELETE) + @DeleteMapping("/{planIds}") + public R remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] planIds) { + return toAjax(iGearShippingPlanService.deleteWithValidByIds(Arrays.asList(planIds), true)); + } +} + 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 index 2408c46..d6fbeba 100644 --- a/gear-oa/src/main/java/com/gear/oa/controller/GearStockController.java +++ b/gear-oa/src/main/java/com/gear/oa/controller/GearStockController.java @@ -22,6 +22,8 @@ import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import java.util.Arrays; import java.util.List; +import java.util.Map; +import java.math.BigDecimal; /** * 库存:原材料/产品与库区/库位的存放关系 @@ -45,6 +47,12 @@ public class GearStockController extends BaseController { return iGearStockService.queryPageList(bo, pageQuery); } + @PostMapping("/sumQuantityByItemIds") + public R> sumQuantityByItemIds(@RequestParam(defaultValue = "product") String itemType, + @RequestBody List itemIds) { + return R.ok(iGearStockService.sumQuantityByItemIds(itemType, itemIds)); + } + /** * 导出库存:原材料/产品与库区/库位的存放关系列表 */ diff --git a/gear-oa/src/main/java/com/gear/oa/domain/GearOrder.java b/gear-oa/src/main/java/com/gear/oa/domain/GearOrder.java index 0761b0c..c3a2029 100644 --- a/gear-oa/src/main/java/com/gear/oa/domain/GearOrder.java +++ b/gear-oa/src/main/java/com/gear/oa/domain/GearOrder.java @@ -44,6 +44,12 @@ public class GearOrder extends BaseEntity { * 销售经理 */ private String salesManager; + + /** + * 销售员ID(挂接销售员管理) + */ + @TableField("salesman_id") + private Long salesmanId; /** * 订单状态(0=新建,1=生产中,2=已完成,3=已取消) */ @@ -70,4 +76,10 @@ public class GearOrder extends BaseEntity { */ private BigDecimal noTaxAmount; + /** + * 合同Excel附件ossId列表(逗号分隔) + */ + @TableField("contract_excel_oss_ids") + private String contractExcelOssIds; + } diff --git a/gear-oa/src/main/java/com/gear/oa/domain/GearOrderProduction.java b/gear-oa/src/main/java/com/gear/oa/domain/GearOrderProduction.java new file mode 100644 index 0000000..6d8ba14 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/GearOrderProduction.java @@ -0,0 +1,44 @@ +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_order_production + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("gear_order_production") +public class GearOrderProduction extends BaseEntity { + + private static final long serialVersionUID = 1L; + + @TableId(value = "production_id") + private Long productionId; + + private Long orderId; + + private Long orderDetailId; + + private Long productId; + + private BigDecimal planQty; + + private BigDecimal finishedQty; + + private BigDecimal badQty; + + private String unit; + + private String remark; + + @TableLogic(value = "0", delval = "2") + private String delFlag; +} + diff --git a/gear-oa/src/main/java/com/gear/oa/domain/GearSalesman.java b/gear-oa/src/main/java/com/gear/oa/domain/GearSalesman.java new file mode 100644 index 0000000..f51b1f3 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/GearSalesman.java @@ -0,0 +1,52 @@ +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_salesman + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("gear_salesman") +public class GearSalesman extends BaseEntity { + + private static final long serialVersionUID = 1L; + + /** + * 销售员ID + */ + @TableId(value = "salesman_id") + private Long salesmanId; + + /** + * 销售员姓名 + */ + private String name; + + /** + * 联系电话 + */ + private String mobile; + + /** + * 状态(0正常 1停用) + */ + private Integer status; + + /** + * 备注 + */ + private String remark; + + /** + * 删除标志(0=正常,1=已删除) + */ + @TableLogic + private Integer delFlag; +} + diff --git a/gear-oa/src/main/java/com/gear/oa/domain/GearShippingOrder.java b/gear-oa/src/main/java/com/gear/oa/domain/GearShippingOrder.java new file mode 100644 index 0000000..85c303b --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/GearShippingOrder.java @@ -0,0 +1,117 @@ +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.util.Date; + +/** + * 发货单据对象 gear_shipping_order + * + * 说明: + * - 用于记录订单发货信息(物流公司/运单号/收货信息等) + * - 与出入库/WMS 单据无关,避免与库存模块耦合 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("gear_shipping_order") +public class GearShippingOrder extends BaseEntity { + + private static final long serialVersionUID = 1L; + + /** + * 发货单据ID + */ + @TableId(value = "shipping_id") + private Long shippingId; + + /** + * 发货单号(唯一) + */ + private String shippingNo; + + /** + * 发货单名称(展示用) + */ + private String shippingName; + + /** + * 发货计划ID + */ + private Long planId; + + /** + * 关联订单ID + */ + private Long orderId; + + /** + * 订单编号快照 + */ + private String orderCode; + + /** + * 收货单位 + */ + private String receiverCompany; + + /** + * 收货客户ID(真实归属客户) + */ + private Long receiverCustomerId; + + /** + * 发货时间 + */ + private Date shipTime; + + /** + * 负责人 + */ + private String responsibleName; + + /** + * 物流公司 + */ + private String logisticsCompany; + + /** + * 运单号 + */ + private String logisticsNo; + + /** + * 收货人 + */ + private String receiverName; + + /** + * 收货电话 + */ + private String receiverPhone; + + /** + * 收货地址 + */ + private String receiverAddress; + + /** + * 完成状态(0未发货 1已打印 2已发货 3已完成) + */ + private String status; + + /** + * 备注 + */ + private String remark; + + /** + * 删除标志(0存在 2删除) + */ + @TableLogic(value = "0", delval = "2") + private String delFlag; +} diff --git a/gear-oa/src/main/java/com/gear/oa/domain/GearShippingPlan.java b/gear-oa/src/main/java/com/gear/oa/domain/GearShippingPlan.java new file mode 100644 index 0000000..72e469f --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/GearShippingPlan.java @@ -0,0 +1,55 @@ +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.fasterxml.jackson.annotation.JsonFormat; +import com.gear.common.core.domain.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +/** + * 发货计划对象 gear_shipping_plan + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("gear_shipping_plan") +public class GearShippingPlan extends BaseEntity { + + private static final long serialVersionUID = 1L; + + /** + * 发货计划ID + */ + @TableId(value = "plan_id") + private Long planId; + + /** + * 计划名称 + */ + private String planName; + + /** + * 计划日期 + */ + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + private Date planDate; + + /** + * 状态(0未完成 1已完成) + */ + private String status; + + /** + * 备注 + */ + private String remark; + + /** + * 删除标志(0存在 2删除) + */ + @TableLogic(value = "0", delval = "2") + private String delFlag; +} diff --git a/gear-oa/src/main/java/com/gear/oa/domain/bo/GearOrderBo.java b/gear-oa/src/main/java/com/gear/oa/domain/bo/GearOrderBo.java index 1f7d775..ef904bf 100644 --- a/gear-oa/src/main/java/com/gear/oa/domain/bo/GearOrderBo.java +++ b/gear-oa/src/main/java/com/gear/oa/domain/bo/GearOrderBo.java @@ -48,6 +48,11 @@ public class GearOrderBo extends BaseEntity { */ private String salesManager; + /** + * 销售员ID(挂接销售员管理) + */ + private Long salesmanId; + /** * 订单状态(0=新建,1=生产中,2=已完成,3=已取消) */ @@ -73,5 +78,9 @@ public class GearOrderBo extends BaseEntity { */ private BigDecimal noTaxAmount; + /** + * 合同Excel附件ossId列表(逗号分隔) + */ + private String contractExcelOssIds; } diff --git a/gear-oa/src/main/java/com/gear/oa/domain/bo/GearOrderProductionBo.java b/gear-oa/src/main/java/com/gear/oa/domain/bo/GearOrderProductionBo.java new file mode 100644 index 0000000..a99620f --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/bo/GearOrderProductionBo.java @@ -0,0 +1,37 @@ +package com.gear.oa.domain.bo; + +import com.gear.common.core.domain.BaseEntity; +import com.gear.common.core.validate.EditGroup; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.NotNull; +import java.math.BigDecimal; + +/** + * 订单生产记录业务对象 gear_order_production + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class GearOrderProductionBo extends BaseEntity { + + private Long productionId; + + private Long orderId; + + private Long orderDetailId; + + private Long productId; + + private BigDecimal planQty; + + @NotNull(message = "完成数量不能为空", groups = {EditGroup.class}) + private BigDecimal finishedQty; + + private BigDecimal badQty; + + private String unit; + + private String remark; +} + diff --git a/gear-oa/src/main/java/com/gear/oa/domain/bo/GearSalesmanBo.java b/gear-oa/src/main/java/com/gear/oa/domain/bo/GearSalesmanBo.java new file mode 100644 index 0000000..1efd8f9 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/bo/GearSalesmanBo.java @@ -0,0 +1,39 @@ +package com.gear.oa.domain.bo; + +import com.gear.common.core.domain.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 销售员业务对象 gear_salesman + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class GearSalesmanBo extends BaseEntity { + + /** + * 销售员ID + */ + private Long salesmanId; + + /** + * 销售员姓名 + */ + private String name; + + /** + * 联系电话 + */ + private String mobile; + + /** + * 状态(0正常 1停用) + */ + private Integer status; + + /** + * 备注 + */ + private String remark; +} + diff --git a/gear-oa/src/main/java/com/gear/oa/domain/bo/GearShippingOrderBo.java b/gear-oa/src/main/java/com/gear/oa/domain/bo/GearShippingOrderBo.java new file mode 100644 index 0000000..6db5dad --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/bo/GearShippingOrderBo.java @@ -0,0 +1,138 @@ +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.NotNull; +import java.util.Date; +import org.springframework.format.annotation.DateTimeFormat; + +/** + * 发货单据业务对象 gear_shipping_order + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class GearShippingOrderBo extends BaseEntity { + + /** + * 发货单据ID + */ + private Long shippingId; + + /** + * 发货单号(唯一) + */ + private String shippingNo; + + /** + * 发货单名称(展示用) + */ + private String shippingName; + + /** + * 发货计划ID + */ + private Long planId; + + /** + * 关联订单ID + * + * 说明: + * - 发货单据必须绑定订单(订单是发货的业务来源) + * - 前端存在“只修改完成状态”的场景(仅提交 shippingId/status),这里仍要求携带 orderId, + * 便于做订单状态联动与数据归属校验 + */ + @NotNull(message = "订单ID不能为空", groups = {AddGroup.class, EditGroup.class}) + private Long orderId; + + /** + * 客户ID(用于按客户维度查询发货单据:通过订单反查) + * + * 说明:发货单据表本身不存 customerId,这里是查询条件,后端会先查出订单ID集合再过滤发货单据 + */ + private Long customerId; + + /** + * 销售员ID(用于按销售员维度查询发货单据:通过订单反查) + * + * 说明:发货单据表本身不存 salesmanId,这里是查询条件,后端会先查出订单ID集合再过滤发货单据 + */ + private Long salesmanId; + + /** + * 订单编号快照 + */ + private String orderCode; + + /** + * 收货单位 + */ + private String receiverCompany; + + /** + * 收货客户ID(真实归属客户) + * + * 说明:用于客户维度归属统计/查询(客户管理页按此字段精确查询“该客户实际收货”的发货单据) + */ + private Long receiverCustomerId; + + /** + * 发货时间 + */ + private Date shipTime; + + /** + * 发货时间范围(开始) + */ + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date shipTimeStart; + + /** + * 发货时间范围(结束) + */ + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date shipTimeEnd; + + /** + * 负责人 + */ + private String responsibleName; + + /** + * 物流公司 + */ + private String logisticsCompany; + + /** + * 运单号 + */ + private String logisticsNo; + + /** + * 收货人 + */ + private String receiverName; + + /** + * 收货电话 + */ + private String receiverPhone; + + /** + * 收货地址 + */ + private String receiverAddress; + + /** + * 完成状态(0未发货 1已打印 2已发货 3已完成) + */ + private String status; + + /** + * 备注 + */ + private String remark; +} diff --git a/gear-oa/src/main/java/com/gear/oa/domain/bo/GearShippingPlanBo.java b/gear-oa/src/main/java/com/gear/oa/domain/bo/GearShippingPlanBo.java new file mode 100644 index 0000000..4f6a6bb --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/bo/GearShippingPlanBo.java @@ -0,0 +1,50 @@ +package com.gear.oa.domain.bo; + +import com.fasterxml.jackson.annotation.JsonFormat; +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 org.springframework.format.annotation.DateTimeFormat; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.Date; + +/** + * 发货计划业务对象 gear_shipping_plan + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class GearShippingPlanBo extends BaseEntity { + + /** + * 发货计划ID + */ + private Long planId; + + /** + * 计划名称 + */ + @NotBlank(message = "计划名称不能为空", groups = {AddGroup.class, EditGroup.class}) + private String planName; + + /** + * 计划日期 + */ + @NotNull(message = "计划日期不能为空", groups = {AddGroup.class, EditGroup.class}) + @DateTimeFormat(pattern = "yyyy-MM-dd") + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + private Date planDate; + + /** + * 状态(0未完成 1已完成) + */ + private String status; + + /** + * 备注 + */ + private String remark; +} diff --git a/gear-oa/src/main/java/com/gear/oa/domain/vo/GearOrderDetailVo.java b/gear-oa/src/main/java/com/gear/oa/domain/vo/GearOrderDetailVo.java index 599ae29..c8be30d 100644 --- a/gear-oa/src/main/java/com/gear/oa/domain/vo/GearOrderDetailVo.java +++ b/gear-oa/src/main/java/com/gear/oa/domain/vo/GearOrderDetailVo.java @@ -76,4 +76,25 @@ public class GearOrderDetailVo { private String productName; private String productCode; + /** + * 产品类型(product=产品/成品,semi=半成品,raw=原料) + * 说明:用于“订单明细”页过滤,只允许成品进入发货 + */ + private String productType; + + /** + * 产品规格(来自产品管理 mat_product) + */ + private String spec; + + /** + * 产品型号(来自产品管理 mat_product) + */ + private String model; + + /** + * 产品单价(来自产品管理 mat_product;用于订单明细快捷填写) + */ + private BigDecimal unitPrice; + } diff --git a/gear-oa/src/main/java/com/gear/oa/domain/vo/GearOrderProductionVo.java b/gear-oa/src/main/java/com/gear/oa/domain/vo/GearOrderProductionVo.java new file mode 100644 index 0000000..24b84c6 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/vo/GearOrderProductionVo.java @@ -0,0 +1,46 @@ +package com.gear.oa.domain.vo; + +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 订单生产记录视图对象 gear_order_production + */ +@Data +public class GearOrderProductionVo { + + private Long productionId; + + private Long orderId; + + private Long orderDetailId; + + private Long productId; + + private BigDecimal planQty; + + private BigDecimal finishedQty; + + private BigDecimal badQty; + + private String unit; + + private String remark; + + private Date createTime; + + private Date updateTime; + + private String productName; + + private String productCode; + + private String productType; + + private String spec; + + private String model; +} + diff --git a/gear-oa/src/main/java/com/gear/oa/domain/vo/GearOrderVo.java b/gear-oa/src/main/java/com/gear/oa/domain/vo/GearOrderVo.java index f24f775..42a7820 100644 --- a/gear-oa/src/main/java/com/gear/oa/domain/vo/GearOrderVo.java +++ b/gear-oa/src/main/java/com/gear/oa/domain/vo/GearOrderVo.java @@ -50,11 +50,16 @@ public class GearOrderVo extends BaseEntity { private Integer company; /** - * 销售经理 + * 销售员(展示用:从 gear_salesman.name 联查得到) */ - @ExcelProperty(value = "销售经理") + @ExcelProperty(value = "销售员") private String salesManager; + /** + * 销售员ID(挂接销售员管理) + */ + private Long salesmanId; + /** * 订单状态(0=新建,1=生产中,2=已完成,3=已取消) */ @@ -86,6 +91,18 @@ public class GearOrderVo extends BaseEntity { @ExcelProperty(value = "无税金额") private BigDecimal noTaxAmount; + /** + * 合同Excel附件ossId列表(逗号分隔) + */ + private String contractExcelOssIds; + private String customerName; + private Integer shippingMaxStatus; + + private Integer shippedFlag; + + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date lastShipTime; + } diff --git a/gear-oa/src/main/java/com/gear/oa/domain/vo/GearSalesmanVo.java b/gear-oa/src/main/java/com/gear/oa/domain/vo/GearSalesmanVo.java new file mode 100644 index 0000000..0b3d274 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/vo/GearSalesmanVo.java @@ -0,0 +1,31 @@ +package com.gear.oa.domain.vo; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import lombok.Data; + +/** + * 销售员视图对象 gear_salesman + */ +@Data +@ExcelIgnoreUnannotated +public class GearSalesmanVo { + + private static final long serialVersionUID = 1L; + + @ExcelProperty(value = "销售员ID") + private Long salesmanId; + + @ExcelProperty(value = "销售员姓名") + private String name; + + @ExcelProperty(value = "联系电话") + private String mobile; + + @ExcelProperty(value = "状态(0正常 1停用)") + private Integer status; + + @ExcelProperty(value = "备注") + private String remark; +} + diff --git a/gear-oa/src/main/java/com/gear/oa/domain/vo/GearShippingOrderVo.java b/gear-oa/src/main/java/com/gear/oa/domain/vo/GearShippingOrderVo.java new file mode 100644 index 0000000..f4914ea --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/vo/GearShippingOrderVo.java @@ -0,0 +1,69 @@ +package com.gear.oa.domain.vo; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import com.gear.common.core.domain.BaseEntity; +import lombok.Data; + +import java.util.Date; + +/** + * 发货单据视图对象 gear_shipping_order + */ +@Data +@ExcelIgnoreUnannotated +public class GearShippingOrderVo extends BaseEntity { + + private static final long serialVersionUID = 1L; + + @ExcelProperty(value = "发货单据ID") + private Long shippingId; + + @ExcelProperty(value = "发货单号") + private String shippingNo; + + @ExcelProperty(value = "发货单名称") + private String shippingName; + + @ExcelProperty(value = "发货计划ID") + private Long planId; + + @ExcelProperty(value = "订单ID") + private Long orderId; + + @ExcelProperty(value = "订单编号") + private String orderCode; + + @ExcelProperty(value = "收货单位") + private String receiverCompany; + + @ExcelProperty(value = "收货客户ID") + private Long receiverCustomerId; + + @ExcelProperty(value = "发货时间") + private Date shipTime; + + @ExcelProperty(value = "负责人") + private String responsibleName; + + @ExcelProperty(value = "物流公司") + private String logisticsCompany; + + @ExcelProperty(value = "运单号") + private String logisticsNo; + + @ExcelProperty(value = "收货人") + private String receiverName; + + @ExcelProperty(value = "收货电话") + private String receiverPhone; + + @ExcelProperty(value = "收货地址") + private String receiverAddress; + + @ExcelProperty(value = "完成状态") + private String status; + + @ExcelProperty(value = "备注") + private String remark; +} diff --git a/gear-oa/src/main/java/com/gear/oa/domain/vo/GearShippingPlanVo.java b/gear-oa/src/main/java/com/gear/oa/domain/vo/GearShippingPlanVo.java new file mode 100644 index 0000000..3d697cb --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/domain/vo/GearShippingPlanVo.java @@ -0,0 +1,37 @@ +package com.gear.oa.domain.vo; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import com.gear.common.core.domain.BaseEntity; +import lombok.Data; + +import java.util.Date; + +/** + * 发货计划视图对象 gear_shipping_plan + */ +@Data +@ExcelIgnoreUnannotated +public class GearShippingPlanVo extends BaseEntity { + + private static final long serialVersionUID = 1L; + + @ExcelProperty(value = "计划ID") + private Long planId; + + @ExcelProperty(value = "计划名称") + private String planName; + + @ExcelProperty(value = "计划日期") + private Date planDate; + + @ExcelProperty(value = "状态") + private String status; + + @ExcelProperty(value = "备注") + private String remark; + + @ExcelProperty(value = "单据数") + private Long shippingCount; +} + diff --git a/gear-oa/src/main/java/com/gear/oa/mapper/GearOrderProductionMapper.java b/gear-oa/src/main/java/com/gear/oa/mapper/GearOrderProductionMapper.java new file mode 100644 index 0000000..5f8fcef --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/mapper/GearOrderProductionMapper.java @@ -0,0 +1,20 @@ +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.GearOrderProduction; +import com.gear.oa.domain.vo.GearOrderProductionVo; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 订单生产记录Mapper接口 + */ +public interface GearOrderProductionMapper extends BaseMapperPlus { + + Page selectVoPagePlus(Page page, @Param("ew") Wrapper wrapper); + + List selectVoListPlus(@Param("ew") Wrapper wrapper); +} diff --git a/gear-oa/src/main/java/com/gear/oa/mapper/GearSalesmanMapper.java b/gear-oa/src/main/java/com/gear/oa/mapper/GearSalesmanMapper.java new file mode 100644 index 0000000..414443b --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/mapper/GearSalesmanMapper.java @@ -0,0 +1,12 @@ +package com.gear.oa.mapper; + +import com.gear.common.core.mapper.BaseMapperPlus; +import com.gear.oa.domain.GearSalesman; +import com.gear.oa.domain.vo.GearSalesmanVo; + +/** + * 销售员Mapper接口 + */ +public interface GearSalesmanMapper extends BaseMapperPlus { +} + diff --git a/gear-oa/src/main/java/com/gear/oa/mapper/GearShippingOrderMapper.java b/gear-oa/src/main/java/com/gear/oa/mapper/GearShippingOrderMapper.java new file mode 100644 index 0000000..18c69f0 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/mapper/GearShippingOrderMapper.java @@ -0,0 +1,12 @@ +package com.gear.oa.mapper; + +import com.gear.common.core.mapper.BaseMapperPlus; +import com.gear.oa.domain.GearShippingOrder; +import com.gear.oa.domain.vo.GearShippingOrderVo; + +/** + * 发货单据Mapper + */ +public interface GearShippingOrderMapper extends BaseMapperPlus { +} + diff --git a/gear-oa/src/main/java/com/gear/oa/mapper/GearShippingPlanMapper.java b/gear-oa/src/main/java/com/gear/oa/mapper/GearShippingPlanMapper.java new file mode 100644 index 0000000..e97309e --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/mapper/GearShippingPlanMapper.java @@ -0,0 +1,50 @@ +package com.gear.oa.mapper; + +import com.gear.common.core.mapper.BaseMapperPlus; +import com.gear.oa.domain.GearShippingPlan; +import com.gear.oa.domain.bo.GearShippingPlanBo; +import com.gear.oa.domain.vo.GearShippingPlanVo; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; + +import java.util.List; + +/** + * 发货计划Mapper + */ +public interface GearShippingPlanMapper extends BaseMapperPlus { + + @Select({ + "" + }) + List selectVoListWithCount(@Param("bo") GearShippingPlanBo bo); +} + 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 index 3e60f78..fbe8a6c 100644 --- a/gear-oa/src/main/java/com/gear/oa/mapper/GearStockMapper.java +++ b/gear-oa/src/main/java/com/gear/oa/mapper/GearStockMapper.java @@ -8,6 +8,8 @@ import com.gear.oa.domain.vo.GearStockVo; import org.apache.ibatis.annotations.Param; import java.math.BigDecimal; +import java.util.List; +import java.util.Map; /** * 库存:原材料/产品与库区/库位的存放关系Mapper接口 @@ -19,6 +21,8 @@ public interface GearStockMapper extends BaseMapperPlus> selectSumQuantityByItemIds(@Param("itemType") String itemType, @Param("itemIds") List itemIds); + /** * 分页联查物品名称和编码,支持Wrapper动态条件,返回Page */ diff --git a/gear-oa/src/main/java/com/gear/oa/service/IGearOrderProductionService.java b/gear-oa/src/main/java/com/gear/oa/service/IGearOrderProductionService.java new file mode 100644 index 0000000..a1c9a18 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/service/IGearOrderProductionService.java @@ -0,0 +1,31 @@ +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.GearOrderProductionBo; +import com.gear.oa.domain.vo.GearOrderProductionVo; + +import java.util.Collection; +import java.util.List; + +/** + * 订单生产记录Service接口 + */ +public interface IGearOrderProductionService { + + GearOrderProductionVo queryById(Long productionId); + + TableDataInfo queryPageList(GearOrderProductionBo bo, PageQuery pageQuery); + + List queryList(GearOrderProductionBo bo); + + Boolean updateByBo(GearOrderProductionBo bo); + + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 初始化/同步:按订单明细生成生产记录,并同步计划数量 + */ + Boolean initByOrderId(Long orderId); +} + diff --git a/gear-oa/src/main/java/com/gear/oa/service/IGearSalesmanService.java b/gear-oa/src/main/java/com/gear/oa/service/IGearSalesmanService.java new file mode 100644 index 0000000..bbd2816 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/service/IGearSalesmanService.java @@ -0,0 +1,34 @@ +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.GearSalesmanBo; +import com.gear.oa.domain.vo.GearCustomerVo; +import com.gear.oa.domain.vo.GearSalesmanVo; + +import java.util.Collection; +import java.util.List; + +/** + * 销售员Service接口 + */ +public interface IGearSalesmanService { + + GearSalesmanVo queryById(Long salesmanId); + + TableDataInfo queryPageList(GearSalesmanBo bo, PageQuery pageQuery); + + List queryList(GearSalesmanBo bo); + + Boolean insertByBo(GearSalesmanBo bo); + + Boolean updateByBo(GearSalesmanBo bo); + + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 查询销售员的跟进客户(从订单中反查:salesManager=销售员姓名 -> customerId -> 客户信息) + */ + TableDataInfo queryFollowCustomers(Long salesmanId, PageQuery pageQuery); +} + diff --git a/gear-oa/src/main/java/com/gear/oa/service/IGearShippingOrderService.java b/gear-oa/src/main/java/com/gear/oa/service/IGearShippingOrderService.java new file mode 100644 index 0000000..460403d --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/service/IGearShippingOrderService.java @@ -0,0 +1,51 @@ +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.GearShippingOrderBo; +import com.gear.oa.domain.vo.GearShippingOrderVo; + +import java.util.Collection; +import java.util.List; + +/** + * 发货单据Service接口 + */ +public interface IGearShippingOrderService { + + /** + * 查询发货单据 + */ + GearShippingOrderVo queryById(Long shippingId); + + /** + * 查询发货单据列表(分页) + */ + TableDataInfo queryPageList(GearShippingOrderBo bo, PageQuery pageQuery); + + /** + * 查询发货单据列表(不分页) + */ + List queryList(GearShippingOrderBo bo); + + /** + * 新增发货单据 + */ + Boolean insertByBo(GearShippingOrderBo bo); + + /** + * 修改发货单据 + */ + Boolean updateByBo(GearShippingOrderBo bo); + + /** + * 删除发货单据 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 根据订单ID查询发货单据 + */ + List queryListByOrderId(Long orderId); +} + diff --git a/gear-oa/src/main/java/com/gear/oa/service/IGearShippingPlanService.java b/gear-oa/src/main/java/com/gear/oa/service/IGearShippingPlanService.java new file mode 100644 index 0000000..6333750 --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/service/IGearShippingPlanService.java @@ -0,0 +1,30 @@ +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.GearShippingPlanBo; +import com.gear.oa.domain.vo.GearShippingPlanVo; + +import java.util.Collection; +import java.util.List; + +/** + * 发货计划Service接口 + */ +public interface IGearShippingPlanService { + + GearShippingPlanVo queryById(Long planId); + + TableDataInfo queryPageList(GearShippingPlanBo bo, PageQuery pageQuery); + + List queryList(GearShippingPlanBo bo); + + List queryListWithCount(GearShippingPlanBo bo); + + Boolean insertByBo(GearShippingPlanBo bo); + + Boolean updateByBo(GearShippingPlanBo 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 index 5693340..14fe576 100644 --- a/gear-oa/src/main/java/com/gear/oa/service/IGearStockService.java +++ b/gear-oa/src/main/java/com/gear/oa/service/IGearStockService.java @@ -8,6 +8,7 @@ import com.gear.oa.domain.vo.GearStockVo; import java.math.BigDecimal; import java.util.Collection; import java.util.List; +import java.util.Map; /** * 库存:原材料/产品与库区/库位的存放关系Service接口 @@ -47,6 +48,8 @@ public interface IGearStockService { */ Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + Map sumQuantityByItemIds(String itemType, List itemIds); + // /** // * 根据原材料ID获取库存数量 (用于生成推荐采购计划) // */ diff --git a/gear-oa/src/main/java/com/gear/oa/service/impl/GearOrderProductionServiceImpl.java b/gear-oa/src/main/java/com/gear/oa/service/impl/GearOrderProductionServiceImpl.java new file mode 100644 index 0000000..8ba49da --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/service/impl/GearOrderProductionServiceImpl.java @@ -0,0 +1,150 @@ +package com.gear.oa.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.IdUtil; +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.GearOrderProduction; +import com.gear.oa.domain.bo.GearOrderProductionBo; +import com.gear.oa.domain.vo.GearOrderDetailVo; +import com.gear.oa.domain.vo.GearOrderProductionVo; +import com.gear.oa.mapper.GearOrderDetailMapper; +import com.gear.oa.mapper.GearOrderProductionMapper; +import com.gear.oa.service.IGearOrderProductionService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * 订单生产记录Service业务层处理 + */ +@RequiredArgsConstructor +@Service +public class GearOrderProductionServiceImpl implements IGearOrderProductionService { + + private final GearOrderProductionMapper baseMapper; + private final GearOrderDetailMapper orderDetailMapper; + + @Override + public GearOrderProductionVo queryById(Long productionId) { + return baseMapper.selectVoById(productionId); + } + + @Override + public TableDataInfo queryPageList(GearOrderProductionBo bo, PageQuery pageQuery) { + QueryWrapper qw = buildQueryWrapperPlus(bo); + Page result = baseMapper.selectVoPagePlus(pageQuery.build(), qw); + return TableDataInfo.build(result); + } + + @Override + public List queryList(GearOrderProductionBo bo) { + QueryWrapper qw = buildQueryWrapperPlus(bo); + return baseMapper.selectVoListPlus(qw); + } + + private QueryWrapper buildQueryWrapperPlus(GearOrderProductionBo bo) { + Map params = bo.getParams(); + QueryWrapper qw = Wrappers.query(); + qw.eq("p.del_flag", "0"); + qw.eq(bo.getProductionId() != null, "p.production_id", bo.getProductionId()); + qw.eq(bo.getOrderId() != null, "p.order_id", bo.getOrderId()); + qw.eq(bo.getOrderDetailId() != null, "p.order_detail_id", bo.getOrderDetailId()); + qw.eq(bo.getProductId() != null, "p.product_id", bo.getProductId()); + qw.orderByAsc("p.order_detail_id"); + qw.orderByDesc("p.update_time"); + qw.orderByDesc("p.create_time"); + return qw; + } + + @Override + public Boolean updateByBo(GearOrderProductionBo bo) { + GearOrderProduction update = BeanUtil.toBean(bo, GearOrderProduction.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + private void validEntityBeforeSave(GearOrderProduction entity) { + if (entity == null) return; + if (entity.getProductionId() == null) { + entity.setProductionId(IdUtil.getSnowflakeNextId()); + } + if (entity.getFinishedQty() == null) { + entity.setFinishedQty(BigDecimal.ZERO); + } + if (entity.getBadQty() == null) { + entity.setBadQty(BigDecimal.ZERO); + } + if (StringUtils.isBlank(entity.getDelFlag())) { + entity.setDelFlag("0"); + } + } + + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if (isValid) { + } + return baseMapper.deleteBatchIds(ids) > 0; + } + + @Override + public Boolean initByOrderId(Long orderId) { + if (orderId == null) return false; + List details = orderDetailMapper.selectVoListByOrderId(orderId); + if (details == null || details.isEmpty()) return true; + + List detailIds = details.stream().map(GearOrderDetailVo::getDetailId).filter(Objects::nonNull).distinct().collect(Collectors.toList()); + if (detailIds.isEmpty()) return true; + + List existing = baseMapper.selectList(Wrappers.lambdaQuery() + .in(GearOrderProduction::getOrderDetailId, detailIds)); + Map existMap = new HashMap<>(); + if (existing != null) { + for (GearOrderProduction e : existing) { + if (e != null && e.getOrderDetailId() != null) { + existMap.put(e.getOrderDetailId(), e); + } + } + } + + for (GearOrderDetailVo d : details) { + if (d == null || d.getDetailId() == null) continue; + GearOrderProduction hit = existMap.get(d.getDetailId()); + BigDecimal planQty = d.getQuantity() == null ? BigDecimal.ZERO : BigDecimal.valueOf(d.getQuantity()); + if (hit == null) { + GearOrderProduction add = new GearOrderProduction(); + add.setProductionId(IdUtil.getSnowflakeNextId()); + add.setOrderId(orderId); + add.setOrderDetailId(d.getDetailId()); + add.setProductId(d.getProductId()); + add.setPlanQty(planQty); + add.setFinishedQty(BigDecimal.ZERO); + add.setBadQty(BigDecimal.ZERO); + add.setUnit(d.getUnit() == null ? "" : d.getUnit()); + add.setDelFlag("0"); + baseMapper.insert(add); + } else { + GearOrderProduction upd = new GearOrderProduction(); + upd.setProductionId(hit.getProductionId()); + upd.setOrderId(orderId); + upd.setOrderDetailId(d.getDetailId()); + upd.setProductId(d.getProductId()); + upd.setPlanQty(planQty); + upd.setUnit(d.getUnit() == null ? "" : d.getUnit()); + baseMapper.updateById(upd); + } + } + return true; + } +} diff --git a/gear-oa/src/main/java/com/gear/oa/service/impl/GearOrderServiceImpl.java b/gear-oa/src/main/java/com/gear/oa/service/impl/GearOrderServiceImpl.java index 1b6ba39..9e13c93 100644 --- a/gear-oa/src/main/java/com/gear/oa/service/impl/GearOrderServiceImpl.java +++ b/gear-oa/src/main/java/com/gear/oa/service/impl/GearOrderServiceImpl.java @@ -13,7 +13,9 @@ import org.springframework.stereotype.Service; import com.gear.oa.domain.bo.GearOrderBo; import com.gear.oa.domain.vo.GearOrderVo; import com.gear.oa.domain.GearOrder; +import com.gear.oa.domain.GearShippingOrder; import com.gear.oa.mapper.GearOrderMapper; +import com.gear.oa.mapper.GearShippingOrderMapper; import com.gear.oa.service.IGearOrderService; import java.util.List; @@ -31,13 +33,51 @@ import java.util.Collection; public class GearOrderServiceImpl implements IGearOrderService { private final GearOrderMapper baseMapper; + private final GearShippingOrderMapper shippingOrderMapper; /** * 查询订单主 */ @Override public GearOrderVo queryById(Long orderId){ - return baseMapper.selectVoById(orderId); + GearOrderVo vo = baseMapper.selectVoById(orderId); + if (vo == null) { + return null; + } + Integer derived = deriveOrderStatusByShipping(orderId, vo.getOrderStatus()); + if (derived != null && vo.getOrderStatus() != null && !derived.equals(vo.getOrderStatus())) { + baseMapper.update(null, Wrappers.lambdaUpdate() + .eq(GearOrder::getOrderId, orderId) + .ne(GearOrder::getOrderStatus, 3) + .in(GearOrder::getOrderStatus, 0, 1) + .set(GearOrder::getOrderStatus, derived)); + vo.setOrderStatus(derived); + } + return vo; + } + + private Integer deriveOrderStatusByShipping(Long orderId, Integer currentStatus) { + if (orderId == null) return currentStatus; + if (currentStatus != null && currentStatus == 3) return 3; + + QueryWrapper qw = new QueryWrapper<>(); + qw.select("MAX(CAST(status AS SIGNED))"); + qw.eq("order_id", orderId); + qw.eq("del_flag", "0"); + List objs = shippingOrderMapper.selectObjs(qw); + Integer maxStatus = null; + if (objs != null && !objs.isEmpty() && objs.get(0) != null) { + try { + maxStatus = Integer.parseInt(String.valueOf(objs.get(0))); + } catch (Exception ignored) { + maxStatus = null; + } + } + + int st = currentStatus == null ? 0 : currentStatus; + if (maxStatus != null && maxStatus >= 3 && (st == 0 || st == 1)) return 2; + if (maxStatus != null && maxStatus >= 2 && st == 0) return 1; + return currentStatus; } /** @@ -55,8 +95,11 @@ public class GearOrderServiceImpl implements IGearOrderService { //表别名的方式进行联查 lqw.like(StringUtils.isNotBlank(bo.getOrderCode()), "o.order_code", bo.getOrderCode()); lqw.eq(bo.getCustomerId() != null, "o.customer_id", bo.getCustomerId()); - lqw.like(StringUtils.isNotBlank(bo.getSalesManager()), "o.sales_manager", bo.getSalesManager()); + lqw.eq(bo.getSalesmanId() != null, "o.salesman_id", bo.getSalesmanId()); + lqw.like(StringUtils.isNotBlank(bo.getSalesManager()), "s.name", bo.getSalesManager()); lqw.eq(bo.getOrderStatus() != null, "o.order_status", bo.getOrderStatus()); + lqw.apply(bo.getOrderStatus() != null && bo.getOrderStatus() == 0, + "NOT EXISTS (SELECT 1 FROM gear_shipping_order so WHERE so.order_id = o.order_id AND so.del_flag = '0' AND CAST(so.status AS SIGNED) >= 2)"); lqw.eq(bo.getTradeType() != null, "o.trade_type", bo.getTradeType()); lqw.eq(bo.getTaxAmount() != null, "o.tax_amount", bo.getTaxAmount()); lqw.eq(bo.getNoTaxAmount() != null, "o.no_tax_amount", bo.getNoTaxAmount()); @@ -78,6 +121,7 @@ public class GearOrderServiceImpl implements IGearOrderService { LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); lqw.like(StringUtils.isNotBlank(bo.getOrderCode()), GearOrder::getOrderCode, bo.getOrderCode()); lqw.eq(bo.getCustomerId() != null, GearOrder::getCustomerId, bo.getCustomerId()); + lqw.eq(bo.getSalesmanId() != null, GearOrder::getSalesmanId, bo.getSalesmanId()); lqw.eq(StringUtils.isNotBlank(bo.getSalesManager()), GearOrder::getSalesManager, bo.getSalesManager()); lqw.eq(bo.getOrderStatus() != null, GearOrder::getOrderStatus, bo.getOrderStatus()); lqw.eq(bo.getTradeType() != null, GearOrder::getTradeType, bo.getTradeType()); diff --git a/gear-oa/src/main/java/com/gear/oa/service/impl/GearSalesmanServiceImpl.java b/gear-oa/src/main/java/com/gear/oa/service/impl/GearSalesmanServiceImpl.java new file mode 100644 index 0000000..0777fbd --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/service/impl/GearSalesmanServiceImpl.java @@ -0,0 +1,131 @@ +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.utils.StringUtils; +import com.gear.oa.domain.GearCustomer; +import com.gear.oa.domain.GearOrder; +import com.gear.oa.domain.GearSalesman; +import com.gear.oa.domain.bo.GearSalesmanBo; +import com.gear.oa.domain.vo.GearCustomerVo; +import com.gear.oa.domain.vo.GearSalesmanVo; +import com.gear.oa.mapper.GearCustomerMapper; +import com.gear.oa.mapper.GearOrderMapper; +import com.gear.oa.mapper.GearSalesmanMapper; +import com.gear.oa.service.IGearSalesmanService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * 销售员Service业务层处理 + */ +@RequiredArgsConstructor +@Service +public class GearSalesmanServiceImpl implements IGearSalesmanService { + + private final GearSalesmanMapper baseMapper; + private final GearOrderMapper gearOrderMapper; + private final GearCustomerMapper gearCustomerMapper; + + @Override + public GearSalesmanVo queryById(Long salesmanId) { + return baseMapper.selectVoById(salesmanId); + } + + @Override + public TableDataInfo queryPageList(GearSalesmanBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + @Override + public List queryList(GearSalesmanBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(GearSalesmanBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.like(StringUtils.isNotBlank(bo.getName()), GearSalesman::getName, bo.getName()); + lqw.eq(StringUtils.isNotBlank(bo.getMobile()), GearSalesman::getMobile, bo.getMobile()); + lqw.eq(bo.getStatus() != null, GearSalesman::getStatus, bo.getStatus()); + return lqw; + } + + @Override + public Boolean insertByBo(GearSalesmanBo bo) { + GearSalesman add = BeanUtil.toBean(bo, GearSalesman.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setSalesmanId(add.getSalesmanId()); + } + return flag; + } + + @Override + public Boolean updateByBo(GearSalesmanBo bo) { + GearSalesman update = BeanUtil.toBean(bo, GearSalesman.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + private void validEntityBeforeSave(GearSalesman entity) { + // TODO 可在这里增加“姓名唯一”等约束校验 + } + + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if (isValid) { + // TODO 可在这里增加“存在关联订单/客户则不允许删除”等业务校验 + } + return baseMapper.deleteBatchIds(ids) > 0; + } + + @Override + public TableDataInfo queryFollowCustomers(Long salesmanId, PageQuery pageQuery) { + GearSalesman salesman = baseMapper.selectById(salesmanId); + if (salesman == null) { + return TableDataInfo.build(new Page<>()); + } + + // 说明:销售经理已挂接销售员,这里通过 salesman_id 反查客户 + LambdaQueryWrapper orderQw = Wrappers.lambdaQuery(); + orderQw.select(GearOrder::getCustomerId); + orderQw.eq(GearOrder::getSalesmanId, salesmanId); + orderQw.eq(GearOrder::getDelFlag, 0); + orderQw.isNotNull(GearOrder::getCustomerId); + orderQw.groupBy(GearOrder::getCustomerId); + List orders = gearOrderMapper.selectList(orderQw); + + Set customerIds = orders.stream() + .map(GearOrder::getCustomerId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + if (customerIds.isEmpty()) { + return TableDataInfo.build(new Page<>()); + } + + // 说明:客户表有逻辑删除标志,这里仅取未删除的数据 + LambdaQueryWrapper customerQw = Wrappers.lambdaQuery(); + customerQw.in(GearCustomer::getCustomerId, customerIds); + customerQw.eq(GearCustomer::getDelFlag, 0); + + Page page = gearCustomerMapper.selectVoPage(pageQuery.build(), customerQw); + return TableDataInfo.build(page); + } +} diff --git a/gear-oa/src/main/java/com/gear/oa/service/impl/GearShippingOrderServiceImpl.java b/gear-oa/src/main/java/com/gear/oa/service/impl/GearShippingOrderServiceImpl.java new file mode 100644 index 0000000..f6b6cae --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/service/impl/GearShippingOrderServiceImpl.java @@ -0,0 +1,195 @@ +package com.gear.oa.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.IdUtil; +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.utils.StringUtils; +import com.gear.oa.domain.GearOrder; +import com.gear.oa.domain.GearShippingOrder; +import com.gear.oa.domain.bo.GearShippingOrderBo; +import com.gear.oa.domain.vo.GearShippingOrderVo; +import com.gear.oa.mapper.GearOrderMapper; +import com.gear.oa.mapper.GearShippingOrderMapper; +import com.gear.oa.service.IGearShippingOrderService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 发货单据Service业务层处理 + */ +@RequiredArgsConstructor +@Service +public class GearShippingOrderServiceImpl implements IGearShippingOrderService { + + private final GearShippingOrderMapper baseMapper; + private final GearOrderMapper orderMapper; + + @Override + public GearShippingOrderVo queryById(Long shippingId) { + return baseMapper.selectVoById(shippingId); + } + + @Override + public TableDataInfo queryPageList(GearShippingOrderBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + @Override + public List queryList(GearShippingOrderBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + @Override + public List queryListByOrderId(Long orderId) { + GearShippingOrderBo bo = new GearShippingOrderBo(); + bo.setOrderId(orderId); + return queryList(bo); + } + + private LambdaQueryWrapper buildQueryWrapper(GearShippingOrderBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(bo.getShippingId() != null, GearShippingOrder::getShippingId, bo.getShippingId()); + lqw.like(StringUtils.isNotBlank(bo.getShippingNo()), GearShippingOrder::getShippingNo, bo.getShippingNo()); + lqw.like(StringUtils.isNotBlank(bo.getShippingName()), GearShippingOrder::getShippingName, bo.getShippingName()); + lqw.eq(bo.getPlanId() != null, GearShippingOrder::getPlanId, bo.getPlanId()); + // receiverCustomerId 是“真实收货客户归属”,用于客户管理页按收货客户精确查询发货单据 + lqw.eq(bo.getReceiverCustomerId() != null, GearShippingOrder::getReceiverCustomerId, bo.getReceiverCustomerId()); + if (bo.getOrderId() != null) { + // 精确查某订单的发货单据 + lqw.eq(GearShippingOrder::getOrderId, bo.getOrderId()); + } else if (bo.getCustomerId() != null || bo.getSalesmanId() != null) { + // 按客户/销售员维度查发货单据:先通过订单表反查订单ID集合,再过滤发货单据 + List orderIds = queryOrderIdsByCustomerOrSalesman(bo.getCustomerId(), bo.getSalesmanId()); + if (orderIds.isEmpty()) { + lqw.eq(GearShippingOrder::getShippingId, -1L); + } else { + lqw.in(GearShippingOrder::getOrderId, orderIds); + } + } + lqw.like(StringUtils.isNotBlank(bo.getOrderCode()), GearShippingOrder::getOrderCode, bo.getOrderCode()); + lqw.like(StringUtils.isNotBlank(bo.getReceiverCompany()), GearShippingOrder::getReceiverCompany, bo.getReceiverCompany()); + lqw.like(StringUtils.isNotBlank(bo.getResponsibleName()), GearShippingOrder::getResponsibleName, bo.getResponsibleName()); + lqw.like(StringUtils.isNotBlank(bo.getLogisticsNo()), GearShippingOrder::getLogisticsNo, bo.getLogisticsNo()); + lqw.eq(StringUtils.isNotBlank(bo.getStatus()), GearShippingOrder::getStatus, bo.getStatus()); + lqw.ge(bo.getShipTimeStart() != null, GearShippingOrder::getShipTime, bo.getShipTimeStart()); + lqw.le(bo.getShipTimeEnd() != null, GearShippingOrder::getShipTime, bo.getShipTimeEnd()); + lqw.orderByDesc(GearShippingOrder::getShipTime); + lqw.orderByDesc(GearShippingOrder::getCreateTime); + return lqw; + } + + private List queryOrderIdsByCustomerOrSalesman(Long customerId, Long salesmanId) { + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.select(GearOrder::getOrderId); + lqw.eq(customerId != null, GearOrder::getCustomerId, customerId); + lqw.eq(salesmanId != null, GearOrder::getSalesmanId, salesmanId); + lqw.eq(GearOrder::getDelFlag, 0); + List list = orderMapper.selectList(lqw); + if (list == null || list.isEmpty()) { + return Collections.emptyList(); + } + return list.stream().map(GearOrder::getOrderId).filter(id -> id != null).distinct().collect(Collectors.toList()); + } + + @Override + public Boolean insertByBo(GearShippingOrderBo bo) { + GearShippingOrder add = BeanUtil.toBean(bo, GearShippingOrder.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setShippingId(add.getShippingId()); + syncOrderStatusIfShipped(add); + } + return flag; + } + + @Override + public Boolean updateByBo(GearShippingOrderBo bo) { + GearShippingOrder update = BeanUtil.toBean(bo, GearShippingOrder.class); + validEntityBeforeSave(update); + boolean ok = baseMapper.updateById(update) > 0; + if (ok) { + syncOrderStatusIfShipped(update); + } + return ok; + } + + private void syncOrderStatusIfShipped(GearShippingOrder entity) { + if (entity == null || entity.getOrderId() == null) return; + Integer statusNum = null; + try { + if (StringUtils.isNotBlank(entity.getStatus())) { + statusNum = Integer.parseInt(entity.getStatus()); + } + } catch (Exception ignored) { + statusNum = null; + } + if (statusNum == null) return; + // 发货单据状态与订单状态联动: + // - 发货单据 >=2(已发货):若订单仍为预订单(0),推进到进行中(1) + // - 发货单据 >=3(已完成):若订单为预订单(0)/进行中(1),推进到已完成(2) + // - 订单若已取消(3),不做推进 + if (statusNum >= 3) { + orderMapper.update(null, Wrappers.lambdaUpdate() + .eq(GearOrder::getOrderId, entity.getOrderId()) + .ne(GearOrder::getOrderStatus, 3) + .in(GearOrder::getOrderStatus, 0, 1) + .set(GearOrder::getOrderStatus, 2)); + return; + } + if (statusNum >= 2) { + orderMapper.update(null, Wrappers.lambdaUpdate() + .eq(GearOrder::getOrderId, entity.getOrderId()) + .eq(GearOrder::getOrderStatus, 0) + .set(GearOrder::getOrderStatus, 1)); + } + } + + private void validEntityBeforeSave(GearShippingOrder entity) { + boolean isInsert = entity.getShippingId() == null; + // 发货单据ID:项目内大部分业务表使用雪花ID,这里保持一致 + if (entity.getShippingId() == null) { + entity.setShippingId(IdUtil.getSnowflakeNextId()); + } + if (isInsert) { + // 发货单号:为空则自动生成 + if (StringUtils.isBlank(entity.getShippingNo())) { + entity.setShippingNo("SHIP_" + IdUtil.getSnowflakeNextIdStr()); + } + // 发货单名称:为空则默认等于发货单号(便于列表展示) + if (StringUtils.isBlank(entity.getShippingName())) { + entity.setShippingName(entity.getShippingNo()); + } + // 默认状态:0正常 + if (StringUtils.isBlank(entity.getStatus())) { + entity.setStatus("0"); + } + // 默认逻辑删除标志:0存在(TableLogic 会在删除时写 2) + if (StringUtils.isBlank(entity.getDelFlag())) { + entity.setDelFlag("0"); + } + } + } + + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if (isValid) { + // 可在此处加入业务校验:例如已对账/已开票的发货单据不允许删除 + } + return baseMapper.deleteBatchIds(ids) > 0; + } +} diff --git a/gear-oa/src/main/java/com/gear/oa/service/impl/GearShippingPlanServiceImpl.java b/gear-oa/src/main/java/com/gear/oa/service/impl/GearShippingPlanServiceImpl.java new file mode 100644 index 0000000..4b3b90c --- /dev/null +++ b/gear-oa/src/main/java/com/gear/oa/service/impl/GearShippingPlanServiceImpl.java @@ -0,0 +1,111 @@ +package com.gear.oa.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.IdUtil; +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.GearShippingOrder; +import com.gear.oa.domain.GearShippingPlan; +import com.gear.oa.domain.bo.GearShippingPlanBo; +import com.gear.oa.domain.vo.GearShippingPlanVo; +import com.gear.oa.mapper.GearShippingOrderMapper; +import com.gear.oa.mapper.GearShippingPlanMapper; +import com.gear.oa.service.IGearShippingPlanService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.Collection; +import java.util.List; + +/** + * 发货计划Service业务层处理 + */ +@RequiredArgsConstructor +@Service +public class GearShippingPlanServiceImpl implements IGearShippingPlanService { + + private final GearShippingPlanMapper baseMapper; + private final GearShippingOrderMapper shippingOrderMapper; + + @Override + public GearShippingPlanVo queryById(Long planId) { + return baseMapper.selectVoById(planId); + } + + @Override + public TableDataInfo queryPageList(GearShippingPlanBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + @Override + public List queryList(GearShippingPlanBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + @Override + public List queryListWithCount(GearShippingPlanBo bo) { + return baseMapper.selectVoListWithCount(bo); + } + + private LambdaQueryWrapper buildQueryWrapper(GearShippingPlanBo bo) { + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(bo.getPlanId() != null, GearShippingPlan::getPlanId, bo.getPlanId()); + lqw.like(StringUtils.isNotBlank(bo.getPlanName()), GearShippingPlan::getPlanName, bo.getPlanName()); + lqw.eq(bo.getPlanDate() != null, GearShippingPlan::getPlanDate, bo.getPlanDate()); + lqw.eq(StringUtils.isNotBlank(bo.getStatus()), GearShippingPlan::getStatus, bo.getStatus()); + lqw.orderByDesc(GearShippingPlan::getPlanDate); + lqw.orderByDesc(GearShippingPlan::getCreateTime); + return lqw; + } + + @Override + public Boolean insertByBo(GearShippingPlanBo bo) { + GearShippingPlan add = BeanUtil.toBean(bo, GearShippingPlan.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setPlanId(add.getPlanId()); + } + return flag; + } + + @Override + public Boolean updateByBo(GearShippingPlanBo bo) { + GearShippingPlan update = BeanUtil.toBean(bo, GearShippingPlan.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + private void validEntityBeforeSave(GearShippingPlan entity) { + if (entity.getPlanId() == null) { + entity.setPlanId(IdUtil.getSnowflakeNextId()); + } + if (StringUtils.isBlank(entity.getStatus())) { + entity.setStatus("0"); + } + if (StringUtils.isBlank(entity.getDelFlag())) { + entity.setDelFlag("0"); + } + } + + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if (isValid && ids != null && !ids.isEmpty()) { + Long cnt = shippingOrderMapper.selectCount(Wrappers.lambdaQuery(GearShippingOrder.class) + .in(GearShippingOrder::getPlanId, ids)); + if (cnt != null && cnt > 0) { + throw new ServiceException("该计划下存在发货单据,无法删除"); + } + } + return baseMapper.deleteBatchIds(ids) > 0; + } +} + 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 index ee6862a..09ac8a0 100644 --- 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 @@ -25,6 +25,7 @@ import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.HashMap; import java.util.Map; /** @@ -176,6 +177,49 @@ public class GearStockServiceImpl implements IGearStockService { return baseMapper.deleteBatchIds(ids) > 0; } + @Override + public Map sumQuantityByItemIds(String itemType, List itemIds) { + if (StringUtils.isBlank(itemType) || itemIds == null || itemIds.isEmpty()) { + return new HashMap<>(); + } + List> rows = baseMapper.selectSumQuantityByItemIds(itemType, itemIds); + Map result = new HashMap<>(); + if (rows == null || rows.isEmpty()) { + return result; + } + for (Map r : rows) { + if (r == null) continue; + Object idObj = r.get("itemId"); + Object qtyObj = r.get("quantity"); + if (idObj == null) continue; + Long id = null; + if (idObj instanceof Number) { + id = ((Number) idObj).longValue(); + } else { + try { + id = Long.valueOf(String.valueOf(idObj)); + } catch (Exception ignored) { + id = null; + } + } + if (id == null) continue; + BigDecimal qty = BigDecimal.ZERO; + if (qtyObj instanceof BigDecimal) { + qty = (BigDecimal) qtyObj; + } else if (qtyObj instanceof Number) { + qty = BigDecimal.valueOf(((Number) qtyObj).doubleValue()); + } else if (qtyObj != null) { + try { + qty = new BigDecimal(String.valueOf(qtyObj)); + } catch (Exception ignored) { + qty = BigDecimal.ZERO; + } + } + result.put(id, qty); + } + return result; + } + // @Override // public BigDecimal getStockByItemId(Long rawMaterialId) { // return baseMapper.getStockByItemId(rawMaterialId); diff --git a/gear-oa/src/main/resources/mapper/oa/GearOrderDetailMapper.xml b/gear-oa/src/main/resources/mapper/oa/GearOrderDetailMapper.xml index b903096..6caf6d6 100644 --- a/gear-oa/src/main/resources/mapper/oa/GearOrderDetailMapper.xml +++ b/gear-oa/src/main/resources/mapper/oa/GearOrderDetailMapper.xml @@ -20,15 +20,31 @@ diff --git a/gear-oa/src/main/resources/mapper/oa/GearOrderMapper.xml b/gear-oa/src/main/resources/mapper/oa/GearOrderMapper.xml index 574d793..f571b93 100644 --- a/gear-oa/src/main/resources/mapper/oa/GearOrderMapper.xml +++ b/gear-oa/src/main/resources/mapper/oa/GearOrderMapper.xml @@ -10,6 +10,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + @@ -20,14 +21,29 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + diff --git a/gear-oa/src/main/resources/mapper/oa/GearOrderProductionMapper.xml b/gear-oa/src/main/resources/mapper/oa/GearOrderProductionMapper.xml new file mode 100644 index 0000000..18b9dda --- /dev/null +++ b/gear-oa/src/main/resources/mapper/oa/GearOrderProductionMapper.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gear-oa/src/main/resources/mapper/oa/GearStockMapper.xml b/gear-oa/src/main/resources/mapper/oa/GearStockMapper.xml index 368c171..05b07c5 100644 --- a/gear-oa/src/main/resources/mapper/oa/GearStockMapper.xml +++ b/gear-oa/src/main/resources/mapper/oa/GearStockMapper.xml @@ -25,6 +25,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" where item_id = #{rawMaterialId} and item_type = 'raw_material' and del_flag = 0 + +