package com.zy.acs.manager.manager.service.impl;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.zy.acs.framework.common.Cools;
|
import com.zy.acs.framework.exception.CoolException;
|
import com.zy.acs.manager.common.exception.BusinessException;
|
import com.zy.acs.manager.manager.entity.Sta;
|
import com.zy.acs.manager.manager.entity.StaReserve;
|
import com.zy.acs.manager.manager.entity.Task;
|
import com.zy.acs.manager.manager.enums.StaReserveStateType;
|
import com.zy.acs.manager.manager.enums.StaReserveType;
|
import com.zy.acs.manager.manager.enums.StatusType;
|
import com.zy.acs.manager.manager.enums.TaskTypeType;
|
import com.zy.acs.manager.manager.mapper.StaMapper;
|
import com.zy.acs.manager.manager.mapper.StaReserveMapper;
|
import com.zy.acs.manager.manager.service.StaReserveService;
|
import com.zy.acs.manager.manager.service.StaService;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import java.util.Date;
|
import java.util.List;
|
import java.util.Objects;
|
import java.util.Optional;
|
|
@Service("staReserveService")
|
public class StaReserveServiceImpl extends ServiceImpl<StaReserveMapper, StaReserve> implements StaReserveService {
|
|
public static final Long RESERVE_EXPIRE_TIME = 30 * 60L;
|
public static final Long WAITING_EXPIRE_TIME = 5 * 60L;
|
|
public static final Integer DEFAULT_QTY = 1;
|
|
@Autowired
|
private StaService staService;
|
@Autowired
|
private StaMapper staMapper;
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public StaReserve reserveStaIn(Sta sta, Task task, Integer qty) {
|
qty = Optional.ofNullable(qty).orElse(DEFAULT_QTY);
|
|
// reserve sta in
|
if (staMapper.tryReserveIn(sta.getId(), qty) < qty) {
|
throw new BusinessException("Sta[" + sta.getStaNo() + "] can't reserve IN");
|
}
|
Date now = new Date();
|
|
// save staReserve
|
StaReserve reserve = new StaReserve();
|
reserve.setStaId(sta.getId());
|
reserve.setTaskId(task.getId());
|
reserve.setType(StaReserveType.IN.toString());
|
reserve.setQty(qty);
|
reserve.setState(StaReserveStateType.RESERVED.toString());
|
|
reserve.setUniqKey(this.generateReserveUniqKey(sta.getId(), task.getId(), StaReserveType.IN));
|
reserve.setExpireTime(new Date(now.getTime() + RESERVE_EXPIRE_TIME));
|
|
reserve.setStatus(StatusType.ENABLE.val);
|
reserve.setCreateTime(now);
|
reserve.setUpdateTime(now);
|
|
if (!this.save(reserve)) {
|
staMapper.releaseReserveIn(sta.getId(), qty);
|
throw new BusinessException("reserve record insert failed");
|
}
|
|
return reserve;
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public StaReserve reserveStaOut(Sta sta, Task task, Integer qty) {
|
qty = Optional.ofNullable(qty).orElse(DEFAULT_QTY);
|
|
// reserve sta out
|
if (staMapper.tryReserveOut(sta.getId(), qty) < qty) {
|
throw new BusinessException("Sta[" + sta.getStaNo() + "] can't reserve OUT");
|
}
|
|
Date now = new Date();
|
|
// save staReserve
|
StaReserve reserve = new StaReserve();
|
reserve.setStaId(sta.getId());
|
reserve.setTaskId(task.getId());
|
reserve.setType(StaReserveType.OUT.toString());
|
reserve.setQty(qty);
|
reserve.setState(StaReserveStateType.RESERVED.toString());
|
|
reserve.setUniqKey(this.generateReserveUniqKey(sta.getId(), task.getId(), StaReserveType.OUT));
|
reserve.setExpireTime(new Date(now.getTime() + RESERVE_EXPIRE_TIME));
|
|
reserve.setStatus(StatusType.ENABLE.val);
|
reserve.setCreateTime(now);
|
reserve.setUpdateTime(now);
|
|
if (!this.save(reserve)) {
|
staMapper.releaseReserveOut(sta.getId(), qty);
|
throw new BusinessException("reserve record insert failed");
|
}
|
|
return reserve;
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public Boolean waitingStaReserve(Sta sta, Task task, Integer qty, StaReserveType type) {
|
qty = Optional.ofNullable(qty).orElse(DEFAULT_QTY);
|
|
// update reserve to be waiting state
|
int changed = this.baseMapper.updateStateToWaiting(task.getId()
|
, sta.getId()
|
, type.toString()
|
, StaReserveStateType.WAITING.toString()
|
, WAITING_EXPIRE_TIME
|
);
|
if (changed > 0) {
|
return true;
|
}
|
|
List<StaReserve> list = this.list(new LambdaQueryWrapper<StaReserve>()
|
.eq(StaReserve::getStaId, sta.getId())
|
.eq(StaReserve::getTaskId, task.getId())
|
.eq(StaReserve::getType, type.toString())
|
.eq(StaReserve::getStatus, StatusType.ENABLE.val)
|
);
|
|
if (Cools.isEmpty(list)) {
|
return false;
|
}
|
StaReserve reserve = list.get(0);
|
|
StaReserveStateType stateType = StaReserveStateType.of(reserve.getState());
|
switch (Objects.requireNonNull(stateType)) {
|
case WAITING:
|
case CONFIRMED:
|
return true;
|
default:
|
return false;
|
}
|
}
|
|
@Override
|
public Boolean rollbackWaitingToReserved(Sta sta, Task task, StaReserveType type) {
|
int changed = this.baseMapper.updateStateBackToWaiting(
|
task.getId()
|
, sta.getId()
|
, type.toString()
|
, StaReserveStateType.RESERVED.toString()
|
, WAITING_EXPIRE_TIME
|
);
|
return changed > 0;
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void confirmStaReserve(Sta sta, Task task, Integer qty, StaReserveType type) {
|
qty = Optional.ofNullable(qty).orElse(DEFAULT_QTY);
|
|
// update reserve state to be confirmed
|
if (0 == this.baseMapper.updateState(task.getId(), sta.getId(), type.toString(), StaReserveStateType.CONFIRMED.toString())) {
|
log.error("failed to confirm sta reserve");
|
return;
|
}
|
|
int cntOfDealWithReserve = 0;
|
switch (type) {
|
case IN:
|
cntOfDealWithReserve = staMapper.confirmReserveIn(sta.getId(), qty);
|
break;
|
case OUT:
|
cntOfDealWithReserve = staMapper.confirmReserveOut(sta.getId(), qty);
|
break;
|
default:
|
break;
|
}
|
if (cntOfDealWithReserve == 0) {
|
throw new BusinessException("Sta[" + sta.getStaNo() + "] confirm failed, type=" + type.toString());
|
}
|
}
|
|
@Override
|
public void cancelStaReserve(Sta sta, Task task, Integer qty, StaReserveType type) {
|
qty = Optional.ofNullable(qty).orElse(DEFAULT_QTY);
|
|
// update reserve state to be canceled
|
if (0 == this.baseMapper.updateState(task.getId(), sta.getId(), type.toString(), StaReserveStateType.CANCELLED.toString())) {
|
log.error("failed to cancel sta reserve");
|
return;
|
}
|
|
int cntOfDealWithReserve = 0;
|
switch (type) {
|
case IN:
|
cntOfDealWithReserve = staMapper.releaseReserveIn(sta.getId(), qty);
|
break;
|
case OUT:
|
cntOfDealWithReserve = staMapper.releaseReserveOut(sta.getId(), qty);
|
break;
|
default:
|
break;
|
}
|
if (cntOfDealWithReserve == 0) {
|
throw new BusinessException("Sta[" + sta.getStaNo() + "] cancel failed, type=" + type.toString());
|
}
|
}
|
|
@Override
|
public void allocateCallBack(Task task, Long agvId) {
|
if (Cools.isEmpty(task, agvId)) {
|
return;
|
}
|
TaskTypeType taskType = TaskTypeType.get(task.getTaskTypeEl());
|
if (null == taskType) {
|
return;
|
}
|
Date now = new Date();
|
StaReserve inStaReserve = null;
|
StaReserve outStaReserve = null;
|
switch (taskType) {
|
case LOC_TO_STA:
|
inStaReserve = this.getOne(new LambdaQueryWrapper<StaReserve>()
|
.eq(StaReserve::getTaskId, task.getId())
|
.eq(StaReserve::getStaId, task.getDestSta())
|
.eq(StaReserve::getType, StaReserveType.IN.toString())
|
.eq(StaReserve::getState, StaReserveStateType.RESERVED.toString())
|
// .gt(StaReserve::getExpireTime, now)
|
);
|
if (null == inStaReserve) {
|
throw new CoolException("failed to find out sta reserve");
|
}
|
break;
|
case STA_TO_LOC:
|
outStaReserve = this.getOne(new LambdaQueryWrapper<StaReserve>()
|
.eq(StaReserve::getTaskId, task.getId())
|
.eq(StaReserve::getStaId, task.getOriSta())
|
.eq(StaReserve::getType, StaReserveType.OUT.toString())
|
.eq(StaReserve::getState, StaReserveStateType.RESERVED.toString())
|
// .gt(StaReserve::getExpireTime, now)
|
);
|
if (null == outStaReserve) {
|
throw new CoolException("failed to find out sta reserve");
|
}
|
break;
|
case STA_TO_STA:
|
inStaReserve = this.getOne(new LambdaQueryWrapper<StaReserve>()
|
.eq(StaReserve::getTaskId, task.getId())
|
.eq(StaReserve::getStaId, task.getDestSta())
|
.eq(StaReserve::getType, StaReserveType.IN.toString())
|
.eq(StaReserve::getState, StaReserveStateType.RESERVED.toString())
|
// .gt(StaReserve::getExpireTime, now)
|
);
|
outStaReserve = this.getOne(new LambdaQueryWrapper<StaReserve>()
|
.eq(StaReserve::getTaskId, task.getId())
|
.eq(StaReserve::getStaId, task.getOriSta())
|
.eq(StaReserve::getType, StaReserveType.OUT.toString())
|
.eq(StaReserve::getState, StaReserveStateType.RESERVED.toString())
|
// .gt(StaReserve::getExpireTime, now)
|
);
|
if (null == inStaReserve) {
|
throw new CoolException("failed to find out sta reserve");
|
}
|
if (null == outStaReserve) {
|
throw new CoolException("failed to find out sta reserve");
|
}
|
break;
|
default:
|
return;
|
}
|
if (null != inStaReserve) {
|
inStaReserve.setAgvId(agvId);
|
inStaReserve.setUpdateTime(now);
|
if (!this.updateById(inStaReserve)) {
|
throw new CoolException("failed to update sta reserve");
|
}
|
}
|
if (null != outStaReserve) {
|
outStaReserve.setAgvId(agvId);
|
outStaReserve.setUpdateTime(now);
|
if (!this.updateById(outStaReserve)) {
|
throw new CoolException("failed to update sta reserve");
|
}
|
}
|
}
|
|
|
private String generateReserveUniqKey(Long staId, Long taskId, StaReserveType type) {
|
return "STA:" + staId + "-TASK:" + taskId + "-T:" + type.toString();
|
}
|
|
}
|