|
|
|
|
@ -27,6 +27,7 @@ package org.springblade.desk.dashboard.service.impl; |
|
|
|
|
|
|
|
|
|
import com.alibaba.fastjson2.JSONObject; |
|
|
|
|
import com.baomidou.mybatisplus.core.conditions.Wrapper; |
|
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
|
|
|
|
import com.baomidou.mybatisplus.core.metadata.IPage; |
|
|
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
|
|
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
|
@ -39,10 +40,8 @@ import org.springblade.core.tool.utils.SpringUtil; |
|
|
|
|
import org.springblade.desk.basic.pojo.entity.BasicClazz; |
|
|
|
|
import org.springblade.desk.basic.pojo.entity.LocallyPlatedPart; |
|
|
|
|
import org.springblade.desk.basic.pojo.entity.Plating; |
|
|
|
|
import org.springblade.desk.basic.service.IBasicClazzService; |
|
|
|
|
import org.springblade.desk.basic.service.ICraftAbilityService; |
|
|
|
|
import org.springblade.desk.basic.service.ILocallyPlatedPartService; |
|
|
|
|
import org.springblade.desk.basic.service.IPlatingService; |
|
|
|
|
import org.springblade.desk.basic.pojo.entity.PlatingAssortment; |
|
|
|
|
import org.springblade.desk.basic.service.*; |
|
|
|
|
import org.springblade.desk.common.constant.BizTypeConstant; |
|
|
|
|
import org.springblade.desk.common.service.IMesNotifyMessageService; |
|
|
|
|
import org.springblade.desk.dashboard.constant.DsPartConstant; |
|
|
|
|
@ -187,8 +186,10 @@ public class DsTaskingServiceImpl extends BaseServiceImpl<DsTaskingMapper, DsTas |
|
|
|
|
IMeasurementRecordsService measurementRecordsService; |
|
|
|
|
|
|
|
|
|
@Autowired |
|
|
|
|
IBasicClazzService basicClazzService; |
|
|
|
|
IPlatingAssortmentService platingAssortmentService; |
|
|
|
|
|
|
|
|
|
@Autowired |
|
|
|
|
IDsDispatchPointerService dsDispatchPointerService; |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public IPage<DsTaskingVO> selectAssignList(IPage<DsTaskingVO> page, DsTaskingVO dsTasking) { |
|
|
|
|
@ -1859,29 +1860,146 @@ public class DsTaskingServiceImpl extends BaseServiceImpl<DsTaskingMapper, DsTas |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public boolean automaticDispatching(String taskingId) { |
|
|
|
|
DsTaskingEntity tasking = this.getById(taskingId); |
|
|
|
|
if(tasking == null){ |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
//获取镀种
|
|
|
|
|
if(StringUtils.isEmpty(tasking.getPlate())){ |
|
|
|
|
return false; |
|
|
|
|
public boolean automaticDispatching() { |
|
|
|
|
//查询所有未分派任务
|
|
|
|
|
List<DsTaskingEntity> dsTaskingList = taskingMapper.selectTaskingByTaskStatus(TaskingConstant.TASK_STATUS_WAIT); |
|
|
|
|
if(!CollectionUtils.isEmpty(dsTaskingList)){ |
|
|
|
|
for (DsTaskingEntity tasking : dsTaskingList) { |
|
|
|
|
|
|
|
|
|
// 根据零件配置码查询镀种分类
|
|
|
|
|
List<DsPartEntity> dsPartEntityList = partService.selectDsPartByPatCode(tasking.getPartCode()); |
|
|
|
|
if (CollectionUtils.isEmpty(dsPartEntityList)) { |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
DsPartEntity part = dsPartEntityList.get(0); |
|
|
|
|
String configCode = part.getConfigCode(); |
|
|
|
|
if(StringUtils.isEmpty(configCode)){ |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
List<Plating> platingList = platingService.selectBsPlatingByConfigNo(configCode); |
|
|
|
|
if(CollectionUtils.isEmpty(platingList)){ |
|
|
|
|
log.warn("未找到镀种分类,零件配置码: {}", configCode); |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
Plating plating = platingList.get(0); |
|
|
|
|
if ( plating.getPlatingAssortmentId() == null) { |
|
|
|
|
log.warn("未找到镀种分类,镀种: {}", tasking.getPlate()); |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
PlatingAssortment platingAssortment = platingAssortmentService.getById(plating.getPlatingAssortmentId()); |
|
|
|
|
if (platingAssortment == null) { |
|
|
|
|
log.warn("镀种分类不存在: {}", plating.getPlatingAssortmentId()); |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 获取镀种分类对应的人员
|
|
|
|
|
String teamId = platingAssortment.getTeamMemberId(); |
|
|
|
|
List<User> userList = new ArrayList<>(); |
|
|
|
|
if (!StringUtils.isEmpty(teamId)) { |
|
|
|
|
userList = userClient.userListByIds(teamId); |
|
|
|
|
userList.sort(Comparator.comparing(User::getCreateTime, Comparator.nullsLast(Comparator.naturalOrder()))); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (userList.isEmpty()) { |
|
|
|
|
log.warn("镀种分类[{}]下没有可分配的人员", platingAssortment.getName()); |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 判断指针类型(烧结新图任务使用独立指针)
|
|
|
|
|
String pointerType = "NORMAL"; |
|
|
|
|
if (isSinteringNewDrawingTask(tasking,part)) { |
|
|
|
|
pointerType = "NEW_DRAWING"; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 获取或创建指针
|
|
|
|
|
DsDispatchPointerEntity pointer = dsDispatchPointerService.getOrCreatePointer( |
|
|
|
|
platingAssortment.getId(), pointerType); |
|
|
|
|
|
|
|
|
|
// 边界处理:如果上次下标超出当前列表长度
|
|
|
|
|
int lastIndex = pointer.getLastIndex(); |
|
|
|
|
if (lastIndex >= userList.size()) { |
|
|
|
|
lastIndex = userList.size() - 1; |
|
|
|
|
pointer.setLastIndex(lastIndex); |
|
|
|
|
dsDispatchPointerService.updateById(pointer); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// ========== 带重试的分派逻辑 ==========
|
|
|
|
|
int maxRetries = userList.size(); |
|
|
|
|
int currentIndex = (lastIndex + 1) % userList.size(); |
|
|
|
|
User assignedUser = null; |
|
|
|
|
int successIndex = -1; |
|
|
|
|
boolean assignedSuccess = false; |
|
|
|
|
|
|
|
|
|
for (int retryCount = 0; retryCount < maxRetries; retryCount++) { |
|
|
|
|
User candidate = userList.get(currentIndex); |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
if (this.assignTechnician(tasking.getId().toString(), candidate.getId().toString(), null)) { |
|
|
|
|
assignedSuccess = true; |
|
|
|
|
assignedUser = candidate; |
|
|
|
|
successIndex = currentIndex; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} catch (Exception e) { |
|
|
|
|
log.error("分派任务给员工[{}]异常", candidate.getId(), e); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
log.warn("分派任务[{}]给人员[{}]失败,尝试下一个人", tasking.getId(), candidate.getName()); |
|
|
|
|
currentIndex = (currentIndex + 1) % userList.size(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!assignedSuccess) { |
|
|
|
|
log.error("任务[{}]分派失败,所有可分配人员都无法接收", tasking.getId()); |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
// ========== 重试逻辑结束 ==========
|
|
|
|
|
|
|
|
|
|
// 更新指针(带乐观锁重试3次)
|
|
|
|
|
boolean updateSuccess = false; |
|
|
|
|
for (int retryCount = 0; retryCount < 3; retryCount++) { |
|
|
|
|
DsDispatchPointerEntity latestPointer = dsDispatchPointerService.getById(pointer.getId()); |
|
|
|
|
|
|
|
|
|
boolean success = dsDispatchPointerService.lambdaUpdate() |
|
|
|
|
.eq(DsDispatchPointerEntity::getId, pointer.getId()) |
|
|
|
|
.eq(DsDispatchPointerEntity::getVersion, latestPointer.getVersion()) |
|
|
|
|
.set(DsDispatchPointerEntity::getLastIndex, successIndex) |
|
|
|
|
.set(DsDispatchPointerEntity::getVersion, latestPointer.getVersion() + 1) |
|
|
|
|
.set(DsDispatchPointerEntity::getUpdateTime, new Date()) |
|
|
|
|
.update(); |
|
|
|
|
|
|
|
|
|
if (success) { |
|
|
|
|
updateSuccess = true; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
log.warn("更新分派指针失败,第{}次重试", retryCount + 1); |
|
|
|
|
try { |
|
|
|
|
Thread.sleep(10); |
|
|
|
|
} catch (InterruptedException e) { |
|
|
|
|
Thread.currentThread().interrupt(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!updateSuccess) { |
|
|
|
|
log.warn("更新分派指针失败,但任务已分派给[{}],下次分派可能重复", assignedUser.getName()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
log.info("任务[{}]自动分派成功,工艺员:{},类型:{},镀种分类:{}", |
|
|
|
|
tasking.getId(), assignedUser.getName(), pointerType, platingAssortment.getName()); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
//根据镀种查询镀种分类
|
|
|
|
|
// Plating plating = platingService.selectBsPlatingByPlating(tasking.getPlate());
|
|
|
|
|
// if(plating == null && plating.getBcId() == null){
|
|
|
|
|
// return false;
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// BasicClazz basicClazz = basicClazzService.getById(plating.getBcId());
|
|
|
|
|
// if(basicClazz == null){
|
|
|
|
|
// return false;
|
|
|
|
|
// }
|
|
|
|
|
//获取镀种分类对应的人员
|
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
|
/** |
|
|
|
|
* 判断是否为烧结新图任务 |
|
|
|
|
*/ |
|
|
|
|
private boolean isSinteringNewDrawingTask(DsTaskingEntity tasking,DsPartEntity part) { |
|
|
|
|
return TaskingConstant.IS_SINTERING.equals(part.getIsSintering()) |
|
|
|
|
&& TaskingConstant.NEW_MAP_TASKS.equals(tasking.getTaskType()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|