Commit 4871c3ad sunke

增加获取工单小料盘绑定数量接口

出库前从Qisda获取产线是否有未解绑料架,如果有未解绑,暂不出库
优化手动提前工单出库功能
优化导出CSV
Fixed: 紧急料分盘料完成时,增加任务完成数量
1 个父辈 591fe8ab
......@@ -704,6 +704,16 @@ public class Barcode extends BaseMongoBean {
}
return true;
}
/**
* 是否是小料(7x8)的料
*/
public boolean isSmallReel(){
if(plateSize == 7){
return height == 8 || height == 12;
}
return false;
}
}
......@@ -179,6 +179,8 @@ public class Settings extends BaseMongoBean {
*/
private String notIntoCids = "";
private boolean checkLineShelf = false;
public Date getLastPcbCheckDate() {
return lastPcbCheckDate;
}
......@@ -426,5 +428,13 @@ public class Settings extends BaseMongoBean {
public void setNotIntoCids(String notIntoCids) {
this.notIntoCids = notIntoCids;
}
public boolean isCheckLineShelf() {
return checkLineShelf;
}
public void setCheckLineShelf(boolean checkLineShelf) {
this.checkLineShelf = checkLineShelf;
}
}
......@@ -127,6 +127,9 @@ public class OutInfo extends BaseMongoBean {
*/
private boolean endOutInfo = false;
@Transient
private String lineBindShelfInfo = "";
@Transient
private Map<String, OutItem> outItemMap = new HashMap<>();
......@@ -471,6 +474,14 @@ public class OutInfo extends BaseMongoBean {
this.endOutInfo = endOutInfo;
}
public String getLineBindShelfInfo() {
return lineBindShelfInfo;
}
public void setLineBindShelfInfo(String lineBindShelfInfo) {
this.lineBindShelfInfo = lineBindShelfInfo;
}
@Override
public String toString() {
return "OutInfo{" +
......
......@@ -645,4 +645,25 @@ public class QisdaApi {
log.error("清理Qisda库存["+posName+"](ClearStockBy)接口出错",e);
}
}
/**
* 检查工单料架是否解绑
*/
public static String GetSerialData(String line, String hserial){
String url = "http://10.85.17.233/ESMTCommonInterface/CommonService.asmx/GetSerialData";
Map<String,Object> paramMap = new HashMap<String,Object>();
paramMap.put("line",line);
paramMap.put("hserial",hserial);
try {
String result = HttpHelper.postParam(url,paramMap);
log.debug("从Qisda检查工单料架是否解绑["+line+"](GetSerialData)返回:" + result);
if(result.contains("VehicleID")){
return result;
}
return "";
} catch (Exception e) {
log.error("从Qisda检查工单料架是否解绑["+line+"])接口(GetSerialData)出错",e);
return "检查出错:" + e.getMessage();
}
}
}
......@@ -293,6 +293,24 @@ public class QisdaController extends BaseController {
return "";
}
/**
* 将出库
* @param request
* @return
*/
@RequestMapping("/service/store/qisda/moveOutInfoToFirst")
@ResponseBody
public String moveOutInfoToFirst(HttpServletRequest request){
String hSerialToMove = request.getParameter("hSerialToMove");
if(Strings.isNullOrEmpty(hSerialToMove)){
return "参数为空";
}
log.info(request.getRemoteAddr() + " 更改需求单["+hSerialToMove+"]出库优先级到第一位");
outInfoCache.changePriority(hSerialToMove);
return "操作成功";
}
@RequestMapping(value = "/service/store/qisda/outInfoList")
......
......@@ -92,12 +92,10 @@ public class OutInfoCache {
}
public void executeOutTask(){
//优先队列中最先出的需求单
OutInfo mustOutInfo = null;
//已到达建议时间的需求单
OutInfo suggestOutInfo = null;
Date now = new Date();
for (OutInfo unEndOutInfo : getCachedOutInfos()) {
List<OutInfo> cachedOutInfos = getCachedOutInfos();
for (OutInfo unEndOutInfo : cachedOutInfos) {
if(!unEndOutInfo.isClosed() && unEndOutInfo.isTaskEnd() && !unEndOutInfo.isReelCutAction()){
long lastEndTime = unEndOutInfo.getTaskEndTime();
......@@ -121,28 +119,57 @@ public class OutInfoCache {
checkOutOutItems(unEndOutInfo.gethSerial());
}
}
}else if(unEndOutInfo.isNew()){
//寻找未执行过的到达建议时间和必须出库时间的工单料(首盘或补料)
if(unEndOutInfo.isTailAction() || unEndOutInfo.isFirstReelAction()){
long firstExecuteTime = unEndOutInfo.getFirstExecuteTime();
if(firstExecuteTime < 0){
if(mustOutInfo == null || firstExecuteTime > mustOutInfo.getFirstExecuteTime()){
mustOutInfo = unEndOutInfo;
}
}else if(firstExecuteTime == 0){
//到达建议时间,且时间最早的
Date suggestDate = unEndOutInfo.getSdate();
if(suggestDate.before(now)){
if(suggestOutInfo == null || suggestDate.before(suggestOutInfo.getSdate())){
suggestOutInfo = unEndOutInfo;
}
}
}
List<String> excludeSerialList = new ArrayList<>();
OutInfo outInfoToNotify = findExecuteOrderHSerial(cachedOutInfos, excludeSerialList);
if(outInfoToNotify != null){
//通知Qisda进行提醒产线人员解绑
QisdaApi.GetSerialData(outInfoToNotify.getLine(),outInfoToNotify.gethSerial());
}
OutInfo outInfoToExecute = null;
do{
OutInfo firstOutInfoToExecute = findExecuteOrderHSerial(cachedOutInfos, excludeSerialList);
if(firstOutInfoToExecute != null){
//补料检查是否有未解绑的料架
String lineHasBindShelf = "";
if(firstOutInfoToExecute.isTailAction()){
lineHasBindShelf = QisdaApi.GetSerialData(firstOutInfoToExecute.getLine(),firstOutInfoToExecute.gethSerial());
}
firstOutInfoToExecute.setLineBindShelfInfo(lineHasBindShelf);
outInfoMap.put(firstOutInfoToExecute.gethSerial(), firstOutInfoToExecute);
if(lineHasBindShelf.isEmpty()){
outInfoToExecute = firstOutInfoToExecute;
break;
}else{
excludeSerialList.add(firstOutInfoToExecute.gethSerial());
if(!dataCache.getSettings().isCheckLineShelf()){
log.info("发料时不检查产线料架解绑状态,忽略产线绑定料架信息");
outInfoToExecute = firstOutInfoToExecute;
break;
}else{
if(lineHasBindShelf.toLowerCase().contains("wait")){
//需要进行等待,直接返回
log.info("需求单["+firstOutInfoToExecute.gethSerial()+"]产线有未解绑料架["+lineHasBindShelf+"]需要进行等待");
return;
}else{
//不需要等待,跳过验证下一个
log.info("需求单["+firstOutInfoToExecute.gethSerial()+"]产线有未解绑料架["+lineHasBindShelf+"]跳过等待,验证下一个需求单");
continue;
}
}
}
}else{
break;
}
}
}while (true);
if(mustOutInfo != null || suggestOutInfo != null){
if(outInfoToExecute != null){
//先看当前是否有执行中的任务
Collection<DataLog> queueTasks = taskService.getQueueTasks();
List<DataLog> allTasks = taskService.getFinishedTasks();
......@@ -161,18 +188,51 @@ public class OutInfoCache {
}
if(!hasOrderTask){
//无工单料任务,如果有优先执行任务先执行,如果没有执行到达建议时间的任务
if(mustOutInfo != null){
log.info("执行优先工单需求单:" + mustOutInfo.gethSerial());
checkOutOutItems(mustOutInfo.gethSerial());
}else if(suggestOutInfo != null){
log.info("执行到达建议时间工单需求单:" + suggestOutInfo.gethSerial());
checkOutOutItems(suggestOutInfo.gethSerial());
}
checkOutOutItems(outInfoToExecute.gethSerial());
}
}
}
private OutInfo findExecuteOrderHSerial(List<OutInfo> cachedOutInfos,List<String> excludeSerialList){
OutInfo mustOutInfo = null;
//已到达建议时间的需求单
OutInfo suggestOutInfo = null;
Date now = new Date();
for (OutInfo unEndOutInfo : cachedOutInfos) {
//寻找未执行过的到达建议时间和必须出库时间的工单料(首盘或补料)
if(unEndOutInfo.isNew()){
if(excludeSerialList.contains(unEndOutInfo.gethSerial())){
continue;
}
//寻找未执行过的到达建议时间和必须出库时间的工单料(首盘或补料)
if(unEndOutInfo.isTailAction() || unEndOutInfo.isFirstReelAction()){
long firstExecuteTime = unEndOutInfo.getFirstExecuteTime();
if(firstExecuteTime < 0){
if(mustOutInfo == null || firstExecuteTime > mustOutInfo.getFirstExecuteTime()){
mustOutInfo = unEndOutInfo;
}
}else if(firstExecuteTime == 0){
//到达建议时间,且时间最早的
Date suggestDate = unEndOutInfo.getSdate();
if(suggestDate.before(now)){
if(suggestOutInfo == null || suggestDate.before(suggestOutInfo.getSdate())){
suggestOutInfo = unEndOutInfo;
}
}
}
}
}
}
if(mustOutInfo != null){
return mustOutInfo;
}
if(suggestOutInfo != null){
return suggestOutInfo;
}
return null;
}
/**
* 执行绑定任务
*/
......@@ -364,6 +424,25 @@ public class OutInfoCache {
}
}
public void changePriority(String hSerial){
if(!Strings.isBlank(hSerial)){
OutInfo outInfoToMove = getOutInfoFromCache(hSerial);
if(outInfoToMove != null){
long sortOrder = - System.currentTimeMillis();
if(outInfoToMove.getFirstExecuteTime() < 0){
for (OutInfo outInfo : outInfoMap.values()) {
long firstExecuteTime = outInfo.getFirstExecuteTime();
if(firstExecuteTime < 0 && firstExecuteTime >= sortOrder){
sortOrder = firstExecuteTime + 1;
}
}
}
updateExecuteTime(outInfoToMove, sortOrder);
}
}
}
/**
* 获取缓存的需求单信息
......
......@@ -42,6 +42,12 @@ public class SettingsController extends BaseUpdateController {
settings = dataCache.updateSettings(settings);
}
String checkLineShelf = request.getParameter("checkLineShelf");
if(!Strings.isNullOrEmpty(checkLineShelf)){
log.info("设置出库前检查产线料架解绑状态:" + checkLineShelf);
settings.setCheckLineShelf(Boolean.valueOf(checkLineShelf));
settings = dataCache.updateSettings(settings);
}
//指定软件是为哪个客户单独定制的
String product = request.getParameter("pro");
......
......@@ -111,16 +111,17 @@ public class DataLogSearchController extends BaseSearchController {
query.addCriteria(criteria);
PageList pageList = searchCriteria.getPageList();
if(pageList.getSortCriterion().equals("id")){
pageList.setSortCriterion("updateDate");
pageList.setSortDirection(SortOrderEnum.DESCENDING);
searchCriteria.setPageList(pageList);
}
//导出
if (request.getParameter(TableTagParameters.PARAMETER_EXPORTING) != null){
pageList.setPageNumber(-1);
}else{
if(pageList.getSortCriterion().equals("id")){
pageList.setSortCriterion("updateDate");
pageList.setSortDirection(SortOrderEnum.DESCENDING);
searchCriteria.setPageList(pageList);
}
}
searchCriteria.setPageList(dataLogDao.findByQuery(query, searchCriteria.getPageList()));
......
......@@ -219,6 +219,28 @@ public class QisdaApiController extends BaseController {
}
/**
* 获取工单的小料盘绑定数量
*/
@RequestMapping(value = "/getSmallBindCount")
@ResponseBody
public ResultBean smallBindCount(HttpServletRequest request){
String soseqStr = receiveParamInfo(request,"soseq");
log.info("收到获取工单的小料盘绑定数量 soseq="+soseqStr);
int smallBindCount = 0;
List<StoragePos> bindPosList = storagePosDao.listSoSeqBindPos(soseqStr);
for (StoragePos storagePos : bindPosList) {
Barcode reel = storagePos.getBarcode();
if(reel.isSmallReel()){
smallBindCount++;
}
}
Map<String,String> resultMap = new HashMap<>();
resultMap.put("soseq", soseqStr);
resultMap.put("smallCount", "" + smallBindCount);
return ResultBean.newOkResult(resultMap);
}
/**
* 检测料盘是否绑定工单
*/
@RequestMapping(value = "/checkLockReel",method = RequestMethod.POST)
......@@ -662,5 +684,4 @@ public class QisdaApiController extends BaseController {
}
}
......@@ -827,9 +827,10 @@ public class TaskService implements ITaskService {
QisdaApi.VMIMateriaRecAss(task, barcode, "E");
}
}
}else if(taskAppendInfo.isUrgentAction()){
//紧急料,增加任务完成数量
}else if(taskAppendInfo.isUrgentAction() || taskAppendInfo.isReelCutAction()){
//紧急料或分盘料,增加任务完成数量
log.info("紧急料或分盘料["+task.getBarcode()+"]任务已出库完成,发料任务完成数量+1");
outInfoCache.incTaskFinishNum(taskAppendInfo.gethSerial(), 0, 0);
}
}
return true;
......
......@@ -116,12 +116,13 @@
<script src="${ctx}/scripts/Sortable.min.js"></script>
<script type="text/javascript">
function getOutInfoHtml(outInfo){
//var index = parseInt(i) + 1;
//var outItems = outInfo.outItems;
var moveHandle = '';
if(!outInfo.executing && !outInfo.sendLess){
moveHandle = '<i class="icon-cursor-move"></i>';
if(outInfo.firstExecuteTime <= 0){
moveHandle = '<span class="glyphicon glyphicon-arrow-up" style="width:30px;display:none;"></span>';
}
var pannelColor = 'panel-default';
......@@ -129,26 +130,35 @@
pannelColor = 'panel-success';
}
var bgClass = '';
var bindShelfInfo = outInfo.lineBindShelfInfo;
if(bindShelfInfo){
bgClass = 'bg-red';
}
var mdate = new Date(outInfo.mdate).Format("yyyy-MM-dd hh:mm:ss");
var sdate = new Date(outInfo.sdate).Format("yyyy-MM-dd hh:mm:ss");
var infoHtml = '<div class="panel '+pannelColor+'">' +
var infoHtml = '<div class="panel '+ pannelColor+' '+ bgClass + '">' +
'<div class="panel-heading">' +
'<h4 class="panel-title">' +
'<a class="accordion-toggle" data-toggle="collapse" href="#'+outInfo.hSerial+'">' +
moveHandle +
moveHandle + outInfo.firstExecuteTime +
'需求单:'+ outInfo.hSerial+' ['+outInfo.action+'] 工单: ' + outInfo.so +' 备料单: ' + outInfo.refno + '[' + outInfo.sendStatus +'] 工单序号:' + outInfo.soseq +
'<span class="right">建议时间: '+sdate+'</span>' +
'<span class="right">必须时间: '+mdate+'</span>' +
//'<span class="right">['+outInfo.firstExecuteTime+']</span>' +
'</a></h4></div>' +
'<div id="'+outInfo.hSerial+'" class="panel-collapse collapse">' +
'<div class="panel-body">' +
'<div class="panel-body bg-grey">' +
'<ul class="list-inline">' +
'<li><i class="fa fa-tasks"></i>工单: '+outInfo.so+'</li>' +
'<li><i class="fa fa-briefcase"></i>备料单: '+outInfo.refno+'</li>' +
'<li><i class="fa fa-calendar"></i>建议时间:'+sdate+'</li>' +
'<li><i class="fa fa-star"></i>必须出仓日期:'+mdate+'</li>' +
'</ul>' +
'<h4 class="list-inline '+bgClass+'">' +
'线体['+outInfo.line+']未解绑料架信息: '+outInfo.lineBindShelfInfo+'' +
'</h4>' +
'</div></div></div></div>';
return infoHtml;
}
......@@ -165,7 +175,11 @@
if(outInfo.executing || outInfo.sendLess || outInfo.firstExecuteTime > 0){
executingHtml = executingHtml + infoHtml;
}else if(outInfo.priority){
priorityHtml = priorityHtml + infoHtml;
if(outInfo.reelCutAction){
executingHtml = executingHtml + infoHtml;
}else{
priorityHtml = priorityHtml + infoHtml;
}
}else{
waitHtml = waitHtml + infoHtml;
}
......@@ -174,17 +188,36 @@
$("#priority").html(priorityHtml);
$("#wait").html(waitHtml);
$(".panel-default").mouseover(function(){
$(this).find(".glyphicon-arrow-up").unbind();
$(this).find(".glyphicon-arrow-up").show();
var hSerial = $(this).parent().attr("href");
$(this).find(".glyphicon-arrow-up").click(function(event){
event.stopPropagation();
var hSerial = $(this).parent().attr("href").replace("#","");
$.post("${ctx}/service/store/qisda/moveOutInfoToFirst", {hSerialToMove: hSerial}, function (data) {
//moving = false;
alert(data);
});
});
});
$(".panel-default").mouseout(function(){
$(this).find(".glyphicon-arrow-up").hide();
});
});
}
flushOutInfos();
var moving = false;
//var moving = false;
setInterval(function(){
if(!moving){
//if(!moving){
flushOutInfos();
}
}, 3000);
//}
}, 1000);
// var dragOptions = {
......@@ -197,46 +230,46 @@
// var sortable = Sortable.create(el,dragOptions);
onSort = function(evt){
moving = true;
var targetSort = "";
$(evt.to).find(".panel-collapse").each(function(){
targetSort = targetSort + $(this).attr('id') + ";";
});
<%--onSort = function(evt){--%>
<%--moving = true;--%>
<%--var targetSort = "";--%>
<%--$(evt.to).find(".panel-collapse").each(function(){--%>
<%--targetSort = targetSort + $(this).attr('id') + ";";--%>
<%--});--%>
$.post("${ctx}/service/store/qisda/changePriority", {hSerialList: targetSort}, function (data) {
moving = false;
});
}
onStart = function(evt){
moving = true;
}
<%--$.post("${ctx}/service/store/qisda/changePriority", {hSerialList: targetSort}, function (data) {--%>
<%--moving = false;--%>
<%--});--%>
<%--}--%>
<%--onStart = function(evt){--%>
<%--moving = true;--%>
<%--}--%>
onEnd = function(evt){
moving = false;
}
<%--onEnd = function(evt){--%>
<%--moving = false;--%>
<%--}--%>
<%--var waitBox = document.getElementById('wait');--%>
<%--var executingBox = document.getElementById("executing");--%>
<%--var priorityBox = document.getElementById('priority');--%>
<%--new Sortable(waitBox, {--%>
<%--group: {--%>
<%--name: 'shared',--%>
<%--put: false // 不允许拖拽进这个列表--%>
<%--},--%>
<%--animation: 150,--%>
<%--sort: false, // 设为false,禁止sort--%>
<%--onStart:onStart,--%>
<%--onEnd: onEnd,--%>
<%--});--%>
var waitBox = document.getElementById('wait');
var executingBox = document.getElementById("executing");
var priorityBox = document.getElementById('priority');
new Sortable(waitBox, {
group: {
name: 'shared',
put: false // 不允许拖拽进这个列表
},
animation: 150,
sort: false, // 设为false,禁止sort
onStart:onStart,
onEnd: onEnd,
});
new Sortable(priorityBox, {
group: 'shared',
animation: 150,
ghostClass: 'panel-move',
onSort:onSort,
onStart:onStart,
onEnd: onEnd,
});
<%--new Sortable(priorityBox, {--%>
<%--group: 'shared',--%>
<%--animation: 150,--%>
<%--ghostClass: 'panel-move',--%>
<%--onSort:onSort,--%>
<%--onStart:onStart,--%>
<%--onEnd: onEnd,--%>
<%--});--%>
</script>
</c:set>
\ No newline at end of file
......@@ -12,6 +12,89 @@
<div class="row">
<div class="col-md-12">
<ul class="timeline">
<li class="timeline-blue">
<div class="timeline-time">
<span class="date">2020 </span>
<span class="time">11-20 </span>
</div>
<div class="timeline-icon">
<i class="fa fa-clock-o"></i>
</div>
<div class="timeline-body">
<h2>版本: V2020112009</h2>
<div class="timeline-content">
<ul>
<li>增加获取工单小料盘绑定数量接口</li>
<li>出库前从Qisda获取产线是否有未解绑料架,如果有未解绑,暂不出库</li>
<li>优化手动提前工单出库功能</li>
<li>优化导出CSV</li>
<li>Fixed: 紧急料分盘料完成时,增加任务完成数量</li>
</ul>
</div>
</div>
</li>
<li class="timeline-yellow">
<div class="timeline-time">
<span class="date">2020 </span>
<span class="time">11-17 </span>
</div>
<div class="timeline-icon">
<i class="fa fa-clock-o"></i>
</div>
<div class="timeline-body">
<h2>版本: V2020111710</h2>
<div class="timeline-content">
<ul>
<li>修正数据量过大无法导出的问题</li>
</ul>
</div>
</div>
</li>
<li class="timeline-grey">
<div class="timeline-time">
<span class="date">2020 </span>
<span class="time">11-11 </span>
</div>
<div class="timeline-icon">
<i class="fa fa-clock-o"></i>
</div>
<div class="timeline-body">
<h2>版本: V2020111111</h2>
<div class="timeline-content">
<ul>
<li>产线未解绑料架提醒</li>
<li>产线有未解绑料架需求单进行等待,暂不出库</li>
<ul>
<li>1 根据可执行但未执行的需求单队列,查找排在最前的需求单, 调用GetSerialData接口进行解绑通知提醒
2 查找可执行但未执行的需求单队列中排在最前的需求单,调用GetSerialData接口进行验证
a)如果对应产线没有未解绑料架,执行出库操作
b)如果对应产线有未解绑的料架,且需要等待(返回结果中包含"Status":"Wait"),不执行出库操作,等待产线进行解绑
c)如果对应产线有未解绑的料架,但不需要等待(返回结果中不包含"Status":"Wait"),跳过该需求单,验证下一个需求单
</li>
</ul>
</ul>
</div>
</div>
</li>
<li class="timeline-purple">
<div class="timeline-time">
<span class="date">2020 </span>
<span class="time">11-06 </span>
</div>
<div class="timeline-icon">
<i class="fa fa-clock-o"></i>
</div>
<div class="timeline-body">
<h2>版本: V2020110609</h2>
<div class="timeline-content">
<ul>
<li>需求单出库时,验证线体上是否有其他工单未解绑的料架,如果有未解绑的料架,不进行出库</li>
<li>没有需要分盘的料盘时,分盘需求单标记为已执行</li>
</ul>
</div>
</div>
</li>
<li class="timeline-green">
<div class="timeline-time">
<span class="date">2020</span>
......
......@@ -239,7 +239,7 @@
<div class="page-footer-inner">
2016&copy; <a href="${ctx}/updateHistory.html">SMD BOX</a>
</div>
<span class="right" style="color: #a3a3a3;">Version: 2020.11.03</span>
<span class="right" style="color: #a3a3a3;">Version: 2020.11.20</span>
<div class="scroll-to-top">
<i class="icon-arrow-up"></i>
</div>
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!