diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/calendar/vo/MesCalCalendarListReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/calendar/vo/MesCalCalendarListReqVO.java index fe587e0..3e9dd62 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/calendar/vo/MesCalCalendarListReqVO.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/calendar/vo/MesCalCalendarListReqVO.java @@ -13,6 +13,15 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @Data public class MesCalCalendarListReqVO { + @Schema(description = "开始日期") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime startDay; + + @Schema(description = "结束日期") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime endDay; + + // TODO @AI:可以是 string,但是具体的 type,通过 public static final 定义常量,避免魔法字符串 @Schema(description = "查询类型:TYPE-按分类,TEAM-按班组,USER-按个人", requiredMode = Schema.RequiredMode.REQUIRED, example = "TYPE") @NotEmpty(message = "查询类型不能为空") private String queryType; @@ -26,12 +35,4 @@ public class MesCalCalendarListReqVO { @Schema(description = "用户编号(queryType=USER 时使用)", example = "1") private Long userId; - @Schema(description = "开始日期") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private LocalDateTime startDay; - - @Schema(description = "结束日期") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private LocalDateTime endDay; - } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/calendar/vo/MesCalCalendarRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/calendar/vo/MesCalCalendarRespVO.java index 35e1e29..636e6de 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/calendar/vo/MesCalCalendarRespVO.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/calendar/vo/MesCalCalendarRespVO.java @@ -15,9 +15,11 @@ import java.util.List; @AllArgsConstructor public class MesCalCalendarRespVO { + // TODO @AI: private LocalDateTime day; 合适点,和 holiday 保持统一; @Schema(description = "日期,格式 yyyy-MM-dd", requiredMode = Schema.RequiredMode.REQUIRED, example = "2025-01-15") private String day; + // TODO @AI:可能在注释上,说下对应的 @Schema(description = "轮班方式", example = "2") private Integer shiftType; diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/cal/calendar/MesCalCalendarServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/cal/calendar/MesCalCalendarServiceImpl.java index 793fca7..de7b93c 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/cal/calendar/MesCalCalendarServiceImpl.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/cal/calendar/MesCalCalendarServiceImpl.java @@ -142,8 +142,10 @@ public class MesCalCalendarServiceImpl implements MesCalCalendarService { List items = dayShifts.stream() .map(ts -> MesCalCalendarRespVO.TeamShiftItem.builder() .teamId(ts.getTeamId()) + // TODO @AI:不用这种 default .teamName(teamNameMap.getOrDefault(ts.getTeamId(), "")) .shiftId(ts.getShiftId()) + // TODO @AI:不用这种 default .shiftName(shiftMap.containsKey(ts.getShiftId()) ? shiftMap.get(ts.getShiftId()).getName() : "") .sort(ts.getSort()) diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/workstation/MesMdWorkstationServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/workstation/MesMdWorkstationServiceImpl.java index 86e6404..15960df 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/workstation/MesMdWorkstationServiceImpl.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/workstation/MesMdWorkstationServiceImpl.java @@ -5,11 +5,17 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.mes.controller.admin.md.workstation.vo.MesMdWorkstationPageReqVO; import cn.iocoder.yudao.module.mes.controller.admin.md.workstation.vo.MesMdWorkstationSaveReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkshopDO; import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO; import cn.iocoder.yudao.module.mes.dal.mysql.md.workstation.MesMdWorkstationMachineMapper; import cn.iocoder.yudao.module.mes.dal.mysql.md.workstation.MesMdWorkstationMapper; import cn.iocoder.yudao.module.mes.dal.mysql.md.workstation.MesMdWorkstationToolMapper; import cn.iocoder.yudao.module.mes.dal.mysql.md.workstation.MesMdWorkstationWorkerMapper; +import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService; +import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseLocationService; +import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseService; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -44,6 +50,15 @@ public class MesMdWorkstationServiceImpl implements MesMdWorkstationService { @Resource private MesMdWorkshopService workshopService; + @Resource + private MesWmWarehouseService warehouseService; + + @Resource + private MesWmWarehouseLocationService locationService; + + @Resource + private MesWmWarehouseAreaService areaService; + @Override public Long createWorkstation(MesMdWorkstationSaveReqVO createReqVO) { // 校验编码唯一 @@ -51,7 +66,9 @@ public class MesMdWorkstationServiceImpl implements MesMdWorkstationService { // 校验名称唯一 validateWorkstationNameUnique(null, createReqVO.getName()); // 校验车间存在 - workshopService.getWorkshop(createReqVO.getWorkshopId()); + validateWorkshopExists(createReqVO.getWorkshopId()); + // 校验仓库层级 + validateWarehouseHierarchy(createReqVO); // 插入 MesMdWorkstationDO workstation = BeanUtils.toBean(createReqVO, MesMdWorkstationDO.class); @@ -68,7 +85,9 @@ public class MesMdWorkstationServiceImpl implements MesMdWorkstationService { // 校验名称唯一 validateWorkstationNameUnique(updateReqVO.getId(), updateReqVO.getName()); // 校验车间存在 - workshopService.getWorkshop(updateReqVO.getWorkshopId()); + validateWorkshopExists(updateReqVO.getWorkshopId()); + // 校验仓库层级 + validateWarehouseHierarchy(updateReqVO); // 更新 MesMdWorkstationDO updateObj = BeanUtils.toBean(updateReqVO, MesMdWorkstationDO.class); @@ -95,6 +114,69 @@ public class MesMdWorkstationServiceImpl implements MesMdWorkstationService { } } + private void validateWorkshopExists(Long workshopId) { + MesMdWorkshopDO workshop = workshopService.getWorkshop(workshopId); + if (workshop == null) { + throw exception(MD_WORKSHOP_NOT_EXISTS); + } + } + + /** + * 校验仓库层级关系 + * + * 仓库层级结构:仓库 -> 库位 -> 库区 + * 校验规则: + * 1. 如果填写了库位,必须填写仓库,且库位必须属于该仓库 + * 2. 如果填写了库区,必须填写库位,且库区必须属于该库位 + * + * @param reqVO 工作站保存请求对象 + */ + private void validateWarehouseHierarchy(MesMdWorkstationSaveReqVO reqVO) { + // 1.1 获取仓库、库位、库区 ID + Long warehouseId = reqVO.getWarehouseId(); + Long locationId = reqVO.getLocationId(); + Long areaId = reqVO.getAreaId(); + // 1.2 如果都为空,则无需校验 + if (warehouseId == null && locationId == null && areaId == null) { + return; + } + + // 2. 校验仓库是否存在 + if (warehouseId != null) { + warehouseService.validateWarehouseExists(warehouseId); + } + + // 3. 校验库位:如果填写了库位,必须填写仓库,且库位必须属于该仓库 + MesWmWarehouseLocationDO location; + if (locationId != null) { + // 3.1 校验库位是否存在 + location = locationService.validateWarehouseLocationExists(locationId); + // 3.2 校验必须填写仓库 + if (warehouseId == null) { + throw exception(WM_WAREHOUSE_REQUIRED); + } + // 3.3 校验库位是否属于该仓库 + if (ObjUtil.notEqual(location.getWarehouseId(), warehouseId)) { + throw exception(WM_WAREHOUSE_LOCATION_RELATION_INVALID); + } + } + + // 4. 校验库区:如果填写了库区,必须填写库位,且库区必须属于该库位 + if (areaId == null) { + return; + } + // 4.1 校验库区是否存在 + MesWmWarehouseAreaDO area = areaService.validateWarehouseAreaExists(areaId); + // 4.2 校验必须填写库位 + if (locationId == null) { + throw exception(WM_WAREHOUSE_LOCATION_REQUIRED); + } + // 4.3 校验库区是否属于该库位 + if (ObjUtil.notEqual(area.getLocationId(), locationId)) { + throw exception(WM_WAREHOUSE_AREA_RELATION_INVALID); + } + } + private void validateWorkstationCodeUnique(Long id, String code) { MesMdWorkstationDO workstation = workstationMapper.selectByCode(code); if (workstation == null) {