@@ -64,6 +64,8 @@ import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired ;
import org.springframework.stereotype.Service ;
import org.springframework.transaction.annotation.Transactional ;
import org.springframework.transaction.support.TransactionSynchronization ;
import org.springframework.transaction.support.TransactionSynchronizationManager ;
import java.math.BigDecimal ;
import java.util.ArrayList ;
@@ -370,6 +372,13 @@ public class SlitterServiceImpl implements SlitterService {
/**
* 拼单规则:双轴不拼,单轴拼,同区域拼
* validateAndGetPlans() - 验证并获取分切计划
* handleExceptionCase() - 处理异常情况
* updatePlanWeights() - 更新分切计划重量
* generateQzzNo() - 生成气胀轴编码
* completeShaftLoading() - 完成套轴
* tryCombineOrder() - 尝试拼单逻辑
* handleNormalProcess() - 处理正常业务流程
* @param param
* @return
*/
@@ -377,286 +386,86 @@ public class SlitterServiceImpl implements SlitterService {
@Override
@Transactional ( rollbackFor = Exception . class )
public JSONObject acsFinishLoadShaft ( JSONObject param ) {
String msg = " " ;
JSONObject res = new JSONObject ( ) ;
// 穿拔轴位
String deviceCode = param . getString ( " device_code " ) ;
List < String > stepTipLogs = getRedisListValue ( " ERROR " + deviceCode ) ;
// 枷锁
RLock lock = redissonClient . getLock ( " doAcsFinishLoadShaft " ) ;
boolean tryLock = lock . tryLock ( 10 , TimeUnit . SECONDS ) ;
try {
if ( tryLock ) {
log . info ( " ACS申请套管完成参数: {} " , param ) ;
// 纸管
BigDecimal weight1 = param . getBigDecimal ( " weight1 " ) ;
String material1 = param . getString ( " material1 " ) ;
BigDecimal weight2 = param . getBigDecimal ( " weight2 " ) ;
String material2 = param . getString ( " material2 " ) ;
BstIvtShafttubeivt startPoint = shafttubeivtService . getOne ( new LambdaQueryWrapper < BstIvtShafttubeivt > ( )
. eq ( BstIvtShafttubeivt : : getPoint_code , deviceCode ) ) ;
// 获取分切计划
List < String > collect = Stream . of ( startPoint . getContainer_name1 ( ) , startPoint . getContainer_name2 ( ) )
. filter ( value - > value ! = null & & ! value . isEmpty ( ) ) . collect ( Collectors . toList ( ) ) ;
if ( collect . size ( ) = = 0 ) {
log . error ( " 找不到[{}]对应的分切计划! " , deviceCode ) ;
stepTipLogs . add ( " 套轴完成->找不到[ " + deviceCode + " ]点位记录的分切计划!分切计划可能被删除或者拼接! " ) ;
redisUtils . set ( " ERROR " + deviceCode , stepTipLogs ) ;
throw new BadRequestException ( " 找不到[ " + deviceCode + " ]对应的分切计划! " ) ;
}
List < PdmBiSlittingproductionplan > plans = slittingproductionplanService . list (
new LambdaQueryWrapper < PdmBiSlittingproductionplan > ( )
. in ( PdmBiSlittingproductionplan : : getContainer_name , collect )
. eq ( PdmBiSlittingproductionplan : : getStatus , " 01 " )
. eq ( PdmBiSlittingproductionplan : : getIs_delete , " 0 " ) ) ;
// 判断是否有未完成的任务
List < SchBaseTask > list = taskService . list ( new LambdaQueryWrapper < SchBaseTask > ( )
. eq ( SchBaseTask : : getPoint_code1 , deviceCode )
. like ( SchBaseTask : : getRequest_param , collect . get ( 0 ) )
. lt ( SchBaseTask : : getTask_status , " 07 " ) ) ;
if ( list . size ( ) > 0 ) {
log . error ( " 点位[{}]存在未完成得任务! " , deviceCode ) ;
stepTipLogs . add ( " 套轴完成->点位[ " + deviceCode + " ]存在未完成得任务! " ) ;
redisUtils . set ( " ERROR " + deviceCode , stepTipLogs ) ;
throw new BadRequestException ( " 点位[ " + deviceCode + " ]存在未完成得任务! " ) ;
}
// 去异常位
if ( plans . size ( ) = = 0 ) {
log . error ( " 找不到[{}]对应的分切计划,分切计划可能被删除或者拼接! " , collect ) ;
// 移动到异常处理位( 随机一个点位, 在送到B2对面的位置)
List < String > exceptionPointCodes = bcutpointivtService . getCanUseMinPointByShelf ( " 4 " , " 0 " ) ;
if ( exceptionPointCodes . size ( ) > 0 ) {
String exceptionPoint = exceptionPointCodes . get ( 0 ) ;
JSONObject exParam = new JSONObject ( ) ;
exParam . put ( " point_code1 " , startPoint . getPoint_code ( ) ) ;
exParam . put ( " point_code2 " , exceptionPoint ) ;
if ( exceptionPoint . endsWith ( " A " ) ) {
exParam . put ( " vehicle_code1 " , collect ) ;
} else {
exParam . put ( " vehicle_code2 " , collect ) ;
}
exParam . put ( " task_type " , SlitterEnum . TASK_TYPE . code ( " 套轴异常处理桁架任务 " ) ) ;
exParam . put ( " product_area " , SlitterConstant . SLITTER_TASK_AREA ) ;
exParam . put ( " acs_task_type " , " 6 " ) ;
exParam . put ( " containers " , collect ) ;
exParam . put ( " qzz_size " , startPoint . getQzz_size ( ) ) ;
sendNBJExceptionPointTask . createTask ( exParam ) ;
res . put ( " status " , HttpStatus . HTTP_OK ) ;
res . put ( " message " , " 创建送至异常处理位! " ) ;
return res ;
}
// 半条任务等待补齐
stepTipLogs . add ( " 套轴完成->[ " + collect + " ]对应的分切计划状态已更改,无暂存位置,创建任务失败! " ) ;
redisUtils . set ( " ERROR " + deviceCode , stepTipLogs ) ;
JSONObject exParam = new JSONObject ( ) ;
exParam . put ( " point_code1 " , startPoint . getPoint_code ( ) ) ;
exParam . put ( " point_code2 " , " - " ) ;
exParam . put ( " vehicle_code1 " , collect ) ;
exParam . put ( " task_type " , SlitterEnum . TASK_TYPE . code ( " 套轴异常处理桁架任务 " ) ) ;
exParam . put ( " product_area " , SlitterConstant . SLITTER_TASK_AREA ) ;
exParam . put ( " task_status " , TaskStatusEnum . SURE_START . getCode ( ) ) ;
exParam . put ( " acs_task_type " , " 6 " ) ;
exParam . put ( " containers " , collect ) ;
exParam . put ( " qzz_size " , startPoint . getQzz_size ( ) ) ;
sendNBJExceptionPointTask . createTask ( exParam ) ;
res . put ( " status " , HttpStatus . HTTP_OK ) ;
res . put ( " message " , " 请求成功 " ) ;
res . put ( " msg " , msg ) ;
return res ;
}
// 分切计划设置纸卷重量
for ( PdmBiSlittingproductionplan plan : plans ) {
if ( SlitterConstant . SLITTER_SUB_VOLUME_LEFT . equals ( plan . getLeft_or_right ( ) ) ) {
plan . setPaper_weight ( String . valueOf ( NumberUtil . round ( weight1 , 2 ) ) ) ;
msg = msg + " 子卷号: " + plan . getContainer_name ( ) + " 的纸管重量: " + weight1 + " | " ;
} else {
plan . setPaper_weight ( String . valueOf ( NumberUtil . round ( weight2 , 2 ) ) ) ;
msg = msg + " 子卷号: " + plan . getContainer_name ( ) + " 的纸管重量: " + weight2 + " | " ;
}
TaskUtils . updateOptMessageBySlitterPlan ( plan ) ;
}
slittingproductionplanService . updateBatchById ( plans ) ;
// 当前套轴的分切计划
PdmBiSlittingproductionplan demoPlan = plans . get ( 0 ) ;
// 分切计划设置套轴完成
String resourceName = demoPlan . getResource_name ( ) ;
String qzzNo = resourceName . substring ( 0 , 2 )
+ resourceName . substring ( resourceName . length ( ) - 2 )
+ demoPlan . getSplit_group ( )
+ TaskUtils . getDateTime ( " yyMMddHHmmss " ) + " - "
+ demoPlan . getUp_or_down ( ) ;
plans . forEach ( plan - > {
plan . setIs_child_tz_ok ( SlitterConstant . SLITTER_YES ) ;
plan . setQzzno ( qzzNo ) ;
TaskUtils . updateOptMessageBySlitterPlan ( plan ) ;
} ) ;
slittingproductionplanService . updateBatchById ( plans ) ;
// 搬运的点
BstIvtCutpointivt cutPoint ;
//============================= 拼单业务 ==============================
// 标记是否是通过拼单的
String flag = " 0 " ;
// 标记气胀轴编码是存到任务的载具号1还是2
String vehicleLocation = " 1 " ;
// 指定点位
String specialPoint = " " ;
// 合单开关
Param codParam = paramService . findByCode ( IS_COMBINED_ORDER ) ;
// 总判断是否有同组(判断自己能不能拼单)
Integer sameNumber = slittingproductionplanService . getSameTripParentContainerPlanCount ( demoPlan ) ;
// 允许拼单
if ( sameNumber = = 0 & & ObjectUtil . isNotEmpty ( codParam ) & & " 1 " . equals ( codParam . getValue ( ) ) ) {
StIvtCutpointivt deviceInfo = cutpointivtService . getPintByExtCode ( resourceName , false ) ;
List < BstIvtCutpointivt > emptyNotTaskPoint ;
// 查找能够拼单(没任务)的点位
emptyNotTaskPoint = slitterMapper . getCombinedOrders ( CombinedOrderDto
. builder ( )
. pointStatus ( " 2 " )
. pointType ( " 1 " )
. pointLocation ( deviceInfo . getPoint_location ( ) )
. plan ( deviceInfo . getPlan ( ) )
. device ( resourceName ) . build ( ) ) ;
flag = " 1 " ;
// 如果为空,看看路上的那根轴能不能拼单
if ( emptyNotTaskPoint . size ( ) = = 0 ) {
SchBaseTask runningTask = taskService . getOne ( new LambdaQueryWrapper < SchBaseTask > ( )
. eq ( SchBaseTask : : getHandle_class , " org.nl.b_lms.sch.tasks.slitter.TrussSendAirShaftTask " )
. lt ( SchBaseTask : : getTask_status , " 07 " )
. eq ( SchBaseTask : : getIs_delete , " 0 " )
. ne ( SchBaseTask : : getPoint_code1 , deviceCode ) ) ;
if ( ObjectUtil . isNotEmpty ( runningTask ) & & ObjectUtil . isNotEmpty ( runningTask . getPoint_code2 ( ) ) ) {
List < PdmBiSlittingproductionplan > runningShafts = slittingproductionplanService . getByQzzNos ( Arrays . asList ( runningTask . getVehicle_code ( ) , runningTask . getVehicle_code2 ( ) ) ) ;
if ( runningShafts . size ( ) > 0 ) {
PdmBiSlittingproductionplan runningShaft = runningShafts . get ( 0 ) ;
// 判断有没有同组同母卷同设备不同轴的卷号,没有则判断和当前计划是不是允许拼单的
Integer otherPlans =
slittingproductionplanService . getSameTripParentContainerPlanCount ( runningShaft ) ;
if ( otherPlans = = 0 ) {
StIvtCutpointivt runDeviceInfo = cutpointivtService . getPintByExtCode ( runningShaft . getResource_name ( ) , false ) ;
// 判断对应设备与当前计划设是否能够拼在一起
if ( runDeviceInfo . getPlan ( ) . equals ( deviceInfo . getPlan ( ) ) ) {
// 可以拼单
BstIvtCutpointivt one = bcutpointivtService . getOne ( new LambdaQueryWrapper < BstIvtCutpointivt > ( )
. eq ( BstIvtCutpointivt : : getTruss_point_code1 , runningTask . getPoint_code2 ( ) ) . or ( )
. eq ( BstIvtCutpointivt : : getTruss_point_code2 , runningTask . getPoint_code2 ( ) ) ) ;
// 判断目标点是否为空
specialPoint = one . getTruss_point_code1 ( ) . equals ( runningTask . getPoint_code2 ( ) )
? one . getTruss_point_code2 ( ) : one . getTruss_point_code1 ( ) ;
vehicleLocation = one . getTruss_point_code1 ( ) . equals ( runningTask . getPoint_code2 ( ) )
? " 2 " : " 1 " ;
if ( ( specialPoint . equals ( one . getTruss_point_code1 ( ) )
& & ObjectUtil . isNotEmpty ( one . getQzz_no1 ( ) ) )
| | ( specialPoint . equals ( one . getTruss_point_code2 ( ) )
& & ObjectUtil . isNotEmpty ( one . getQzz_no2 ( ) ) ) ) {
emptyNotTaskPoint . add ( one ) ;
flag = " 2 " ;
}
}
}
}
}
}
if ( emptyNotTaskPoint . size ( ) > 0 ) {
cutPoint = emptyNotTaskPoint . get ( 0 ) ;
// 创建任务
JSONObject taskParam = new JSONObject ( ) ;
taskParam . put ( " point_code1 " , startPoint . getPoint_code ( ) ) ;
taskParam . put ( " point_code2 " ,
" 2 " . equals ( flag ) ? specialPoint
: " 1 " . equals ( flag ) ? ObjectUtil . isEmpty ( cutPoint . getQzz_no1 ( ) )
? cutPoint . getTruss_point_code1 ( ) : cutPoint . getTruss_point_code2 ( )
: SlitterConstant . SLITTER_SHAFT_UP . equals ( demoPlan . getUp_or_down ( ) )
? cutPoint . getTruss_point_code1 ( ) : cutPoint . getTruss_point_code2 ( ) ) ;
taskParam . put ( " vehicle_code1 " ,
" 2 " . equals ( flag ) ? " 1 " . equals ( vehicleLocation ) ? qzzNo : " "
: " 1 " . equals ( flag ) ? ObjectUtil . isEmpty ( cutPoint . getQzz_no1 ( ) )
? qzzNo : " "
: SlitterConstant . SLITTER_SHAFT_UP . equals ( demoPlan . getUp_or_down ( ) ) ? qzzNo : " " ) ;
taskParam . put ( " vehicle_code2 " ,
" 2 " . equals ( flag ) ? " 2 " . equals ( vehicleLocation ) ? qzzNo : " "
: " 1 " . equals ( flag ) ? ObjectUtil . isEmpty ( cutPoint . getQzz_no2 ( ) )
? qzzNo : " "
: SlitterConstant . SLITTER_SHAFT_DOWN . equals ( demoPlan . getUp_or_down ( ) ) ? qzzNo : " " ) ;
taskParam . put ( " task_type " , " 010814 " ) ;
taskParam . put ( " product_area " , SlitterConstant . SLITTER_TASK_AREA ) ;
taskParam . put ( " immediateNotifyAcs " , " 1 " ) ;
trussSendAirShaftTask . createTask ( taskParam ) ;
res . put ( " status " , HttpStatus . HTTP_OK ) ;
res . put ( " message " , " 请求成功 " ) ;
res . put ( " msg " , msg ) ;
return res ;
}
}
flag = " 0 " ;
//============================= 不进行拼单的正常业务 ==============================
// 查找是否有同组的气胀轴位置
cutPoint = slitterMapper . getSameGroupPoint ( demoPlan ) ;
if ( ObjectUtil . isEmpty ( cutPoint ) ) {
// 也有可能在路上, 获取任务的终点
String endPoint = slitterMapper . getSameGroupTaskPoint ( demoPlan ) ;
if ( ObjectUtil . isNotEmpty ( endPoint ) ) {
cutPoint = bcutpointivtService . getOne ( new LambdaQueryWrapper < BstIvtCutpointivt > ( )
. eq ( BstIvtCutpointivt : : getTruss_point_code1 , endPoint ) . or ( )
. eq ( BstIvtCutpointivt : : getTruss_point_code2 , endPoint ) ) ;
}
}
if ( ObjectUtil . isEmpty ( cutPoint ) ) {
// 获取一个空位 (上下区域)
List < BstIvtCutpointivt > emptyNotTaskPoint = bcutpointivtService . getNBJAreaNotTaskPointByStatus (
" 1 " , " 1 " , startPoint . getPoint_location ( ) , " 1 " ) ;
if ( emptyNotTaskPoint . size ( ) > 0 ) {
cutPoint = emptyNotTaskPoint . get ( 0 ) ;
} else {
stepTipLogs . add ( " 提示:套轴完成->找不到可用套轴对接位, 创建半条任务, 等待AGV取货完成触发! " ) ;
redisUtils . set ( " ERROR " + deviceCode , stepTipLogs ) ;
// 创建任务
JSONObject taskParam = new JSONObject ( ) ;
taskParam . put ( " point_code1 " , startPoint . getPoint_code ( ) ) ;
taskParam . put ( " point_code2 " , " - " ) ;
taskParam . put ( " needPosition " , SlitterConstant . SLITTER_SHAFT_UP . equals ( demoPlan . getUp_or_down ( ) )
? " A " : " B " ) ;
taskParam . put ( " vehicle_code1 " , SlitterConstant . SLITTER_SHAFT_UP . equals ( demoPlan . getUp_or_down ( ) ) ? qzzNo : " " ) ;
taskParam . put ( " vehicle_code2 " , SlitterConstant . SLITTER_SHAFT_DOWN . equals ( demoPlan . getUp_or_down ( ) ) ? qzzNo : " " ) ;
taskParam . put ( " task_type " , " 010814 " ) ;
taskParam . put ( " containers " , collect ) ;
taskParam . put ( " qzz_size " , demoPlan . getQzz_size ( ) ) ;
taskParam . put ( " task_status " , TaskStatusEnum . SURE_START . getCode ( ) ) ;
taskParam . put ( " product_area " , SlitterConstant . SLITTER_TASK_AREA ) ;
taskParam . put ( " immediateNotifyAcs " , " 0 " ) ;
trussSendAirShaftTask . createTask ( taskParam ) ;
}
}
if ( ObjectUtil . isNotEmpty ( cutPoint ) ) {
// 创建任务
JSONObject taskParam = new JSONObject ( ) ;
taskParam . put ( " point_code1 " , startPoint . getPoint_code ( ) ) ;
taskParam . put ( " point_code2 " , SlitterConstant . SLITTER_SHAFT_UP . equals ( demoPlan . getUp_or_down ( ) )
? cutPoint . getTruss_point_code1 ( ) : cutPoint . getTruss_point_code2 ( ) ) ;
taskParam . put ( " vehicle_code1 " , SlitterConstant . SLITTER_SHAFT_UP . equals ( demoPlan . getUp_or_down ( ) ) ? qzzNo : " " ) ;
taskParam . put ( " vehicle_code2 " , SlitterConstant . SLITTER_SHAFT_DOWN . equals ( demoPlan . getUp_or_down ( ) ) ? qzzNo : " " ) ;
taskParam . put ( " task_type " , " 010814 " ) ;
taskParam . put ( " containers " , collect ) ;
taskParam . put ( " qzz_size " , demoPlan . getQzz_size ( ) ) ;
taskParam . put ( " product_area " , SlitterConstant . SLITTER_TASK_AREA ) ;
taskParam . put ( " immediateNotifyAcs " , " 1 " ) ;
trussSendAirShaftTask . createTask ( taskParam ) ;
}
} else {
if ( ! tryLock ) {
stepTipLogs . add ( " 套轴完成->系统繁忙,稍后在试! " ) ;
redisUtils . set ( " ERROR " + deviceCode , stepTipLogs ) ;
throw new BadRequestException ( " 系统繁忙,稍后在试! " ) ;
}
log . info ( " ACS申请套管完成参数: {} " , param ) ;
// 1. 获取起点和分切计划
BstIvtShafttubeivt startPoint = shafttubeivtService . getOne (
new LambdaQueryWrapper < BstIvtShafttubeivt > ( )
. eq ( BstIvtShafttubeivt : : getPoint_code , deviceCode ) ) ;
List < PdmBiSlittingproductionplan > plans = validateAndGetPlans ( deviceCode , startPoint , stepTipLogs ) ;
// 2. 处理异常情况 - 分切计划不存在
if ( plans . isEmpty ( ) ) {
List < String > containerNames = Stream . of ( startPoint . getContainer_name1 ( ) , startPoint . getContainer_name2 ( ) )
. filter ( ObjectUtil : : isNotEmpty )
. collect ( Collectors . toList ( ) ) ;
return handleExceptionCase ( deviceCode , startPoint , containerNames , stepTipLogs ) ;
}
// 3. 更新分切计划重量
BigDecimal weight1 = param . getBigDecimal ( " weight1 " ) ;
BigDecimal weight2 = param . getBigDecimal ( " weight2 " ) ;
String msg = updatePlanWeights ( plans , weight1 , weight2 ) ;
// 4. 生成气胀轴编码并完成套轴
PdmBiSlittingproductionplan demoPlan = plans . get ( 0 ) ;
String qzzNo = generateQzzNo ( demoPlan ) ;
completeShaftLoading ( plans , qzzNo ) ;
// 5. 获取子卷名称列表
List < String > containerNames = Stream . of ( startPoint . getContainer_name1 ( ) , startPoint . getContainer_name2 ( ) )
. filter ( ObjectUtil : : isNotEmpty )
. collect ( Collectors . toList ( ) ) ;
// 6. 尝试拼单
BstIvtCutpointivt combinedPoint = tryCombineOrder ( demoPlan , deviceCode , startPoint , qzzNo ) ;
if ( combinedPoint = = null ) {
// 7. 正常业务流程(不拼单)
handleNormalProcess ( demoPlan , startPoint , qzzNo , containerNames , deviceCode , stepTipLogs ) ;
}
JSONObject res = new JSONObject ( ) ;
res . put ( " status " , HttpStatus . HTTP_OK ) ;
res . put ( " message " , " 请求成功 " ) ;
res . put ( " msg " , msg ) ;
return res ;
} finally {
if ( tryLock ) {
lock . unlock ( ) ;
// 使用 TransactionSynchronization 在事务提交后释放锁
// 避免锁释放但事务未提交导致的并发问题
if ( TransactionSynchronizationManager . isSynchronizationActive ( ) ) {
TransactionSynchronizationManager . registerSynchronization ( new TransactionSynchronization ( ) {
@Override
public void afterCompletion ( int status ) {
try {
lock . unlock ( ) ;
log . debug ( " 分布式锁已在事务完成后释放: doAcsFinishLoadShaft, 事务状态: {} " ,
status = = STATUS_COMMITTED ? " 已提交 " : " 已回滚 " ) ;
} catch ( Exception e ) {
log . error ( " 释放分布式锁失败 " , e ) ;
}
}
} ) ;
} else {
// 如果没有事务,直接释放锁
lock . unlock ( ) ;
}
}
}
res . put ( " status " , HttpStatus . HTTP_OK ) ;
res . put ( " message " , " 请求成功 " ) ;
res . put ( " msg " , msg ) ;
return res ;
}
@SneakyThrows
@@ -3506,4 +3315,377 @@ public class SlitterServiceImpl implements SlitterService {
}
return stepTipLogs ;
}
/**
* 验证并获取分切计划
*/
private List < PdmBiSlittingproductionplan > validateAndGetPlans ( String deviceCode , BstIvtShafttubeivt startPoint , List < String > stepTipLogs ) {
List < String > containerNames = Stream . of ( startPoint . getContainer_name1 ( ) , startPoint . getContainer_name2 ( ) )
. filter ( value - > value ! = null & & ! value . isEmpty ( ) )
. collect ( Collectors . toList ( ) ) ;
if ( containerNames . isEmpty ( ) ) {
log . error ( " 找不到[{}]对应的分切计划! " , deviceCode ) ;
stepTipLogs . add ( " 套轴完成->找不到[ " + deviceCode + " ]点位记录的分切计划!分切计划可能被删除或者拼接! " ) ;
redisUtils . set ( " ERROR " + deviceCode , stepTipLogs ) ;
throw new BadRequestException ( " 找不到[ " + deviceCode + " ]对应的分切计划! " ) ;
}
// 判断是否有未完成的任务
List < SchBaseTask > existingTasks = taskService . list ( new LambdaQueryWrapper < SchBaseTask > ( )
. eq ( SchBaseTask : : getPoint_code1 , deviceCode )
. like ( SchBaseTask : : getRequest_param , containerNames . get ( 0 ) )
. lt ( SchBaseTask : : getTask_status , " 07 " ) ) ;
if ( ! existingTasks . isEmpty ( ) ) {
log . error ( " 点位[{}]存在未完成得任务! " , deviceCode ) ;
stepTipLogs . add ( " 套轴完成->点位[ " + deviceCode + " ]存在未完成得任务! " ) ;
redisUtils . set ( " ERROR " + deviceCode , stepTipLogs ) ;
throw new BadRequestException ( " 点位[ " + deviceCode + " ]存在未完成得任务! " ) ;
}
return slittingproductionplanService . list (
new LambdaQueryWrapper < PdmBiSlittingproductionplan > ( )
. in ( PdmBiSlittingproductionplan : : getContainer_name , containerNames )
. eq ( PdmBiSlittingproductionplan : : getStatus , " 01 " )
. eq ( PdmBiSlittingproductionplan : : getIs_delete , " 0 " ) ) ;
}
/**
* 处理异常情况 - 分切计划不存在
*/
private JSONObject handleExceptionCase ( String deviceCode , BstIvtShafttubeivt startPoint ,
List < String > containerNames , List < String > stepTipLogs ) {
log . error ( " 找不到[{}]对应的分切计划,分切计划可能被删除或者拼接! " , containerNames ) ;
// 尝试移动到异常处理位
List < String > exceptionPointCodes = bcutpointivtService . getCanUseMinPointByShelf ( " 4 " , " 0 " ) ;
if ( ! exceptionPointCodes . isEmpty ( ) ) {
String exceptionPoint = exceptionPointCodes . get ( 0 ) ;
JSONObject exParam = buildExceptionTaskParam ( startPoint , exceptionPoint , containerNames ) ;
sendNBJExceptionPointTask . createTask ( exParam ) ;
JSONObject res = new JSONObject ( ) ;
res . put ( " status " , HttpStatus . HTTP_OK ) ;
res . put ( " message " , " 创建送至异常处理位! " ) ;
return res ;
}
// 创建半条任务等待补齐
stepTipLogs . add ( " 套轴完成->[ " + containerNames + " ]对应的分切计划状态已更改,无暂存位置,创建任务失败! " ) ;
redisUtils . set ( " ERROR " + deviceCode , stepTipLogs ) ;
JSONObject exParam = buildWaitingTaskParam ( startPoint , containerNames ) ;
sendNBJExceptionPointTask . createTask ( exParam ) ;
JSONObject res = new JSONObject ( ) ;
res . put ( " status " , HttpStatus . HTTP_OK ) ;
res . put ( " message " , " 请求成功 " ) ;
return res ;
}
/**
* 构建异常任务参数
*/
private JSONObject buildExceptionTaskParam ( BstIvtShafttubeivt startPoint , String exceptionPoint , List < String > containerNames ) {
JSONObject exParam = new JSONObject ( ) ;
exParam . put ( " point_code1 " , startPoint . getPoint_code ( ) ) ;
exParam . put ( " point_code2 " , exceptionPoint ) ;
if ( exceptionPoint . endsWith ( " A " ) ) {
exParam . put ( " vehicle_code1 " , containerNames ) ;
} else {
exParam . put ( " vehicle_code2 " , containerNames ) ;
}
exParam . put ( " task_type " , SlitterEnum . TASK_TYPE . code ( " 套轴异常处理桁架任务 " ) ) ;
exParam . put ( " product_area " , SlitterConstant . SLITTER_TASK_AREA ) ;
exParam . put ( " acs_task_type " , " 6 " ) ;
exParam . put ( " containers " , containerNames ) ;
exParam . put ( " qzz_size " , startPoint . getQzz_size ( ) ) ;
return exParam ;
}
/**
* 构建等待任务参数
*/
private JSONObject buildWaitingTaskParam ( BstIvtShafttubeivt startPoint , List < String > containerNames ) {
JSONObject exParam = new JSONObject ( ) ;
exParam . put ( " point_code1 " , startPoint . getPoint_code ( ) ) ;
exParam . put ( " point_code2 " , " - " ) ;
exParam . put ( " vehicle_code1 " , containerNames ) ;
exParam . put ( " task_type " , SlitterEnum . TASK_TYPE . code ( " 套轴异常处理桁架任务 " ) ) ;
exParam . put ( " product_area " , SlitterConstant . SLITTER_TASK_AREA ) ;
exParam . put ( " task_status " , TaskStatusEnum . SURE_START . getCode ( ) ) ;
exParam . put ( " acs_task_type " , " 6 " ) ;
exParam . put ( " containers " , containerNames ) ;
exParam . put ( " qzz_size " , startPoint . getQzz_size ( ) ) ;
return exParam ;
}
/**
* 更新分切计划重量
*/
private String updatePlanWeights ( List < PdmBiSlittingproductionplan > plans , BigDecimal weight1 , BigDecimal weight2 ) {
StringBuilder msg = new StringBuilder ( ) ;
for ( PdmBiSlittingproductionplan plan : plans ) {
if ( SlitterConstant . SLITTER_SUB_VOLUME_LEFT . equals ( plan . getLeft_or_right ( ) ) ) {
plan . setPaper_weight ( String . valueOf ( NumberUtil . round ( weight1 , 2 ) ) ) ;
msg . append ( " 子卷号: " ) . append ( plan . getContainer_name ( ) ) . append ( " 的纸管重量: " ) . append ( weight1 ) . append ( " | " ) ;
} else {
plan . setPaper_weight ( String . valueOf ( NumberUtil . round ( weight2 , 2 ) ) ) ;
msg . append ( " 子卷号: " ) . append ( plan . getContainer_name ( ) ) . append ( " 的纸管重量: " ) . append ( weight2 ) . append ( " | " ) ;
}
TaskUtils . updateOptMessageBySlitterPlan ( plan ) ;
}
slittingproductionplanService . updateBatchById ( plans ) ;
return msg . toString ( ) ;
}
/**
* 生成气胀轴编码
*/
private String generateQzzNo ( PdmBiSlittingproductionplan demoPlan ) {
String resourceName = demoPlan . getResource_name ( ) ;
return resourceName . substring ( 0 , 2 )
+ resourceName . substring ( resourceName . length ( ) - 2 )
+ demoPlan . getSplit_group ( )
+ TaskUtils . getDateTime ( " yyMMddHHmmss " ) + " - "
+ demoPlan . getUp_or_down ( ) ;
}
/**
* 完成套轴并更新计划
*/
private void completeShaftLoading ( List < PdmBiSlittingproductionplan > plans , String qzzNo ) {
plans . forEach ( plan - > {
plan . setIs_child_tz_ok ( SlitterConstant . SLITTER_YES ) ;
plan . setQzzno ( qzzNo ) ;
TaskUtils . updateOptMessageBySlitterPlan ( plan ) ;
} ) ;
slittingproductionplanService . updateBatchById ( plans ) ;
}
/**
* 尝试拼单逻辑
*/
private BstIvtCutpointivt tryCombineOrder ( PdmBiSlittingproductionplan demoPlan , String deviceCode ,
BstIvtShafttubeivt startPoint , String qzzNo ) {
Param codParam = paramService . findByCode ( IS_COMBINED_ORDER ) ;
// 判断是否有同组(判断自己能不能拼单)
Integer sameNumber = slittingproductionplanService . getSameTripParentContainerPlanCount ( demoPlan ) ;
// 不允许拼单(未开启拼单逻辑)
if ( sameNumber ! = 0 | | ObjectUtil . isEmpty ( codParam ) | | ! " 1 " . equals ( codParam . getValue ( ) ) ) {
log . info ( " 本身不允许拼单或者拼单配置未设置或者设置不拼单... " ) ;
return null ;
}
String resourceName = demoPlan . getResource_name ( ) ;
StIvtCutpointivt deviceInfo = cutpointivtService . getPintByExtCode ( resourceName , false ) ;
// 查找能够拼单的点位(查找套轴对接位)
List < BstIvtCutpointivt > emptyNotTaskPoint = slitterMapper . getCombinedOrders (
CombinedOrderDto . builder ( )
. pointStatus ( " 2 " )
. pointType ( " 1 " )
. pointLocation ( deviceInfo . getPoint_location ( ) )
. plan ( deviceInfo . getPlan ( ) )
. device ( resourceName )
. build ( ) ) ;
// 如果没有空点位,尝试与路上的轴拼单
if ( emptyNotTaskPoint . isEmpty ( ) ) {
emptyNotTaskPoint = tryMatchRunningTask ( demoPlan , deviceCode , deviceInfo ) ;
}
// 如果找到可拼单点位,创建任务
if ( ! emptyNotTaskPoint . isEmpty ( ) ) {
BstIvtCutpointivt cutPoint = emptyNotTaskPoint . get ( 0 ) ;
createCombinedOrderTask ( cutPoint , startPoint , demoPlan , qzzNo ) ;
return cutPoint ;
}
return null ;
}
/**
* 尝试与运行中的任务拼单
*/
private List < BstIvtCutpointivt > tryMatchRunningTask ( PdmBiSlittingproductionplan demoPlan ,
String deviceCode , StIvtCutpointivt deviceInfo ) {
List < BstIvtCutpointivt > result = new ArrayList < > ( ) ;
SchBaseTask runningTask = taskService . getOne ( new LambdaQueryWrapper < SchBaseTask > ( )
. eq ( SchBaseTask : : getHandle_class , " org.nl.b_lms.sch.tasks.slitter.TrussSendAirShaftTask " )
. lt ( SchBaseTask : : getTask_status , " 07 " )
. eq ( SchBaseTask : : getIs_delete , " 0 " )
. ne ( SchBaseTask : : getPoint_code1 , deviceCode ) ) ;
if ( ObjectUtil . isEmpty ( runningTask ) | | ObjectUtil . isEmpty ( runningTask . getPoint_code2 ( ) ) ) {
return result ;
}
List < PdmBiSlittingproductionplan > runningShafts = slittingproductionplanService . getByQzzNos (
Arrays . asList ( runningTask . getVehicle_code ( ) , runningTask . getVehicle_code2 ( ) ) ) ;
if ( runningShafts . isEmpty ( ) ) {
return result ;
}
PdmBiSlittingproductionplan runningShaft = runningShafts . get ( 0 ) ;
// 判断路上的轴能不能拼
Integer otherPlans = slittingproductionplanService . getSameTripParentContainerPlanCount ( runningShaft ) ;
if ( otherPlans = = 0 ) {
StIvtCutpointivt runDeviceInfo = cutpointivtService . getPintByExtCode ( runningShaft . getResource_name ( ) , false ) ;
// 同个子区域
if ( runDeviceInfo . getPlan ( ) . equals ( deviceInfo . getPlan ( ) ) ) {
BstIvtCutpointivt one = bcutpointivtService . getOne ( new LambdaQueryWrapper < BstIvtCutpointivt > ( )
. eq ( BstIvtCutpointivt : : getTruss_point_code1 , runningTask . getPoint_code2 ( ) ) . or ( )
. eq ( BstIvtCutpointivt : : getTruss_point_code2 , runningTask . getPoint_code2 ( ) ) ) ;
if ( one ! = null & & canCombineWithRunningTask ( one , runningTask ) ) {
result . add ( one ) ;
}
}
}
return result ;
}
/**
* 判断是否可以与运行中的任务拼单
*/
private boolean canCombineWithRunningTask ( BstIvtCutpointivt one , SchBaseTask runningTask ) {
String specialPoint = one . getTruss_point_code1 ( ) . equals ( runningTask . getPoint_code2 ( ) )
? one . getTruss_point_code2 ( ) : one . getTruss_point_code1 ( ) ;
return ( specialPoint . equals ( one . getTruss_point_code1 ( ) ) & & ObjectUtil . isNotEmpty ( one . getQzz_no1 ( ) ) )
| | ( specialPoint . equals ( one . getTruss_point_code2 ( ) ) & & ObjectUtil . isNotEmpty ( one . getQzz_no2 ( ) ) ) ;
}
/**
* 创建拼单任务
* @param cutPoint 分切点位
* @param startPoint 穿拔轴点位
* @param demoPlan 分切计划
* @param qzzNo 气胀轴编码
*/
private void createCombinedOrderTask ( BstIvtCutpointivt cutPoint , BstIvtShafttubeivt startPoint ,
PdmBiSlittingproductionplan demoPlan , String qzzNo ) {
JSONObject taskParam = new JSONObject ( ) ;
taskParam . put ( " point_code1 " , startPoint . getPoint_code ( ) ) ;
String pointCode2 = ObjectUtil . isEmpty ( cutPoint . getQzz_no1 ( ) )
? cutPoint . getTruss_point_code1 ( ) : cutPoint . getTruss_point_code2 ( ) ;
taskParam . put ( " point_code2 " , pointCode2 ) ;
String vehicleCode1 = ObjectUtil . isEmpty ( cutPoint . getQzz_no1 ( ) ) ? qzzNo : " " ;
String vehicleCode2 = ObjectUtil . isEmpty ( cutPoint . getQzz_no2 ( ) ) ? qzzNo : " " ;
taskParam . put ( " vehicle_code1 " , vehicleCode1 ) ;
taskParam . put ( " vehicle_code2 " , vehicleCode2 ) ;
taskParam . put ( " flag " , " 1 " ) ;
taskParam . put ( " task_type " , " 010814 " ) ;
taskParam . put ( " product_area " , SlitterConstant . SLITTER_TASK_AREA ) ;
taskParam . put ( " immediateNotifyAcs " , " 1 " ) ;
trussSendAirShaftTask . createTask ( taskParam ) ;
}
/**
* 处理正常业务流程(不拼单)
*/
private void handleNormalProcess ( PdmBiSlittingproductionplan demoPlan , BstIvtShafttubeivt startPoint ,
String qzzNo , List < String > containerNames , String deviceCode ,
List < String > stepTipLogs ) {
// 查找是否有同组的气胀轴位置
BstIvtCutpointivt cutPoint = findSameGroupPoint ( demoPlan ) ;
if ( ObjectUtil . isEmpty ( cutPoint ) ) {
// 获取一个空位
List < BstIvtCutpointivt > emptyNotTaskPoint = bcutpointivtService . getNBJAreaNotTaskPointByStatus (
" 1 " , " 1 " , startPoint . getPoint_location ( ) , " 1 " ) ;
if ( ! emptyNotTaskPoint . isEmpty ( ) ) {
cutPoint = emptyNotTaskPoint . get ( 0 ) ;
} else {
// 创建半条任务
createHalfTask ( startPoint , demoPlan , qzzNo , containerNames , deviceCode , stepTipLogs ) ;
return ;
}
}
// 创建完整任务
createNormalTask ( cutPoint , startPoint , demoPlan , qzzNo , containerNames ) ;
}
/**
* 查找同组点位
*/
private BstIvtCutpointivt findSameGroupPoint ( PdmBiSlittingproductionplan demoPlan ) {
BstIvtCutpointivt cutPoint = slitterMapper . getSameGroupPoint ( demoPlan ) ;
if ( ObjectUtil . isEmpty ( cutPoint ) ) {
String endPoint = slitterMapper . getSameGroupTaskPoint ( demoPlan ) ;
if ( ObjectUtil . isNotEmpty ( endPoint ) ) {
cutPoint = bcutpointivtService . getOne ( new LambdaQueryWrapper < BstIvtCutpointivt > ( )
. eq ( BstIvtCutpointivt : : getTruss_point_code1 , endPoint ) . or ( )
. eq ( BstIvtCutpointivt : : getTruss_point_code2 , endPoint ) ) ;
}
}
return cutPoint ;
}
/**
* 创建半条任务
*/
private void createHalfTask ( BstIvtShafttubeivt startPoint , PdmBiSlittingproductionplan demoPlan ,
String qzzNo , List < String > containerNames , String deviceCode ,
List < String > stepTipLogs ) {
stepTipLogs . add ( " 提示:套轴完成->找不到可用套轴对接位, 创建半条任务, 等待AGV取货完成触发! " ) ;
redisUtils . set ( " ERROR " + deviceCode , stepTipLogs ) ;
JSONObject taskParam = new JSONObject ( ) ;
taskParam . put ( " point_code1 " , startPoint . getPoint_code ( ) ) ;
taskParam . put ( " point_code2 " , " - " ) ;
taskParam . put ( " needPosition " , SlitterConstant . SLITTER_SHAFT_UP . equals ( demoPlan . getUp_or_down ( ) ) ? " A " : " B " ) ;
taskParam . put ( " vehicle_code1 " , SlitterConstant . SLITTER_SHAFT_UP . equals ( demoPlan . getUp_or_down ( ) ) ? qzzNo : " " ) ;
taskParam . put ( " vehicle_code2 " , SlitterConstant . SLITTER_SHAFT_DOWN . equals ( demoPlan . getUp_or_down ( ) ) ? qzzNo : " " ) ;
taskParam . put ( " task_type " , " 010814 " ) ;
taskParam . put ( " containers " , containerNames ) ;
taskParam . put ( " qzz_size " , demoPlan . getQzz_size ( ) ) ;
taskParam . put ( " task_status " , TaskStatusEnum . SURE_START . getCode ( ) ) ;
taskParam . put ( " product_area " , SlitterConstant . SLITTER_TASK_AREA ) ;
taskParam . put ( " immediateNotifyAcs " , " 0 " ) ;
trussSendAirShaftTask . createTask ( taskParam ) ;
}
/**
* 创建正常任务
*/
private void createNormalTask ( BstIvtCutpointivt cutPoint , BstIvtShafttubeivt startPoint ,
PdmBiSlittingproductionplan demoPlan , String qzzNo ,
List < String > containerNames ) {
JSONObject taskParam = new JSONObject ( ) ;
taskParam . put ( " point_code1 " , startPoint . getPoint_code ( ) ) ;
taskParam . put ( " point_code2 " , SlitterConstant . SLITTER_SHAFT_UP . equals ( demoPlan . getUp_or_down ( ) )
? cutPoint . getTruss_point_code1 ( ) : cutPoint . getTruss_point_code2 ( ) ) ;
taskParam . put ( " vehicle_code1 " , SlitterConstant . SLITTER_SHAFT_UP . equals ( demoPlan . getUp_or_down ( ) ) ? qzzNo : " " ) ;
taskParam . put ( " vehicle_code2 " , SlitterConstant . SLITTER_SHAFT_DOWN . equals ( demoPlan . getUp_or_down ( ) ) ? qzzNo : " " ) ;
taskParam . put ( " task_type " , " 010814 " ) ;
taskParam . put ( " containers " , containerNames ) ;
taskParam . put ( " flag " , " 0 " ) ;
taskParam . put ( " qzz_size " , demoPlan . getQzz_size ( ) ) ;
taskParam . put ( " product_area " , SlitterConstant . SLITTER_TASK_AREA ) ;
taskParam . put ( " immediateNotifyAcs " , " 1 " ) ;
trussSendAirShaftTask . createTask ( taskParam ) ;
}
}