feat(wms): 添加管制卷移库记录和管件信息缺失预警功能

新增管制卷移库记录管理模块,支持查询、标记完成、重新移库操作
新增成品入库管件信息为空预警定时任务
新增前端管制卷移库记录页面
子卷定级接口添加处理结果字段获取和保存到数据库
外箱标签打印改为| 为分隔符,适配公司名称中带,情况
This commit is contained in:
yangyufu
2026-08-10 13:58:20 +08:00
parent ff31082748
commit e3d169901b
23 changed files with 1904 additions and 58 deletions

View File

@@ -160,6 +160,9 @@ public class PdmBiSlittingproductionplan implements Serializable {
/** 子卷等级*/
private String level;
/** 子卷等级描述*/
private String appear_result;
/** 子卷重量 */
private String weight;

View File

@@ -0,0 +1,141 @@
package org.nl.b_lms.sch.tasks.frp_paper.auto;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.nl.b_lms.sch.tasks.frp_paper.service.IFrpOrPaperEmptyService;
import org.nl.modules.common.exception.BadRequestException;
import org.nl.modules.wql.util.SpringContextHolder;
import org.nl.system.service.param.impl.SysParamServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author ManMan.Yang
* @version V1.1
* @date 2026/7/17
* @description 新成品入库查询报表管件FRP/纸管)信息为空预警任务
*/
@Slf4j
@Component
public class AutoFrpOrPaperEmptyAlarmTask {
private static final Integer time_out = 120000;
@Autowired
private IFrpOrPaperEmptyService frpOrPaperEmptyService;
public void run() {
try {
List<Map<String,Object>> alarmEmptyData = frpOrPaperEmptyService.queryFrpOrPaperEmptyData();
//判断是否为空
if(ObjectUtil.isEmpty(alarmEmptyData)){
log.info("成品入库关键信息预警数据为空");
return;
}
//构造预警信息请求体
alarmEmptyData.forEach(alarmMap ->{
String sales_owner = alarmMap.get("sales_owner")+"";
if(StrUtil.isNotBlank(sales_owner)){
String[] split = sales_owner.split("\\|");
if(split.length == 2){
String userNum = split[1];
if(StrUtil.isNotBlank(sales_owner) && !"null".equals(userNum)){
alarmMap.put("userNum",userNum);
}else{
alarmMap.put("userNum","");
}
}else{
alarmMap.put("userNum","");
}
}else{
alarmMap.put("userNum","");
}
});
//发送预警信息到飞书对应人员
this.sendFeiShuAlarmMsg(alarmEmptyData);
} catch (Exception ex) {
log.error(ex.getMessage());
}
}
/**
* @description: 发送预警信息到飞书
* @author ManMan.Yang
* @date: 2026/7/20 16:23
**/
public void sendFeiShuAlarmMsg(List<Map<String,Object>> buildMsgBody){
if(ObjectUtil.isEmpty(buildMsgBody)){
return;
}
//构造一个年月日 // "2026-07-18"
String alarmDate = DateUtil.today();
// 年月日时分秒 // "2026-07-18 13:16:00"
String alarmPushDateTime = DateUtil.now();
JSONArray userList = new JSONArray();
String userListStr = SpringContextHolder.getBean(SysParamServiceImpl.class).findByCode("FRPORPAPER_FEISHU").getValue();
if(StrUtil.isNotBlank(userListStr)){
String[] split = userListStr.split(",");
for (String s : split) {
JSONObject jo = new JSONObject();
jo.put("User", s);
userList.add(jo);
}
}
//循环处理发送所有的预警信息
buildMsgBody.forEach(stringObjectMap -> {
JSONObject root = new JSONObject();
// 创建 card 对象
JSONObject cardData = new JSONObject();
String userNum = stringObjectMap.get("userNum") + "";
if(StrUtil.isNotBlank(userNum)){
JSONObject jo = new JSONObject();
jo.put("User", userNum);
userList.add(jo);
}else{
cardData.put("TL_ALARM_EMPTY", "成品入库关键信息缺失预警客户负责人员获取失败,请确认!");
}
// 添加 Code 属性
root.put("Code", "AAqWkiZZVCeKH");
root.put("UserList", userList);
cardData.put("TL_ALARM_PUSHTIME", alarmPushDateTime);
cardData.put("TL_ALARM_SON", stringObjectMap.get("sale_order_name"));
cardData.put("TL_ALARM_CN", stringObjectMap.get("customer_description"));
cardData.put("TL_ALARM_NUM", stringObjectMap.get("num"));
cardData.put("TL_ALARM_DATE", alarmDate);
cardData.put("TL_ALARM_CC", stringObjectMap.get("customer_name"));
root.put("card", cardData);
//发送飞书
this.sendFeiShuCardInfo(root);
});
}
public void sendFeiShuCardInfo(JSONObject root){
String url = SpringContextHolder.getBean(SysParamServiceImpl.class).findByCode("FEISHU_URL").getValue();
String api = "/FeiShuNoticesWebApi/SendCard";
url = url + api;
try {
String resultMsg = HttpRequest.post(url)
.body(String.valueOf(root))
.timeout(time_out)//超时时间,毫秒
.execute().body();
JSONObject result = JSONObject.parseObject(resultMsg);
log.info("成品入库关键信息预警推送接口返回参数为:-----------------" + result.toString());
String RTYPE = result.getString("RTYPE");
if ("E".equals(RTYPE)) {
throw new BadRequestException(result.getString("RTMSG"));
}
} catch (Exception e) {
throw new BadRequestException("飞书提示错误:" + e.getMessage());
}
}
}

View File

@@ -0,0 +1,16 @@
package org.nl.b_lms.sch.tasks.frp_paper.mapper;
import java.util.List;
import java.util.Map;
/**
* @author ManMan.Yang
* @version V1.1
* @date 2026/7/17
* @description TODO
*/
public interface FrpOrPaperEmptyMapper {
List<Map<String, Object>> selectFrpOrPaperEmptyData();
}

View File

@@ -0,0 +1,112 @@
<?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.sch.tasks.frp_paper.mapper.FrpOrPaperEmptyMapper">
<select id="selectFrpOrPaperEmptyData" resultType="java.util.Map">
select
m.sale_order_name,
m.customer_name ,
m.customer_description,
m.sales_owner,
count(1) num
from (
select
dis.pcsn,
sub.sap_pcsn,
sub.customer_name,
cust.sales_owner,
sub.customer_description,
sub.sale_order_name,
case
when plan.paper_tube_or_FRP = '1' then '纸管'
when plan.paper_tube_or_FRP = '2' then 'FRP管'
end as paper_type,
case
when plan.paper_tube_or_FRP = '1' then plan.paper_tube_material
when plan.paper_tube_or_FRP = '2' then plan.FRP_material
end as paper_code,
case
when plan.paper_tube_or_FRP = '1' then plan.paper_tube_description
when plan.paper_tube_or_FRP = '2' then plan.FRP_description
end as paper_name
from
(
select
MIN(a.iostorinvdis_id) as iostorinvdis_id
from
st_ivt_iostorinvdis a
left join st_ivt_iostorinv b on
a.iostorinv_id = b.iostorinv_id
where
b.io_type = '0'
and b.bill_type = '0001'
and b.bill_status = '99'
group by
pcsn
union
select
MIN(a.iostorinvdis_id) as iostorinvdis_id
from
st_ivt_iostorinvdis a
left join st_ivt_iostorinv b on
a.iostorinv_id = b.iostorinv_id
where
b.io_type = '0'
and b.bill_type = '0007'
and b.bill_status = '99'
group by
pcsn
) c
left join st_ivt_iostorinvdis dis on
dis.iostorinvdis_id = c.iostorinvdis_id
left join st_ivt_iostorinv mst on
mst.iostorinv_id = dis.iostorinv_id
inner join pdm_bi_subpackagerelationrecord sub
on
sub.container_name = dis.pcsn
and sub.package_box_sn = dis.box_no
and sub.bill_id = dis.iostorinv_id
left join md_cs_customerbase cust on
cust.cust_code = sub.customer_name
left join (
select
container_name,
MAX(paper_tube_or_FRP) as paper_tube_or_FRP,
MAX(paper_tube_material) as paper_tube_material
,
MAX(paper_tube_description) as paper_tube_description,
MAX(paper_tube_model) as paper_tube_model
,
MAX(FRP_material) as FRP_material,
MAX(parent_container_name) as parent_container_name
,
MAX(restruct_container_name) as restruct_container_name,
MAX(FRP_description) as FRP_description
,
MAX(FRP_model) as FRP_model,
MAX(foil_container_name) as foil_container_name
from
pdm_bi_slittingproductionplan plan1
where
plan1.is_delete = '0'
group by
container_name
) plan
on
plan.container_name = sub.container_name
left join md_me_materialbase mb on
mb.material_code = sub.box_type
where
mst.io_type = '0'
and mst.is_delete = '0'
and mst.bill_status = '99'
and IFNULL(sub.sub_type, '') = ''
) m
inner join st_ivt_structivt sis on m.pcsn = sis.pcsn
where m.paper_code is null or m.paper_code = ''
group by m.sale_order_name,
m.customer_name ,
m.sales_owner,
m.customer_description
</select>
</mapper>

View File

@@ -0,0 +1,16 @@
package org.nl.b_lms.sch.tasks.frp_paper.service;
import java.util.List;
import java.util.Map;
/**
* @author ManMan.Yang
* @version V1.1
* @date 2026/7/17
* @description TODO
*/
public interface IFrpOrPaperEmptyService {
List<Map<String, Object>> queryFrpOrPaperEmptyData();
}

View File

@@ -0,0 +1,30 @@
package org.nl.b_lms.sch.tasks.frp_paper.service.impl;
import org.nl.b_lms.sch.tasks.frp_paper.mapper.FrpOrPaperEmptyMapper;
import org.nl.b_lms.sch.tasks.frp_paper.service.IFrpOrPaperEmptyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* @author ManMan.Yang
* @version V1.1
* @date 2026/7/17
* @description TODO
*/
@Service
public class FrpOrPaperEmptyServiceImpl implements IFrpOrPaperEmptyService {
@Autowired
private FrpOrPaperEmptyMapper frpOrPaperEmptyMapper;
@Override
public List<Map<String, Object>> queryFrpOrPaperEmptyData() {
return frpOrPaperEmptyMapper.selectFrpOrPaperEmptyData();
}
}

View File

@@ -58,6 +58,7 @@ import org.nl.wms.sch.manage.AbstractAcsTask;
import org.nl.wms.sch.tasks.CoolCutTask;
import org.nl.wms.st.inbill.service.CheckOutBillService;
import org.nl.wms.st.instor.service.impl.ProductScrapServiceImpl;
import org.nl.wms.st.levelchange.service.impl.StIvtLevelchangedtlServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -67,6 +68,7 @@ import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
@Service
@@ -2134,7 +2136,7 @@ public class MesToLmsServiceImpl implements MesToLmsService {
String ContainerName = param.getString("ContainerName");
String Level = param.getString("Level");
String AppearResult = param.getString("AppearResult");
try {
if (StrUtil.isEmpty(ContainerName)) {
throw new BadRequestException("子卷号不能为空!");
@@ -2143,13 +2145,28 @@ public class MesToLmsServiceImpl implements MesToLmsService {
throw new BadRequestException("子卷等级不能为空!");
}
if (StrUtil.isEmpty(AppearResult)) {
throw new BadRequestException("子卷处理结果不能为空!");
}
PdmBiSlittingproductionplan plan = slittingproductionplanService.getOne(new LambdaQueryWrapper<PdmBiSlittingproductionplan>().eq(PdmBiSlittingproductionplan::getContainer_name, ContainerName)
.eq(PdmBiSlittingproductionplan::getIs_delete, "0"));
if (ObjectUtil.isEmpty(plan)) {
throw new BadRequestException("未查询到对应的分切计划!");
}
String old_level = plan.getLevel();
String old_appearResult = plan.getAppear_result();
plan.setLevel(Level);
plan.setAppear_result(AppearResult);
slittingproductionplanService.update(plan);
//异步调用其他代码,不阻塞主线程返回
CompletableFuture.runAsync(() -> {
try {
SpringContextHolder.getBean(StIvtLevelchangedtlServiceImpl.class).ChangeLevelAndMoveStep(ContainerName,Level,old_level,AppearResult,old_appearResult);
} catch (Exception e) {
log.error("异步处理失败", e);
//处理异步任务事变, 记录当前异常任务
}
});
resultParam.put("RTYPE", "S");
resultParam.put("Code", "0");
resultParam.put("RTMSG", "操作成功!");
@@ -2158,8 +2175,6 @@ public class MesToLmsServiceImpl implements MesToLmsService {
resultParam.put("Code", "1");
resultParam.put("RTMSG", "操作失败!" + e.getMessage());
}
return resultParam;
}

View File

@@ -134,33 +134,33 @@ public class PrintServiceImpl implements PrintService {
BufferedWriter bw = new BufferedWriter(write);
bw.write("bz_print_no,package_box_sn1,package_box_sn2,sale_order_name,product_description,product_name,width,pcsn,date_of_FG_inbound,box_weight,date_of_production,quanlity_in_box,quality_guaran_period,nspector,storage_conditions,weight,customer_name,customer_description,thickness,mass_per_unit_area,length,box_type,sap_pcsn,box_length,box_width,box_high,material_type,joint_type\n");
bw.write(bz_print_no + ","
+ package_box_sn1 + ","
+ package_box_sn2 + ","
+ sale_order_name + ","
+ product_description + ","
+ product_name + ","
+ width + ","
+ pcsn + ","
+ date_of_FG_inbound + ","
+ box_weight + "KG,"
+ date_of_production + ","
+ quanlity_in_box + ","
+ quality_guaran_period + ","
+ nspector + ","
+ storage_conditions + ","
+ NumberUtil.round(weight, 2).toString() + "KG,"
+ box_jo.getString("customer_name") + ","
+ box_jo.getString("customer_description") + ","
+ box_jo.getString("thickness") + ","
+ box_jo.getString("mass_per_unit_area") + ","
+ NumberUtil.round(box_jo.getString("length"), 2) + ","
+ box_jo.getString("box_type") + ","
+ box_jo.getString("sap_pcsn") + ","
+ box_jo.getString("box_length") + ","
+ box_jo.getString("box_width") + ","
+ box_jo.getString("box_high") + ","
+ box_jo.getString("material_type") + ","
bw.write(bz_print_no + "|"
+ package_box_sn1 + "|"
+ package_box_sn2 + "|"
+ sale_order_name + "|"
+ product_description + "|"
+ product_name + "|"
+ width + "|"
+ pcsn + "|"
+ date_of_FG_inbound + "|"
+ box_weight + "KG|"
+ date_of_production + "|"
+ quanlity_in_box + "|"
+ quality_guaran_period + "|"
+ nspector + "|"
+ storage_conditions + "|"
+ NumberUtil.round(weight, 2).toString() + "KG|"
+ box_jo.getString("customer_name") + "|"
+ box_jo.getString("customer_description") + "|"
+ box_jo.getString("thickness") + "|"
+ box_jo.getString("mass_per_unit_area") + "|"
+ NumberUtil.round(box_jo.getString("length"), 2) + "|"
+ box_jo.getString("box_type") + "|"
+ box_jo.getString("sap_pcsn") + "|"
+ box_jo.getString("box_length") + "|"
+ box_jo.getString("box_width") + "|"
+ box_jo.getString("box_high") + "|"
+ box_jo.getString("material_type") + "|"
+ NumberUtil.round(box_jo.getString("joint_type"),2) + "\n"
);

View File

@@ -27,6 +27,8 @@ import org.nl.wms.ext.acs.service.WmsToAcsService;
import org.nl.wms.ext.acs.service.impl.AcsToWmsServiceImpl;
import org.nl.wms.ext.acs.service.impl.WmsToAcsServiceImpl;
import org.nl.wms.ext.mes.service.LmsToMesService;
import org.nl.b_lms.pdm.bi.slittingproductionplan.service.IPdmBiSlittingproductionplanService;
import org.nl.b_lms.pdm.bi.slittingproductionplan.service.dao.PdmBiSlittingproductionplan;
import org.nl.wms.pda.st.service.ProductInstorService;
import org.nl.wms.sch.tasks.CutConveyorTask;
import org.nl.wms.st.inbill.service.RawAssistIStorService;
@@ -68,6 +70,10 @@ public class ProductInstorServiceImpl implements ProductInstorService {
private final LmsToMesService lmsToMesService;
private final IPdmBiSlittingproductionplanService pdmBiSlittingproductionplanService;
@Override
public JSONObject boxQuery(JSONObject whereJson) {
String box_no = whereJson.getString("box_no");
@@ -120,7 +126,7 @@ public class ProductInstorServiceImpl implements ProductInstorService {
String material_code = whereJson.getString("material_code");
String point_code = whereJson.getString("point_code");
String is_virtual = whereJson.getString("is_virtual");
String sect_id = whereJson.getString("sect_id");
ArrayList<HashMap> box_rows = (ArrayList<HashMap>) whereJson.get("box_jo");
HashMap<String, String> map = new HashMap<>();
@@ -128,7 +134,37 @@ public class ProductInstorServiceImpl implements ProductInstorService {
String currentUserId = SecurityUtils.getCurrentUserId();
String nickName = SecurityUtils.getCurrentNickName();
//如果是 生产入库 需要校验管制卷级别和对应入库
if("2".equals(option)){
// 循环box_rows里面的数据
for (int i = 0; i < box_rows.size(); i++) {
HashMap box_row = box_rows.get(i);
String containerName = String.valueOf(box_row.get("container_name"));
// 根据卷号查找分切计划里面卷的级别和卷的结果描述
PdmBiSlittingproductionplan plan = pdmBiSlittingproductionplanService.getByContainerName(containerName);
if (ObjectUtil.isEmpty(plan)) {
throw new BadRequestException("子卷" + containerName + "未查询到分切计划信息!");
}
String level = plan.getLevel();
String appearResult = plan.getAppear_result();
//1、子卷级别为A+、A、A-level为1、2、3LMS手持只能入虚拟库或立体库
if ("1".equals(level) || "2".equals(level) || "3".equals(level)) {
if ("1".equals(is_virtual) && !"1586913215886004224".equals(sect_id)) {
throw new BadRequestException("子卷" + containerName + "级别为A+/A/A-,只能入虚拟库或立体库!");
}
}
//2、子卷级别为管制level为6且处理结果为入不良品区可入成品库且LMS手持只能入不良品库区
if ("6".equals(level) && "入不良品区".equals(appearResult)) {
if ("1".equals(is_virtual) && !"1702508256146100224".equals(sect_id)) {
throw new BadRequestException("子卷" + containerName + "为管制卷且需入不良品区,只能入不良品区!");
}
}
//3、子卷级别为管制level为6处理结果为其他的无法装箱无法入成品库
if ("6".equals(level) && !"入不良品区".equals(appearResult)) {
throw new BadRequestException("子卷" + containerName + "为管制卷且处理结果为其他,不能入库!");
}
}
}
//如果是入虚拟库直接入库并确认,如果是入成品库则生成入库单,生成一个二楼去一楼的任务
JSONObject mst_jo = new JSONObject();
mst_jo.put("tableData", box_rows);

View File

@@ -30,6 +30,12 @@ public interface HandMoveStorService {
*/
void insertDtl(Map whereJson);
/**
* 管制卷移库新增出库单
*
* @param whereJson /
*/
String insertGzMove(Map whereJson);
/**
* 新增出库单2
*

View File

@@ -293,6 +293,53 @@ public class HandMoveStorServiceImpl implements HandMoveStorService {
wo_mst.insert(map);
}
}
/**
* @description: 管制卷移库特殊处理
* @author ManMan.Yang
* @date: 2026/7/30 16:07
**/
@Transactional(rollbackFor = Exception.class)
public String insertGzMove(Map map) {
if (ObjectUtil.isNotEmpty(map.get("tableData"))) {
//主表
WQLObject wo_mst = WQLObject.getWQLObject("ST_IVT_MoveInv");
ArrayList<Map> rows = (ArrayList<Map>) map.get("tableData");
JSONArray arrayTwo = MapUtil.get(map, "tableData", JSONArray.class);
map.remove("tableData");
String currentUserId = "1626577629308999999";
String nickName = "管制卷移库用户";
String now = DateUtil.now();
String moveinv_id = IdUtil.getLongId() + "";
String bill_code = CodeUtil.getNewCode("MOVE_CODE");
String biz_date = (String) map.get("biz_date");
biz_date = biz_date.substring(0, 10);
map.put("moveinv_id", moveinv_id);
map.put("bill_code", bill_code);
map.put("buss_type", "");
map.put("create_mode", "01");
map.put("input_optid", currentUserId + "");
map.put("input_optname", nickName);
map.put("input_time", now);
map.put("update_optid", currentUserId + "");
map.put("update_optname", nickName);
map.put("update_time", now);
map.put("is_delete", "0");
map.put("is_upload", "0");
map.put("biz_date", biz_date);
Long deptId = SecurityUtils.getDeptId();
map.put("sysdeptid", deptId);
map.put("syscompanyid", deptId);
JSONObject jo_mst = JSONObject.parseObject(JSON.toJSONString(map));
//调用明细处理方法 -- 如果是二期移库则调用
JSONObject ret = this.insertDtlByRows(jo_mst, rows);
map.put("detail_count", ret.getString("detail_count"));
map.put("total_qty", ret.getString("total_qty"));
wo_mst.insert(map);
return bill_code;
}
return "";
}
@Transactional(rollbackFor = Exception.class)
public Map roadInsertDtl(Map map) {

View File

@@ -171,6 +171,9 @@
struct.sect_id AS turnout_sect_id,
struct.sect_name AS turnout_sect_name,
struct.sect_code AS turnout_sect_code,
struct.stor_id AS turnout_stor_id,
struct.stor_code AS turnout_stor_code,
struct.stor_name AS turnout_stor_name,
struct.storagevehicle_id,
struct.storagevehicle_code,
mu.unit_name AS qty_unit_name,

View File

@@ -0,0 +1,88 @@
package org.nl.wms.st.levelchange.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;
/**
* 管制卷移库记录表 Entity
*
* @author Auto Generated
* @date 2026/7/23
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("st_ivt_levelchangedtl")
public class StIvtLevelchangedtl implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/** 子卷号 */
private String container_name;
/** 创建时间 */
private String create_time;
/** 创建人姓名 */
private String create_optname;
/** 状态 0 未完成 1 已完成 9 移库异常 */
private String status;
/** 修改人姓名 */
private String update_optname;
/** 修改时间 */
private String update_time;
/** 是否删除 0 否 1 是 */
private String is_delete;
/** 新级别 */
private String new_level;
/** 旧级别 */
private String old_level;
/** 新处理结果 */
private String new_result;
/** 旧处理结果 */
private String old_result;
/** 移库结果 */
private String result_message;
/** 移库单据号 */
private String move_bill_code;
/**
* 装配管制卷移库记录对象
*/
public static StIvtLevelchangedtl build(String containerName, String status, String newLevel,
String oldLevel, String newResult, String oldResult,
String resultMessage, String moveBillCode, String createOptname) {
StIvtLevelchangedtl entity = new StIvtLevelchangedtl();
entity.setContainer_name(containerName);
entity.setStatus(status);
entity.setNew_level(newLevel);
entity.setOld_level(oldLevel);
entity.setNew_result(newResult);
entity.setOld_result(oldResult);
entity.setResult_message(resultMessage);
entity.setMove_bill_code(moveBillCode);
entity.setCreate_optname(createOptname);
String now = cn.hutool.core.date.DateUtil.now();
entity.setCreate_time(now);
entity.setIs_delete("0");
return entity;
}
}

View File

@@ -0,0 +1,42 @@
package org.nl.wms.st.levelchange.dao.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import org.nl.wms.st.levelchange.dao.StIvtLevelchangedtl;
import java.util.List;
import java.util.Map;
/**
* 管制卷移库记录表 Mapper
*
* @author Auto Generated
* @date 2026/7/23
*/
public interface StIvtLevelchangedtlMapper extends BaseMapper<StIvtLevelchangedtl> {
List<Map<String, Object>> selectPackageInfoByContainerName(String containerName);
List<Map<String, Object>> selectStructivtsByContainerName(String containerName);
Integer countLevel6ByContainerNames(@Param("containerNames") List<String> containerNames);
/**
* 根据箱号模糊查询不良品库库存(含货位、物料、包装关系等关联信息)
*/
List<Map<String, Object>> selectHandMoveStorIvtByBoxNo(@Param("packageBoxSn") String packageBoxSn);
/**
* 查询可用货位属性
*/
List<Map<String, Object>> selectStructAttr(@Param("storId") String storId,
@Param("sectId") String sectId,
@Param("lockType") String lockType,
@Param("layerNum") String layerNum,
@Param("isUsed") String isUsed);
/**
* 根据extId查询仓库信息
*/
Map<String, Object> selectStorByExtId(@Param("extId") String extId);
}

View File

@@ -0,0 +1,97 @@
<?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.wms.st.levelchange.dao.mapper.StIvtLevelchangedtlMapper">
<select id="selectPackageInfoByContainerName" resultType="java.util.Map">
SELECT *
FROM pdm_bi_subpackagerelation
WHERE package_box_sn = (
SELECT package_box_sn
FROM pdm_bi_subpackagerelation
WHERE container_name = #{containerName}
)
</select>
<select id="selectStructivtsByContainerName" resultType="java.util.Map">
SELECT *
FROM st_ivt_structivt
WHERE pcsn = #{pcsn}
</select>
<select id="countLevel6ByContainerNames" resultType="java.lang.Integer">
SELECT COUNT(*)
FROM pdm_bi_slittingproductionplan
WHERE container_name IN
<foreach collection="containerNames" item="name" open="(" separator="," close=")">
#{name}
</foreach>
AND level = '6'
</select>
<select id="selectHandMoveStorIvtByBoxNo" resultType="java.util.Map">
SELECT
ivt2.stockrecord_id,
ivt2.material_id,
ivt2.pcsn,
ivt2.quality_scode,
ivt2.qty_unit_id,
ivt2.ivt_qty AS qty,
mb.material_code,
mb.material_name,
struct.struct_id AS turnout_struct_id,
struct.struct_code AS turnout_struct_code,
struct.struct_name AS turnout_struct_name,
struct.sect_id AS turnout_sect_id,
struct.sect_name AS turnout_sect_name,
struct.sect_code AS turnout_sect_code,
struct.stor_id AS turnout_stor_id,
struct.stor_code AS turnout_stor_code,
struct.stor_name AS turnout_stor_name,
struct.storagevehicle_id,
struct.storagevehicle_code,
mu.unit_name AS qty_unit_name,
sub.sale_order_name,
sub.customer_name,
sub.customer_description,
sub.sap_pcsn
FROM
st_ivt_structattr struct
INNER JOIN st_ivt_structivt ivt2 ON struct.struct_id = ivt2.struct_id
LEFT JOIN md_me_materialbase mb ON mb.material_id = ivt2.material_id
LEFT JOIN md_pb_measureunit mu ON mu.measure_unit_id = ivt2.qty_unit_id
LEFT JOIN pdm_bi_subpackagerelation sub ON sub.container_name = ivt2.pcsn
AND sub.package_box_sn = struct.storagevehicle_code
WHERE
struct.lock_type = '1'
AND sub.package_box_sn LIKE #{packageBoxSn}
</select>
<select id="selectStructAttr" resultType="java.util.Map">
SELECT
struct.*
FROM
st_ivt_structattr struct
WHERE
struct.is_delete = '0'
AND struct.storagevehicle_code is null
AND struct.stor_id = #{storId}
AND struct.sect_id = #{sectId}
AND struct.lock_type = #{lockType}
AND struct.layer_num = #{layerNum}
AND struct.is_used = #{isUsed}
ORDER BY struct.struct_code ASC
</select>
<select id="selectStorByExtId" resultType="java.util.Map">
SELECT
stor_id,
stor_code,
stor_name
FROM
st_ivt_bsrealstorattr
WHERE
is_delete = '0'
AND ext_id = #{extId}
</select>
</mapper>

View File

@@ -0,0 +1,108 @@
package org.nl.wms.st.levelchange.rest;
import java.util.Map;
import java.util.Set;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.nl.common.TableDataInfo;
import org.nl.common.domain.query.PageQuery;
import org.nl.modules.logging.annotation.Log;
import org.nl.wms.st.levelchange.dao.StIvtLevelchangedtl;
import org.nl.wms.st.levelchange.service.IStIvtLevelchangedtlService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
/**
* 管制卷移库记录表(StIvtLevelchangedtl)控制层
*
* @author Auto Generated
* @date 2026/7/23
*/
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/levelchangedtl")
@Slf4j
public class StIvtLevelchangedtlController {
private final IStIvtLevelchangedtlService levelchangedtlService;
/**
* 分页查询
*
* @param whereJson 查询条件
* @param page 分页参数
*/
@GetMapping
@Log("查询管制卷移库记录")
public ResponseEntity<Object> query(@RequestParam Map whereJson, PageQuery page) {
return new ResponseEntity<>(TableDataInfo.build(levelchangedtlService.queryAll(whereJson, page)), HttpStatus.OK);
}
/**
* 新增数据
*
* @param entity 实体对象
* @return 新增结果
*/
@PostMapping
@Log("新增管制卷移库记录")
public ResponseEntity<Object> create(StIvtLevelchangedtl entity) {
levelchangedtlService.create(entity);
return new ResponseEntity<>(HttpStatus.OK);
}
/**
* 修改数据
*
* @param entity 实体对象
* @return 修改结果
*/
@PutMapping
@Log("修改管制卷移库记录")
public ResponseEntity<Object> update(StIvtLevelchangedtl entity) {
levelchangedtlService.update(entity);
return new ResponseEntity<>(HttpStatus.OK);
}
/**
* 删除数据
*
* @param ids 多个主键Id
* @return 删除结果
*/
@DeleteMapping
@Log("删除管制卷移库记录")
public ResponseEntity<Object> delete(@RequestBody Set<String> ids) {
levelchangedtlService.deleteAll(ids);
return new ResponseEntity<>(HttpStatus.OK);
}
/**
* 重新移库
*
* @param entity 实体对象(包含container_name、new_level、old_level)
* @return 操作结果
*/
@PostMapping("/retryMove")
@Log("重新执行管制卷移库")
public ResponseEntity<Object> retryMove(@RequestBody StIvtLevelchangedtl entity) {
levelchangedtlService.retryMove(entity);
return new ResponseEntity<>(HttpStatus.OK);
}
/**
* 标记已完成
*
* @param id 记录主键
* @return 操作结果
*/
@PostMapping("/markComplete")
@Log("标记管制卷移库已完成")
public ResponseEntity<Object> markComplete(@RequestBody StIvtLevelchangedtl entity) {
levelchangedtlService.markComplete(entity.getId());
return new ResponseEntity<>(HttpStatus.OK);
}
}

View File

@@ -0,0 +1,49 @@
package org.nl.wms.st.levelchange.service;
import org.nl.b_lms.pdm.bi.slittingproductionplan.service.dao.PdmBiSlittingproductionplan;
import org.nl.common.domain.query.PageQuery;
import org.nl.wms.st.levelchange.dao.StIvtLevelchangedtl;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 管制卷移库记录表 Service 接口
*
* @author Auto Generated
* @date 2026/7/23
*/
public interface IStIvtLevelchangedtlService {
/**
* 分页查询
*/
List<StIvtLevelchangedtl> queryAll(Map whereJson, PageQuery page);
/**
* 新增
*/
void create(StIvtLevelchangedtl entity);
/**
* 修改
*/
void update(StIvtLevelchangedtl entity);
/**
* 批量删除
*/
void deleteAll(Set<String> ids);
/**
* 重新移库
*/
void retryMove(StIvtLevelchangedtl entity);
/**
* 标记已完成
*/
void markComplete(Long id);
}

View File

@@ -0,0 +1,308 @@
package org.nl.wms.st.levelchange.service.impl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.nl.common.domain.query.PageQuery;
import org.nl.common.utils.SecurityUtils;
import org.nl.modules.common.exception.BadRequestException;
import org.nl.modules.wql.core.bean.WQLObject;
import org.nl.wms.st.instor.service.HandMoveStorService;
import org.nl.wms.st.levelchange.dao.StIvtLevelchangedtl;
import org.nl.wms.st.levelchange.service.IStIvtLevelchangedtlService;
import org.nl.wms.st.levelchange.dao.mapper.StIvtLevelchangedtlMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
/**
* 管制卷移库记录表 Service 实现
*
* @author Auto Generated
* @date 2026/7/23
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class StIvtLevelchangedtlServiceImpl implements IStIvtLevelchangedtlService {
private final StIvtLevelchangedtlMapper levelchangedtlMapper;
private final HandMoveStorService handMoveStorService;
@Resource
private StIvtLevelchangedtlServiceImpl self;
@Override
public List<StIvtLevelchangedtl> queryAll(Map whereJson, PageQuery page) {
LambdaQueryWrapper<StIvtLevelchangedtl> wrapper = new LambdaQueryWrapper<>();
// 根据 whereJson 动态添加查询条件,可按需扩展
wrapper.eq(StIvtLevelchangedtl::getIs_delete, "0");
wrapper.orderByDesc(StIvtLevelchangedtl::getCreate_time);
IPage<StIvtLevelchangedtl> iPage = new Page<>(page.getPage(), page.getSize());
levelchangedtlMapper.selectPage(iPage, wrapper);
return iPage.getRecords();
}
@Override
@Transactional(rollbackFor = Exception.class)
public void create(StIvtLevelchangedtl entity) {
String now = DateUtil.now();
entity.setCreate_time(now);
entity.setUpdate_time(now);
entity.setIs_delete("0");
levelchangedtlMapper.insert(entity);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void update(StIvtLevelchangedtl entity) {
StIvtLevelchangedtl exist = levelchangedtlMapper.selectById(entity.getId());
if (ObjectUtil.isEmpty(exist)) {
throw new BadRequestException("未查询到对应的记录!");
}
entity.setUpdate_time(DateUtil.now());
levelchangedtlMapper.updateById(entity);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteAll(Set<String> ids) {
for (String id : ids) {
StIvtLevelchangedtl entity = levelchangedtlMapper.selectById(id);
if (ObjectUtil.isNotEmpty(entity)) {
entity.setIs_delete("1");
entity.setUpdate_time(DateUtil.now());
levelchangedtlMapper.updateById(entity);
}
}
}
/*
* @description: 管制卷修改子卷级别后 进行移库操作
* @author ManMan.Yang
* @date: 2026/7/23 15:10
*
* 管制6, 报废5 , 改切4, A- 3, A 2, A+ 1,
*
* 判断卷原来的级别是不是管制卷,如果不是,不走移库操作。
* 根据卷号获取包装关系查询木箱信息,判断一箱有几个卷。
如果是单卷,就走判断。
判断当前子卷是否有库存
如果有库存,就进行移库。
如果是多卷需要判断每一卷是否都已完成卷改级。
如果没完成,就保存改级记录。
如果完成先判断是否存在库存,如果没有库存就跳过。
如果有库存,就进行移库。
获取移库记录结果。
保存移库记录。
**/
@Transactional(rollbackFor = Exception.class)
public void ChangeLevelAndMoveStep(String containerName,String newLevel,String oldLevel,String newResult,String oldResult){
log.info("==================管制卷改级实物移库逻辑开始=========================");
String resultMessage = "";
String status = "";
String moveBillCode = "";
try{
//判断卷原来的级别是不是管制卷,如果不是,不走移库操作。
if(!"6".equals(oldLevel)){
log.info("非管制卷改级,不需要进行实物移库!");
throw new BadRequestException("非管制卷改级,不需要进行实物移库!!");
}
List<Map<String,Object>> packages = levelchangedtlMapper.selectPackageInfoByContainerName(containerName);
if(ObjectUtil.isEmpty(packages)){
log.error("传入数据包装关系异常,请确认!");
throw new BadRequestException("传入数据包装关系异常,请确认!");
}
int nums = packages.size();
String boxNo = packages.get(0).get("package_box_sn")+"";
String extCode = packages.get(0).get("ext_code")+"";
//是一箱一卷
if(nums == 1){
//判断当前子卷是否有库存
List<Map<String,Object>> structivts = levelchangedtlMapper.selectStructivtsByContainerName(containerName);
if(ObjectUtil.isEmpty(structivts) || structivts.isEmpty()){
resultMessage = "管制卷"+containerName + "暂无可用库存,不进行移库操作";
status = "9";
}else{
moveBillCode = moveStorPreStep(boxNo,extCode);
resultMessage = "管制卷"+containerName + "移库完成";
status = "1";
}
}else{
//是一箱多卷,先判断分切计划中不算当前这一卷,其他的卷的级别是否都是不为管制卷
//构造in 查询条件
List<String> containerNames = packages.stream()
.map(p -> String.valueOf(p.get("container_name")))
.collect(Collectors.toList());
Integer count = levelchangedtlMapper.countLevel6ByContainerNames(containerNames);
if (count != null && count > 0) {
// 还有卷级别是6不满足"都不是6"的条件
resultMessage = "同箱其他卷还存在管制卷,管制卷"+containerName + "暂不进行移库,";
status = "1";
log.info("同箱其他卷还存在管制卷,管制卷"+containerName + "暂不进行移库,");
} else {
moveBillCode = moveStorPreStep(boxNo,extCode);
resultMessage = "管制卷"+containerName + "移库完成";
status = "1";
}
}
saveOrUpdateRecord(containerName, status, newLevel, oldLevel, newResult, oldResult, resultMessage, moveBillCode, "mes接口触发");
}catch (Exception exception){
log.error("管制卷移库异常", exception);
resultMessage = "管制卷"+containerName + "移库异常,错误提示:"+exception.getMessage().substring(0,Math.min(exception.getMessage().length(), 100));
status = "9";
// 使用新事务保存异常记录不受外层回滚影响通过self代理调用确保@Transactional生效
self.saveErrorRecord(containerName, status, newLevel, oldLevel, newResult, oldResult, resultMessage, moveBillCode);
throw new RuntimeException(exception);
}
log.info("==================管制卷改级实物移库逻辑结束=========================");
}
/**
* 保存或更新管制卷移库记录根据container_name判断
*/
private void saveOrUpdateRecord(String containerName, String status, String newLevel, String oldLevel,
String newResult, String oldResult, String resultMessage,
String moveBillCode, String optName) {
StIvtLevelchangedtl exist = levelchangedtlMapper.selectOne(
new LambdaQueryWrapper<StIvtLevelchangedtl>()
.eq(StIvtLevelchangedtl::getContainer_name, containerName)
.eq(StIvtLevelchangedtl::getIs_delete, "0"));
String now = DateUtil.now();
if (ObjectUtil.isNotEmpty(exist)) {
exist.setStatus(status);
exist.setNew_level(newLevel);
exist.setOld_level(oldLevel);
exist.setNew_result(newResult);
exist.setOld_result(oldResult);
exist.setResult_message(resultMessage);
exist.setMove_bill_code(moveBillCode);
exist.setUpdate_optname(optName);
exist.setUpdate_time(now);
levelchangedtlMapper.updateById(exist);
} else {
StIvtLevelchangedtl build = StIvtLevelchangedtl.build(containerName, status, newLevel, oldLevel, newResult, oldResult, resultMessage, moveBillCode, optName);
levelchangedtlMapper.insert(build);
}
}
/**
* 独立事务保存异常记录,确保入库回滚后异常记录仍能保留
*/
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
public void saveErrorRecord(String containerName, String status, String newLevel, String oldLevel,
String newResult, String oldResult, String resultMessage, String moveBillCode) {
saveOrUpdateRecord(containerName, status, newLevel, oldLevel, newResult, oldResult, resultMessage, moveBillCode, "mes接口触发");
}
public String moveStorPreStep(String boxNo,String extCode){
WQLObject wo_mst = WQLObject.getWQLObject("ST_IVT_MoveInv");
//查询仓库
Map<String, Object> storInfo = levelchangedtlMapper.selectStorByExtId(extCode);
if (ObjectUtil.isEmpty(storInfo)) {
throw new BadRequestException("未查询到编码为" + extCode + "对应的仓库信息!");
}
//获取不良品库库存
List<Map<String, Object>> structivtRows = levelchangedtlMapper.selectHandMoveStorIvtByBoxNo("%" + boxNo + "%");
if(ObjectUtil.isEmpty(structivtRows)){
throw new BadRequestException("库存数据查询异常,管制卷移库失败!");
}
Map<String, Object> firstRow = structivtRows.get(0);
String sect_id = "";
String stor_id = firstRow.get("turnout_stor_id")+"";
//获取库区 二期虚拟区 1712667908095741952 一期虚拟区 1586913215886004224
if("F001".equals(extCode)){
sect_id = "1586913215886004224";
}else{
sect_id = "1712667908095741952";
}
List<Map<String, Object>> structAttrRows = levelchangedtlMapper.selectStructAttr(stor_id, sect_id, "1", "1", "1");
if(ObjectUtil.isEmpty(structAttrRows)){
throw new BadRequestException("管制卷移库暂无可用库位!");
}
// 为每条库存分配移入货位
Set<String> usedStructIds = new HashSet<>();
int attrIndex = 0;
double totalQty = 0;
for (Map<String, Object> ivtRow : structivtRows) {
// 跳过已分配完的货位
if (attrIndex >= structAttrRows.size()) {
throw new BadRequestException("可用货位不足,管制卷移库失败!");
}
Map<String, Object> attrRow = structAttrRows.get(attrIndex);
String structId = attrRow.get("struct_id")+"";
// 校验该货位是否已被设置
if (usedStructIds.contains(structId)) {
throw new BadRequestException("货位" + String.valueOf(attrRow.get("struct_code")) + "已被设置,不允许重复设置!");
}
usedStructIds.add(structId);
// 设置移入货位信息
ivtRow.put("turnin_struct_id", attrRow.get("struct_id"));
ivtRow.put("turnin_struct_code", attrRow.get("struct_code"));
ivtRow.put("turnin_struct_name", attrRow.get("struct_name"));
ivtRow.put("turnin_sect_id", attrRow.get("sect_id"));
ivtRow.put("turnin_sect_code", attrRow.get("sect_code"));
ivtRow.put("turnin_sect_name", attrRow.get("sect_name"));
attrIndex++;
// 累加重量
Object qtyObj = ivtRow.get("qty");
if (ObjectUtil.isNotEmpty(qtyObj)) {
totalQty += Double.parseDouble(qtyObj.toString());
}
}
Map<String,Object> moveParam = new HashMap<>();
moveParam.put("bill_code","");
moveParam.put("bill_status","10");
moveParam.put("bill_type","32");
moveParam.put("biz_date",DateUtil.now());
moveParam.put("block_num","");
moveParam.put("create_mode","");
moveParam.put("detail_count",structivtRows.size());
moveParam.put("remark","");
moveParam.put("stor_code", storInfo.get("stor_code"));
moveParam.put("stor_id", storInfo.get("stor_id"));
moveParam.put("stor_name", storInfo.get("stor_name"));
moveParam.put("total_qty", totalQty);
moveParam.put("tableData",structivtRows);
String bill_code = handMoveStorService.insertGzMove(moveParam);
//查询移库单id 根据movebillcode
JSONObject jo_mst = wo_mst.query("bill_code='" + bill_code + "'").uniqueResult(0);
if (null != jo_mst) {
handMoveStorService.confirm(jo_mst);
}
return bill_code;
}
@Override
public void retryMove(StIvtLevelchangedtl entity) {
this.ChangeLevelAndMoveStep(entity.getContainer_name(), entity.getNew_level(), entity.getOld_level(),entity.getNew_result(), entity.getOld_result());
}
@Override
@Transactional(rollbackFor = Exception.class)
public void markComplete(Long id) {
StIvtLevelchangedtl exist = levelchangedtlMapper.selectById(id);
if (ObjectUtil.isEmpty(exist)) {
throw new BadRequestException("未查询到对应的记录!");
}
exist.setStatus("1");
exist.setUpdate_optname(SecurityUtils.getCurrentNickName());
exist.setUpdate_time(DateUtil.now());
levelchangedtlMapper.updateById(exist);
}
}

View File

@@ -115,13 +115,19 @@ public class InBillQueryServiceImpl implements InBillQueryService {
String classes = MapUtil.getStr(whereJson, "classes");
String sale_order_name = MapUtil.getStr(whereJson, "sale_order_name");
String is_all = MapUtil.getStr(whereJson, "is_all");
String is_empty = MapUtil.getStr(whereJson, "is_empty");
String is_join = MapUtil.getStr(whereJson, "is_join");
String pcsn = MapUtil.getStr(whereJson, "pcsn");
String sap_pcsn = MapUtil.getStr(whereJson, "sap_pcsn");
String thickness_request = MapUtil.getStr(whereJson, "thickness_request");
JSONObject map = new JSONObject();
if ("0".equals(is_all)) {
if("1".equals(is_join)){
map.put("flag", "9");
}else{
map.put("flag", "5");
}
} else {
map.put("flag", "6");
}
@@ -133,6 +139,9 @@ public class InBillQueryServiceImpl implements InBillQueryService {
map.put("classes", classes);
map.put("thickness_request", thickness_request);
map.put("sap_pcsn", sap_pcsn);
map.put("is_empty", is_empty);
map.put("is_join", is_join);
// 处理时间
if (ObjectUtil.isNotEmpty(begin_time) && ObjectUtil.isNotEmpty(end_time)) {
@@ -378,11 +387,17 @@ public class InBillQueryServiceImpl implements InBillQueryService {
String pcsn = MapUtil.getStr(map, "pcsn");
String sap_pcsn = MapUtil.getStr(map, "sap_pcsn");
String is_all = MapUtil.getStr(map, "is_all");
String is_empty = MapUtil.getStr(map, "is_empty");
String is_join = MapUtil.getStr(map, "is_join");
String thickness_request = MapUtil.getStr(map, "thickness_request");
JSONObject mapParam = new JSONObject();
if ("0".equals(is_all)) {
mapParam.put("flag", "55");
if("1".equals(is_join)){
mapParam.put("flag", "9");
}else{
mapParam.put("flag", "5");
}
} else {
mapParam.put("flag", "66");
}
@@ -394,6 +409,8 @@ public class InBillQueryServiceImpl implements InBillQueryService {
mapParam.put("classes", classes);
mapParam.put("thickness_request", thickness_request);
mapParam.put("sap_pcsn", sap_pcsn);
mapParam.put("is_empty", is_empty);
mapParam.put("is_join", is_join);
// 处理时间
if (ObjectUtil.isNotEmpty(begin_time) && ObjectUtil.isNotEmpty(end_time)) {

View File

@@ -23,6 +23,8 @@
输入.pcsn TYPEAS s_string
输入.is_virtual TYPEAS s_string
输入.classes TYPEAS s_string
输入.is_empty TYPEAS s_string
输入.is_join TYPEAS s_string
输入.thickness_request TYPEAS s_string
输入.sap_pcsn TYPEAS s_string
输入.areas TYPEAS f_string
@@ -657,9 +659,9 @@
mst.input_optname,
sub.width,
sub.width_standard,
case when plan.paper_tube_or_FRP = '1' then '纸管' when plan.paper_tube_or_FRP = '2' then 'FRP管' end AS paper_type,
case when plan.paper_tube_or_FRP = '1' then plan.paper_tube_material when plan.paper_tube_or_FRP = '2' then plan.FRP_material end AS paper_code,
case when plan.paper_tube_or_FRP = '1' then plan.paper_tube_description when plan.paper_tube_or_FRP = '2' then plan.FRP_description end AS paper_name,
plan.paper_tube_or_FRP paper_type,
plan.paper_tube_material paper_code,
plan.paper_tube_description paper_name,
plan.foil_container_name,
sub.thickness,
sub.box_weight,
@@ -744,21 +746,31 @@
) AS c
LEFT JOIN st_ivt_iostorinvdis dis ON dis.iostorinvdis_id = c.iostorinvdis_id
LEFT JOIN st_ivt_iostorinv mst ON mst.iostorinv_id = dis.iostorinv_id
OPTION 输入.is_join = "1"
inner join st_ivt_structivt sis on sis.pcsn = dis.pcsn
ENDOPTION
LEFT JOIN st_ivt_sectattr sect ON sect.sect_id = dis.sect_id
LEFT JOIN md_me_materialbase mater ON mater.material_id = dis.material_id
INNER JOIN pdm_bi_subpackagerelationrecord sub ON sub.container_name = dis.pcsn AND sub.package_box_sn = dis.box_no AND sub.bill_id = dis.iostorinv_id
LEFT JOIN md_cs_customerbase cust ON cust.cust_code = sub.customer_name
LEFT JOIN (SELECT
container_name,
MAX(paper_tube_or_FRP) AS paper_tube_or_FRP,
MAX(paper_tube_material) AS paper_tube_material,
MAX(paper_tube_description) AS paper_tube_description,
MAX(paper_tube_model) AS paper_tube_model,
MAX(FRP_material) AS FRP_material,
CASE
WHEN plan1.paper_tube_or_FRP = '1' THEN '纸管'
WHEN plan1.paper_tube_or_FRP = '2' THEN 'FRP管'
END AS paper_tube_or_FRP,
CASE
WHEN plan1.paper_tube_or_FRP = '1' THEN plan1.paper_tube_material
WHEN plan1.paper_tube_or_FRP = '2' THEN plan1.FRP_material
END AS paper_tube_material,
CASE
WHEN plan1.paper_tube_or_FRP = '1' THEN plan1.paper_tube_description
WHEN plan1.paper_tube_or_FRP = '2' THEN plan1.FRP_description
END AS paper_tube_description,
MAX(parent_container_name) AS parent_container_name,
MAX(restruct_container_name) AS restruct_container_name,
MAX(FRP_description) AS FRP_description,
MAX(FRP_model) AS FRP_model,
MAX(foil_container_name) AS foil_container_name
FROM
pdm_bi_slittingproductionplan plan1
@@ -766,6 +778,7 @@
plan1.is_delete = '0'
GROUP BY container_name) plan ON plan.container_name = sub.container_name
LEFT JOIN md_me_materialbase mb ON mb.material_code = sub.box_type
WHERE
mst.io_type = '0'
AND mst.is_delete = '0'
@@ -804,7 +817,6 @@
sub.sub_type = '2'
ENDOPTION
OPTION 输入.begin_time <> ""
mst.confirm_time >= 输入.begin_time
ENDOPTION
@@ -817,6 +829,14 @@
CONCAT( sub.thickness_request,'*',sub.width) = 输入.with
ENDOPTION
OPTION 输入.is_empty = "0"
plan.paper_tube_material is not null
ENDOPTION
OPTION 输入.is_empty = "1"
plan.paper_tube_material is null
ENDOPTION
OPTION 输入.classes = "1"
DATE_FORMAT( mst.confirm_time, '%H:%i:%s' ) >='08:00:00' AND DATE_FORMAT( mst.confirm_time, '%H:%i:%s' ) <= '19:59:59'
ENDOPTION
@@ -898,12 +918,14 @@
GROUP BY
pcsn
) AS c
LEFT JOIN st_ivt_iostorinvdis dis ON dis.iostorinvdis_id = c.iostorinvdis_id
LEFT JOIN st_ivt_iostorinv mst ON mst.iostorinv_id = dis.iostorinv_id
LEFT JOIN st_ivt_sectattr sect ON sect.sect_id = dis.sect_id
LEFT JOIN md_me_materialbase mater ON mater.material_id = dis.material_id
INNER JOIN pdm_bi_subpackagerelationrecord sub ON sub.container_name = dis.pcsn AND sub.package_box_sn = dis.box_no AND sub.bill_id = dis.iostorinv_id
LEFT JOIN md_cs_customerbase cust ON cust.cust_code = sub.customer_name
WHERE
mst.io_type = '0'
AND mst.is_delete = '0'
@@ -991,9 +1013,9 @@
sub.date_of_production,
mst.input_optname,
sub.width,
case when plan.paper_tube_or_FRP = '1' then '纸管' when plan.paper_tube_or_FRP = '2' then 'FRP管' end AS paper_type,
case when plan.paper_tube_or_FRP = '1' then plan.paper_tube_material when plan.paper_tube_or_FRP = '2' then plan.FRP_material end AS paper_code,
case when plan.paper_tube_or_FRP = '1' then plan.paper_tube_description when plan.paper_tube_or_FRP = '2' then plan.FRP_description end AS paper_name,
plan.paper_tube_or_FRP paper_type,
plan.paper_tube_material paper_code,
plan.paper_tube_description paper_name,
sub.thickness,
sub.box_weight,
sub.length,
@@ -1084,15 +1106,20 @@
LEFT JOIN md_cs_customerbase cust ON cust.cust_code = sub.customer_name
LEFT JOIN (SELECT
container_name,
MAX(paper_tube_or_FRP) AS paper_tube_or_FRP,
MAX(paper_tube_material) AS paper_tube_material,
MAX(paper_tube_description) AS paper_tube_description,
MAX(paper_tube_model) AS paper_tube_model,
MAX(FRP_material) AS FRP_material,
CASE
WHEN plan1.paper_tube_or_FRP = '1' THEN '纸管'
WHEN plan1.paper_tube_or_FRP = '2' THEN 'FRP管'
END AS paper_tube_or_FRP,
CASE
WHEN plan1.paper_tube_or_FRP = '1' THEN plan1.paper_tube_material
WHEN plan1.paper_tube_or_FRP = '2' THEN plan1.FRP_material
END AS paper_tube_material,
CASE
WHEN plan1.paper_tube_or_FRP = '1' THEN plan1.paper_tube_description
WHEN plan1.paper_tube_or_FRP = '2' THEN plan1.FRP_description
END AS paper_tube_description,
MAX(parent_container_name) AS parent_container_name,
MAX(restruct_container_name) AS restruct_container_name,
MAX(FRP_description) AS FRP_description,
MAX(FRP_model) AS FRP_model,
MAX(foil_container_name) AS foil_container_name
FROM
pdm_bi_slittingproductionplan plan1
@@ -1138,7 +1165,6 @@
sub.sub_type = '2'
ENDOPTION
OPTION 输入.begin_time <> ""
mst.confirm_time >= 输入.begin_time
ENDOPTION
@@ -1151,6 +1177,14 @@
CONCAT( sub.thickness_request,'*',sub.width) = 输入.with
ENDOPTION
OPTION 输入.is_empty = "0"
plan.paper_tube_material is not null
ENDOPTION
OPTION 输入.is_empty = "1"
plan.paper_tube_material is null
ENDOPTION
OPTION 输入.classes = "1"
DATE_FORMAT( mst.confirm_time, '%H:%i:%s' ) >='08:00:00' AND DATE_FORMAT( mst.confirm_time, '%H:%i:%s' ) <= '19:59:59'
ENDOPTION
@@ -1419,4 +1453,354 @@
ENDQUERY
ENDIF
IF 输入.flag = "9"
PAGEQUERY
SELECT
mst.stor_name,
dis.sect_name,
dis.struct_code,
dis.struct_name,
mst.bill_type,
dis.box_no,
mater.material_code,
mater.material_name,
mb.material_name AS box_name,
dis.pcsn,
sub.sap_pcsn,
sub.net_weight,
dis.qty_unit_name,
sub.customer_name,
cust.sales_owner,
cust.cust_name,
sub.quanlity_in_box,
sub.customer_description,
sub.sale_order_name,
mst.input_time,
mst.confirm_time,
sub.date_of_production,
mst.input_optname,
sub.width,
sub.width_standard,
plan.paper_tube_or_FRP paper_type,
plan.paper_tube_material paper_code,
plan.paper_tube_description paper_name,
plan.foil_container_name,
sub.thickness,
sub.box_weight,
sub.length,
sub.thickness_request,
sub.width_standard,
sub.mass_per_unit_area,
sub.demand_limit,
sub.standard_limit,
sub.actual_value,
(case when plan.parent_container_name <> '' then plan.parent_container_name else plan.restruct_container_name end) AS parent_container_name,
mst.remark,
(case when DATE_FORMAT( mst.confirm_time, '%H:%i:%s' ) >='08:00:00' AND DATE_FORMAT( mst.confirm_time, '%H:%i:%s' ) <= '19:59:59' then '白班'
when ((
DATE_FORMAT( mst.confirm_time, '%H:%i:%s' ) >='20:00:00' AND DATE_FORMAT( mst.confirm_time, '%H:%i:%s' ) <= '23:59:59'
OR
DATE_FORMAT( mst.confirm_time, '%H:%i:%s' ) >='00:00:00' AND DATE_FORMAT( mst.confirm_time, '%H:%i:%s' ) <= '07:59:59'
)) then '晚班' end) AS classes,
CONCAT( sub.box_length,'*',sub.box_width,'*',sub.box_high) AS box_size,
CASE
WHEN DATE_FORMAT( mst.confirm_time, '%H:%i:%s' ) >= '08:00:00' AND DATE_FORMAT( mst.confirm_time, '%H:%i:%s' ) <= '23:59:59'
THEN mst.confirm_time
WHEN DATE_FORMAT( mst.confirm_time, '%H:%i:%s' ) >= '00:00:00' AND DATE_FORMAT( mst.confirm_time, '%H:%i:%s' ) <= '07:59:59'
THEN DATE_SUB(mst.confirm_time,INTERVAL 1 day)
END AS confirm_time_class
FROM
(
SELECT
MIN( a.iostorinvdis_id ) AS iostorinvdis_id
FROM
st_ivt_iostorinvdis a
LEFT JOIN st_ivt_iostorinv b ON a.iostorinv_id = b.iostorinv_id
WHERE
b.io_type = '0'
OPTION 输入.bill_type <> ""
b.bill_type = 输入.bill_type
ENDOPTION
OPTION 输入.pcsn <> ""
a.pcsn = 输入.pcsn
ENDOPTION
OPTION 输入.begin_time <> ""
b.confirm_time >= 输入.begin_time
ENDOPTION
OPTION 输入.end_time <> ""
b.confirm_time <= 输入.end_time
ENDOPTION
AND b.bill_status = '99'
GROUP BY
pcsn
UNION
SELECT
MIN( a.iostorinvdis_id ) AS iostorinvdis_id
FROM
st_ivt_iostorinvdis a
LEFT JOIN st_ivt_iostorinv b ON a.iostorinv_id = b.iostorinv_id
WHERE
b.io_type = '0'
OPTION 输入.bill_type = "0001"
b.bill_type = '0007'
ENDOPTION
OPTION 输入.bill_type <> "0001"
b.bill_type = '-1'
ENDOPTION
OPTION 输入.pcsn <> ""
a.pcsn = 输入.pcsn
ENDOPTION
OPTION 输入.begin_time <> ""
b.confirm_time >= 输入.begin_time
ENDOPTION
OPTION 输入.end_time <> ""
b.confirm_time <= 输入.end_time
ENDOPTION
AND b.bill_status = '99'
GROUP BY
pcsn
) AS c
LEFT JOIN st_ivt_iostorinvdis dis ON dis.iostorinvdis_id = c.iostorinvdis_id
LEFT JOIN st_ivt_iostorinv mst ON mst.iostorinv_id = dis.iostorinv_id
INNER JOIN st_ivt_structivt sis on sis.pcsn = dis.pcsn
LEFT JOIN st_ivt_sectattr sect ON sect.sect_id = dis.sect_id
LEFT JOIN md_me_materialbase mater ON mater.material_id = dis.material_id
INNER JOIN pdm_bi_subpackagerelationrecord sub ON sub.container_name = dis.pcsn AND sub.package_box_sn = dis.box_no AND sub.bill_id = dis.iostorinv_id
LEFT JOIN md_cs_customerbase cust ON cust.cust_code = sub.customer_name
LEFT JOIN (SELECT
container_name,
CASE
WHEN plan1.paper_tube_or_FRP = '1' THEN '纸管'
WHEN plan1.paper_tube_or_FRP = '2' THEN 'FRP管'
END AS paper_tube_or_FRP,
CASE
WHEN plan1.paper_tube_or_FRP = '1' THEN plan1.paper_tube_material
WHEN plan1.paper_tube_or_FRP = '2' THEN plan1.FRP_material
END AS paper_tube_material,
CASE
WHEN plan1.paper_tube_or_FRP = '1' THEN plan1.paper_tube_description
WHEN plan1.paper_tube_or_FRP = '2' THEN plan1.FRP_description
END AS paper_tube_description,
MAX(parent_container_name) AS parent_container_name,
MAX(restruct_container_name) AS restruct_container_name,
MAX(foil_container_name) AS foil_container_name
FROM
pdm_bi_slittingproductionplan plan1
WHERE
plan1.is_delete = '0'
GROUP BY container_name) plan ON plan.container_name = sub.container_name
LEFT JOIN md_me_materialbase mb ON mb.material_code = sub.box_type
WHERE
mst.io_type = '0'
AND mst.is_delete = '0'
AND mst.bill_status = '99'
OPTION 输入.storIds <> ""
mst.stor_id in 输入.storIds
ENDOPTION
OPTION 输入.is_virtual = "0"
sect.sect_type_attr <> '09'
ENDOPTION
OPTION 输入.is_virtual = "1"
sect.sect_type_attr = '09'
ENDOPTION
OPTION 输入.areas <> ""
(LEFT(sub.container_name,2) IN 输入.areas OR SUBSTRING(sub.container_name,2,2) IN 输入.areas)
ENDOPTION
OPTION 输入.thickness_request <> ""
sub.thickness_request = 输入.thickness_request
ENDOPTION
OPTION 输入.bill_type = "0001"
IFNULL(sub.sub_type,'') = ''
ENDOPTION
OPTION 输入.sale_order_name <> ""
sub.sale_order_name = 输入.sale_order_name
ENDOPTION
OPTION 输入.sap_pcsn <> ""
sub.sap_pcsn = 输入.sap_pcsn
ENDOPTION
OPTION 输入.bill_type = "0007"
sub.sub_type = '2'
ENDOPTION
OPTION 输入.begin_time <> ""
mst.confirm_time >= 输入.begin_time
ENDOPTION
OPTION 输入.end_time <> ""
mst.confirm_time <= 输入.end_time
ENDOPTION
OPTION 输入.with <> ""
CONCAT( sub.thickness_request,'*',sub.width) = 输入.with
ENDOPTION
OPTION 输入.is_empty = "0"
plan.paper_tube_material is not null
ENDOPTION
OPTION 输入.is_empty = "1"
plan.paper_tube_material is null
ENDOPTION
OPTION 输入.classes = "1"
DATE_FORMAT( mst.confirm_time, '%H:%i:%s' ) >='08:00:00' AND DATE_FORMAT( mst.confirm_time, '%H:%i:%s' ) <= '19:59:59'
ENDOPTION
OPTION 输入.classes = "2"
(
DATE_FORMAT( mst.confirm_time, '%H:%i:%s' ) >='20:00:00' AND DATE_FORMAT( mst.confirm_time, '%H:%i:%s' ) <= '23:59:59'
OR
DATE_FORMAT( mst.confirm_time, '%H:%i:%s' ) >='00:00:00' AND DATE_FORMAT( mst.confirm_time, '%H:%i:%s' ) <= '07:59:59'
)
ENDOPTION
ENDSELECT
ENDPAGEQUERY
ENDIF
IF 输入.flag = "6"
PAGEQUERY
SELECT
MAX(mst.stor_name) AS stor_name,
MAX(dis.sect_name) AS sect_name,
MAX(dis.struct_code) AS struct_code,
MAX(dis.struct_name) AS struct_name,
MAX(mst.bill_type) AS bill_type,
MAX(mater.material_code) AS material_code,
MAX(mater.material_name) AS material_name,
MAX(dis.qty_unit_name) AS qty_unit_name,
MAX(sub.customer_description) AS customer_description,
MAX(mst.input_optname) AS input_optname,
MAX(mst.remark) AS remark,
mst.iostorinv_id,
dis.box_no,
MAX(cust.sales_owner) AS sales_owner,
MAX(cust.cust_name) AS cust_name,
MAX(sub.customer_name) AS customer_name,
MAX(sub.sale_order_name) AS sale_order_name,
MAX(sub.date_of_production) AS date_of_production,
SUM(sub.net_weight) AS net_weight,
MAX(mst.input_time) AS input_time,
MAX(mst.confirm_time) AS confirm_time,
CONCAT_WS('',MAX(sub.thickness_request),'*',MAX(sub.width)) AS specification,
CONCAT( MAX(sub.box_length),'*',MAX(sub.box_width),'*',MAX(sub.box_high)) AS box_size,
(case when DATE_FORMAT( mst.confirm_time, '%H:%i:%s' ) >='08:00:00' AND DATE_FORMAT( mst.confirm_time, '%H:%i:%s' ) <= '19:59:59' then '白班'
when ((
DATE_FORMAT( mst.confirm_time, '%H:%i:%s' ) >='20:00:00' AND DATE_FORMAT( mst.confirm_time, '%H:%i:%s' ) <= '23:59:59'
OR
DATE_FORMAT( mst.confirm_time, '%H:%i:%s' ) >='00:00:00' AND DATE_FORMAT( mst.confirm_time, '%H:%i:%s' ) <= '07:59:59'
)) then '晚班' end) AS classes,
CASE
WHEN DATE_FORMAT( mst.confirm_time, '%H:%i:%s' ) >= '08:00:00' AND DATE_FORMAT( mst.confirm_time, '%H:%i:%s' ) <= '23:59:59'
THEN mst.confirm_time
WHEN DATE_FORMAT( mst.confirm_time, '%H:%i:%s' ) >= '00:00:00' AND DATE_FORMAT( mst.confirm_time, '%H:%i:%s' ) <= '07:59:59'
THEN DATE_SUB(mst.confirm_time,INTERVAL 1 day)
END AS confirm_time_class
FROM
(
SELECT
MIN( a.iostorinvdis_id ) AS iostorinvdis_id
FROM
st_ivt_iostorinvdis a
LEFT JOIN st_ivt_iostorinv b ON a.iostorinv_id = b.iostorinv_id
WHERE
b.io_type = '0'
OPTION 输入.bill_type <> ""
b.bill_type = 输入.bill_type
ENDOPTION
OPTION 输入.pcsn <> ""
a.pcsn = 输入.pcsn
ENDOPTION
OPTION 输入.begin_time <> ""
b.confirm_time >= 输入.begin_time
ENDOPTION
OPTION 输入.end_time <> ""
b.confirm_time <= 输入.end_time
ENDOPTION
AND b.bill_status = '99'
GROUP BY
pcsn
) AS c
LEFT JOIN st_ivt_iostorinvdis dis ON dis.iostorinvdis_id = c.iostorinvdis_id
LEFT JOIN st_ivt_iostorinv mst ON mst.iostorinv_id = dis.iostorinv_id
LEFT JOIN st_ivt_sectattr sect ON sect.sect_id = dis.sect_id
LEFT JOIN md_me_materialbase mater ON mater.material_id = dis.material_id
INNER JOIN pdm_bi_subpackagerelationrecord sub ON sub.container_name = dis.pcsn AND sub.package_box_sn = dis.box_no AND sub.bill_id = dis.iostorinv_id
LEFT JOIN md_cs_customerbase cust ON cust.cust_code = sub.customer_name
WHERE
mst.io_type = '0'
AND mst.is_delete = '0'
AND mst.bill_status = '99'
OPTION 输入.storIds <> ""
mst.stor_id = 输入.storIds
ENDOPTION
OPTION 输入.is_virtual = "0"
sect.sect_type_attr <> '09'
ENDOPTION
OPTION 输入.is_virtual = "1"
sect.sect_type_attr = '09'
ENDOPTION
OPTION 输入.areas <> ""
(LEFT(sub.container_name,2) IN 输入.areas OR SUBSTRING(sub.container_name,2,2) IN 输入.areas)
ENDOPTION
OPTION 输入.thickness_request <> ""
sub.thickness_request = 输入.thickness_request
ENDOPTION
OPTION 输入.bill_type <> ""
mst.bill_type = 输入.bill_type
ENDOPTION
OPTION 输入.sale_order_name <> ""
sub.sale_order_name = 输入.sale_order_name
ENDOPTION
OPTION 输入.begin_time <> ""
mst.confirm_time >= 输入.begin_time
ENDOPTION
OPTION 输入.end_time <> ""
mst.confirm_time <= 输入.end_time
ENDOPTION
OPTION 输入.with <> ""
CONCAT( sub.thickness_request,'*',sub.width) = 输入.with
ENDOPTION
OPTION 输入.classes = "1"
DATE_FORMAT( mst.confirm_time, '%H:%i:%s' ) >='08:00:00' AND DATE_FORMAT( mst.confirm_time, '%H:%i:%s' ) <= '19:59:59'
ENDOPTION
OPTION 输入.classes = "2"
(
DATE_FORMAT( mst.confirm_time, '%H:%i:%s' ) >='20:00:00' AND DATE_FORMAT( mst.confirm_time, '%H:%i:%s' ) <= '23:59:59'
OR
DATE_FORMAT( mst.confirm_time, '%H:%i:%s' ) >='00:00:00' AND DATE_FORMAT( mst.confirm_time, '%H:%i:%s' ) <= '07:59:59'
)
ENDOPTION
GROUP BY
mst.iostorinv_id,
dis.box_no
ENDSELECT
ENDPAGEQUERY
ENDIF

View File

@@ -0,0 +1,254 @@
<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="80px"
label-suffix=":"
>
<el-form-item label="子卷号">
<el-input
v-model="query.container_name"
size="mini"
clearable
placeholder="子卷号"
@keyup.enter.native="crud.toQuery"
/>
</el-form-item>
<el-form-item label="状态">
<el-select
v-model="query.status"
clearable
size="mini"
placeholder="全部"
class="filter-item"
@change="crud.toQuery"
>
<el-option label="已完成" value="1" />
<el-option label="未完成" value="0" />
<el-option label="移库异常" value="9" />
</el-select>
</el-form-item>
<el-form-item label="移库单据号" label-width="100px">
<el-input
v-model="query.move_bill_code"
size="mini"
clearable
placeholder="移库单据号"
@keyup.enter.native="crud.toQuery"
/>
</el-form-item>
<el-form-item label="创建时间">
<el-date-picker
v-model="query.createTime"
type="daterange"
value-format="yyyy-MM-dd HH:mm:ss"
start-placeholder="开始日期"
end-placeholder="结束日期"
:default-time="['00:00:00', '23:59:59']"
@change="crud.toQuery"
/>
</el-form-item>
<rrOperation />
</el-form>
</div>
<!--操作栏-->
<crudOperation :permission="permission" />
<el-button
type="success"
icon="el-icon-check"
size="mini"
:disabled="!canOperate"
@click="handleMarkComplete(crud.selections[0])"
>
标记完成
</el-button>
<el-button
type="warning"
icon="el-icon-refresh"
size="mini"
:disabled="!canOperate"
@click="handleRetryMove(crud.selections[0])"
>
重新移库
</el-button>
<div style="margin-bottom: 10px"></div>
<!--表格渲染-->
<el-table
ref="table"
v-loading="crud.loading"
size="mini"
:data="crud.data"
highlight-current-row
style="width: 100%;"
@selection-change="crud.selectionChangeHandler"
>
<el-table-column type="selection" width="55" />
<el-table-column show-overflow-tooltip label="移库单据号" width="150">
<template slot-scope="scope">
<span style="color: #f89b0c; font-weight: bold;">{{ scope.row.move_bill_code }}</span>
</template>
</el-table-column>
<el-table-column show-overflow-tooltip prop="container_name" label="子卷号" width="180" />
<el-table-column show-overflow-tooltip prop="status" label="状态" width="100">
<template slot-scope="scope">
<el-tag v-if="scope.row.status === '1'" type="success" size="mini">已完成</el-tag>
<el-tag v-else-if="scope.row.status === '0'" type="info" size="mini">未完成</el-tag>
<el-tag v-else-if="scope.row.status === '9'" type="danger" size="mini">移库异常</el-tag>
<span v-else>{{ scope.row.status }}</span>
</template>
</el-table-column>
<el-table-column show-overflow-tooltip prop="old_level" label="旧级别" width="80" :render-header="renderLevelHeader" />
<el-table-column show-overflow-tooltip prop="old_result" label="旧处理结果" width="120" />
<el-table-column show-overflow-tooltip prop="new_level" label="新级别" width="80" :render-header="renderLevelHeader" />
<el-table-column show-overflow-tooltip prop="new_result" label="新处理结果" width="120" />
<el-table-column show-overflow-tooltip prop="result_message" label="操作结果" min-width="400" />
<el-table-column show-overflow-tooltip prop="create_optname" label="创建人" width="100" />
<el-table-column show-overflow-tooltip prop="create_time" label="创建时间" width="160" />
<el-table-column show-overflow-tooltip prop="update_optname" label="修改人" width="100" />
<el-table-column show-overflow-tooltip prop="update_time" label="修改时间" width="160" />
</el-table>
<!--分页组件-->
<pagination />
</div>
<!--移库单详情弹窗复用moveStor的AddDialog-->
<AddDialog @AddChanged="crud.toQuery" />
</div>
</template>
<script>
import levelchangedtl from '@/views/wms/st/levelchange/levelchangedtl'
import CRUD, { crud, header, presenter } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation'
import pagination from '@crud/Pagination'
import request from '@/utils/request'
import AddDialog from '@/views/wms/st/inStor/moveStor/AddDialog'
export default {
name: 'Levelchangedtl',
components: { crudOperation, rrOperation, pagination, AddDialog },
cruds() {
return CRUD({
title: '管制卷移库记录',
url: '/api/levelchangedtl',
idField: 'id',
sort: 'create_time,desc',
crudMethod: { ...levelchangedtl },
optShow: {
add: false,
edit: false,
del: false,
download: false,
reset: true
},
queryOnPresenterCreated: false
})
},
mixins: [presenter(), header(), crud()],
data() {
return {
permission: {
add: ['admin', 'levelchangedtl:add'],
edit: ['admin', 'levelchangedtl:edit'],
del: ['admin', 'levelchangedtl:del']
}
}
},
computed: {
canOperate() {
if (this.crud.selections.length === 0) return false
const row = this.crud.selections[0]
return row.status === '0' || row.status === '9'
}
},
created() {
this.initQuery()
},
methods: {
// 自定义级别列表头(含问号提示)
renderLevelHeader(h, { column }) {
return h('span', [
h('span', column.label || '级别'),
h('el-tooltip', {
props: {
effect: 'dark',
placement: 'top',
content: '级别对应关系说明:\n 6级 → 管制、\n 5级→报废、\n 4级→改切 、\n 3级→A- 、\n 2级→A 、\n 1级→A+'
}
}, [
h('i', {
class: 'el-icon-question',
style: { marginLeft: '4px', color: '#909399', cursor: 'pointer', fontSize: '14px' }
})
])
])
},
handleMarkComplete(row) {
this.$confirm('确认将子卷 ' + row.container_name + ' 标记为完成吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
levelchangedtl.markComplete(row).then(res => {
this.crud.notify('标记完成成功', CRUD.NOTIFICATION_TYPE.SUCCESS)
this.crud.toQuery()
})
}).catch(() => {})
},
handleRetryMove(row) {
this.$confirm('确认对子卷 ' + row.container_name + ' 重新执行移库操作吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
levelchangedtl.retryMove(row).then(res => {
this.crud.notify('重新移库完成', CRUD.NOTIFICATION_TYPE.SUCCESS)
this.crud.toQuery()
})
}).catch(() => {
this.crud.toQuery()
})
},
/* 搜索框创建时间默认最近一周 */
initQuery() {
const end = new Date()
const start = new Date()
const endYear = end.getFullYear()
var endMonth = end.getMonth() + 1
if (end.getMonth() + 1 < 10) {
endMonth = '0' + endMonth.toString()
}
var endDay = end.getDate()
if (end.getDate() < 10) {
endDay = '0' + endDay.toString()
}
const endDate = endYear + '-' + endMonth + '-' + endDay + ' 23:59:59'
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
const startYear = start.getFullYear()
var startMonth = start.getMonth() + 1
if (start.getMonth() + 1 < 10) {
startMonth = '0' + startMonth.toString()
}
var startDay = start.getDate()
if (start.getDate() < 10) {
startDay = '0' + startDay.toString()
}
const startDate = startYear + '-' + startMonth + '-' + startDay + ' 00:00:00'
this.$set(this.query, 'createTime', [startDate, endDate])
this.crud.toQuery()
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
::v-deep .el-dialog__body {
padding-top: 10px;
}
</style>

View File

@@ -0,0 +1,43 @@
import request from '@/utils/request'
export function add(data) {
return request({
url: '/api/levelchangedtl',
method: 'post',
data
})
}
export function del(ids) {
return request({
url: '/api/levelchangedtl',
method: 'delete',
data: ids
})
}
export function edit(data) {
return request({
url: '/api/levelchangedtl',
method: 'put',
data
})
}
export function retryMove(data) {
return request({
url: '/api/levelchangedtl/retryMove',
method: 'post',
data
})
}
export function markComplete(data) {
return request({
url: '/api/levelchangedtl/markComplete',
method: 'post',
data
})
}
export default { add, edit, del, retryMove, markComplete }

View File

@@ -160,7 +160,38 @@
size="mini"
placeholder="请选择"
class="filter-item"
@change="crud.toQuery"
>
<el-option
v-for="item in dict.IS_OR_NOT"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="管件信息是否为空" label-width="140px">
<el-select
v-model="query.is_empty"
clearable
size="mini"
placeholder="请选择"
class="filter-item"
>
<el-option
v-for="item in dict.IS_OR_NOT"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="是否有库存" label-width="140px">
<el-select
v-model="query.is_join"
clearable
size="mini"
placeholder="请选择"
class="filter-item"
>
<el-option
v-for="item in dict.IS_OR_NOT"