From b852254d90e7d1955db31db154193ec8ee84d8b3 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期三, 09 九月 2026 10:57:59 +0800
Subject: [PATCH] feat(hrm): 新增员工用工性质、班组归属字段及考勤异常处理优化
---
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/machinery/MesDvMachineryServiceImpl.java | 186 ++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 179 insertions(+), 7 deletions(-)
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/machinery/MesDvMachineryServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/machinery/MesDvMachineryServiceImpl.java
index 9e74cf6..45568db 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/machinery/MesDvMachineryServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/machinery/MesDvMachineryServiceImpl.java
@@ -3,30 +3,51 @@
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
-import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
+import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemCreateReqDTO;
+import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
+import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
+import cn.iocoder.yudao.module.mdm.enums.MdmItemTypeEnum;
+import cn.iocoder.yudao.module.mes.api.item.MesMdItemApi;
+import cn.iocoder.yudao.module.mes.api.item.dto.MesMdItemSyncReqDTO;
import cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.MesDvMachineryImportExcelVO;
import cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.MesDvMachineryImportRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.MesDvMachineryPageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.MesDvMachinerySaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.dv.machinery.MesDvMachineryDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.dv.machinery.MesDvMachineryTypeDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemTypeDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkshopDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO;
import cn.iocoder.yudao.module.mes.dal.mysql.dv.machinery.MesDvMachineryMapper;
+import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
import cn.iocoder.yudao.module.mes.enums.wm.BarcodeBizTypeEnum;
+import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum;
import cn.iocoder.yudao.module.mes.service.dv.checkplan.MesDvCheckPlanMachineryService;
import cn.iocoder.yudao.module.mes.service.dv.checkrecord.MesDvCheckRecordService;
import cn.iocoder.yudao.module.mes.service.dv.maintenrecord.MesDvMaintenRecordService;
import cn.iocoder.yudao.module.mes.service.dv.repair.MesDvRepairService;
+import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemTypeService;
+import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkshopService;
import cn.iocoder.yudao.module.mes.service.wm.barcode.MesWmBarcodeService;
+import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService;
+import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO;
+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.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
+import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
@@ -38,11 +59,20 @@
/**
* MES 璁惧鍙拌处 Service 瀹炵幇绫�
*
- * @author 鑺嬮亾婧愮爜
+ * @author 瓒呯骇绠$悊鍛�
*/
@Service
@Validated
public class MesDvMachineryServiceImpl implements MesDvMachineryService {
+
+ /**
+ * 璁惧鑱斿姩鐗╂枡鐨勭被鍨嬬紪鐮侊紙mes_md_item_type / mdm_item_category 涓�滆澶団�濊鐨� code锛�
+ */
+ private static final String EQUIPMENT_ITEM_TYPE_CODE = "EQUIPMENT";
+ /**
+ * 璁惧鑱斿姩鐗╂枡鐨勮閲忓崟浣嶇紪鐮侊紙mes_md_unit_measure / mdm_unit_measure 涓�滃彴鈥濊鐨� code锛�
+ */
+ private static final String EQUIPMENT_UNIT_CODE = "TAI";
@Resource
private MesDvMachineryMapper machineryMapper;
@@ -53,6 +83,9 @@
@Resource
@Lazy
private MesMdWorkshopService workshopService;
+ @Resource
+ @Lazy
+ private cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService workstationService;
@Resource
private MesWmBarcodeService barcodeService;
@Resource
@@ -68,7 +101,30 @@
@Lazy
private MesDvRepairService repairService;
+ // ========== 璁惧鐗╂枡鑱斿姩渚濊禆 ==========
+ @Resource
+ private MdmItemApi mdmItemApi;
+ @Resource
+ private MdmUnitMeasureApi mdmUnitMeasureApi;
+ @Resource
+ private MesMdItemApi mesMdItemApi;
+ @Resource
+ @Lazy
+ private MesMdItemTypeService mesMdItemTypeService;
+ @Resource
+ @Lazy
+ private MesMdUnitMeasureService mesMdUnitMeasureService;
+ @Resource
+ private MesWmTransactionService wmTransactionService;
+ @Resource
+ private MesWmWarehouseService wmWarehouseService;
+ @Resource
+ private MesWmWarehouseLocationService wmLocationService;
+ @Resource
+ private MesWmWarehouseAreaService wmAreaService;
+
@Override
+ @Transactional(rollbackFor = Exception.class)
public Long createMachinery(MesDvMachinerySaveReqVO createReqVO) {
// 鏍¢獙璁惧绫诲瀷瀛樺湪
machineryTypeService.getMachineryType(createReqVO.getMachineryTypeId());
@@ -77,13 +133,20 @@
// 鏍¢獙缂栫爜鍞竴
validateMachineryCodeUnique(null, createReqVO.getCode());
- // 鎻掑叆
+ // 鍒涘缓瀵瑰簲 MDM 鐗╂枡骞跺悓姝� MES 鐗╂枡锛堝悓涓�浜嬪姟锛屽け璐ユ暣浣撳洖婊氾級
+ Long itemId = createEquipmentMaterial(createReqVO.getCode(), createReqVO.getName(),
+ createReqVO.getSpecification(), createReqVO.getRemark());
+
+ // 鎻掑叆璁惧鍙拌处
MesDvMachineryDO machinery = BeanUtils.toBean(createReqVO, MesDvMachineryDO.class);
+ machinery.setItemId(itemId);
machineryMapper.insert(machinery);
// 鑷姩鐢熸垚鏉$爜
barcodeService.autoGenerateBarcode(BarcodeBizTypeEnum.MACHINERY.getValue(),
machinery.getId(), machinery.getCode(), machinery.getName());
+ // 鑷姩鍏ヨ澶囦粨锛堝簱瀛� + 娴佹按锛�
+ createEquipmentStock(itemId, machinery.getId(), machinery.getCode());
return machinery.getId();
}
@@ -91,6 +154,7 @@
public void updateMachinery(MesDvMachinerySaveReqVO updateReqVO) {
// 鏍¢獙瀛樺湪
validateMachineryExists(updateReqVO.getId());
+ MesDvMachineryDO existMachinery = machineryMapper.selectById(updateReqVO.getId());
// 鏍¢獙璁惧绫诲瀷瀛樺湪
machineryTypeService.getMachineryType(updateReqVO.getMachineryTypeId());
// 鏍¢獙杞﹂棿瀛樺湪
@@ -100,6 +164,8 @@
// 鏇存柊
MesDvMachineryDO updateObj = BeanUtils.toBean(updateReqVO, MesDvMachineryDO.class);
+ // 鐗╂枡鍏宠仈鐢卞垱寤烘椂鑷姩鐢熸垚锛屾洿鏂颁笉鍏佽娓呯┖锛堝墠绔篃涓嶄紶鍏� itemId锛�
+ updateObj.setItemId(existMachinery.getItemId());
machineryMapper.updateById(updateObj);
}
@@ -107,6 +173,11 @@
public void deleteMachinery(Long id) {
// 鏍¢獙瀛樺湪
validateMachineryExists(id);
+ // 鏍¢獙宸茬敓鎴愮墿鏂欏苟鍏ヨ澶囦粨锛氶伩鍏嶅簱瀛�/娴佹按澶卞幓涓氬姟涓讳綋锛岀姝㈠垹闄�
+ MesDvMachineryDO machinery = machineryMapper.selectById(id);
+ if (machinery.getItemId() != null) {
+ throw exception(DV_MACHINERY_HAS_ITEM);
+ }
// 鏍¢獙鍏宠仈鏁版嵁
if (checkPlanMachineryService.getCheckPlanMachineryCountByMachineryId(id) > 0) {
throw exception(DV_MACHINERY_HAS_CHECK_PLAN);
@@ -201,7 +272,7 @@
throw exception(DV_MACHINERY_IMPORT_LIST_IS_EMPTY);
}
- // 2. 鎵归噺鍔犺浇璁惧绫诲瀷鍜岃溅闂达紝鏋勫缓缂栫爜鍒板疄浣撶殑鏄犲皠
+ // 2. 鎵归噺鍔犺浇璁惧绫诲瀷銆佽溅闂村拰宸ヤ綔绔欙紝鏋勫缓缂栫爜鍒板疄浣撶殑鏄犲皠
List<MesDvMachineryTypeDO> allTypes = machineryTypeService.getMachineryTypeList(
new cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.type.MesDvMachineryTypeListReqVO());
Map<String, MesDvMachineryTypeDO> typeCodeMap = allTypes.stream()
@@ -210,6 +281,13 @@
cn.iocoder.yudao.framework.common.enums.CommonStatusEnum.ENABLE.getStatus());
Map<String, MesMdWorkshopDO> workshopCodeMap = allWorkshops.stream()
.collect(Collectors.toMap(MesMdWorkshopDO::getCode, w -> w, (a, b) -> a));
+ List<cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO> allWorkstations =
+ workstationService.getWorkstationListByStatus(
+ cn.iocoder.yudao.framework.common.enums.CommonStatusEnum.ENABLE.getStatus());
+ Map<String, cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO> workstationCodeMap =
+ allWorkstations.stream().collect(Collectors.toMap(
+ cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO::getCode,
+ w -> w, (a, b) -> a));
// 3. 閬嶅巻锛岄�愪釜鍒涘缓 or 鏇存柊
MesDvMachineryImportRespVO respVO = MesDvMachineryImportRespVO.builder()
@@ -249,24 +327,45 @@
return;
}
- // 3.4 鍒ゆ柇锛氬垱寤� or 鏇存柊
+ // 3.4 鏍¢獙宸ヤ綔绔欑紪鐮侊紙鍙�夛級
+ Long workstationId = null;
+ if (StrUtil.isNotBlank(importItem.getWorkstationCode())) {
+ cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO workstation =
+ workstationCodeMap.get(importItem.getWorkstationCode());
+ if (workstation == null) {
+ respVO.getFailureCodes().put(key, "宸ヤ綔绔欑紪鐮乕" + importItem.getWorkstationCode() + "]涓嶅瓨鍦�");
+ return;
+ }
+ workstationId = workstation.getId();
+ }
+
+ // 3.5 鍒ゆ柇锛氬垱寤� or 鏇存柊
MesDvMachineryDO existMachinery = machineryMapper.selectByCode(importItem.getCode());
if (existMachinery == null) {
- // 3.4.1 鍒涘缓
+ // 3.5.1 鍒涘缓
MesDvMachineryDO machinery = BeanUtils.toBean(importItem, MesDvMachineryDO.class);
machinery.setMachineryTypeId(machineryType.getId());
machinery.setWorkshopId(workshop.getId());
+ machinery.setWorkstationId(workstationId);
+ // 鍒涘缓瀵瑰簲 MDM 鐗╂枡骞跺悓姝� MES 鐗╂枡锛堝悓涓�浜嬪姟锛�
+ machinery.setItemId(createEquipmentMaterial(machinery.getCode(), machinery.getName(),
+ machinery.getSpecification(), machinery.getRemark()));
machineryMapper.insert(machinery);
// 鑷姩鐢熸垚鏉$爜
barcodeService.autoGenerateBarcode(BarcodeBizTypeEnum.MACHINERY.getValue(),
machinery.getId(), machinery.getCode(), machinery.getName());
+ // 鑷姩鍏ヨ澶囦粨锛堝簱瀛� + 娴佹按锛�
+ createEquipmentStock(machinery.getItemId(), machinery.getId(), machinery.getCode());
respVO.getCreateCodes().add(importItem.getCode());
} else if (updateSupport) {
- // 3.4.2 鏇存柊
+ // 3.5.2 鏇存柊
MesDvMachineryDO updateObj = BeanUtils.toBean(importItem, MesDvMachineryDO.class);
updateObj.setId(existMachinery.getId());
updateObj.setMachineryTypeId(machineryType.getId());
updateObj.setWorkshopId(workshop.getId());
+ updateObj.setWorkstationId(workstationId);
+ // 鐗╂枡鍏宠仈鐢卞垱寤烘椂鑷姩鐢熸垚锛屾洿鏂颁笉鍏佽娓呯┖
+ updateObj.setItemId(existMachinery.getItemId());
machineryMapper.updateById(updateObj);
respVO.getUpdateCodes().add(importItem.getCode());
} else {
@@ -277,4 +376,77 @@
return respVO;
}
+ /**
+ * 鍒涘缓璁惧瀵瑰簲鐗╂枡锛氬厛鍦� MDM 寤轰富鏁版嵁鐗╂枡锛屽啀鏄惧紡鍚屾 MES 鐗╂枡锛堜袱濂椾富鏁版嵁 id 瀵归綈锛夈��
+ *
+ * @return MDM 鐗╂枡缂栧彿锛�= MES 鐗╂枡缂栧彿锛�
+ */
+ private Long createEquipmentMaterial(String code, String name, String specification, String remark) {
+ // 1. 瑙f瀽鈥滆澶団�濈被鍨嬶紙MES 渚э級涓庘�滃彴鈥濆崟浣嶏紙MDM 渚� + MES 渚э級锛岀己澶卞垯鎻愮ず涓绘暟鎹湭鍒濆鍖�
+ MesMdItemTypeDO itemType = mesMdItemTypeService.getItemTypeByCode(EQUIPMENT_ITEM_TYPE_CODE);
+ if (itemType == null) {
+ throw exception(DV_MACHINERY_EQUIP_MASTER_MISSING);
+ }
+ if (mesMdUnitMeasureService.getUnitMeasureByCode(EQUIPMENT_UNIT_CODE) == null) {
+ throw exception(DV_MACHINERY_EQUIP_MASTER_MISSING);
+ }
+ CommonResult<MdmUnitMeasureRespDTO> unitResult = mdmUnitMeasureApi.getUnitMeasureByCode(EQUIPMENT_UNIT_CODE);
+ MdmUnitMeasureRespDTO mdmUnit = unitResult.isSuccess() ? unitResult.getData() : null;
+ if (mdmUnit == null) {
+ throw exception(DV_MACHINERY_EQUIP_MASTER_MISSING);
+ }
+
+ // 2. 鍒涘缓 MDM 鐗╂枡锛涘垎绫讳娇鐢ㄢ�滆澶団�濆垎绫伙紙鍏� id 涓� MES 绫诲瀷 id 瀵归綈锛岀敱鍒濆鍖栬剼鏈繚璇侊級
+ MdmItemCreateReqDTO createReqDTO = new MdmItemCreateReqDTO();
+ createReqDTO.setCode(code);
+ createReqDTO.setName(name);
+ createReqDTO.setSpecification(specification);
+ createReqDTO.setRemark(remark);
+ createReqDTO.setCategoryId(itemType.getId());
+ createReqDTO.setUnitMeasureId(mdmUnit.getId());
+ createReqDTO.setItemType(MdmItemTypeEnum.EQUIPMENT.getType());
+ createReqDTO.setStatus(0);
+ createReqDTO.setIsBatchManaged(false);
+ Long mdmItemId = mdmItemApi.createItem(createReqDTO).getCheckedData();
+
+ // 3. 鏄惧紡鍚屾 MES 鐗╂枡锛圡dmItemCreateReqDTO 鏃� syncMes 寮�鍏筹紝涓嶄細鑷姩鍚屾锛�
+ MesMdItemSyncReqDTO syncReqDTO = new MesMdItemSyncReqDTO();
+ syncReqDTO.setCode(code);
+ syncReqDTO.setName(name);
+ syncReqDTO.setSpecification(specification);
+ syncReqDTO.setRemark(remark);
+ syncReqDTO.setUnitCode(EQUIPMENT_UNIT_CODE);
+ syncReqDTO.setItemTypeCode(EQUIPMENT_ITEM_TYPE_CODE);
+ syncReqDTO.setBatchFlag(false);
+ syncReqDTO.setSafeStockFlag(false);
+ syncReqDTO.setStatus(0);
+ syncReqDTO.setMdmItemId(mdmItemId);
+ mesMdItemApi.createItem(syncReqDTO);
+ return mdmItemId;
+ }
+
+ /**
+ * 璁惧鑷姩鍏ヨ澶囦粨锛氬垱寤轰竴鏉″叆搴撴暟閲忎负 1 鐨勫簱瀛樹簨鍔★紝浠撳簱/搴撳尯/搴撲綅鍙栫郴缁熷唴缃澶囦粨銆�
+ * 搴撳瓨琛屻�佹暟閲忎笌娴佹按缁熶竴缁� {@link MesWmTransactionService}锛岀姝㈢洿鎺ュ啓搴撳瓨琛ㄣ��
+ */
+ private void createEquipmentStock(Long itemId, Long machineryId, String machineryCode) {
+ MesWmWarehouseDO warehouse = wmWarehouseService.getWarehouseByCode(MesWmWarehouseDO.EQUIPMENT_WAREHOUSE);
+ MesWmWarehouseLocationDO location = wmLocationService.getWarehouseLocationByCode(MesWmWarehouseLocationDO.EQUIPMENT_LOCATION);
+ MesWmWarehouseAreaDO area = wmAreaService.getWarehouseAreaByCode(MesWmWarehouseAreaDO.EQUIPMENT_AREA);
+ if (warehouse == null || location == null || area == null) {
+ throw exception(DV_MACHINERY_EQUIP_MASTER_MISSING);
+ }
+ wmTransactionService.createTransaction(new MesWmTransactionSaveReqDTO()
+ .setType(MesWmTransactionTypeEnum.IN.getType())
+ .setItemId(itemId)
+ .setQuantity(BigDecimal.ONE)
+ .setWarehouseId(warehouse.getId())
+ .setLocationId(location.getId())
+ .setAreaId(area.getId())
+ .setBizType(MesBizTypeConstants.DV_MACHINERY)
+ .setBizId(machineryId)
+ .setBizCode(machineryCode)
+ .setBizLineId(machineryId));
+ }
+
}
--
Gitblit v1.9.3