Merge remote-tracking branch 'origin/0.8.X' into 0.8.X

This commit is contained in:
2025-07-19 10:49:54 +08:00
25 changed files with 1702 additions and 203 deletions

View File

@@ -1,8 +1,11 @@
package com.klp.controller;
import java.util.List;
import java.util.Arrays;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.*;
import com.klp.domain.bo.WmsSchedulePlanDetailBo;
import com.klp.domain.vo.*;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
@@ -18,10 +21,14 @@ import com.klp.common.core.validate.AddGroup;
import com.klp.common.core.validate.EditGroup;
import com.klp.common.enums.BusinessType;
import com.klp.common.utils.poi.ExcelUtil;
import com.klp.domain.vo.WmsProductionLineVo;
import com.klp.domain.bo.WmsProductionLineBo;
import com.klp.service.IWmsProductionLineService;
import com.klp.common.core.page.TableDataInfo;
import com.klp.service.IWmsSchedulePlanDetailService;
import com.klp.service.IWmsOrderService;
import com.klp.service.IWmsOrderDetailService;
import com.klp.service.IWmsProductService;
import com.klp.service.IWmsSchedulePlanService;
/**
* 产线
@@ -36,6 +43,11 @@ import com.klp.common.core.page.TableDataInfo;
public class WmsProductionLineController extends BaseController {
private final IWmsProductionLineService iWmsProductionLineService;
private final IWmsSchedulePlanDetailService iWmsSchedulePlanDetailService;
private final IWmsOrderService iWmsOrderService;
private final IWmsOrderDetailService iWmsOrderDetailService;
private final IWmsProductService iWmsProductService;
private final IWmsSchedulePlanService iWmsSchedulePlanService;
/**
* 查询产线列表
@@ -97,4 +109,77 @@ public class WmsProductionLineController extends BaseController {
@PathVariable Long[] lineIds) {
return toAjax(iWmsProductionLineService.deleteWithValidByIds(Arrays.asList(lineIds), true));
}
/**
* 产线甘特图接口
* @param lineId 产线ID
* @return 甘特图数据
*/
@GetMapping("/gantt")
public R<?> gantt(@RequestParam Long lineId) {
// 查询排产计划明细(按产线过滤,返回所有订单的任务)
WmsSchedulePlanDetailBo detailBo = new WmsSchedulePlanDetailBo();
detailBo.setLineId(lineId);
List<WmsSchedulePlanDetailVo> allDetails = iWmsSchedulePlanDetailService.queryList(detailBo);
// 查询产品、订单信息补充remark
Set<Long> orderIdSet = new HashSet<>();
for (WmsSchedulePlanDetailVo detail : allDetails) {
// 查询产品名和订单编号
String productName = null;
if (detail.getProductId() != null) {
WmsProductVo product = iWmsProductService.queryById(detail.getProductId());
if (product != null) {
productName = product.getProductName();
}
}
String orderCode = null;
Long orderId = null;
if (detail.getPlanId() != null) {
WmsSchedulePlanVo planVo = iWmsSchedulePlanService.queryById(detail.getPlanId());
if (planVo != null && planVo.getOrderId() != null) {
orderId = planVo.getOrderId();
WmsOrderVo orderVo = iWmsOrderService.queryById(orderId);
if (orderVo != null) {
orderCode = orderVo.getOrderCode();
}
}
}
// 设置remark为“订单编号-产品名”
String remark = (orderCode != null ? orderCode : "") + (productName != null ? ("-" + productName) : "");
detail.setRemark(remark);
// 查询产线日产能
BigDecimal capacity = null;
if (detail.getLineId() != null) {
WmsProductionLineVo lineVo = iWmsProductionLineService.queryById(detail.getLineId());
if (lineVo != null) {
capacity = lineVo.getCapacity();
}
}
// 计算天数和总产能
BigDecimal totalCapacity = null;
int days = 0;
if (detail.getStartDate() != null && detail.getEndDate() != null) {
long diff = detail.getEndDate().getTime() - detail.getStartDate().getTime();
days = (int) (diff / (1000 * 3600 * 24)) + 1;
if (capacity != null) {
totalCapacity = capacity.multiply(new BigDecimal(days));
}
}
// 计划生产数量
BigDecimal planQuantity = detail.getQuantity();
// 直接set字段无需反射
detail.setCapacity(capacity);
detail.setTotalCapacity(totalCapacity);
detail.setDays(days);
detail.setPlanQuantity(planQuantity);
}
// 查询所有相关订单信息
List<WmsOrderVo> orderList = new ArrayList<>();
// 返回结构
return R.ok(new HashMap<String, Object>() {{
put("tasks", allDetails);
put("orders", orderList);
}});
}
}

View File

@@ -36,6 +36,13 @@ public class WmsPurchasePlanController extends BaseController {
private final IWmsPurchasePlanService iWmsPurchasePlanService;
/**
* 新增采购计划(含明细)
*/
@PostMapping("/addWithDetails")
public R<Void> addPurchasePlan(@RequestBody WmsPurchasePlanVo planVo) {
return toAjax(iWmsPurchasePlanService.insertWithDetails(planVo));
}
/**
* 根据订单ID生成推荐采购计划只返回不落库
*/

View File

@@ -32,6 +32,11 @@ public class WmsSchedulePlanBo extends BaseEntity {
*/
private Long orderId;
/**
* 版本
*/
private String version;
/**
* 状态0=新建1=已排产2=生产中3=已完成)
*/

View File

@@ -48,11 +48,13 @@ public class WmsSchedulePlanDetailBo extends BaseEntity {
/**
* 计划开始日期
*/
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSX", timezone = "GMT+8")
private Date startDate;
/**
* 计划结束日期
*/
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSX", timezone = "GMT+8")
private Date endDate;
/**

View File

@@ -70,5 +70,24 @@ public class WmsSchedulePlanDetailVo {
@ExcelProperty(value = "备注")
private String remark;
/**
* 产线日产能
*/
private BigDecimal capacity;
/**
* 总产能
*/
private BigDecimal totalCapacity;
/**
* 目标生产数量
*/
private BigDecimal planQuantity;
/**
* 天数
*/
private Integer days;
}

View File

@@ -17,6 +17,11 @@ import java.util.List;
*/
public interface IWmsPurchasePlanService {
/**
* 新增采购计划(含明细)
*/
Boolean insertWithDetails(WmsPurchasePlanVo planVo);
/**
* 根据订单ID生成推荐采购计划只返回不落库
*/
@@ -51,4 +56,5 @@ public interface IWmsPurchasePlanService {
* 校验并批量删除采购计划主信息
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

View File

@@ -74,6 +74,7 @@ public class WmsPurchasePlanDetailServiceImpl implements IWmsPurchasePlanDetailS
*/
@Override
public Boolean insertByBo(WmsPurchasePlanDetailBo bo) {
WmsPurchasePlanDetail add = BeanUtil.toBean(bo, WmsPurchasePlanDetail.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;

View File

@@ -7,21 +7,22 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.klp.common.utils.StringUtils;
import com.klp.domain.WmsOrderDetail;
import com.klp.domain.WmsProductBom;
import com.klp.domain.WmsPurchasePlanDetail;
import com.klp.domain.vo.WmsOrderDetailVo;
import com.klp.domain.vo.WmsPurchasePlanDetailVo;
import com.klp.service.IWmsOrderDetailService;
import com.klp.service.IWmsProductBomService;
import com.klp.service.IWmsStockService;
import com.klp.mapper.WmsPurchasePlanDetailMapper;
import com.klp.service.*;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import com.klp.domain.bo.WmsPurchasePlanBo;
import com.klp.domain.vo.WmsPurchasePlanVo;
import com.klp.domain.WmsPurchasePlan;
import com.klp.mapper.WmsPurchasePlanMapper;
import com.klp.service.IWmsPurchasePlanService;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
@@ -43,6 +44,28 @@ public class WmsPurchasePlanServiceImpl implements IWmsPurchasePlanService {
private final IWmsStockService wmsStockService;
@Resource
private WmsPurchasePlanDetailMapper wmsPurchasePlanDetailMapper;
@Transactional
@Override
public Boolean insertWithDetails(WmsPurchasePlanVo planVo) {
// 1. 保存主表
WmsPurchasePlan plan = new WmsPurchasePlan();
BeanUtils.copyProperties(planVo, plan);
int flag = 0;
flag += baseMapper.insert(plan);
// 2. 保存明细表
for (WmsPurchasePlanDetailVo detailVo : planVo.getDetailList()) {
WmsPurchasePlanDetail detail = new WmsPurchasePlanDetail();
BeanUtils.copyProperties(detailVo, detail);
detail.setPlanId(plan.getPlanId()); // 关联主表ID
flag += wmsPurchasePlanDetailMapper.insert(detail);
}
return flag > 0;
}
@Override
public WmsPurchasePlanVo recommendPurchasePlanByOrder(Long orderId) {
// 1. 查询订单明细

View File

@@ -74,6 +74,16 @@ public class WmsSchedulePlanDetailServiceImpl implements IWmsSchedulePlanDetailS
*/
@Override
public Boolean insertByBo(WmsSchedulePlanDetailBo bo) {
// 校验产线时间段是否已排产
List<WmsSchedulePlanDetail> existList = baseMapper.selectList(
Wrappers.lambdaQuery(WmsSchedulePlanDetail.class)
.eq(WmsSchedulePlanDetail::getLineId, bo.getLineId())
.le(WmsSchedulePlanDetail::getStartDate, bo.getEndDate())
.ge(WmsSchedulePlanDetail::getEndDate, bo.getStartDate())
);
if (existList != null && !existList.isEmpty()) {
throw new RuntimeException("该产线该时间段已排产,请选择其他时间或产线!");
}
WmsSchedulePlanDetail add = BeanUtil.toBean(bo, WmsSchedulePlanDetail.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;