Commit afb85857b72c36718f79b2d66e2e87c3389da621

Authored by YunaiV
1 parent 5a3fe940

feat(mes): 新增开始日期和结束日期字段,优化排班日历请求和响应对象

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_ @@ -13,6 +13,15 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
13 @Data 13 @Data
14 public class MesCalCalendarListReqVO { 14 public class MesCalCalendarListReqVO {
15 15
  16 + @Schema(description = "开始日期")
  17 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  18 + private LocalDateTime startDay;
  19 +
  20 + @Schema(description = "结束日期")
  21 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  22 + private LocalDateTime endDay;
  23 +
  24 + // TODO @AI:可以是 string,但是具体的 type,通过 public static final 定义常量,避免魔法字符串
16 @Schema(description = "查询类型:TYPE-按分类,TEAM-按班组,USER-按个人", requiredMode = Schema.RequiredMode.REQUIRED, example = "TYPE") 25 @Schema(description = "查询类型:TYPE-按分类,TEAM-按班组,USER-按个人", requiredMode = Schema.RequiredMode.REQUIRED, example = "TYPE")
17 @NotEmpty(message = "查询类型不能为空") 26 @NotEmpty(message = "查询类型不能为空")
18 private String queryType; 27 private String queryType;
@@ -26,12 +35,4 @@ public class MesCalCalendarListReqVO { @@ -26,12 +35,4 @@ public class MesCalCalendarListReqVO {
26 @Schema(description = "用户编号(queryType=USER 时使用)", example = "1") 35 @Schema(description = "用户编号(queryType=USER 时使用)", example = "1")
27 private Long userId; 36 private Long userId;
28 37
29 - @Schema(description = "开始日期")  
30 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
31 - private LocalDateTime startDay;  
32 -  
33 - @Schema(description = "结束日期")  
34 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
35 - private LocalDateTime endDay;  
36 -  
37 } 38 }
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; @@ -15,9 +15,11 @@ import java.util.List;
15 @AllArgsConstructor 15 @AllArgsConstructor
16 public class MesCalCalendarRespVO { 16 public class MesCalCalendarRespVO {
17 17
  18 + // TODO @AI: private LocalDateTime day; 合适点,和 holiday 保持统一;
18 @Schema(description = "日期,格式 yyyy-MM-dd", requiredMode = Schema.RequiredMode.REQUIRED, example = "2025-01-15") 19 @Schema(description = "日期,格式 yyyy-MM-dd", requiredMode = Schema.RequiredMode.REQUIRED, example = "2025-01-15")
19 private String day; 20 private String day;
20 21
  22 + // TODO @AI:可能在注释上,说下对应的
21 @Schema(description = "轮班方式", example = "2") 23 @Schema(description = "轮班方式", example = "2")
22 private Integer shiftType; 24 private Integer shiftType;
23 25
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 { @@ -142,8 +142,10 @@ public class MesCalCalendarServiceImpl implements MesCalCalendarService {
142 List<MesCalCalendarRespVO.TeamShiftItem> items = dayShifts.stream() 142 List<MesCalCalendarRespVO.TeamShiftItem> items = dayShifts.stream()
143 .map(ts -> MesCalCalendarRespVO.TeamShiftItem.builder() 143 .map(ts -> MesCalCalendarRespVO.TeamShiftItem.builder()
144 .teamId(ts.getTeamId()) 144 .teamId(ts.getTeamId())
  145 + // TODO @AI:不用这种 default
145 .teamName(teamNameMap.getOrDefault(ts.getTeamId(), "")) 146 .teamName(teamNameMap.getOrDefault(ts.getTeamId(), ""))
146 .shiftId(ts.getShiftId()) 147 .shiftId(ts.getShiftId())
  148 + // TODO @AI:不用这种 default
147 .shiftName(shiftMap.containsKey(ts.getShiftId()) 149 .shiftName(shiftMap.containsKey(ts.getShiftId())
148 ? shiftMap.get(ts.getShiftId()).getName() : "") 150 ? shiftMap.get(ts.getShiftId()).getName() : "")
149 .sort(ts.getSort()) 151 .sort(ts.getSort())
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; @@ -5,11 +5,17 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
6 import cn.iocoder.yudao.module.mes.controller.admin.md.workstation.vo.MesMdWorkstationPageReqVO; 6 import cn.iocoder.yudao.module.mes.controller.admin.md.workstation.vo.MesMdWorkstationPageReqVO;
7 import cn.iocoder.yudao.module.mes.controller.admin.md.workstation.vo.MesMdWorkstationSaveReqVO; 7 import cn.iocoder.yudao.module.mes.controller.admin.md.workstation.vo.MesMdWorkstationSaveReqVO;
  8 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkshopDO;
8 import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO; 9 import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO;
  10 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO;
  11 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO;
9 import cn.iocoder.yudao.module.mes.dal.mysql.md.workstation.MesMdWorkstationMachineMapper; 12 import cn.iocoder.yudao.module.mes.dal.mysql.md.workstation.MesMdWorkstationMachineMapper;
10 import cn.iocoder.yudao.module.mes.dal.mysql.md.workstation.MesMdWorkstationMapper; 13 import cn.iocoder.yudao.module.mes.dal.mysql.md.workstation.MesMdWorkstationMapper;
11 import cn.iocoder.yudao.module.mes.dal.mysql.md.workstation.MesMdWorkstationToolMapper; 14 import cn.iocoder.yudao.module.mes.dal.mysql.md.workstation.MesMdWorkstationToolMapper;
12 import cn.iocoder.yudao.module.mes.dal.mysql.md.workstation.MesMdWorkstationWorkerMapper; 15 import cn.iocoder.yudao.module.mes.dal.mysql.md.workstation.MesMdWorkstationWorkerMapper;
  16 +import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
  17 +import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseLocationService;
  18 +import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseService;
13 import jakarta.annotation.Resource; 19 import jakarta.annotation.Resource;
14 import org.springframework.stereotype.Service; 20 import org.springframework.stereotype.Service;
15 import org.springframework.transaction.annotation.Transactional; 21 import org.springframework.transaction.annotation.Transactional;
@@ -44,6 +50,15 @@ public class MesMdWorkstationServiceImpl implements MesMdWorkstationService { @@ -44,6 +50,15 @@ public class MesMdWorkstationServiceImpl implements MesMdWorkstationService {
44 @Resource 50 @Resource
45 private MesMdWorkshopService workshopService; 51 private MesMdWorkshopService workshopService;
46 52
  53 + @Resource
  54 + private MesWmWarehouseService warehouseService;
  55 +
  56 + @Resource
  57 + private MesWmWarehouseLocationService locationService;
  58 +
  59 + @Resource
  60 + private MesWmWarehouseAreaService areaService;
  61 +
47 @Override 62 @Override
48 public Long createWorkstation(MesMdWorkstationSaveReqVO createReqVO) { 63 public Long createWorkstation(MesMdWorkstationSaveReqVO createReqVO) {
49 // 校验编码唯一 64 // 校验编码唯一
@@ -51,7 +66,9 @@ public class MesMdWorkstationServiceImpl implements MesMdWorkstationService { @@ -51,7 +66,9 @@ public class MesMdWorkstationServiceImpl implements MesMdWorkstationService {
51 // 校验名称唯一 66 // 校验名称唯一
52 validateWorkstationNameUnique(null, createReqVO.getName()); 67 validateWorkstationNameUnique(null, createReqVO.getName());
53 // 校验车间存在 68 // 校验车间存在
54 - workshopService.getWorkshop(createReqVO.getWorkshopId()); 69 + validateWorkshopExists(createReqVO.getWorkshopId());
  70 + // 校验仓库层级
  71 + validateWarehouseHierarchy(createReqVO);
55 72
56 // 插入 73 // 插入
57 MesMdWorkstationDO workstation = BeanUtils.toBean(createReqVO, MesMdWorkstationDO.class); 74 MesMdWorkstationDO workstation = BeanUtils.toBean(createReqVO, MesMdWorkstationDO.class);
@@ -68,7 +85,9 @@ public class MesMdWorkstationServiceImpl implements MesMdWorkstationService { @@ -68,7 +85,9 @@ public class MesMdWorkstationServiceImpl implements MesMdWorkstationService {
68 // 校验名称唯一 85 // 校验名称唯一
69 validateWorkstationNameUnique(updateReqVO.getId(), updateReqVO.getName()); 86 validateWorkstationNameUnique(updateReqVO.getId(), updateReqVO.getName());
70 // 校验车间存在 87 // 校验车间存在
71 - workshopService.getWorkshop(updateReqVO.getWorkshopId()); 88 + validateWorkshopExists(updateReqVO.getWorkshopId());
  89 + // 校验仓库层级
  90 + validateWarehouseHierarchy(updateReqVO);
72 91
73 // 更新 92 // 更新
74 MesMdWorkstationDO updateObj = BeanUtils.toBean(updateReqVO, MesMdWorkstationDO.class); 93 MesMdWorkstationDO updateObj = BeanUtils.toBean(updateReqVO, MesMdWorkstationDO.class);
@@ -95,6 +114,69 @@ public class MesMdWorkstationServiceImpl implements MesMdWorkstationService { @@ -95,6 +114,69 @@ public class MesMdWorkstationServiceImpl implements MesMdWorkstationService {
95 } 114 }
96 } 115 }
97 116
  117 + private void validateWorkshopExists(Long workshopId) {
  118 + MesMdWorkshopDO workshop = workshopService.getWorkshop(workshopId);
  119 + if (workshop == null) {
  120 + throw exception(MD_WORKSHOP_NOT_EXISTS);
  121 + }
  122 + }
  123 +
  124 + /**
  125 + * 校验仓库层级关系
  126 + *
  127 + * 仓库层级结构:仓库 -> 库位 -> 库区
  128 + * 校验规则:
  129 + * 1. 如果填写了库位,必须填写仓库,且库位必须属于该仓库
  130 + * 2. 如果填写了库区,必须填写库位,且库区必须属于该库位
  131 + *
  132 + * @param reqVO 工作站保存请求对象
  133 + */
  134 + private void validateWarehouseHierarchy(MesMdWorkstationSaveReqVO reqVO) {
  135 + // 1.1 获取仓库、库位、库区 ID
  136 + Long warehouseId = reqVO.getWarehouseId();
  137 + Long locationId = reqVO.getLocationId();
  138 + Long areaId = reqVO.getAreaId();
  139 + // 1.2 如果都为空,则无需校验
  140 + if (warehouseId == null && locationId == null && areaId == null) {
  141 + return;
  142 + }
  143 +
  144 + // 2. 校验仓库是否存在
  145 + if (warehouseId != null) {
  146 + warehouseService.validateWarehouseExists(warehouseId);
  147 + }
  148 +
  149 + // 3. 校验库位:如果填写了库位,必须填写仓库,且库位必须属于该仓库
  150 + MesWmWarehouseLocationDO location;
  151 + if (locationId != null) {
  152 + // 3.1 校验库位是否存在
  153 + location = locationService.validateWarehouseLocationExists(locationId);
  154 + // 3.2 校验必须填写仓库
  155 + if (warehouseId == null) {
  156 + throw exception(WM_WAREHOUSE_REQUIRED);
  157 + }
  158 + // 3.3 校验库位是否属于该仓库
  159 + if (ObjUtil.notEqual(location.getWarehouseId(), warehouseId)) {
  160 + throw exception(WM_WAREHOUSE_LOCATION_RELATION_INVALID);
  161 + }
  162 + }
  163 +
  164 + // 4. 校验库区:如果填写了库区,必须填写库位,且库区必须属于该库位
  165 + if (areaId == null) {
  166 + return;
  167 + }
  168 + // 4.1 校验库区是否存在
  169 + MesWmWarehouseAreaDO area = areaService.validateWarehouseAreaExists(areaId);
  170 + // 4.2 校验必须填写库位
  171 + if (locationId == null) {
  172 + throw exception(WM_WAREHOUSE_LOCATION_REQUIRED);
  173 + }
  174 + // 4.3 校验库区是否属于该库位
  175 + if (ObjUtil.notEqual(area.getLocationId(), locationId)) {
  176 + throw exception(WM_WAREHOUSE_AREA_RELATION_INVALID);
  177 + }
  178 + }
  179 +
98 private void validateWorkstationCodeUnique(Long id, String code) { 180 private void validateWorkstationCodeUnique(Long id, String code) {
99 MesMdWorkstationDO workstation = workstationMapper.selectByCode(code); 181 MesMdWorkstationDO workstation = workstationMapper.selectByCode(code);
100 if (workstation == null) { 182 if (workstation == null) {