add:木箱库

This commit is contained in:
2025-07-15 13:27:27 +08:00
parent fbd6c2df4c
commit 61cf71e2a3
39 changed files with 3109 additions and 71 deletions

View File

@@ -0,0 +1,62 @@
package org.nl.b_lms.bst.ivt.boxstack.controller;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.nl.b_lms.bst.ivt.boxstack.service.IBstIvtBoxstackService;
import org.nl.b_lms.bst.ivt.boxstack.service.dto.BstIvtBoxstackDto;
import org.nl.b_lms.bst.ivt.boxstack.service.dto.BstIvtBoxstackQuery;
import org.nl.common.domain.query.PageQuery;
import org.nl.modules.logging.annotation.Log;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.Set;
/**
* @Description TODO
* @Author Gengby
* @Date 2025/7/8
*/
@Slf4j
@RestController
@RequestMapping("/api/bstIvtboxstack")
public class BstIvtBoxstackController {
@Autowired
private IBstIvtBoxstackService boxstackService;
@GetMapping
@Log("查询木箱堆叠位")
public ResponseEntity<Object> query(BstIvtBoxstackQuery whereJson, PageQuery page) {
return new ResponseEntity<>(boxstackService.queryAll(whereJson, page), HttpStatus.OK);
}
@PostMapping
@Log("新增木箱堆叠位")
public ResponseEntity<Object> create(@Validated @RequestBody BstIvtBoxstackDto entity) {
boxstackService.create(entity);
return new ResponseEntity<>(HttpStatus.OK);
}
@PutMapping
@Log("修改木箱堆叠位")
public ResponseEntity<Object> update(@Validated @RequestBody BstIvtBoxstackDto entity) {
boxstackService.update(entity);
return new ResponseEntity<>(HttpStatus.OK);
}
@Log("删除木箱堆叠位")
@DeleteMapping
public ResponseEntity<Object> delete(@RequestBody Set<String> ids) {
boxstackService.deleteAll(ids);
return new ResponseEntity<>(HttpStatus.OK);
}
@PostMapping("/saveBoxStack")
public ResponseEntity<Object> saveBoxStack(@Validated @RequestBody JSONObject reqParam) {
boxstackService.saveBoxStack(reqParam);
return new ResponseEntity<>(HttpStatus.OK);
}
}

View File

@@ -0,0 +1,34 @@
package org.nl.b_lms.bst.ivt.boxstack.controller;
import lombok.extern.slf4j.Slf4j;
import org.nl.b_lms.bst.ivt.boxstack.service.IBstIvtBoxstacklayerService;
import org.nl.b_lms.bst.ivt.boxstack.service.dto.BstIvtBoxstackQuery;
import org.nl.common.domain.query.PageQuery;
import org.nl.modules.logging.annotation.Log;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @Description TODO
* @Author Gengby
* @Date 2025/7/8
*/
@Slf4j
@RestController
@RequestMapping("/api/bstIvtboxstacklayer")
public class BstIvtBoxstacklayerController {
@Autowired
private IBstIvtBoxstacklayerService boxstacklayerService;
@GetMapping("/getBoxLayer/{stackId}")
@Log("根据堆叠位ID查询堆叠位层数详情")
public ResponseEntity<Object> query(@PathVariable String stackId) {
return new ResponseEntity<>(boxstacklayerService.getByStackId(stackId), HttpStatus.OK);
}
}

View File

@@ -0,0 +1,54 @@
package org.nl.b_lms.bst.ivt.boxstack.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;
import org.nl.common.utils.MapOf;
import org.nl.modules.common.exception.BadRequestException;
import java.util.Map;
/**
* 木箱出入库业务相关枚举类
*
* @author lxy
* @Date 2023/11/14 20:11
*/
@AllArgsConstructor
@Getter
public enum BoxStackEnum {
// 木箱任务类型
TASK_TYPE(MapOf.of("木箱入库", "010702", "木箱出库", "010704", "木箱移库", "010705")),
// 木箱出入库任务二次分配类型
AGV_ACTION_TYPE(MapOf.of("普通任务", "1", "取货二次分配", "2", "放货二次分配", "3", "取放货二次分配", "4")),
//木箱库二次分配等待点
AGV_WAIT_POINT(MapOf.of("木箱等待点1", "MX_WAIT_1", "木箱等待点2", "MX_WAIT_2")),
//木箱库ACS任务类型
ACS_TASK_TYPE(MapOf.of("agv任务", "1")),
//木箱库AGV系统类型
AGV_SYSTEM_TYPE(MapOf.of("1楼诺宝任务", "1", "2楼1区域AGV系统", "2", "1楼叉车任务", "3")),
//木箱库位启用状态
IS_USED(MapOf.of("启用", "1", "未启用", "0")),
//木箱库区域
POINT_STATUS(MapOf.of("密集区", "1", "零散区", "2", "缓存区", "3"));
private Map<String, String> code;
public String code(String desc) {
String code = this.getCode().get(desc);
if (StringUtils.isNotEmpty(code)) {
return code;
}
throw new BadRequestException(this.name() + "对应类型" + desc + "未定义");
}
public String check(String code) {
for (Map.Entry<String, String> entry : this.getCode().entrySet()) {
if (entry.getValue().equals("code")) {
return entry.getValue();
}
}
throw new BadRequestException(this.name() + "对应类型" + code + "未定义");
}
}

View File

@@ -0,0 +1,55 @@
package org.nl.b_lms.bst.ivt.boxstack.service;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.IService;
import org.nl.b_lms.bst.ivt.boxstack.service.dao.BstIvtBoxstack;
import org.nl.b_lms.bst.ivt.boxstack.service.dto.BstIvtBoxstackDto;
import org.nl.b_lms.bst.ivt.boxstack.service.dto.BstIvtBoxstackQuery;
import org.nl.common.domain.query.PageQuery;
import java.util.Set;
/**
* @Description TODO
* @Author Gengby
* @Date 2025/7/8
*/
public interface IBstIvtBoxstackService extends IService<BstIvtBoxstack> {
/**
* 查询数据分页
*
* @param whereJson 条件
* @param pageable 分页参数
* @return IPage<BstIvtCutpointivt>
*/
Object queryAll(BstIvtBoxstackQuery whereJson, PageQuery pageable);
/**
* 创建
*
* @param entity /
*/
void create(BstIvtBoxstackDto entity);
/**
* 编辑
*
* @param entity /
*/
void update(BstIvtBoxstackDto entity);
/**
* 多选删除
*
* @param ids /
*/
void deleteAll(Set<String> ids);
/**
* 保存木箱堆叠信息
*
* @param reqParam
*/
void saveBoxStack(JSONObject reqParam);
}

View File

@@ -0,0 +1,17 @@
package org.nl.b_lms.bst.ivt.boxstack.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.nl.b_lms.bst.ivt.boxstack.service.dao.BstIvtBoxstacklayer;
import java.util.List;
/**
* @Description TODO
* @Author Gengby
* @Date 2025/7/8
*/
public interface IBstIvtBoxstacklayerService extends IService<BstIvtBoxstacklayer> {
List<BstIvtBoxstacklayer> getByStackId(String stackId);
}

View File

@@ -0,0 +1,103 @@
package org.nl.b_lms.bst.ivt.boxstack.service.dao;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
/**
* @Description TODO
* @Author Gengby
* @Date 2025/7/8
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("bst_ivt_boxstack")
public class BstIvtBoxstack implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "stack_id", type = IdType.NONE)
/**
* 唯一标识
*/
private String stack_id;
/**
* 堆叠位编码
*/
private String stack_code;
/**
* 堆叠位名称
*/
private String stack_name;
/**
* 当前堆叠层数
*/
private Integer current_layer_count;
/**
* 最大堆叠层数
*/
private Integer max_layer_count;
/**
* 区域
*/
private String point_status;
/**
* 木箱规格(物料编码)
*/
private String box_spec;
/**
* 排
*/
private Integer x;
/**
* 列
*/
private Integer y;
/**
* 是否启用(0禁用,1启用)
*/
private String is_used;
/**
* 创建人id
*/
private String created_id;
/**
* 创建人名称
*/
private String created_name;
/**
* 创建时间yyyy-MM-dd HH:mm:ss
*/
private String created_time;
/**
* 修改人id
*/
private String update_id;
/**
* 修改人名称
*/
private String update_name;
/**
* 修改时间yyyy-MM-dd HH:mm:ss
*/
private String update_time;
}

View File

@@ -0,0 +1,73 @@
package org.nl.b_lms.bst.ivt.boxstack.service.dao;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
/**
* @Description TODO
* @Author Gengby
* @Date 2025/7/8
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("bst_ivt_boxstacklayer")
public class BstIvtBoxstacklayer implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
@TableId(value = "stack_layer_id", type = IdType.NONE)
private String stack_layer_id;
/**
* 堆叠位id
*/
private String stack_id;
/**
* 木箱编码
*/
private String box_code;
/**
* 层号
*/
private Integer layer_index;
/**
* 创建人id
*/
private String created_id;
/**
* 创建人名称
*/
private String created_name;
/**
* 创建时间yyyy-MM-dd HH:mm:ss
*/
private String created_time;
/**
* 修改人id
*/
private String update_id;
/**
* 修改人名称
*/
private String update_name;
/**
* 修改时间yyyy-MM-dd HH:mm:ss
*/
private String update_time;
}

View File

@@ -0,0 +1,16 @@
package org.nl.b_lms.bst.ivt.boxstack.service.dao.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import org.nl.b_lms.bst.ivt.boxstack.service.dao.BstIvtBoxstack;
import org.nl.b_lms.bst.ivt.boxstack.service.dto.BstIvtBoxstackQuery;
import org.nl.common.domain.query.PageQuery;
import java.util.List;
import java.util.Map;
public interface BstIvtBoxstackMapper extends BaseMapper<BstIvtBoxstack> {
List<Map> pageQuery(@Param("query") BstIvtBoxstackQuery query, @Param("pageQuery") PageQuery pageQuery);
}

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.nl.b_lms.bst.ivt.boxstack.service.dao.mapper.BstIvtBoxstackMapper">
<select id="pageQuery" resultType="java.util.Map">
SELECT bs.stack_id,
bs.stack_code,
bs.stack_name,
bs.current_layer_count,
bs.max_layer_count,
bs.point_status,
bs.box_spec,
bs.x,
bs.y,
bs.is_used,
bs.created_id,
bs.created_name,
bs.created_time,
bs.update_id,
bs.update_name,
bs.update_time,
mb.material_name AS box_spec_name
FROM bst_ivt_boxstack bs
LEFT JOIN md_me_materialbase mb ON mb.material_code = bs.box_spec
<where>
<if test="query != null">
<if test="query.stack_info != null and query.stack_info != ''">
AND (bs.stack_code LIKE CONCAT('%', #{query.stack_info}, '%')
OR bs.stack_name LIKE CONCAT('%', #{query.stack_info}, '%'))
</if>
<if test="query.point_status != null and query.point_status != ''">
AND bs.point_status = #{query.point_status}
</if>
<if test="query.box_spec != null and query.box_spec != ''">
AND bs.box_spec = #{query.box_spec}
</if>
<if test="query.is_used != null">
AND bs.is_used = #{query.is_used}
</if>
</if>
</where>
ORDER BY bs.stack_code ASC
</select>
</mapper>

View File

@@ -0,0 +1,10 @@
package org.nl.b_lms.bst.ivt.boxstack.service.dao.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.nl.b_lms.bst.ivt.boxstack.service.dao.BstIvtBoxstack;
import org.nl.b_lms.bst.ivt.boxstack.service.dao.BstIvtBoxstacklayer;
public interface BstIvtBoxstacklayerMapper extends BaseMapper<BstIvtBoxstacklayer> {
}

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.nl.b_lms.bst.ivt.boxstack.service.dao.mapper.BstIvtBoxstacklayerMapper">
</mapper>

View File

@@ -0,0 +1,65 @@
package org.nl.b_lms.bst.ivt.boxstack.service.dto;
import lombok.Data;
import java.io.Serializable;
/**
* @Description TODO
* @Author Gengby
* @Date 2025/7/8
*/
@Data
public class BstIvtBoxstackDto implements Serializable {
/**
* 唯一标识
*/
private String stack_id;
/**
* 堆叠位编码
*/
private String stack_code;
/**
* 堆叠位名称
*/
private String stack_name;
/**
* 当前堆叠层数
*/
private Integer current_layer_count;
/**
* 最大堆叠层数
*/
private Integer max_layer_count;
/**
* 区域
*/
private String point_status;
/**
* 木箱规格(物料编码)
*/
private String box_spec;
/**
* 是否启用(0禁用,1启用)
*/
private String is_used;
/**
* 排
*/
private Integer x;
/**
* 列
*/
private Integer y;
}

View File

@@ -0,0 +1,29 @@
package org.nl.b_lms.bst.ivt.boxstack.service.dto;
import lombok.Data;
/**
* @Description TODO
* @Author Gengby
* @Date 2025/7/8
*/
@Data
public class BstIvtBoxstackQuery {
/**
* 堆叠位信息
*/
private String stack_info;
/**
* 区域
*/
private String point_status;
/**
* 木箱规格
*/
private String box_spec;
/**
* 是否弃用
*/
private Boolean is_used;
}

View File

@@ -0,0 +1,12 @@
package org.nl.b_lms.bst.ivt.boxstack.service.dto;
import lombok.Data;
/**
* @Description TODO
* @Author Gengby
* @Date 2025/7/8
*/
@Data
public class BstIvtBoxstackVo {
}

View File

@@ -0,0 +1,61 @@
package org.nl.b_lms.bst.ivt.boxstack.service.dto;
import lombok.Builder;
import lombok.Data;
import java.io.Serializable;
/**
* @Description TODO
* @Author Gengby
* @Date 2025/7/8
*/
@Data
public class BstIvtBoxstacklayerDto implements Serializable {
private String stack_layer_id;
/**
* 堆叠位id
*/
private String stack_id;
/**
* 木箱编码
*/
private String box_code;
/**
* 层号
*/
private Integer layer_index;
/**
* 创建人id
*/
private String created_id;
/**
* 创建人名称
*/
private String created_name;
/**
* 创建时间yyyy-MM-dd HH:mm:ss
*/
private String created_time;
/**
* 修改人id
*/
private String update_id;
/**
* 修改人名称
*/
private String update_name;
/**
* 修改时间yyyy-MM-dd HH:mm:ss
*/
private String update_time;
}

View File

@@ -0,0 +1,12 @@
package org.nl.b_lms.bst.ivt.boxstack.service.dto;
import lombok.Data;
/**
* @Description TODO
* @Author Gengby
* @Date 2025/7/8
*/
@Data
public class BstIvtBoxstacklayerQuery {
}

View File

@@ -0,0 +1,12 @@
package org.nl.b_lms.bst.ivt.boxstack.service.dto;
import lombok.Data;
/**
* @Description TODO
* @Author Gengby
* @Date 2025/7/8
*/
@Data
public class BstIvtBoxstacklayerVo {
}

View File

@@ -0,0 +1,185 @@
package org.nl.b_lms.bst.ivt.boxstack.service.impl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.nl.b_lms.bst.ivt.boxstack.service.IBstIvtBoxstackService;
import org.nl.b_lms.bst.ivt.boxstack.service.IBstIvtBoxstacklayerService;
import org.nl.b_lms.bst.ivt.boxstack.service.dao.BstIvtBoxstack;
import org.nl.b_lms.bst.ivt.boxstack.service.dao.BstIvtBoxstacklayer;
import org.nl.b_lms.bst.ivt.boxstack.service.dao.mapper.BstIvtBoxstackMapper;
import org.nl.b_lms.bst.ivt.boxstack.service.dto.BstIvtBoxstackDto;
import org.nl.b_lms.bst.ivt.boxstack.service.dto.BstIvtBoxstackQuery;
import org.nl.b_lms.storage_manage.database.service.IBstIvtBoxinfoService;
import org.nl.b_lms.storage_manage.database.service.dao.BstIvtBoxinfo;
import org.nl.common.TableDataInfo;
import org.nl.common.domain.query.PageQuery;
import org.nl.common.utils.IdUtil;
import org.nl.common.utils.SecurityUtils;
import org.nl.modules.common.exception.BadRequestException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/**
* @Description TODO
* @Author Gengby
* @Date 2025/7/8
*/
@Slf4j
@Service
public class BstIvtBoxstackServiceImpl extends ServiceImpl<BstIvtBoxstackMapper, BstIvtBoxstack> implements IBstIvtBoxstackService {
@Autowired
private BstIvtBoxstackMapper boxstackMapper;
@Autowired
private IBstIvtBoxstacklayerService boxstacklayerService;
@Autowired
private IBstIvtBoxinfoService boxinfoService;
@Override
public Object queryAll(BstIvtBoxstackQuery whereJson, PageQuery pageQuery) {
Page<Object> page = PageHelper.startPage(pageQuery.getPage() + 1, pageQuery.getSize());
List<Map> list = boxstackMapper.pageQuery(whereJson, pageQuery);
TableDataInfo<Map> build = TableDataInfo.build(list);
build.setTotalElements(page.getTotal());
return build;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void create(BstIvtBoxstackDto entity) {
if (entity.getMax_layer_count() <= 0) {
throw new RuntimeException("最大堆叠数必须大于0");
}
String currentUserId = SecurityUtils.getCurrentUserId();
String currentNickName = SecurityUtils.getCurrentNickName();
String now = DateUtil.now();
BstIvtBoxstack boxstack = new BstIvtBoxstack();
boxstack.setStack_id(IdUtil.getStringId());
boxstack.setStack_code(entity.getStack_code());
boxstack.setStack_name(entity.getStack_name());
boxstack.setCurrent_layer_count(entity.getCurrent_layer_count());
boxstack.setMax_layer_count(entity.getMax_layer_count());
boxstack.setPoint_status(entity.getPoint_status());
boxstack.setBox_spec(entity.getBox_spec());
boxstack.setX(entity.getX());
boxstack.setY(entity.getY());
boxstack.setIs_used(entity.getIs_used());
boxstack.setCreated_id(currentUserId);
boxstack.setCreated_name(currentNickName);
boxstack.setCreated_time(now);
boxstackMapper.insert(boxstack);
for (Integer i = 0; i < entity.getMax_layer_count(); i++) {
BstIvtBoxstacklayer boxstacklayer = new BstIvtBoxstacklayer();
boxstacklayer.setStack_layer_id(IdUtil.getStringId());
boxstacklayer.setStack_id(boxstack.getStack_id());
boxstacklayer.setLayer_index(i + 1);
boxstacklayer.setCreated_id(currentUserId);
boxstacklayer.setCreated_name(currentNickName);
boxstacklayer.setCreated_time(now);
boxstacklayerService.save(boxstacklayer);
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void update(BstIvtBoxstackDto entity) {
BstIvtBoxstack boxstack = this.getById(entity.getStack_id());
if (ObjectUtil.isNotNull(boxstack)) {
boxstack.setStack_code(entity.getStack_code());
boxstack.setStack_name(entity.getStack_name());
boxstack.setPoint_status(entity.getPoint_status());
boxstack.setX(entity.getX());
boxstack.setY(entity.getY());
boxstack.setIs_used(entity.getIs_used());
boxstack.setUpdate_id(SecurityUtils.getCurrentUserId());
boxstack.setUpdate_name(SecurityUtils.getCurrentNickName());
boxstackMapper.updateById(boxstack);
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteAll(Set<String> ids) {
boxstackMapper.deleteBatchIds(ids);
boxstacklayerService.remove(new LambdaQueryWrapper<BstIvtBoxstacklayer>().in(BstIvtBoxstacklayer::getStack_id, ids));
}
@Override
@Transactional(rollbackFor = Exception.class)
public void saveBoxStack(JSONObject reqParam) {
String box_spec = reqParam.getString("box_spec");
String stack_id = reqParam.getString("stack_id");
JSONArray layers = reqParam.getJSONArray("tableData");
int current_layer_count = reqParam.getIntValue("current_layer_count");
boolean hasBoxSpec = StringUtils.isNotBlank(box_spec);
List<String> boxCodes = layers.stream()
.map(obj -> {
if (obj instanceof JSONObject) {
return ((JSONObject) obj).getString("box_code");
} else if (obj instanceof Map) {
return (String) ((Map<?, ?>) obj).get("box_code");
}
return null;
})
.collect(Collectors.toList());
boolean allBoxCodesEmpty = boxCodes.stream()
.allMatch(code -> StringUtils.isBlank(code));
boolean anyBoxCodeNotEmpty = boxCodes.stream()
.anyMatch(code -> StringUtils.isNotBlank(code));
if (!hasBoxSpec && anyBoxCodeNotEmpty) {
throw new BadRequestException("木箱规格为空,但是木箱条码不为空");
}
if (hasBoxSpec && allBoxCodesEmpty) {
throw new BadRequestException("木箱规格不为空,但是木箱条码全部为空");
}
String now = DateUtil.now();
String currentNickName = SecurityUtils.getCurrentNickName();
String currentUserId = SecurityUtils.getCurrentUserId();
for (int i = 0; i < layers.size(); i++) {
JSONObject layer = layers.getJSONObject(i);
String stack_layer_id = layer.getString("stack_layer_id");
String box_code = layer.getString("box_code");
if (StringUtils.isNotBlank(box_code)) {
BstIvtBoxinfo boxinfo = boxinfoService.getOne(new LambdaQueryWrapper<BstIvtBoxinfo>().eq(BstIvtBoxinfo::getBox_no, box_code));
if (ObjectUtil.isEmpty(boxinfo)) {
throw new BadRequestException("请核对木箱号, 木箱号:" + box_code + "在木箱信息表中不存在");
}
}
BstIvtBoxstacklayer boxstacklayer = boxstacklayerService.getOne(new LambdaQueryWrapper<BstIvtBoxstacklayer>()
.eq(BstIvtBoxstacklayer::getStack_layer_id, stack_layer_id));
if (!ObjectUtil.isEmpty(boxstacklayer)) {
boxstacklayer.setBox_code(box_code);
boxstacklayer.setUpdate_time(now);
boxstacklayer.setUpdate_id(currentUserId);
boxstacklayer.setUpdate_name(currentNickName);
boxstacklayerService.updateById(boxstacklayer);
}
}
BstIvtBoxstack boxstack = this.getOne(new LambdaQueryWrapper<BstIvtBoxstack>()
.eq(BstIvtBoxstack::getStack_id, stack_id));
if (!ObjectUtil.isEmpty(boxstack)) {
boxstack.setBox_spec(box_spec);
boxstack.setCurrent_layer_count(current_layer_count);
boxstack.setUpdate_time(now);
boxstack.setUpdate_id(currentUserId);
boxstack.setUpdate_name(currentNickName);
this.updateById(boxstack);
}
}
}

View File

@@ -0,0 +1,27 @@
package org.nl.b_lms.bst.ivt.boxstack.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.nl.b_lms.bst.ivt.boxstack.service.IBstIvtBoxstacklayerService;
import org.nl.b_lms.bst.ivt.boxstack.service.dao.BstIvtBoxstacklayer;
import org.nl.b_lms.bst.ivt.boxstack.service.dao.mapper.BstIvtBoxstacklayerMapper;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @Description TODO
* @Author Gengby
* @Date 2025/7/8
*/
@Slf4j
@Service
public class BstIvtBoxstacklayerServiceImpl extends ServiceImpl<BstIvtBoxstacklayerMapper, BstIvtBoxstacklayer> implements IBstIvtBoxstacklayerService {
@Override
public List<BstIvtBoxstacklayer> getByStackId(String stackId) {
return this.list(new LambdaQueryWrapper<BstIvtBoxstacklayer>().eq(BstIvtBoxstacklayer::getStack_id, stackId));
}
}

View File

@@ -0,0 +1,34 @@
package org.nl.b_lms.pda.controller;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.nl.b_lms.pda.service.BoxStackInOutService;
import org.nl.modules.logging.annotation.Log;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @Description TODO
* @Author Gengby
* @Date 2025/7/14
*/
@RestController
@RequestMapping("/api/boxStackInOut")
@Slf4j
public class BoxStackInOutController {
@Autowired
private BoxStackInOutService boxStackInOutService;
@PostMapping("/boxIn")
@Log("木箱入库")
public ResponseEntity<Object> confirmPass(@RequestBody JSONObject reqParam) {
boxStackInOutService.boxIn(reqParam);
return new ResponseEntity<>( HttpStatus.OK);
}
}

View File

@@ -0,0 +1,18 @@
package org.nl.b_lms.pda.service;
import com.alibaba.fastjson.JSONObject;
/**
* @Description TODO
* @Author Gengby
* @Date 2025/7/14
*/
public interface BoxStackInOutService {
/**
* 入库
*
* @param reqParam
*/
void boxIn(JSONObject reqParam);
}

View File

@@ -0,0 +1,136 @@
package org.nl.b_lms.pda.service.impl;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.nl.b_lms.bst.ivt.boxstack.enums.BoxStackEnum;
import org.nl.b_lms.bst.ivt.boxstack.service.IBstIvtBoxstackService;
import org.nl.b_lms.bst.ivt.boxstack.service.dao.BstIvtBoxstack;
import org.nl.b_lms.pda.service.BoxStackInOutService;
import org.nl.b_lms.sch.task.dao.SchBaseTask;
import org.nl.b_lms.sch.task.service.IschBaseTaskService;
import org.nl.b_lms.sch.tasks.boxstack.MxInTask;
import org.nl.b_lms.storage_manage.database.service.IBstIvtBoxinfoService;
import org.nl.b_lms.storage_manage.database.service.dao.BstIvtBoxinfo;
import org.nl.modules.common.exception.BadRequestException;
import org.nl.wms.sch.service.PointService;
import org.nl.wms.sch.service.dto.PointDto;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* @Description TODO
* @Author Gengby
* @Date 2025/7/14
*/
@Service
public class BoxStackInOutServiceImpl implements BoxStackInOutService {
@Resource
private MxInTask mxInTask;
@Resource
private RedissonClient redissonClient;
@Resource
private PointService pointService;
@Resource
private IBstIvtBoxinfoService boxinfoService;
@Resource
private IschBaseTaskService taskService;
@Resource
private IBstIvtBoxstackService boxstackService;
@SneakyThrows
@Override
public void boxIn(JSONObject reqParam) {
String point_code = reqParam.getString("point_code");
if (StringUtils.isBlank(point_code)) {
throw new BadRequestException("请输入入库点位");
}
PointDto pointDto = pointService.findByCode(point_code);
if (ObjectUtil.isEmpty(pointDto)) {
throw new BadRequestException("入库点位不存在");
}
String vehicle_code = reqParam.getString("vehicle_code");
if (StringUtils.isBlank(vehicle_code)) {
throw new BadRequestException("请输入木箱号");
}
String[] vehicle_codes = vehicle_code.split(",");
List<String> box_specs = new ArrayList<>();
for (String vehicle_code1 : vehicle_codes) {
if (StringUtils.isBlank(vehicle_code1)) {
BstIvtBoxinfo boxinfo = boxinfoService.getOne(new LambdaQueryWrapper<BstIvtBoxinfo>().eq(BstIvtBoxinfo::getBox_no, vehicle_code1));
if (ObjectUtil.isEmpty(boxinfo)) {
throw new BadRequestException("木箱号:" + vehicle_code1 + "不存在");
}
box_specs.add(boxinfo.getMaterial_code());
}
}
String firstMaterial = box_specs.get(0);
boolean allMatch = box_specs.stream().allMatch(code -> code.equals(firstMaterial));
if (!allMatch) {
throw new BadRequestException("木箱规格不一致");
}
RLock lock = redissonClient.getLock("boxIn");
boolean tryLock = lock.tryLock(0, TimeUnit.SECONDS);
try {
if (tryLock) {
//查询第一排非缓存区的并且无货的库位
List<BstIvtBoxstack> noHasGoodsPointList = boxstackService.list(new LambdaQueryWrapper<BstIvtBoxstack>()
.isNull(BstIvtBoxstack::getBox_spec)
.notIn(BstIvtBoxstack::getPoint_status, BoxStackEnum.POINT_STATUS.code("缓存区"))
.eq(BstIvtBoxstack::getX, 1)
.eq(BstIvtBoxstack::getIs_used, BoxStackEnum.IS_USED.code("启用")));
//判断是否满足最大数量,如果不满足
if (noHasGoodsPointList.size() <= 3) {
//获取相同木箱规格的的第一排的库位
List<BstIvtBoxstack> hasGoodsPointList = boxstackService.list(new LambdaQueryWrapper<BstIvtBoxstack>()
.eq(BstIvtBoxstack::getBox_spec, firstMaterial)
.notIn(BstIvtBoxstack::getPoint_status, BoxStackEnum.POINT_STATUS.code("缓存区"))
.eq(BstIvtBoxstack::getX, 1)
.eq(BstIvtBoxstack::getIs_used, BoxStackEnum.IS_USED.code("启用")));
//遍历相同木箱规格同列不同排的库位是否大于最大数量
int currentCanUseCount = 0;
for (BstIvtBoxstack bstIvtBoxstack : hasGoodsPointList) {
Integer x = bstIvtBoxstack.getX();
Integer y = bstIvtBoxstack.getY();
List<BstIvtBoxstack> list = boxstackService.list(new LambdaQueryWrapper<BstIvtBoxstack>()
.isNull(BstIvtBoxstack::getBox_spec)
.eq(BstIvtBoxstack::getY, y)
.eq(BstIvtBoxstack::getIs_used, BoxStackEnum.IS_USED.code("启用"))
.notIn(BstIvtBoxstack::getX, x)
.notIn(BstIvtBoxstack::getPoint_status, BoxStackEnum.POINT_STATUS.code("缓存区")));
currentCanUseCount += list.size();
}
if (currentCanUseCount <= 3) {
List<String> taskTypes = new ArrayList<>(Collections.singletonList(BoxStackEnum.TASK_TYPE.code("木箱入库")));
List<SchBaseTask> existTask = taskService.getExistTasks(taskTypes);
if (existTask.size() >= 3) {
throw new BadRequestException("木箱入库任务超过最大数量");
}
}
}
JSONObject taskParam = new JSONObject();
taskParam.put("material_code", box_specs.get(0));
taskParam.put("vehicle_code", vehicle_code);
taskParam.put("vehicle_code2", BoxStackEnum.AGV_ACTION_TYPE.code("放货二次分配"));
taskParam.put("task_type", BoxStackEnum.TASK_TYPE.code("木箱入库"));
taskParam.put("point_code1", point_code);
taskParam.put("point_code2", BoxStackEnum.AGV_WAIT_POINT.code("木箱等待点1"));
mxInTask.createTask(reqParam);
}
} finally {
if (lock.isLocked() && lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
}
}

View File

@@ -0,0 +1,226 @@
package org.nl.b_lms.sch.tasks.boxstack;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.nl.b_lms.bst.ivt.boxstack.enums.BoxStackEnum;
import org.nl.b_lms.bst.ivt.boxstack.service.IBstIvtBoxstackService;
import org.nl.b_lms.bst.ivt.boxstack.service.IBstIvtBoxstacklayerService;
import org.nl.b_lms.bst.ivt.boxstack.service.dao.BstIvtBoxstack;
import org.nl.b_lms.bst.ivt.boxstack.service.dao.BstIvtBoxstacklayer;
import org.nl.b_lms.sch.task.dao.SchBaseTask;
import org.nl.b_lms.sch.task.dto.SchBaseTaskVO;
import org.nl.b_lms.sch.task.service.IschBaseTaskService;
import org.nl.b_lms.storage_manage.ios.enums.IOSEnum;
import org.nl.common.enums.PackageInfoIvtEnum;
import org.nl.common.utils.IdUtil;
import org.nl.common.utils.SecurityUtils;
import org.nl.modules.common.exception.BadRequestException;
import org.nl.wms.sch.AcsTaskDto;
import org.nl.wms.sch.manage.AbstractAcsTask;
import org.nl.wms.sch.manage.TaskStatusEnum;
import org.nl.wms.util.TaskUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
/**
* 1 木箱入库任务 木箱入库位->木箱库
*
* @author gbx
* @since 2024-01-24
*/
@Service()
@RequiredArgsConstructor
@Slf4j
public class MxInTask extends AbstractAcsTask {
private final String THIS_CLASS = MxInTask.class.getName();
@Resource
private IschBaseTaskService taskService;
@Resource
private IBstIvtBoxstackService boxstackService;
@Resource
private IBstIvtBoxstacklayerService boxstacklayerService;
@Override
public List<AcsTaskDto> addTask() {
ArrayList<AcsTaskDto> resultList = new ArrayList<>();
List<SchBaseTask> taskList = taskService.list(new LambdaUpdateWrapper<SchBaseTask>().eq(SchBaseTask::getHandle_class, THIS_CLASS)
.eq(SchBaseTask::getTask_status, TaskStatusEnum.START_AND_POINT.getCode())
.eq(SchBaseTask::getIs_delete, 0)
);
taskList.forEach(r -> {
AcsTaskDto dto = AcsTaskDto.builder()
.ext_task_id(r.getTask_id())
.task_code(r.getTask_code())
.task_type(r.getAcs_task_type())
.start_device_code(r.getPoint_code1())
.next_device_code(r.getPoint_code2())
.vehicle_code(r.getVehicle_code())
.priority(r.getPriority())
.remark(r.getRemark())
.product_area(r.getProduct_area())
.agv_action_type(r.getVehicle_code2())
.agv_system_type(BoxStackEnum.AGV_SYSTEM_TYPE.code("1楼诺宝任务"))
.interaction_json(JSON.parseObject(r.getRequest_param()))
.build();
resultList.add(dto);
});
return resultList;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateTaskStatus(JSONObject taskObj, String status) {
String now = DateUtil.now();
String currentUserId = SecurityUtils.getCurrentUserId();
String currentNickName = SecurityUtils.getCurrentNickName();
SchBaseTask schBaseTask = taskService.getOne(new LambdaUpdateWrapper<SchBaseTask>().eq(SchBaseTask::getTask_id, taskObj.getString("task_id")), false);
if (TaskUtil.checkParams(schBaseTask, THIS_CLASS, TaskStatusEnum.FINISHED.getCode())) return;
LambdaUpdateWrapper<SchBaseTask> updateWrapper = new LambdaUpdateWrapper<SchBaseTask>()
.eq(SchBaseTask::getTask_id, taskObj.getString("task_id"))
.set(SchBaseTask::getUpdate_optid, currentUserId)
.set(SchBaseTask::getUpdate_optname, currentNickName)
.set(SchBaseTask::getUpdate_time, now);
if (TaskStatusEnum.EXECUTING.getCode().equals(status)) {
// 更新任务状态为执行中
if (TaskUtil.checkParams(schBaseTask, THIS_CLASS, TaskStatusEnum.EXECUTING.getCode())) return;
updateWrapper.set(SchBaseTask::getTask_status, TaskStatusEnum.EXECUTING.getCode());
}
if (StrUtil.equals(status, TaskStatusEnum.FINISHED.getCode())) {
log.info("任务编号为:" + schBaseTask.getTask_code() + "的任务完成接口在" + now + "被调用---------------------------------------------");
//更新终点库存
String box_spec = schBaseTask.getMaterial_code();
String vehicle_code = schBaseTask.getVehicle_code();
String[] boxNos = vehicle_code.split(",");
//修改木箱库木箱规格信息
BstIvtBoxstack boxstack = boxstackService.getOne(new LambdaQueryWrapper<BstIvtBoxstack>()
.eq(BstIvtBoxstack::getStack_code, schBaseTask.getPoint_code2()));
if (!ObjectUtil.isEmpty(boxstack)) {
for (int i = 0; i < boxNos.length; i++) {
//修改每层的木箱号信息
String boxNo = boxNos[i];
BstIvtBoxstacklayer boxstacklayer = boxstacklayerService.getOne(new LambdaQueryWrapper<BstIvtBoxstacklayer>()
.eq(BstIvtBoxstacklayer::getStack_id, boxstack.getStack_id())
.eq(BstIvtBoxstacklayer::getLayer_index, i + 1));
if (!ObjectUtil.isEmpty(boxstacklayer)) {
boxstacklayer.setBox_code(boxNo);
boxstacklayer.setUpdate_time(now);
boxstacklayer.setUpdate_id(currentUserId);
boxstacklayer.setUpdate_name(currentNickName);
boxstacklayerService.updateById(boxstacklayer);
}
}
boxstack.setBox_spec(box_spec);
boxstack.setUpdate_time(now);
boxstack.setUpdate_id(currentUserId);
boxstack.setUpdate_name(currentNickName);
boxstackService.updateById(boxstack);
}
//3.更改任务状态为完成
updateWrapper.set(SchBaseTask::getTask_status, TaskStatusEnum.FINISHED.getCode());
}
// 取消
if (status.equals(IOSEnum.IS_NOTANDYES.code(""))) {
if (Integer.parseInt(schBaseTask.getTask_status()) > Integer.parseInt(TaskStatusEnum.ISSUE.getCode())) {
throw new BadRequestException("任务已执行不能取消");
}
//任务被标记为取消
updateWrapper.set(SchBaseTask::getIs_delete, IOSEnum.IS_NOTANDYES.code(""));
updateWrapper.set(SchBaseTask::getTask_status, TaskStatusEnum.CANCEL.getCode());
updateWrapper.set(SchBaseTask::getRemark, "任务被ACS在:" + schBaseTask.getUpdate_time() + "调用接口强制取消。");
}
taskService.update(null, updateWrapper);
}
@Override
@Transactional
public String createTask(JSONObject form) {
Assert.notNull(form, "请求参数不能为空");
String taskType = form.getString("task_type");
if (StrUtil.isBlank(taskType)) {
throw new BadRequestException("业务类型不能为空");
}
String vehicleCode = form.getString("vehicle_code");
String pointCode1 = form.getString("point_code1");
if (StrUtil.isBlank(pointCode1)) {
throw new BadRequestException("起点不能为空");
}
String pointCode2 = form.getString("point_code2");
if (StrUtil.isBlank(pointCode2)) {
throw new BadRequestException("下一点不能为空");
}
//是否立即下发
boolean isSend = !StrUtil.isNotBlank(form.getString("is_send")) || BooleanUtil.toBoolean(form.getString("is_send"));
SchBaseTaskVO schBaseTaskVo = SchBaseTaskVO.builder()
.task_type(taskType)
.vehicle_code(vehicleCode)
//二次分配要用的类型
.vehicle_code2(form.getString("vehicle_code2"))
.point_code1(pointCode1)
.point_code2(pointCode2)
.task_group_id(form.getString("task_group_id"))
.task_id(IdUtil.getStringId())
.task_code(IdUtil.getStringId())
.handle_class(THIS_CLASS)
.create_id(SecurityUtils.getCurrentUserId())
.create_name(SecurityUtils.getCurrentUsername())
.create_time(DateUtil.now())
.is_send(isSend ? "1" : "0")
.acs_task_type(StrUtil.isEmpty(form.getString("acs_task_type")) ? PackageInfoIvtEnum.ACS_TASK_TYPE.code("agv任务") : form.getString("acs_task_type"))
.task_status(StrUtil.isEmpty(form.getString("task_status")) ? TaskStatusEnum.START_AND_POINT.getCode() : form.getString("task_status"))
.build();
SchBaseTask task = new SchBaseTask();
BeanUtils.copyProperties(schBaseTaskVo, task);
taskService.save(task);
//如果目标点位没有空位先创建不下发
if (isSend) {
this.immediateNotifyAcs(null);
}
return task.getTask_id();
}
@Override
@Transactional
public void forceFinish(String taskId) {
SchBaseTask schBaseTask = taskService.getOne(new LambdaUpdateWrapper<SchBaseTask>()
.eq(SchBaseTask::getTask_id, taskId), false);
if (TaskUtil.checkParams(schBaseTask, THIS_CLASS, TaskStatusEnum.FINISHED.getCode())) return;
updateTaskStatus(JSONObject.parseObject(JSON.toJSONString(schBaseTask)), TaskStatusEnum.FINISHED.getCode());
}
@Override
public void cancel(String taskId) {
SchBaseTask schBaseTask = taskService.getOne(new LambdaUpdateWrapper<SchBaseTask>()
.eq(SchBaseTask::getTask_id, taskId), false);
if (schBaseTask == null) {
throw new BadRequestException("木箱入库取消接口任务号为空!");
}
LambdaUpdateWrapper<SchBaseTask> updateWrapper = new LambdaUpdateWrapper<SchBaseTask>()
.eq(SchBaseTask::getTask_id, taskId)
.set(SchBaseTask::getUpdate_optid, SecurityUtils.getCurrentUserId())
.set(SchBaseTask::getUpdate_optname, SecurityUtils.getCurrentUsername())
.set(SchBaseTask::getUpdate_time, DateUtil.now());
//任务被标记为取消
updateWrapper.set(SchBaseTask::getIs_delete, IOSEnum.IS_NOTANDYES.code(""));
updateWrapper.set(SchBaseTask::getTask_status, TaskStatusEnum.CANCEL.getCode());
updateWrapper.set(SchBaseTask::getRemark, "任务被用户:" + schBaseTask.getUpdate_optname() + "在:" + DateUtil.now() + "强制取消。");
taskService.update(null, updateWrapper);
}
}

View File

@@ -0,0 +1,226 @@
package org.nl.b_lms.sch.tasks.boxstack;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.nl.b_lms.bst.ivt.boxstack.service.IBstIvtBoxstackService;
import org.nl.b_lms.bst.ivt.boxstack.service.IBstIvtBoxstacklayerService;
import org.nl.b_lms.bst.ivt.boxstack.service.dao.BstIvtBoxstack;
import org.nl.b_lms.bst.ivt.boxstack.service.dao.BstIvtBoxstacklayer;
import org.nl.b_lms.sch.task.dao.SchBaseTask;
import org.nl.b_lms.sch.task.dto.SchBaseTaskVO;
import org.nl.b_lms.sch.task.service.IschBaseTaskService;
import org.nl.b_lms.storage_manage.ios.enums.IOSEnum;
import org.nl.common.enums.PackageInfoIvtEnum;
import org.nl.common.utils.IdUtil;
import org.nl.common.utils.SecurityUtils;
import org.nl.modules.common.exception.BadRequestException;
import org.nl.wms.sch.AcsTaskDto;
import org.nl.wms.sch.manage.AbstractAcsTask;
import org.nl.wms.sch.manage.TaskStatusEnum;
import org.nl.wms.util.TaskUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
/**
* 2 木箱移库任务 木箱库密集区、零散区->木箱库缓存区
*
* @author gbx
* @since 2024-01-24
*/
@Service()
@RequiredArgsConstructor
@Slf4j
public class MxMoveTask extends AbstractAcsTask {
private final String THIS_CLASS = MxMoveTask.class.getName();
@Resource
private IschBaseTaskService taskService;
@Resource
private IBstIvtBoxstackService boxstackService;
@Resource
private IBstIvtBoxstacklayerService boxstacklayerService;
@Override
public List<AcsTaskDto> addTask() {
ArrayList<AcsTaskDto> resultList = new ArrayList<>();
List<SchBaseTask> taskList = taskService.list(new LambdaUpdateWrapper<SchBaseTask>().eq(SchBaseTask::getHandle_class, THIS_CLASS)
.eq(SchBaseTask::getTask_status, TaskStatusEnum.START_AND_POINT.getCode())
.eq(SchBaseTask::getIs_delete, 0)
);
taskList.forEach(r -> {
AcsTaskDto dto = AcsTaskDto.builder()
.ext_task_id(r.getTask_id().toString())
.task_code(r.getTask_code())
.task_type(r.getAcs_task_type())
.start_device_code(r.getPoint_code1())
.next_device_code(r.getPoint_code2())
.vehicle_code(r.getVehicle_code())
.priority(r.getPriority())
.remark(r.getRemark())
.product_area(r.getProduct_area())
.agv_action_type(r.getVehicle_code2())
.agv_system_type(PackageInfoIvtEnum.AGV_SYSTEM_TYPE.code("1楼诺宝任务"))
.interaction_json(JSON.parseObject(r.getRequest_param()))
.build();
resultList.add(dto);
});
return resultList;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateTaskStatus(JSONObject taskObj, String status) {
String now = DateUtil.now();
String currentNickName = SecurityUtils.getCurrentNickName();
String currentUserId = SecurityUtils.getCurrentUserId();
SchBaseTask schBaseTask = taskService.getOne(new LambdaUpdateWrapper<SchBaseTask>().eq(SchBaseTask::getTask_id, taskObj.getString("task_id")), false);
if (TaskUtil.checkParams(schBaseTask, THIS_CLASS, TaskStatusEnum.FINISHED.getCode())) return;
LambdaUpdateWrapper<SchBaseTask> updateWrapper = new LambdaUpdateWrapper<SchBaseTask>()
.eq(SchBaseTask::getTask_id, taskObj.getString("task_id"))
.set(SchBaseTask::getUpdate_optid, SecurityUtils.getCurrentUserId())
.set(SchBaseTask::getUpdate_optname, SecurityUtils.getCurrentUsername())
.set(SchBaseTask::getUpdate_time, now);
if (TaskStatusEnum.EXECUTING.getCode().equals(status)) {
// 更新任务状态为执行中
if (TaskUtil.checkParams(schBaseTask, THIS_CLASS, TaskStatusEnum.EXECUTING.getCode())) return;
updateWrapper.set(SchBaseTask::getTask_status, TaskStatusEnum.EXECUTING.getCode());
}
if (StrUtil.equals(status, TaskStatusEnum.FINISHED.getCode())) {
log.info("任务编号为:" + schBaseTask.getTask_code() + "的任务完成接口在" + now + "被调用---------------------------------------------");
//更新终点库存
String box_spec = schBaseTask.getMaterial_code();
String vehicle_code = schBaseTask.getVehicle_code();
String[] boxNos = vehicle_code.split(",");
//修改木箱库木箱规格信息
BstIvtBoxstack boxstack = boxstackService.getOne(new LambdaQueryWrapper<BstIvtBoxstack>()
.eq(BstIvtBoxstack::getStack_code, schBaseTask.getPoint_code2()));
if (!ObjectUtil.isEmpty(boxstack)) {
for (int i = 0; i < boxNos.length; i++) {
//修改每层的木箱号信息
String boxNo = boxNos[i];
BstIvtBoxstacklayer boxstacklayer = boxstacklayerService.getOne(new LambdaQueryWrapper<BstIvtBoxstacklayer>()
.eq(BstIvtBoxstacklayer::getStack_id, boxstack.getStack_id())
.eq(BstIvtBoxstacklayer::getLayer_index, i + 1));
if (!ObjectUtil.isEmpty(boxstacklayer)) {
boxstacklayer.setBox_code(boxNo);
boxstacklayer.setUpdate_time(now);
boxstacklayer.setUpdate_id(currentUserId);
boxstacklayer.setUpdate_name(currentNickName);
boxstacklayerService.updateById(boxstacklayer);
}
}
boxstack.setBox_spec(box_spec);
boxstack.setUpdate_time(now);
boxstack.setUpdate_id(currentUserId);
boxstack.setUpdate_name(currentNickName);
boxstackService.updateById(boxstack);
}
//3.更改任务状态为完成
updateWrapper.set(SchBaseTask::getTask_status, TaskStatusEnum.FINISHED.getCode());
}
// 取消
if (status.equals(IOSEnum.IS_NOTANDYES.code(""))) {
if (Integer.parseInt(schBaseTask.getTask_status()) > Integer.parseInt(TaskStatusEnum.ISSUE.getCode())) {
throw new BadRequestException("任务已执行不能取消");
}
//任务被标记为取消
updateWrapper.set(SchBaseTask::getIs_delete, IOSEnum.IS_NOTANDYES.code(""));
updateWrapper.set(SchBaseTask::getTask_status, TaskStatusEnum.CANCEL.getCode());
updateWrapper.set(SchBaseTask::getRemark, "任务被ACS在:" + schBaseTask.getUpdate_time() + "调用接口强制取消。");
}
taskService.update(null, updateWrapper);
}
@Override
@Transactional
public String createTask(JSONObject form) {
Assert.notNull(form, "请求参数不能为空");
String taskType = form.getString("task_type");
if (StrUtil.isBlank(taskType)) {
throw new BadRequestException("业务类型不能为空");
}
String vehicleCode = form.getString("vehicle_code");
String pointCode1 = form.getString("point_code1");
if (StrUtil.isBlank(pointCode1)) {
throw new BadRequestException("起点不能为空");
}
String pointCode2 = form.getString("point_code2");
if (StrUtil.isBlank(pointCode2)) {
throw new BadRequestException("下一点不能为空");
}
//是否立即下发
boolean isSend = !StrUtil.isNotBlank(form.getString("is_send")) || BooleanUtil.toBoolean(form.getString("is_send"));
SchBaseTaskVO schBaseTaskVo = SchBaseTaskVO.builder()
.task_type(taskType)
.material_code(form.getString("material_code"))
.vehicle_code(vehicleCode)
.vehicle_code2(form.getString("vehicle_code2"))
.point_code1(pointCode1)
.point_code2(pointCode2)
.task_group_id(form.getString("task_group_id"))
.task_id(IdUtil.getStringId())
.task_code(IdUtil.getStringId())
.handle_class(THIS_CLASS)
.create_id(SecurityUtils.getCurrentUserId())
.create_name(SecurityUtils.getCurrentUsername())
.create_time(DateUtil.now())
.is_send(isSend ? "1" : "0")
.acs_task_type(StrUtil.isEmpty(form.getString("acs_task_type")) ? PackageInfoIvtEnum.ACS_TASK_TYPE.code("agv任务") : form.getString("acs_task_type"))
.task_status(StrUtil.isEmpty(form.getString("task_status")) ? TaskStatusEnum.START_AND_POINT.getCode() : form.getString("task_status"))
.build();
SchBaseTask task = new SchBaseTask();
BeanUtils.copyProperties(schBaseTaskVo, task);
taskService.save(task);
//如果目标点位没有空位先创建不下发
if (isSend) {
this.immediateNotifyAcs(null);
}
return task.getTask_id();
}
@Override
@Transactional
public void forceFinish(String taskId) {
SchBaseTask schBaseTask = taskService.getOne(new LambdaUpdateWrapper<SchBaseTask>()
.eq(SchBaseTask::getTask_id, taskId), false);
if (TaskUtil.checkParams(schBaseTask, THIS_CLASS, TaskStatusEnum.FINISHED.getCode())) return;
updateTaskStatus(JSONObject.parseObject(JSON.toJSONString(schBaseTask)), TaskStatusEnum.FINISHED.getCode());
}
@Override
public void cancel(String taskId) {
SchBaseTask schBaseTask = taskService.getOne(new LambdaUpdateWrapper<SchBaseTask>()
.eq(SchBaseTask::getTask_id, taskId), false);
if (schBaseTask == null) {
throw new BadRequestException("木箱移库取消接口任务号为空!");
}
LambdaUpdateWrapper<SchBaseTask> updateWrapper = new LambdaUpdateWrapper<SchBaseTask>()
.eq(SchBaseTask::getTask_id, taskId)
.set(SchBaseTask::getUpdate_optid, SecurityUtils.getCurrentUserId())
.set(SchBaseTask::getUpdate_optname, SecurityUtils.getCurrentUsername())
.set(SchBaseTask::getUpdate_time, DateUtil.now());
//任务被标记为取消
updateWrapper.set(SchBaseTask::getIs_delete, IOSEnum.IS_NOTANDYES.code(""));
updateWrapper.set(SchBaseTask::getTask_status, TaskStatusEnum.CANCEL.getCode());
updateWrapper.set(SchBaseTask::getRemark, "任务被用户:" + schBaseTask.getUpdate_optname() + "在:" + DateUtil.now() + "强制取消。");
taskService.update(null, updateWrapper);
}
}

View File

@@ -0,0 +1,224 @@
package org.nl.b_lms.sch.tasks.boxstack;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.nl.b_lms.sch.point.dao.BstIvtPackageinfoivt;
import org.nl.b_lms.sch.point.service.IbstIvtPackageinfoivtService;
import org.nl.b_lms.sch.task.dao.SchBaseTask;
import org.nl.b_lms.sch.task.dto.SchBaseTaskVO;
import org.nl.b_lms.sch.task.service.IschBaseTaskService;
import org.nl.b_lms.storage_manage.ios.enums.IOSEnum;
import org.nl.common.enums.PackageInfoIvtEnum;
import org.nl.common.utils.SecurityUtils;
import org.nl.modules.common.exception.BadRequestException;
import org.nl.wms.sch.AcsTaskDto;
import org.nl.wms.sch.manage.AbstractAcsTask;
import org.nl.wms.sch.manage.TaskStatusEnum;
import org.nl.wms.util.TaskUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* 3 木箱出库任务 木箱库密集区、缓存区、零散区->出库对接位
*
* @author gbx
* @since 2024-01-24
*/
@Service()
@RequiredArgsConstructor
@Slf4j
public class MxOutTask extends AbstractAcsTask {
private final String THIS_CLASS = MxOutTask.class.getName();
@Resource
private IschBaseTaskService taskService;
@Resource
private IbstIvtPackageinfoivtService packageinfoivtService;
@Override
public List<AcsTaskDto> addTask() {
ArrayList<AcsTaskDto> resultList = new ArrayList<>();
List<SchBaseTask> taskList = taskService.list(new LambdaUpdateWrapper<SchBaseTask>().eq(SchBaseTask::getHandle_class, THIS_CLASS)
.eq(SchBaseTask::getTask_status, TaskStatusEnum.START_AND_POINT.getCode())
.eq(SchBaseTask::getIs_delete, 0)
);
taskList.forEach(r -> {
AcsTaskDto dto = AcsTaskDto.builder()
.ext_task_id(r.getTask_id().toString())
.task_code(r.getTask_code())
.task_type(r.getAcs_task_type())
.start_device_code(r.getPoint_code1())
.next_device_code(r.getPoint_code2())
.vehicle_code(r.getVehicle_code())
.priority(r.getPriority())
.remark(r.getRemark())
.product_area(r.getProduct_area())
.agv_action_type(r.getVehicle_code2())
.agv_system_type(PackageInfoIvtEnum.AGV_SYSTEM_TYPE.code("1楼诺宝任务"))
.interaction_json(JSON.parseObject(r.getRequest_param()))
.build();
resultList.add(dto);
});
return resultList;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateTaskStatus(JSONObject taskObj, String status) {
String now = DateUtil.now();
SchBaseTask schBaseTask = taskService.getOne(new LambdaUpdateWrapper<SchBaseTask>().eq(SchBaseTask::getTask_id, taskObj.getString("task_id")), false);
if (TaskUtil.checkParams(schBaseTask, THIS_CLASS, TaskStatusEnum.FINISHED.getCode())) return;
LambdaUpdateWrapper<SchBaseTask> updateWrapper = new LambdaUpdateWrapper<SchBaseTask>()
.eq(SchBaseTask::getTask_id, taskObj.getString("task_id"))
.set(SchBaseTask::getUpdate_optid, SecurityUtils.getCurrentUserId())
.set(SchBaseTask::getUpdate_optname, SecurityUtils.getCurrentUsername())
.set(SchBaseTask::getUpdate_time, now);
if (TaskStatusEnum.EXECUTING.getCode().equals(status)) {
// 更新任务状态为执行中
if (TaskUtil.checkParams(schBaseTask, THIS_CLASS, TaskStatusEnum.EXECUTING.getCode())) return;
updateWrapper.set(SchBaseTask::getTask_status, TaskStatusEnum.EXECUTING.getCode());
}
if (StrUtil.equals(status, TaskStatusEnum.FINISHED.getCode())) {
log.info("任务编号为:" + schBaseTask.getTask_code() + "的任务完成接口在" + now + "被调用---------------------------------------------");
//1.改变起点点位状态
packageinfoivtService.update(null, new UpdateWrapper<BstIvtPackageinfoivt>().set("update_time", now).set("ivt_status", PackageInfoIvtEnum.IVT_STATUS.code("")).set("container_name", null).eq("point_code", schBaseTask.getPoint_code1()));
//2.更新库存记录
packageinfoivtService.update(null, new UpdateWrapper<BstIvtPackageinfoivt>().set("update_time", now).set("ivt_status", PackageInfoIvtEnum.IVT_STATUS.code("空载具")).eq("point_code", schBaseTask.getPoint_code2()));
//3.更改任务状态为完成
updateWrapper.set(SchBaseTask::getTask_status, TaskStatusEnum.FINISHED.getCode());
}
// 取消
if (status.equals(IOSEnum.IS_NOTANDYES.code(""))) {
if (Integer.parseInt(schBaseTask.getTask_status()) > Integer.parseInt(TaskStatusEnum.ISSUE.getCode())) {
throw new BadRequestException("任务已执行不能取消");
}
//任务被标记为取消
updateWrapper.set(SchBaseTask::getIs_delete, IOSEnum.IS_NOTANDYES.code(""));
updateWrapper.set(SchBaseTask::getTask_status, TaskStatusEnum.CANCEL.getCode());
updateWrapper.set(SchBaseTask::getRemark, "任务被ACS在:" + schBaseTask.getUpdate_time() + "调用接口强制取消。");
}
taskService.update(null, updateWrapper);
}
public void exchangeTaskPoint(SchBaseTask schBaseTask) {
List<SchBaseTask> taskList = taskService.list(new LambdaQueryWrapper<SchBaseTask>()
.lt(SchBaseTask::getTask_status, TaskStatusEnum.FINISHED.getCode())
.eq(SchBaseTask::getIs_delete, IOSEnum.IS_NOTANDYES.code(""))
.and(
r -> r.eq(SchBaseTask::getTask_type, PackageInfoIvtEnum.TASK_TYPE.code("补空(管制区->空载具缓存位)"))
.or()
.eq(SchBaseTask::getTask_type, PackageInfoIvtEnum.TASK_TYPE.code("补空(待检区->空载具缓存位)"))
.or()
));
List<SchBaseTask> SamePointtaskList = taskList.stream().filter(r -> r.getPoint_code4().equals(schBaseTask.getPoint_code2()) && !r.getTask_id().equals(schBaseTask.getTask_id())).collect(Collectors.toList());
if (ObjectUtils.isNotEmpty(SamePointtaskList)) {
UpdateWrapper<SchBaseTask> updateWrapper1 = new UpdateWrapper<>();
updateWrapper1.eq("task_id", SamePointtaskList.get(0).getTask_id());
updateWrapper1.set("point_code4", schBaseTask.getPoint_code4());
taskService.update(null, updateWrapper1);
}
}
@Override
@Transactional
public String createTask(JSONObject form) {
Assert.notNull(form, "请求参数不能为空");
String taskType = form.getString("task_type");
if (StrUtil.isBlank(taskType)) {
throw new BadRequestException("业务类型不能为空");
}
String vehicleCode = form.getString("vehicle_code");
// if (StrUtil.isBlank(vehicleCode)) {
// throw new BadRequestException("载具号不能为空");
// }
String pointCode1 = form.getString("point_code1");
if (StrUtil.isBlank(pointCode1)) {
throw new BadRequestException("起点不能为空");
}
String pointCode2 = form.getString("point_code2");
if (StrUtil.isBlank(pointCode2)) {
throw new BadRequestException("下一点不能为空");
}
String pointCode3 = form.getString("point_code3");
//是否立即下发
boolean isSend = !StrUtil.isNotBlank(form.getString("is_send")) || BooleanUtil.toBoolean(form.getString("is_send"));
SchBaseTaskVO schBaseTaskVo = SchBaseTaskVO.builder()
.task_type(taskType)
.vehicle_code(vehicleCode)
.vehicle_code2(form.getString("vehicle_code2"))
.point_code1(pointCode1)
.point_code2(pointCode2)
.point_code3(pointCode3)
.point_code4(form.getString("point_code4"))
.task_group_id(form.getString("task_group_id"))
.task_id(org.nl.common.utils.IdUtil.getStringId())
.task_code(org.nl.common.utils.IdUtil.getStringId())
.handle_class(THIS_CLASS)
.create_id(SecurityUtils.getCurrentUserId())
.create_name(SecurityUtils.getCurrentUsername())
.create_time(DateUtil.now())
.is_send(isSend ? "1" : "0")
.acs_task_type(StrUtil.isEmpty(form.getString("acs_task_type")) ? PackageInfoIvtEnum.ACS_TASK_TYPE.code("agv任务") : form.getString("acs_task_type"))
.task_status(StrUtil.isEmpty(form.getString("task_status")) ? TaskStatusEnum.START_AND_POINT.getCode() : form.getString("task_status"))
.product_area(StrUtil.isEmpty(form.getString("product_area")) ? "BLK" : form.getString("product_area"))
.build();
SchBaseTask task = new SchBaseTask();
BeanUtils.copyProperties(schBaseTaskVo, task);
taskService.save(task);
//如果目标点位没有空位先创建不下发
if (isSend) {
this.immediateNotifyAcs(null);
}
return task.getTask_id();
}
@Override
@Transactional
public void forceFinish(String taskId) {
SchBaseTask schBaseTask = taskService.getOne(new LambdaUpdateWrapper<SchBaseTask>()
.eq(SchBaseTask::getTask_id, taskId), false);
if (TaskUtil.checkParams(schBaseTask, THIS_CLASS, TaskStatusEnum.FINISHED.getCode())) return;
updateTaskStatus(JSONObject.parseObject(JSON.toJSONString(schBaseTask)), TaskStatusEnum.FINISHED.getCode());
}
@Override
public void cancel(String taskId) {
SchBaseTask schBaseTask = taskService.getOne(new LambdaUpdateWrapper<SchBaseTask>()
.eq(SchBaseTask::getTask_id, taskId), false);
if (schBaseTask == null) {
throw new BadRequestException("待检区->空载具缓存位取消接口任务号为空!");
}
LambdaUpdateWrapper<SchBaseTask> updateWrapper = new LambdaUpdateWrapper<SchBaseTask>()
.eq(SchBaseTask::getTask_id, taskId)
.set(SchBaseTask::getUpdate_optid, SecurityUtils.getCurrentUserId())
.set(SchBaseTask::getUpdate_optname, SecurityUtils.getCurrentUsername())
.set(SchBaseTask::getUpdate_time, DateUtil.now());
//任务被标记为取消
updateWrapper.set(SchBaseTask::getIs_delete, IOSEnum.IS_NOTANDYES.code(""));
updateWrapper.set(SchBaseTask::getTask_status, TaskStatusEnum.CANCEL.getCode());
updateWrapper.set(SchBaseTask::getRemark, "任务被用户:" + schBaseTask.getUpdate_optname() + "在:" + DateUtil.now() + "强制取消。");
taskService.update(null, updateWrapper);
}
}

View File

@@ -0,0 +1,180 @@
package org.nl.b_lms.sch.tasks.boxstack.auto;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.nl.b_lms.bst.ivt.boxstack.enums.BoxStackEnum;
import org.nl.b_lms.bst.ivt.boxstack.service.IBstIvtBoxstackService;
import org.nl.b_lms.bst.ivt.boxstack.service.IBstIvtBoxstacklayerService;
import org.nl.b_lms.bst.ivt.boxstack.service.dao.BstIvtBoxstack;
import org.nl.b_lms.sch.task.dao.SchBaseTask;
import org.nl.b_lms.sch.task.service.IschBaseTaskService;
import org.nl.b_lms.sch.tasks.boxstack.MxMoveTask;
import org.nl.common.utils.IdUtil;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@Slf4j
@Component
@RequiredArgsConstructor
public class AutoMxMoveTask {
@Resource
private IschBaseTaskService taskService;
private final String THIS_CLASS = AutoMxMoveTask.class.getName();
@Resource
private RedissonClient redissonClient;
@Resource
private MxMoveTask mxMoveTask;
@Resource
private IBstIvtBoxstackService boxstackService;
//满轴->待检区agv自动搬运任务
public void run() {
try {
this.sendMxMove();
} catch (Exception ex) {
log.error(ex.getMessage());
}
}
@SneakyThrows
public void sendMxMove() {
log.info(THIS_CLASS + "-根据装箱计划木箱库移库定时任务开始执行扫描。");
RLock lock = redissonClient.getLock("boxMove");
boolean tryLock = lock.tryLock(0, TimeUnit.SECONDS);
try {
if (tryLock) {
//获取装箱计划
List<String> zxjhs = new ArrayList<>();
for (String box_spec : zxjhs) {
//判断木箱库是否存在该木箱规格的木箱
List<BstIvtBoxstack> hasGoodsPoint = boxstackService.list(new LambdaQueryWrapper<BstIvtBoxstack>()
.eq(BstIvtBoxstack::getBox_spec, box_spec)
.notIn(BstIvtBoxstack::getPoint_status, BoxStackEnum.POINT_STATUS.code("缓存区"))
.eq(BstIvtBoxstack::getIs_used, BoxStackEnum.IS_USED.code("启用")));
if (!CollectionUtil.isEmpty(hasGoodsPoint)) {
//查询缓存区可用库位的数量
List<BstIvtBoxstack> hcqNoHasGoodsPointList = boxstackService.list(new LambdaQueryWrapper<BstIvtBoxstack>()
.isNull(BstIvtBoxstack::getBox_spec)
.eq(BstIvtBoxstack::getPoint_status, BoxStackEnum.POINT_STATUS.code("缓存区"))
.eq(BstIvtBoxstack::getX, 1)
.eq(BstIvtBoxstack::getIs_used, BoxStackEnum.IS_USED.code("启用")));
if (hcqNoHasGoodsPointList.size() <= 3) {
//获取缓存区相同木箱规格的的第一排的库位
List<BstIvtBoxstack> hcqHasGoodsPointList = boxstackService.list(new LambdaQueryWrapper<BstIvtBoxstack>()
.eq(BstIvtBoxstack::getBox_spec, box_spec)
.eq(BstIvtBoxstack::getPoint_status, BoxStackEnum.POINT_STATUS.code("缓存区"))
.eq(BstIvtBoxstack::getX, 1)
.eq(BstIvtBoxstack::getIs_used, BoxStackEnum.IS_USED.code("启用")));
//遍历相同木箱规格同列不同排的库位是否大于最大数量
int currentCanUseCount = 0;
for (BstIvtBoxstack bstIvtBoxstack : hcqHasGoodsPointList) {
Integer x = bstIvtBoxstack.getX();
Integer y = bstIvtBoxstack.getY();
List<BstIvtBoxstack> list = boxstackService.list(new LambdaQueryWrapper<BstIvtBoxstack>()
.isNull(BstIvtBoxstack::getBox_spec)
.eq(BstIvtBoxstack::getY, y)
.eq(BstIvtBoxstack::getIs_used, BoxStackEnum.IS_USED.code("启用"))
.notIn(BstIvtBoxstack::getX, x)
.eq(BstIvtBoxstack::getPoint_status, BoxStackEnum.POINT_STATUS.code("缓存区")));
currentCanUseCount += list.size();
}
if (currentCanUseCount <= 3) {
List<String> taskTypes = new ArrayList<>(Collections.singletonList(BoxStackEnum.TASK_TYPE.code("木箱移库")));
List<SchBaseTask> existTask = taskService.getExistTasks(taskTypes);
if (existTask.size() >= 3) {
break;
}
}
}
//如果存在则根据装箱计划获取需要移库的木箱规格的数量
int needBoxNum = 10;
int hasBoxNum = hasGoodsPoint.stream()
.map(BstIvtBoxstack::getCurrent_layer_count)
.filter(Objects::nonNull)
.mapToInt(Integer::intValue)
.sum();
//如果需要的木箱数量小于木箱库内的该木箱规格的数量
if (needBoxNum <= hasBoxNum) {
List<BstIvtBoxstack> sortedList = hasGoodsPoint.stream()
.sorted(Comparator
.comparing(BstIvtBoxstack::getY)
.thenComparing(Comparator.comparingInt(BstIvtBoxstack::getX).reversed()))
.collect(Collectors.toList());
List<BstIvtBoxstack> selected = new ArrayList<>();
int total = 0;
for (BstIvtBoxstack boxstack : sortedList) {
if (total >= needBoxNum) break;
Integer layerCount = boxstack.getCurrent_layer_count();
selected.add(boxstack);
total += layerCount;
}
String task_group_id = IdUtil.getStringId();
for (int i = 0; i < selected.size(); i++) {
JSONObject requestParam = new JSONObject();
requestParam.put("needQty", needBoxNum);
JSONObject taskParam = new JSONObject();
taskParam.put("task_group_id", task_group_id);
taskParam.put("material_code", box_spec);
taskParam.put("vehicle_code2", BoxStackEnum.AGV_ACTION_TYPE.code("取放货二次分配"));
taskParam.put("task_type", BoxStackEnum.TASK_TYPE.code("木箱移库"));
taskParam.put("vehicle_code", null);
taskParam.put("point_code1", BoxStackEnum.AGV_WAIT_POINT.code("木箱等待点1"));
taskParam.put("point_code2", BoxStackEnum.AGV_WAIT_POINT.code("木箱等待点2"));
taskParam.put("requestParam", requestParam);
mxMoveTask.createTask(taskParam);
}
} else {
String task_group_id = IdUtil.getStringId();
//如果需要的该木箱规格的数量大于木箱库内的数量
for (int i = 0; i < hasGoodsPoint.size(); i++) {
JSONObject requestParam = new JSONObject();
requestParam.put("needQty", hasBoxNum);
JSONObject taskParam = new JSONObject();
taskParam.put("task_group_id", task_group_id);
taskParam.put("material_code", box_spec);
taskParam.put("vehicle_code2", BoxStackEnum.AGV_ACTION_TYPE.code("取放货二次分配"));
taskParam.put("task_type", BoxStackEnum.TASK_TYPE.code("木箱移库"));
taskParam.put("vehicle_code", null);
taskParam.put("point_code1", BoxStackEnum.AGV_WAIT_POINT.code("木箱等待点1"));
taskParam.put("point_code2", BoxStackEnum.AGV_WAIT_POINT.code("木箱等待点2"));
taskParam.put("requestParam", requestParam);
mxMoveTask.createTask(taskParam);
}
// for (BstIvtBoxstack bstIvtBoxstack : hasGoodsPoint) {
// List<BstIvtBoxstacklayer> boxstacklayerList = boxstacklayerService.list(new LambdaQueryWrapper<BstIvtBoxstacklayer>()
// .eq(BstIvtBoxstacklayer::getStack_id, bstIvtBoxstack.getStack_id()));
// String vehicle_code = boxstacklayerList.stream()
// .map(BstIvtBoxstacklayer::getBox_code)
// .filter(Objects::nonNull)
// .filter(boxNo -> !boxNo.isEmpty())
// .collect(Collectors.joining(","));
// }
//TODO 是否修改装箱计划中剩余需要移库木箱的数量
}
}
}
} else {
log.info("木箱移库自动搬运任务正在创建被锁住。");
}
} finally {
if (lock.isLocked() && lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
}
}

View File

@@ -41,7 +41,7 @@ public class BstIvtBoxinfoController {
return new ResponseEntity<>(iBstIvtBoxinfoService.boxIvtQuery(whereJson, page), HttpStatus.OK);
}
@PostMapping("/saveBoxInfo")
@PostMapping
@Log("保存木箱信息")
public ResponseEntity<Object> saveBoxInfo(@RequestBody JSONObject jsonObject) {
return new ResponseEntity<>(iBstIvtBoxinfoService.saveBoxInfo(jsonObject), HttpStatus.OK);

View File

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
import org.nl.b_lms.storage_manage.database.service.dao.BstIvtBoxinfo;
import org.springframework.data.domain.Pageable;
import java.util.List;
import java.util.Map;
/**
@@ -42,7 +43,7 @@ public interface IBstIvtBoxinfoService extends IService<BstIvtBoxinfo> {
*/
BstIvtBoxinfo mesInsert(JSONObject whereJson);
JSONObject saveBoxInfo(JSONObject jsonObject);
List<BstIvtBoxinfo> saveBoxInfo(JSONObject jsonObject);
BstIvtBoxinfo getBoxInfo(JSONObject jsonObject);

View File

@@ -80,7 +80,7 @@ public class BstIvtBoxinfo implements Serializable {
/*
* 捆绑数量
*/
private String lash_num;
private String lash_num = "1";
/*
* 插入时间

View File

@@ -1,5 +1,6 @@
package org.nl.b_lms.storage_manage.database.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
@@ -14,6 +15,7 @@ import org.nl.b_lms.storage_manage.database.service.dao.BstIvtBoxinfo;
import org.nl.b_lms.storage_manage.database.service.dao.MdpbBoxtype;
import org.nl.b_lms.storage_manage.database.service.dao.mapper.BstIvtBoxinfoMapper;
import org.nl.common.TableDataInfo;
import org.nl.common.utils.CodeUtil;
import org.nl.common.utils.IdUtil;
import org.nl.modules.common.exception.BadRequestException;
import org.nl.modules.wql.util.SpringContextHolder;
@@ -25,9 +27,12 @@ import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* <p>
@@ -59,6 +64,7 @@ public class BstIvtBoxinfoServiceImpl extends ServiceImpl<BstIvtBoxinfoMapper, B
if (whereJson.containsKey("is_packing")) {
queryWrapper.eq(BstIvtBoxinfo::getIs_packing, whereJson.get("is_packing"));
}
queryWrapper.orderByDesc(BstIvtBoxinfo::getInsert_time);
IPage<BstIvtBoxinfo> result = bstIvtBoxinfoMapper.selectPage(new Page<>(page.getPageNumber() + 1, page.getPageSize()), queryWrapper);
mapReslt.put("content", result.getRecords());
mapReslt.put("totalElements", result.getTotal());
@@ -83,8 +89,8 @@ public class BstIvtBoxinfoServiceImpl extends ServiceImpl<BstIvtBoxinfoMapper, B
if (ObjectUtil.isEmpty(boxDao)) {
String height = whereJson.getString("Height");
int i = height.indexOf("|");
if (i>1){
height=height.substring(0,i);
if (i > 1) {
height = height.substring(0, i);
}
boxDao = BstIvtBoxinfo.builder()
.box_id(IdUtil.getStringId())
@@ -112,11 +118,11 @@ public class BstIvtBoxinfoServiceImpl extends ServiceImpl<BstIvtBoxinfoMapper, B
this.save(boxDao);
}else {
} else {
String height = whereJson.getString("Height");
int i = height.indexOf("|");
if (i>1){
height=height.substring(0,i);
if (i > 1) {
height = height.substring(0, i);
}
boxDao.setBox_high(height);
boxDao.setBox_length(whereJson.getString("Length"));
@@ -137,20 +143,50 @@ public class BstIvtBoxinfoServiceImpl extends ServiceImpl<BstIvtBoxinfoMapper, B
return boxDao;
}
@Override
public JSONObject saveBoxInfo(JSONObject jsonObject) {
public List<BstIvtBoxinfo> saveBoxInfo(JSONObject jsonObject) {
//从MES获取包装关系
String boxNo = jsonObject.getString("box_no");
String material_code = jsonObject.getString("material_code");
String material_name = jsonObject.getString("material_name");
String num = jsonObject.getString("num");
String lash_num = jsonObject.getString("lash_num");
String vehicle_type = jsonObject.getString("vehicle_type");
String is_packing = jsonObject.getString("is_packing");
String box_weight = jsonObject.getString("box_weight");
BstIvtBoxinfo boxinfo = bstIvtBoxinfoMapper.selectOne(new LambdaQueryWrapper<BstIvtBoxinfo>().eq(BstIvtBoxinfo::getBox_no, boxNo));
if (boxinfo == null) {
throw new BadRequestException("未查询到该木箱对应的木箱信息");
int box_num = jsonObject.getIntValue("box_num");
Pattern pattern = Pattern.compile("(\\d+\\*\\d+\\*\\d+)");
Matcher matcher = pattern.matcher(material_name);
if (!matcher.find()) {
throw new BadRequestException("木箱名称有误,不包含长宽高!");
}
boxinfo.setBox_weight(box_weight);
bstIvtBoxinfoMapper.updateById(boxinfo);
JSONObject jo = new JSONObject();
jo.put("message", "修改成功!");
return jo;
String lwh = matcher.group(1);
String[] lwhs = lwh.split("\\*");
String box_length = lwhs[0];
String box_width = lwhs[1];
String box_high = lwhs[2];
List<BstIvtBoxinfo> boxinfos = new ArrayList<>();
for (int i = 0; i < box_num; i++) {
BstIvtBoxinfo boxinfo = BstIvtBoxinfo.builder()
.box_id(IdUtil.getStringId())
.box_no(CodeUtil.getNewCode("BOX_CODE"))
.material_code(material_code)
.material_name(material_name)
.num(num)
.box_length(box_length)
.box_width(box_width)
.box_high(box_high)
.vehicle_type(vehicle_type)
.is_packing(is_packing)
.insert_time(DateUtil.now())
.box_weight(box_weight)
.build();
boxinfos.add(boxinfo);
}
if (CollectionUtil.isNotEmpty(boxinfos)) {
this.saveBatch(boxinfos);
}
return boxinfos;
}
@Override

View File

@@ -91,7 +91,6 @@ public interface MaterialbaseService {
JSONArray getProductSeries(String parent_class_id);
/**
* 通过物料编码获取物料列表JSONObject
* <p>使用mybatis-plus</p>

View File

@@ -32,6 +32,14 @@ export function getMaterOptType(data) {
})
}
export function getMaterialByName(data) {
return request({
url: 'api/Materialbase/getMaterialByName',
method: 'post',
data
})
}
export function isAlongMaterType(data) {
return request({
url: 'api/Materialbase/isAlongMaterType',
@@ -47,4 +55,4 @@ export function getProductSeries() {
})
}
export default { add, edit, del, getMaterOptType, isAlongMaterType, getProductSeries }
export default { add, edit, del, getMaterOptType, isAlongMaterType, getProductSeries, getMaterialByName }

View File

@@ -0,0 +1,160 @@
<template>
<el-dialog
title="物料选择"
append-to-body
:visible.sync="dialogVisible"
destroy-on-close
width="1000px"
@close="close"
@open="open"
>
<el-form
:inline="true"
class="demo-form-inline"
label-position="right"
label-width="80px"
label-suffix=":"
>
<el-form-item label="模糊搜索">
<el-input
v-model="query.search"
clearable
size="mini"
placeholder="请输入物料编码或名称"
@keyup.enter.native="crud.toQuery"
/>
</el-form-item>
<rrOperation/>
</el-form>
<!--表格渲染-->
<el-table
ref="table"
v-loading="crud.loading"
:data="crud.data"
style="width: 100%;"
size="mini"
border
:header-cell-style="{background:'#f5f7fa',color:'#606266'}"
@select="handleSelectionChange"
@select-all="onSelectAll"
@current-change="clickChange"
>
<el-table-column v-if="!isSingle" type="selection" width="55"/>
<el-table-column v-if="isSingle" label="选择" width="55">
<template slot-scope="scope">
<el-radio v-model="tableRadio" :label="scope.row"><i/></el-radio>
</template>
</el-table-column>
<el-table-column prop="material_code" label="物料编码" min-width="150" show-overflow-tooltip/>
<el-table-column prop="material_name" label="物料名称" min-width="200" show-overflow-tooltip/>
<el-table-column prop="unit_name" label="计量单位"/>
</el-table>
<!--分页组件-->
<pagination/>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button>
<el-button type="primary" @click="submit"> </el-button>
</span>
</el-dialog>
</template>
<script>
import crudMaterialbase from '@/views/wms/basedata/master/material/materialbase'
import CRUD, {header, presenter} from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import pagination from '@crud/Pagination'
export default {
name: 'MaterDtl',
components: {rrOperation, pagination},
cruds() {
return CRUD({title: '物料', url: 'api/Materialbase', crudMethod: {...crudMaterialbase}, optShow: {}})
},
mixins: [presenter(), header()],
dicts: ['product_series'],
props: {
dialogShow: {
type: Boolean,
default: false
},
isSingle: {
type: Boolean,
default: true
},
materOptCode: {
type: String,
default: '木箱'
}
},
data() {
return {
dialogVisible: false,
tableRadio: null,
checkrow: null,
rows: []
}
},
watch: {
dialogShow: {
handler(newValue) {
this.dialogVisible = newValue
}
}
},
methods: {
[CRUD.HOOK.beforeRefresh]() {
this.crud.query.box = this.materOptCode
},
clickChange(item) {
this.tableRadio = item
},
seriesFormat(row) {
return this.dict.label.product_series[row.product_series]
},
open() {
},
handleSelectionChange(val, row) {
if (this.isSingle) {
if (val.length > 1) {
this.$refs.table.clearSelection()
this.$refs.table.toggleRowSelection(val.pop())
} else {
this.checkrow = row
}
}
},
onSelectAll() {
this.$refs.table.clearSelection()
},
close() {
this.crud.resetQuery(false)
this.$emit('update:dialogShow', false)
},
submit() {
// 处理单选
if (this.isSingle && this.tableRadio) {
this.$emit('update:dialogShow', false)
this.$emit('handleSetMaterialValue', this.tableRadio)
return
}
this.rows = this.$refs.table.selection
if (this.rows.length <= 0) {
this.$message('请先勾选物料')
return
}
this.crud.resetQuery(false)
this.$emit('update:dialogShow', false)
this.$emit('handleSetMaterialValue', this.rows)
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
::v-deep .el-dialog__body {
padding-top: 0px;
}
</style>

View File

@@ -37,76 +37,114 @@
</el-select>
</el-form-item>
<rrOperation />
<rrOperation/>
</el-form>
</div>
<!--如果想在工具栏加入更多按钮可以使用插槽方式 slot = 'left' or 'right'-->
<crudOperation :permission="permission" />
<crudOperation :permission="permission">
<el-button
slot="right"
class="filter-item"
type="success"
icon="el-icon-printer"
size="mini"
@click="print"
>
打印
</el-button>
</crudOperation>
<!--表单组件-->
<!--<el-dialog
<el-dialog
:close-on-click-modal="false"
:before-close="crud.cancelCU"
:visible.sync="crud.status.cu > 0"
:title="crud.status.title"
width="800px"
>
<el-form ref="form" :model="form" :rules="rules" size="mini" label-width="120px">
<el-form ref="form" :model="form" :rules="rules" size="mini" label-width="130px">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="木箱类型:" prop="box_type">
<el-input v-model="form.box_type" style="width: 200px;" :disabled="crud.status.edit > 0" />
<el-form-item label="物料编码:" prop="material_code">
<!-- <el-input v-model="form.material_code" style="width: 200px;" :disabled="crud.status.edit > 0"/>-->
<el-input
v-model="form.material_code" style="width: 200px;"
:disabled="crud.status.edit > 0"
@click.native="openMaterialDialog"
readonly
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="木箱描述:" prop="box_name">
<el-input v-model="form.box_name" style="width: 200px;" :disabled="crud.status.edit > 0" />
<el-form-item label="物料名称:" prop="material_name">
<el-input v-model="form.material_name" style="width: 200px;" disabled/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="捆扎模版:" prop="lash_num">
<el-input v-model="form.lash_num" style="width: 200px;" />
<el-form-item label="生成木箱号数量:" prop="box_num">
<el-input-number :step="1" :min="1" :max="100" v-model="form.box_num" size="mini"
:controls="false" style="width: 200px"/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="叉车取货宽度:" prop="expend_width">
<el-input-number :precision="2" :step="0.1" :min="0" :max="100" v-model="form.expend_width" size="mini" :controls="false" style="width: 200px" />
<el-form-item label="最大子卷数:" prop="num">
<el-input-number :step="1" :min="1" :max="100" v-model="form.num" size="mini"
:controls="false" style="width: 200px"/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="一次捆扎次数:" prop="lash_num_one">
<el-input-number :precision="0" :step="1" :min="0" :max="9" v-model="form.lash_num_one" size="mini" :controls="false" style="width: 200px" />
<el-form-item label="载具类型:" prop="vehicle_type">
<el-select v-model="form.vehicle_type" placeholder="请选择载具类型" clearable style="width: 200px;">
<el-option
v-for="item in vehicleTypeList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="二次捆扎次数:" prop="lash_num_tow">
<el-input-number :precision="0" :step="1" :min="0" :max="9" v-model="form.lash_num_tow" size="mini" :controls="false" style="width: 200px" />
<el-form-item label="木箱重量:" prop="box_weight">
<el-input-number
:value="form.box_weight === null ? undefined : form.box_weight"
@input="val => form.box_weight = val"
:precision="2"
:step="0.1"
:min="0"
:max="1000"
size="mini"
:controls="false" style="width: 200px;"
clearable
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="是否一次捆扎:" prop="need_lash_one">
<el-radio v-model="form.need_lash_one" label="1" style="width: 79px;" border>是</el-radio>
<el-radio v-model="form.need_lash_one" label="0" style="width: 79px;" border>否</el-radio>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="是否二次捆扎:" prop="need_lash_two">
<el-radio v-model="form.need_lash_two" label="1" style="width: 79px;" border>是</el-radio>
<el-radio v-model="form.need_lash_two" label="0" style="width: 79px;" border>否</el-radio>
<el-form-item label="是否装箱:" prop="is_packing">
<el-radio-group v-model="form.is_packing" size="mini">
<el-radio
v-for="item in packingList"
:key="item.value"
:label="item.value"
>
{{ item.label }}
</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="text" @click="crud.cancelCU">取消</el-button>
<el-button :loading="crud.cu === 2" type="primary" @click="crud.submitCU">确认</el-button>
<el-button type="text" :loading="crud.cu === 2" @click="crud.submitCU">保存</el-button>
<el-button :loading="crud.cu === 2" type="primary" @click="savePrint">保存并打印</el-button>
</div>
</el-dialog>-->
</el-dialog>
<!--表格渲染-->
<el-table
ref="table"
@@ -116,18 +154,21 @@
style="width: 100%;"
@selection-change="crud.selectionChangeHandler"
>
<el-table-column prop="box_no" sortable label="木箱号" :min-width="flexWidth('box_no',crud.data,'木箱号')" />
<el-table-column prop="material_code" label="物料编码" :min-width="flexWidth('material_code',crud.data,'物料编码')" />
<el-table-column prop="material_name" label="物料名称" :min-width="flexWidth('material_name',crud.data,'物料名称')" />
<el-table-column prop="num" label="最大子卷数" :min-width="flexWidth('num',crud.data,'最大子卷数')" />
<el-table-column prop="box_length" label="木箱长度" :min-width="flexWidth('box_length',crud.data,'木箱长度')" />
<el-table-column prop="box_width" label="木箱" :min-width="flexWidth('box_width',crud.data,'木箱度')" />
<el-table-column prop="box_high" label="木箱" :min-width="flexWidth('box_high',crud.data,'木箱度')" />
<el-table-column prop="vehicle_type" label="载具类型" :min-width="flexWidth('vehicle_type',crud.data,'载具类型')" :formatter="formattTwo"/>
<el-table-column prop="is_packing" label="是否装箱" :min-width="flexWidth('is_packing',crud.data,'是否装箱')" :formatter="formatOne" />
<el-table-column prop="box_weight" label="木箱重量" :min-width="flexWidth('box_weight',crud.data,'木箱重量')" />
<el-table-column prop="insert_time" label="创建时间" :min-width="flexWidth('insert_time',crud.data,'创建时间')" />
<!-- <el-table-column
<el-table-column type="selection" width="55"/>
<el-table-column prop="box_no" sortable label="木箱号" :min-width="flexWidth('box_no',crud.data,'木箱号')"/>
<el-table-column prop="material_code" label="物料编码" :min-width="flexWidth('material_code',crud.data,'物料编码')"/>
<el-table-column prop="material_name" label="物料名称" :min-width="flexWidth('material_name',crud.data,'物料名称')"/>
<el-table-column prop="num" label="最大子卷数" :min-width="flexWidth('num',crud.data,'最大子卷数')"/>
<el-table-column prop="box_length" label="木箱" :min-width="flexWidth('box_length',crud.data,'木箱度')"/>
<el-table-column prop="box_width" label="木箱" :min-width="flexWidth('box_width',crud.data,'木箱度')"/>
<el-table-column prop="box_high" label="木箱高度" :min-width="flexWidth('box_high',crud.data,'木箱高度')"/>
<el-table-column prop="vehicle_type" label="载具类型" :min-width="flexWidth('vehicle_type',crud.data,'载具类型')"
:formatter="formattTwo"/>
<el-table-column prop="is_packing" label="是否装箱" :min-width="flexWidth('is_packing',crud.data,'是否装箱')"
:formatter="formatOne"/>
<el-table-column prop="box_weight" label="木箱重量" :min-width="flexWidth('box_weight',crud.data,'木箱重量')"/>
<el-table-column prop="insert_time" label="创建时间" :min-width="flexWidth('insert_time',crud.data,'创建时间')"/>
<el-table-column
v-permission="['admin','sectattr:edit','sectattr:del']"
label="操作"
width="120px"
@@ -140,50 +181,61 @@
:permission="permission"
/>
</template>
</el-table-column>-->
</el-table-column>
</el-table>
<!--分页组件-->
<pagination />
<pagination/>
</div>
<mater-dialog
ref="materDialog"
:dialog-show="dialogMaterialVisible"
is-single
mater-opt-code="木箱"
@handleSetMaterialValue="handleSetMaterialValue"
/>
</div>
</template>
<script>
import crudBoxinfo from '@/views/wms/basedata/st/boxInfo/boxinfo'
import CRUD, { crud, form, header, presenter } from '@crud/crud'
import CRUD, {crud, form, header, presenter} from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation'
import udOperation from '@crud/UD.operation'
import pagination from '@crud/Pagination'
import MaterDialog from '@/views/wms/basedata/st/boxInfo/MaterDialog'
import { getLodop } from '@/assets/js/lodop/LodopFuncs'
const defaultForm = {
box_id: null,
box_no: null,
box_num: 1,
material_code: null,
material_name: null,
num: null,
num: 1,
box_length: null,
box_width: null,
box_high: null,
insert_time: null,
lash_num: null,
vehicle_type: null,
is_packing: null,
is_packing: '0',
box_weight: null
}
export default {
name: 'BoxInfo',
dicts: ['IS_OR_NOT'],
components: { pagination, crudOperation, rrOperation, udOperation },
components: {pagination, crudOperation, rrOperation, udOperation, MaterDialog},
mixins: [presenter(), header(), form(defaultForm), crud()],
cruds() {
return CRUD({
title: '木箱信息',
optShow: { add: false, reset: true },
optShow: {add: true, edit: true, del: true, reset: true},
url: 'api/boxinfo',
idField: 'box_id',
sort: 'box_no,desc',
crudMethod: { ...crudBoxinfo }
crudMethod: {...crudBoxinfo}
})
},
data() {
@@ -195,10 +247,33 @@ export default {
del: ['admin', 'user:del']
},
packingList: [
{ 'label': '是', 'value': '1' },
{ 'label': '否', 'value': '0' }
{'label': '是', 'value': '1'},
{'label': '否', 'value': '0'}
],
vehicleTypeList: [
{'label': '小托盘', 'value': '1'},
{'label': '大托盘', 'value': '2'}
],
dialogMaterialVisible: false,
rules: {
material_code: [
{required: true, message: '木箱规格编码不能为空', trigger: 'blur'}
],
material_name: [
{required: true, message: '木箱规格名称不能为空', trigger: 'blur'}
],
box_num: [
{required: true, message: '生成木箱号数量不能为空', trigger: 'blur'}
],
num: [
{required: true, message: '最大子卷数量不能为空', trigger: 'blur'}
],
vehicle_type: [
{required: true, message: '载具类型不能为空', trigger: 'blur'}
],
is_packing: [
{required: true, message: '是否装箱不能为空', trigger: 'blur'}
]
}
}
},
@@ -207,9 +282,27 @@ export default {
[CRUD.HOOK.beforeRefresh]() {
return true
},
openMaterialDialog() {
if (this.crud.status.edit > 0) return // 如果是编辑状态,则不允许重新选择
this.dialogMaterialVisible = true
},
handleSetMaterialValue(material) {
this.form.material_code = material.material_code
this.form.material_name = material.material_name
this.dialogMaterialVisible = false
},
formatOne(row) {
return this.dict.label.IS_OR_NOT[row.is_packing]
},
savePrint() {
crudBoxinfo.savePrint(this.form).then(() => {
// 这里可以调用打印逻辑,比如 window.print() 或其他打印插件
this.$message.success('保存成功,准备打印...')
}).catch(err => {
this.$message.error('保存失败')
console.error(err)
})
},
formattTwo(row) {
if (row.vehicle_type === '1') {
return '小托盘'
@@ -218,7 +311,58 @@ export default {
if (row.vehicle_type === '2') {
return '大托盘'
}
}
},
print() {
const _selectData = this.$refs.table.selection
if (!_selectData || _selectData.length < 1) {
this.crud.notify('请选择一条记录', CRUD.NOTIFICATION_TYPE.INFO)
return
}
for (let i = 0; i < _selectData.length; i++) {
const code = _selectData[i].box_no
const material_code = item.material_code
const material_name = item.material_name
const LODOP = getLodop()
LODOP.SET_SHOW_MODE('HIDE_DISBUTTIN_SETUP', 1)// 隐藏那些无效按钮
// 打印纸张大小设置https://www.it610.com/article/2094844.html
LODOP.SET_PRINT_PAGESIZE(1, '50mm', '30mm', '')
// LODOP.ADD_PRINT_RECT('0mm', '0mm', '48mm', '28mm', 0, 1)
LODOP.ADD_PRINT_BARCODE('4.3mm', '8.2mm', '40mm', '20mm', '128Auto', code)
// LODOP.PREVIEW()// 预览
LODOP.PRINT()// 打印
this.crud.notify('打印成功', CRUD.NOTIFICATION_TYPE.SUCCESS)
this.crud.toQuery()
}
},
addAndprint() {
const data = this.form
if (!this.form.storagevehicle_type) {
this.crud.notify('载具类型不能为空', CRUD.NOTIFICATION_TYPE.INFO)
return false
}
if (!this.form.num) {
this.crud.notify('数量不能为空', CRUD.NOTIFICATION_TYPE.INFO)
return false
}
crudBoxinfo.add(data).then(res => {
res.forEach((item) => {
const box_no = item.box_no
const material_code = item.material_code
const material_name = item.material_name
const LODOP = getLodop()
LODOP.SET_SHOW_MODE('HIDE_DISBUTTIN_SETUP', 1)// 隐藏那些无效按钮
// 打印纸张大小设置https://www.it610.com/article/2094844.html
LODOP.SET_PRINT_PAGESIZE(1, '50mm', '30mm', '1')
// LODOP.ADD_PRINT_RECT('0mm', '0mm', '50mm', '30mm', 0, 1)
LODOP.ADD_PRINT_BARCODE('4.3mm', '6.2mm', '40mm', '20mm', '128Auto', item)
// LODOP.PREVIEW()// 预览
LODOP.PRINT()// 打印
})
this.crud.status.add = CRUD.STATUS.NORMAL
this.crud.toQuery()
this.crud.notify('操作成功', CRUD.NOTIFICATION_TYPE.SUCCESS)
})
},
}
}
</script>

View File

@@ -0,0 +1,247 @@
<template>
<el-dialog
:visible.sync="dialogVisible"
append-to-body
fullscreen
title="堆叠位详情"
@close="close"
@open="open"
>
<el-card class="box-card" shadow="never">
<el-form ref="form" :inline="true" :model="form" :rules="rules" label-width="180px" size="mini">
<el-form-item label="堆叠位编码">
<el-input v-model="form.stack_code" disabled style="width: 200px;"/>
</el-form-item>
<el-form-item label="堆叠位名称">
<el-input v-model="form.stack_name" disabled style="width: 200px;"/>
</el-form-item>
<el-form-item label="堆叠位区域">
<el-select
disabled
v-model="form.point_status"
size="mini"
class="filter-item"
style="width: 200px;"
>
<el-option
v-for="item in dict.boxinfo_area"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="最大堆叠数">
<el-input v-model="form.max_layer_count" disabled style="width: 200px;"/>
</el-form-item>
<el-form-item label="当前堆叠数">
<el-input v-model="form.current_layer_count" disabled style="width: 200px;"/>
</el-form-item>
<el-form-item label="排">
<el-input v-model="form.x" disabled style="width: 200px;"/>
</el-form-item>
<el-form-item label="列">
<el-input v-model="form.y" disabled style="width: 200px;"/>
</el-form-item>
<el-form-item label="木箱规格">
<el-input
v-model="form.box_spec" style="width: 200px;"
@click.native="openMaterialDialog"
clearable
/>
</el-form-item>
</el-form>
</el-card>
<div class="crud-opts2" style="margin-top: 30px;margin-bottom: 15px">
<span class="role-span">堆叠位层数详情</span>
<span class="crud-opts-right2">
<!--左侧插槽-->
<slot name="left"/>
</span>
</div>
<!--表格渲染-->
<el-table
ref="table"
:data="form.tableData"
:header-cell-style="{background:'#f5f7fa',color:'#606266'}"
:highlight-current-row="true"
border
max-height="300"
style="width: 100%;"
>
<el-table-column label="木箱层数" prop="layer_index"/>
<el-table-column label="木箱号" prop="box_code">
<template scope="scope">
<div v-if="scope.row.editing">
<el-input v-model="scope.row.box_code"/>
</div>
<div v-else>
{{ scope.row.box_code }}
</div>
</template>
</el-table-column>
<el-table-column align="center" label="操作" width="160" fixed="right">
<template scope="scope">
<el-button
v-if="!scope.row.editing"
type="primary"
class="filter-item"
size="mini"
icon="el-icon-edit"
@click="enableEdit(scope.row)"
/>
<el-button
v-if="scope.row.editing"
type="success"
class="filter-item"
size="mini"
icon="el-icon-finished"
@click="editFinish(scope.row)"
/>
</template>
</el-table-column>
</el-table>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="dialogVisible = false"> </el-button>
<el-button type="primary" @click="submit"> </el-button>
</span>
<mater-dialog
:key="materialDialogKey"
ref="materDialog"
:dialog-show="dialogMaterialVisible"
is-single
mater-opt-code="木箱"
@handleSetMaterialValue="handleSetMaterialValue"
/>
</el-dialog>
</template>
<script>
import {crud} from '@crud/crud'
import MaterDialog from './MaterDialog'
import crudBoxstack from './boxstack'
export default {
name: 'LayerViewDialog',
components: {MaterDialog},
dicts: ['IS_OR_NOT', 'boxinfo_area'],
mixins: [crud()],
props: {
dialogShow: {
type: Boolean,
default: false
},
bussConfig: {
type: Object
},
openParam: {
type: Object
}
},
data() {
return {
dialogMaterialVisible: false,
materialDialogKey: 0,
dialogVisible: false,
form: {
stack_id: null,
stack_code: null,
stack_name: null,
point_status: null,
max_layer_count: null,
current_layer_count: null,
box_spec: null,
x: null,
y: null,
tableData: []
},
rules: {}
}
},
watch: {
dialogShow: {
handler(newValue) {
this.dialogVisible = newValue
}
}
},
methods: {
enableEdit(row) {
row.editing = true
},
editFinish(row) {
row.editing = false
const filledBoxNum = this.form.tableData.filter(item => item.box_code).length
this.form.current_layer_count = filledBoxNum
},
submit() {
const tableData = this.form.tableData || []
if (!this.form.box_spec && tableData.some(item => item.box_code)) {
this.$message.error('请填写木箱规格')
return
}
if (this.form.box_spec && tableData.every(item => !item.box_code)) {
this.$message.error('请填写至少一个木箱号')
return
}
crudBoxstack.saveBoxStack(this.form).then(res => {
this.$emit('editChanged')
this.dialogVisible = false
this.crud.notify('保存成功', CRUD.NOTIFICATION_TYPE.SUCCESS)
})
},
openMaterialDialog() {
if (this.crud.status.edit > 0) return // 如果是编辑状态,则不允许重新选择
this.dialogMaterialVisible = true
this.materialDialogKey += 1;
},
handleSetMaterialValue(material) {
this.form.box_spec = material.material_code
this.dialogMaterialVisible = false
},
setForm(row) {
this.dialogVisible = true
crudBoxstack.getBoxLayer(row.stack_id).then(res => {
this.form.tableData = res.map(item => ({
...item,
editing: false
}))
})
this.form.stack_id = row.stack_id
this.form.stack_code = row.stack_code
this.form.stack_name = row.stack_name
this.form.point_status = row.point_status
this.form.x = row.x
this.form.y = row.y
this.form.box_spec = row.box_spec
this.form.max_layer_count = row.max_layer_count
this.form.current_layer_count = row.current_layer_count
},
open() {
},
close() {
this.$emit('editChanged')
}
}
}
</script>
<style>
.crud-opts2 {
padding: 0 0;
display: -webkit-flex;
display: flex;
align-items: center;
}
.crud-opts2 .crud-opts-right2 {
margin-left: auto;
padding: 4px 4px;
}
.input-with-select {
background-color: #fff;
}
</style>

View File

@@ -0,0 +1,161 @@
<template>
<el-dialog
title="物料选择"
append-to-body
:visible.sync="dialogVisible"
destroy-on-close
width="1000px"
@close="close"
@open="open"
>
<el-form
:inline="true"
class="demo-form-inline"
label-position="right"
label-width="80px"
label-suffix=":"
>
<el-form-item label="模糊搜索">
<el-input
v-model="query.search"
clearable
size="mini"
placeholder="请输入物料编码或名称"
@keyup.enter.native="crud.toQuery"
/>
</el-form-item>
<rrOperation/>
</el-form>
<!--表格渲染-->
<el-table
ref="table"
v-loading="crud.loading"
:data="crud.data"
style="width: 100%;"
size="mini"
border
:header-cell-style="{background:'#f5f7fa',color:'#606266'}"
@select="handleSelectionChange"
@select-all="onSelectAll"
@current-change="clickChange"
>
<el-table-column v-if="!isSingle" type="selection" width="55"/>
<el-table-column v-if="isSingle" label="选择" width="55">
<template slot-scope="scope">
<el-radio v-model="tableRadio" :label="scope.row"><i/></el-radio>
</template>
</el-table-column>
<el-table-column prop="material_code" label="物料编码" min-width="150" show-overflow-tooltip/>
<el-table-column prop="material_name" label="物料名称" min-width="200" show-overflow-tooltip/>
<el-table-column prop="unit_name" label="计量单位"/>
</el-table>
<!--分页组件-->
<pagination/>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button>
<el-button type="primary" @click="submit"> </el-button>
</span>
</el-dialog>
</template>
<script>
import crudMaterialbase from '@/views/wms/basedata/master/material/materialbase'
import CRUD, {header, presenter} from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import pagination from '@crud/Pagination'
export default {
name: 'MaterDtl',
components: {rrOperation, pagination},
cruds() {
return CRUD({title: '物料', url: 'api/Materialbase', crudMethod: {...crudMaterialbase}, optShow: {}})
},
mixins: [presenter(), header()],
dicts: ['product_series'],
props: {
dialogShow: {
type: Boolean,
default: false
},
isSingle: {
type: Boolean,
default: true
},
materOptCode: {
type: String,
default: '木箱'
}
},
data() {
return {
dialogVisible: false,
tableRadio: null,
checkrow: null,
rows: []
}
},
watch: {
dialogShow: {
handler(newValue) {
this.dialogVisible = newValue
},
immediate: true
}
},
methods: {
[CRUD.HOOK.beforeRefresh]() {
this.crud.query.box = this.materOptCode
},
clickChange(item) {
this.tableRadio = item
},
seriesFormat(row) {
return this.dict.label.product_series[row.product_series]
},
open() {
},
handleSelectionChange(val, row) {
if (this.isSingle) {
if (val.length > 1) {
this.$refs.table.clearSelection()
this.$refs.table.toggleRowSelection(val.pop())
} else {
this.checkrow = row
}
}
},
onSelectAll() {
this.$refs.table.clearSelection()
},
close() {
this.crud.resetQuery(false)
this.$emit('update:dialogShow', false)
},
submit() {
// 处理单选
if (this.isSingle && this.tableRadio) {
this.$emit('update:dialogShow', false)
this.$emit('handleSetMaterialValue', this.tableRadio)
return
}
this.rows = this.$refs.table.selection
if (this.rows.length <= 0) {
this.$message('请先勾选物料')
return
}
this.crud.resetQuery(false)
this.$emit('update:dialogShow', false)
this.$emit('handleSetMaterialValue', this.rows)
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
::v-deep .el-dialog__body {
padding-top: 0px;
}
</style>

View File

@@ -0,0 +1,42 @@
import request from '@/utils/request'
export function add(data) {
return request({
url: 'api/bstIvtboxstack',
method: 'post',
data
})
}
export function del(ids) {
return request({
url: 'api/bstIvtboxstack',
method: 'delete',
data: ids
})
}
export function edit(data) {
return request({
url: 'api/bstIvtboxstack',
method: 'put',
data
})
}
export function getBoxLayer(id) {
return request({
url: 'api/bstIvtboxstacklayer/getBoxLayer/' + id,
method: 'get',
})
}
export function saveBoxStack(data) {
return request({
url: 'api/bstIvtboxstack/saveBoxStack',
method: 'post',
data
})
}
export default {add, edit, del, getBoxLayer, saveBoxStack}

View File

@@ -0,0 +1,320 @@
<template>
<div class="app-container">
<!--工具栏-->
<div class="head-container">
<div v-if="crud.props.searchToggle">
<!-- 搜索 -->
<el-form
:inline="true"
class="demo-form-inline"
label-position="right"
label-width="90px"
label-suffix=":"
>
<el-form-item label="堆叠位信息">
<el-input
v-model="query.stack_info"
clearable
placeholder="输入堆叠位编码或名称"
style="width: 185px;"
class="filter-item"
@keyup.enter.native="crud.toQuery"
/>
</el-form-item>
<el-form-item label="木箱规格">
<el-input
v-model="query.box_spec"
clearable
placeholder="输入木箱规格"
style="width: 185px;"
class="filter-item"
@keyup.enter.native="crud.toQuery"
/>
</el-form-item>
<el-form-item label="点位区域">
<el-select
v-model="query.point_status"
clearable
filterable
size="mini"
class="filter-item"
style="width: 185px;"
@change="hand"
>
<el-option
v-for="item in dict.boxinfo_area"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="是否启用">
<el-switch
v-model="query.is_used"
active-value="0"
inactive-value="1"
active-color="#C0CCDA"
inactive-color="#409EFF"
@change="hand"
/>
</el-form-item>
<rrOperation :crud="crud"/>
</el-form>
</div>
<!--如果想在工具栏加入更多按钮可以使用插槽方式 slot = 'left' or 'right'-->
<crudOperation :permission="permission"/>
<!--表单组件-->
<el-dialog
:close-on-click-modal="false"
:before-close="crud.cancelCU"
:visible.sync="crud.status.cu > 0"
:title="crud.status.title"
width="500px"
>
<br>
<el-form ref="form" :model="form" :rules="rules" size="mini" label-width="100px">
<el-form-item label="堆叠位编码" prop="stack_code">
<el-input v-model="form.stack_code" style="width: 300px;"/>
</el-form-item>
<el-form-item label="堆叠位名称" prop="stack_name">
<el-input v-model="form.stack_name" style="width: 300px;"/>
</el-form-item>
<el-form-item label="堆叠位区域" prop="point_status">
<el-select
v-model="form.point_status"
clearable
filterable
size="mini"
class="filter-item"
style="width: 300px;"
@change="hand"
>
<el-option
v-for="item in dict.boxinfo_area"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="最大堆叠数" prop="max_layer_count">
<el-input
v-model.number="form.max_layer_count" style="width: 300px;"
oninput="this.value = this.value.replace(/[^0-9]/g, '')"
placeholder="请输入大于等于1的整数"
/>
</el-form-item>
<el-form-item label="当前堆叠数" prop="current_layer_count">
<el-input disabled v-model="form.current_layer_count" style="width: 300px;"/>
</el-form-item>
<el-form-item label="" prop="x">
<el-input
v-model.number="form.x" style="width: 300px;"
oninput="this.value = this.value.replace(/[^0-9]/g, '')"
placeholder="请输入大于等于1的整数"
/>
</el-form-item>
<el-form-item label="" prop="y">
<el-input
v-model.number="form.y" style="width: 300px;"
oninput="this.value = this.value.replace(/[^0-9]/g, '')"
placeholder="请输入大于等于1的整数"
/>
</el-form-item>
<el-form-item label="是否启用" prop="is_used">
<el-switch v-model="form.is_used" active-value="1" inactive-value="0"/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="text" @click="crud.cancelCU">取消</el-button>
<el-button :loading="crud.cu === 2" type="primary" @click="crud.submitCU">确认</el-button>
</div>
</el-dialog>
<!--表格渲染-->
<el-table
ref="table"
v-loading="crud.loading"
:data="crud.data"
size="mini"
:row-style="rowStyle"
style="width: 100%;"
@selection-change="crud.selectionChangeHandler"
>
<el-table-column type="selection" width="55"/>
<el-table-column prop="stack_code" label="堆叠位编码" width="100px">
<template slot-scope="scope">
<el-link type="warning" @click="toView(scope.row)">{{ scope.row.stack_code }}</el-link>
</template>
</el-table-column>
<el-table-column prop="stack_name" label="堆叠位名称" width="140px"/>
<el-table-column prop="point_status" label="区域类型">
<template slot-scope="scope">
{{ dict.label.boxinfo_area[scope.row.point_status] }}
</template>
</el-table-column>
<el-table-column prop="current_layer_count" label="当前堆叠数" width="140px"/>
<el-table-column prop="max_layer_count" label="最大堆叠数" width="100px"/>
<el-table-column prop="box_spec" label="木箱规格" show-overflow-tooltip width="150px"/>
<el-table-column prop="box_spec_name" label="木箱规格名称" show-overflow-tooltip width="200px"/>
<el-table-column prop="x" label="" width="100px"/>
<el-table-column prop="y" label="" width="100px"/>
<el-table-column prop="is_used" label="是否启用">
<template slot-scope="scope">
{{ dict.label.is_used[scope.row.is_used] }}
</template>
</el-table-column>
<el-table-column prop="created_name" label="创建人" min-width="150" show-overflow-tooltip/>
<el-table-column prop="created_time" label="创建时间" min-width="150" show-overflow-tooltip/>
<el-table-column prop="update_name" label="修改人" min-width="150" show-overflow-tooltip/>
<el-table-column prop="update_time" label="修改时间" min-width="150" show-overflow-tooltip/>
<el-table-column v-permission="[]" label="操作" width="120px" align="center" fixed="right">
<template slot-scope="scope">
<udOperation
:data="scope.row"
:permission="permission"
:is-visiable-del="false"
/>
</template>
</el-table-column>
</el-table>
<!--分页组件-->
<pagination/>
</div>
<mater-dialog
:key="materialDialogKey"
ref="materDialog"
:dialog-show="dialogMaterialVisible"
is-single
mater-opt-code="木箱"
@handleSetMaterialValue="handleSetMaterialValue"
/>
<LayerViewDialog ref="boxStackLayerView" @editChanged="crud.toQuery()"/>
</div>
</template>
<script>
import crudBoxStack from './boxstack'
import CRUD, {crud, form, header, presenter} from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation'
import udOperation from '@crud/UD.operation'
import pagination from '@crud/Pagination'
import MaterDialog from './MaterDialog'
import LayerViewDialog from './LayerViewDialog'
const defaultForm = {
stack_id: null,
stack_code: null,
stack_name: null,
current_layer_count: 0,
max_layer_count: 3,
point_status: null,
box_spec: null,
is_used: "1",
x: null,
y: null,
create_id: null,
create_name: null,
create_time: null,
update_id: null,
update_name: null,
update_time: null
}
export default {
name: 'Boxstack',
components: {pagination, crudOperation, rrOperation, udOperation, MaterDialog, LayerViewDialog},
dicts: ['boxinfo_area', 'is_used'],
mixins: [presenter(), header(), form(defaultForm), crud()],
cruds() {
return CRUD({
title: '木箱库',
url: 'api/bstIvtboxstack',
idField: 'stack_id',
sort: 'stack_id,desc',
crudMethod: {...crudBoxStack},
optShow: {
add: true,
edit: true,
del: true,
download: false,
reset: true
}
})
},
data() {
return {
permission: {},
dialogMaterialVisible: false,
materialDialogKey: 0,
rules: {
stack_code: [
{required: true, message: '堆叠位编码不能为空', trigger: 'blur'}
],
stack_name: [
{required: true, message: '堆叠位名称不能为空', trigger: 'blur'}
],
current_layer_count: [
{required: true, message: '当前堆叠数不能为空', trigger: 'blur'}
],
max_layer_count: [
{required: true, message: '最大堆叠数不能为空', trigger: 'blur'}
],
point_status: [
{required: true, message: '区域不能为空', trigger: 'blur'}
],
x: [
{required: true, message: '木箱排不能为空', trigger: 'blur'}
],
y: [
{required: true, message: '木箱列不能为空', trigger: 'blur'}
],
is_used: [
{required: true, message: '是否启用不能为空', trigger: 'blur'}
]
}
}
},
methods: {
// 钩子在获取表格数据之前执行false 则代表不获取数据
[CRUD.HOOK.beforeRefresh]() {
return true
},
toView(row) {
if (row !== null) {
this.$refs.boxStackLayerView.setForm(row)
}
},
openMaterialDialog() {
if (this.crud.status.edit > 0) return // 如果是编辑状态,则不允许重新选择
this.dialogMaterialVisible = true
this.materialDialogKey += 1;
},
handleSetMaterialValue(material) {
this.form.box_spec = material.material_code
this.dialogMaterialVisible = false
},
rowStyle({row, index}) {
let backgroun = {}
if (row.container_name != null && row.update_time != null && row.update_time != undefined) {
let now = new Date()
let before = new Date(row.update_time)
const diff = now.getTime() - before.getTime();
let min = Math.floor(diff / (1000 * 60))
console.log(min)
if (min > 120) {
backgroun.background = 'red';
}
}
return backgroun;
},
hand(value) {
this.crud.toQuery()
}
}
}
</script>
<style scoped>
</style>