Commit 5789fbf3 sunke

暂停入库和暂停出库开关,达到同一时间只入库或只出库的目的

手动对无物料库位出库时,不禁用库位
1 个父辈 10d18dd8
......@@ -168,11 +168,16 @@ public class Settings extends BaseMongoBean {
private String orderFileDir;
/**
* 准备进行更新,不允许需求单出库
* 不允许需求单出库
*/
private boolean stopOut = false;
/**
* 不允许入库
*/
private boolean stopIn = false;
/**
* 停止定时器任务
*/
private boolean stopJob = false;
......@@ -439,5 +444,13 @@ public class Settings extends BaseMongoBean {
public void setCheckLineShelf(boolean checkLineShelf) {
this.checkLineShelf = checkLineShelf;
}
public boolean isStopIn() {
return stopIn;
}
public void setStopIn(boolean stopIn) {
this.stopIn = stopIn;
}
}
package com.myproject.bean.update.qisda;
import com.myproject.bean.BaseMongoBean;
import com.myproject.bean.qisda.EventItem;
import com.myproject.util.StorageConstants;
import org.apache.logging.log4j.util.Strings;
import org.springframework.data.annotation.Transient;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
......@@ -41,6 +44,7 @@ public class OutInfo extends BaseMongoBean {
/**
* 需求单号
*/
@Indexed
private String hSerial;
/**
......@@ -135,6 +139,11 @@ public class OutInfo extends BaseMongoBean {
@Transient
private Map<String, OutItem> outItemMap = new HashMap<>();
/**
* 事件日志
*/
private List<EventItem> eventItems = new ArrayList<>();
public String getAction() {
return action;
}
......@@ -500,6 +509,18 @@ public class OutInfo extends BaseMongoBean {
this.lineBindShelfInfo = lineBindShelfInfo;
}
public List<EventItem> getEventItems() {
return eventItems;
}
public void setEventItems(List<EventItem> eventItems) {
this.eventItems = eventItems;
}
public void addEventItem(EventItem eventItem){
eventItems.add(eventItem);
}
@Override
public String toString() {
return "OutInfo{" +
......
package com.myproject.dao.mongo.qisda;
import com.myproject.bean.qisda.EventItem;
import com.myproject.bean.update.qisda.OutInfo;
import com.myproject.bean.update.qisda.OutItem;
import com.myproject.dao.mongo.IMongoDao;
......@@ -31,4 +32,6 @@ public interface IOutInfoDao extends IMongoDao {
void updateOutReelNum(String hSerial, int outReelNum);
void updateExecuteTime(String hSerial, long firstExecuteTime);
void updateEventList(String hSerial, List<EventItem> eventItemList);
}
package com.myproject.dao.mongo.qisda.impl;
import com.myproject.bean.BaseMongoBean;
import com.myproject.bean.qisda.EventItem;
import com.myproject.bean.update.qisda.OutInfo;
import com.myproject.bean.update.qisda.OutItem;
import com.myproject.dao.mongo.AbstractMongoDao;
......@@ -122,6 +123,11 @@ public class OutInfoDaoImpl extends AbstractMongoDao implements IOutInfoDao {
update(hSerial, "firstExecuteTime", firstExecuteTime);
}
@Override
public void updateEventList(String hSerial, List<EventItem> eventItemList){
update(hSerial, "eventItems", eventItemList);
}
private void update(String hSerial, String key, Object value){
Criteria c = Criteria.where("hSerial").is(hSerial);
Query query = Query.query(c);
......
......@@ -43,9 +43,6 @@ public class OutInfoSearchController extends BaseSearchController {
@RequestMapping("/outInfoSearch*")
public String onSubmit(@ModelAttribute("searchCriteria") BaseSearchCriteria searchCriteria, HttpServletRequest request) {
boolean stopOut = dataCache.getSettings().isStopOut();
request.setAttribute("stopOut",stopOut);
Query query = new Query();
Criteria criteria = new Criteria();
......
......@@ -197,9 +197,6 @@ public class QisdaController extends BaseController {
@RequestMapping("/service/store/qisda/bindDn")
@ResponseBody
public String bindDn(HttpServletRequest request){
if(dataCache.getSettings().isStopOut()){
return "x系统更新中,暂停出入库,请稍后再试";
}
String rfid = request.getParameter("rfid");
String dnNo = request.getParameter("dnNo");
String facility = request.getParameter("facility");
......
......@@ -146,7 +146,7 @@ public class OutInfoCache {
if(!unEndOutInfo.isClosed() && unEndOutInfo.isTaskEnd() && !unEndOutInfo.isReelCutAction()){
long lastEndTime = unEndOutInfo.getTaskEndTime();
if(now.getTime() - lastEndTime >= 5 * 60 * 1000){
if(lastEndTime>0 && now.getTime() - lastEndTime >= 5 * 60 * 1000){
//任务已结束5分钟
if(unEndOutInfo.isEndOutInfo()){
log.info("需求单["+unEndOutInfo.gethSerial()+"]已执行过,且是工单的最后一个需求单,关闭工单"+unEndOutInfo.getSo()+"["+unEndOutInfo.getSoseq()+"]");
......@@ -181,6 +181,7 @@ public class OutInfoCache {
do{
OutInfo firstOutInfoToExecute = findExecuteOrderHSerial(cachedOutInfos, excludeSerialList);
if(firstOutInfoToExecute != null){
String oldBindShelf = firstOutInfoToExecute.getLineBindShelfInfo();
//补料检查是否有未解绑的料架
String lineHasBindShelf = "";
if(firstOutInfoToExecute.isTailAction()){
......@@ -202,6 +203,10 @@ public class OutInfoCache {
if(lineHasBindShelf.toLowerCase().contains("wait")){
//需要进行等待,直接返回
log.info("需求单["+firstOutInfoToExecute.gethSerial()+"]产线有未解绑料架["+lineHasBindShelf+"]需要进行等待");
if(!oldBindShelf.equals(lineHasBindShelf)){
String eventMsg = "料架["+getBindShelfStr(lineHasBindShelf)+"]未解绑,等待解绑";
addEventItem(firstOutInfoToExecute,eventMsg);
}
return;
}else{
int shelfCountToLine = shelfCountToLine(firstOutInfoToExecute.getSoseq(),lineHasBindShelf);
......@@ -218,6 +223,10 @@ public class OutInfoCache {
log.info("补料需求单["+firstOutInfoToExecute.gethSerial()+"]对应产线可放料架["+shelfCountToLine+"],暂不进行出库");
}
}
if(!oldBindShelf.equals(lineHasBindShelf)){
String eventMsg = "料架["+getBindShelfStr(lineHasBindShelf)+"]未解绑,跳过出库";
addEventItem(firstOutInfoToExecute,eventMsg);
}
//不需要等待,跳过验证下一个
log.info("需求单["+firstOutInfoToExecute.gethSerial()+"]产线有未解绑料架["+lineHasBindShelf+"]跳过等待,验证下一个需求单");
continue;
......@@ -251,7 +260,42 @@ public class OutInfoCache {
checkOutOutItems(outInfoToExecute.gethSerial());
}
}
}
/**
* 添加事件信息
* @param outInfo
* @param eventMsg
*/
private OutInfo addEventItem(OutInfo outInfo, String eventMsg){
EventItem eventItem = EventItem.newEvent(eventMsg);
outInfo.addEventItem(eventItem);
outInfoDao.updateEventList(outInfo.gethSerial(),outInfo.getEventItems());
outInfoMap.put(outInfo.gethSerial(),outInfo);
return outInfo;
}
private String getBindShelfStr(String lineHasBindShelfJsonStr){
if(lineHasBindShelfJsonStr.isEmpty()){
return "";
}
List<String> shelfList = new ArrayList<>();
try{
Map<String, Object> map = JsonUtil.toMap(lineHasBindShelfJsonStr);
Object data = map.get("data");
if(data != null){
List<Object> dataList = (List)data;
for (Object info : dataList) {
Map<String,String> infoMap = (Map)info;
String hSerial = infoMap.get("Serial");
String vehicleID = infoMap.get("VehicleID");
shelfList.add(vehicleID);
}
}
}catch(Exception e){
log.error("获取绑定料架字符串出错",e);
}
return String.join(",",shelfList);
}
/**
......@@ -332,8 +376,9 @@ public class OutInfoCache {
}else if(firstExecuteTime == 0){
//到达建议时间,且时间最早的
Date suggestDate = unEndOutInfo.getSdate();
Date mustDate = unEndOutInfo.getMdate();
if(suggestDate.before(now)){
if(suggestOutInfo == null || suggestDate.before(suggestOutInfo.getSdate())){
if(suggestOutInfo == null || mustDate.before(suggestOutInfo.getMdate())){
suggestOutInfo = unEndOutInfo;
}
}
......@@ -504,6 +549,8 @@ public class OutInfoCache {
log.info("关闭需求单["+outInfo.gethSerial()+"]so=["+outInfo.getSo()+"]soseq=["+outInfo.getSoseq()+"]");
int sendStatus = StorageConstants.SEND_STATUS.CLOSED;
outInfoDao.updateStatus(outInfo.gethSerial(), -1 ,sendStatus);
String eventMsg = "解绑工单序号["+soseq+"]";
addEventItem(outInfo, eventMsg);
}
removeFromCache(outInfo.gethSerial());
}
......@@ -619,9 +666,9 @@ public class OutInfoCache {
// return result;
}
//都为0即未执行过的,到这里的,理论上都是未达到必须出库时间(达到必须出库时间的,已经修改过优先级)
Date sdate1 = o1.getSdate();
Date sdate2 = o2.getSdate();
return sdate1.compareTo(sdate2);
Date mdate1 = o1.getMdate();
Date mdate2 = o2.getMdate();
return mdate1.compareTo(mdate2);
}
});
return outInfoList;
......@@ -763,7 +810,22 @@ public class OutInfoCache {
//已经执行过的不能更新
outInfoDao.updateSMDate(outInfo);
outInfoMap.put(outInfo.gethSerial(),outInfo);
log.info("更新需求单["+outInfo.gethSerial()+"]的建议时间为:"+outInfo.getMdate() + " 必须时间为:" + outInfo.getSdate());
log.info("更新需求单["+outInfo.gethSerial()+"]的建议时间为:"+outInfo.getSdate() + " 必须时间为:" + outInfo.getMdate());
//为所有执行的需求单添加一条修改记录
String mustDateStr = DateUtil.toDateString(outInfo.getMdate(),"yyyy-MM-dd HH:mm");
String eventMsg = "需求单["+outInfo.gethSerial()+"]更新必须时间为:" + mustDateStr;
List<OutInfo> allOutInfos = getCachedOutInfos();
for (OutInfo cacheOutInfo : allOutInfos) {
if(cacheOutInfo.getFirstExecuteTime() <= 0){
if(cacheOutInfo.isTailAction() || cacheOutInfo.isFirstReelAction()){
//未执行过的首盘或补料,添加一个修改事件
addEventItem(cacheOutInfo,eventMsg);
}
}
}
}
/**
......@@ -879,7 +941,7 @@ public class OutInfoCache {
*/
private ResultBean checkOutInfoCanOut(OutInfo outInfo){
if(dataCache.getSettings().isStopOut()){
return ResultBean.newErrorResult(100, "系统更新中,暂停出库,请稍后再试",false);
return ResultBean.newErrorResult(100, "系统已暂停出库,请联系管理员或稍后再试",false);
}
if(outInfo == null){
......@@ -1090,7 +1152,8 @@ public class OutInfoCache {
// }
}
String eventMsg = "开始执行";
outInfo = addEventItem(outInfo, eventMsg);
String msg = "";
int outReelNum = tasks.size();
if(outReelNum > 0){
......@@ -1147,7 +1210,7 @@ public class OutInfoCache {
int shelfCountToLine = shelfCountToLine(outInfo.getSoseq(),lineHasBindShelf);
List<ShelfInfo> allDShelfs = InquiryShelfBean.getAllDShelf(outInfo.gethSerial());
try{
log.info("产线可放料架数:"+shelfCountToLine+" 需求单["+outInfo.gethSerial()+"]分配小料架数:" + allDShelfs.size());
log.info(lineHasBindShelf + "产线可放料架数:"+shelfCountToLine+" 需求单["+outInfo.gethSerial()+"]分配小料架数:" + allDShelfs.size());
if(shelfCountToLine > 0 && shelfCountToLine < allDShelfs.size()){
//产线不可放下那么多料架,需要删减一车
int dShelfToRemove = allDShelfs.size() - shelfCountToLine;
......
......@@ -99,7 +99,8 @@ public class SettingsController extends BaseUpdateController {
oldSettings.setOrderFileDir(settings.getOrderFileDir());
oldSettings.setInactionDay(settings.getInactionDay());
log.info("设置 停止出入库="+settings.isStopOut()+" 停止自动任务=isStopJob()");
log.info("设置 停止出库="+settings.isStopOut()+"停止入库="+settings.isStopIn()+" 停止自动任务=" + settings.isStopJob());
oldSettings.setStopIn(settings.isStopIn());
oldSettings.setStopOut(settings.isStopOut());
oldSettings.setStopJob(settings.isStopJob());
......
......@@ -421,7 +421,6 @@ public class QisdaApiController extends BaseController {
log.error("替代料请求处理出错", e);
return ResultBean.newErrorResult(1001,"内部错误:" + e.getMessage());
}
}
/**
......@@ -440,24 +439,40 @@ public class QisdaApiController extends BaseController {
List<RequestOutItemBean> items = JsonUtil.toList(paramInfo, RequestOutItemBean.class);
Map<String,String> resultMap = new HashMap<>();
log.info("需求单修改时间请求解析成功,开始处理");
for (RequestOutItemBean itemBean : items) {
OutItem outItem = new OutItem(itemBean);
String hSerial = outItem.gethSerial();
OutInfo outInfo = outInfoCache.getOutInfoFromCache(hSerial);
String resultMsg = "";
if(outInfo == null){
resultMap.put(hSerial,"单号不存在");
log.info("需求单号["+hSerial+"]不存在");
resultMsg = "需求单号不存在";
}else{
boolean outInfoExecuted = outInfo.getFirstExecuteTime() > 0;
if(outInfoExecuted){
resultMap.put(hSerial,"已执行过,不允许修改");
resultMsg = "需求单已执行过,不允许修改";
}else{
outInfo.setMdate(outItem.getMdate());
outInfo.setSdate(outItem.getSdate());
outInfoCache.updateSMDate(outInfo);
resultMap.put(hSerial,"ok");
Date now = new Date();
Date oldMustDate = outInfo.getMdate();
Date newSuggestDate = outItem.getSdate();
Date newMustDate = outItem.getMdate();
// if(oldMustDate.before(now)){
// resultMsg = "需求单已到达必须时间,不允许修改";
// }else
if(newSuggestDate.before(now)){
resultMsg = "新的建议时间不能早于当前时间";
}else if(newMustDate.before(now)){
resultMsg = "新的必须时间不能早于当前时间";
}else{
outInfo.setMdate(outItem.getMdate());
outInfo.setSdate(outItem.getSdate());
outInfoCache.updateSMDate(outInfo);
resultMsg = "ok";
}
}
}
resultMap.put(hSerial, resultMsg);
log.info("需求单["+hSerial+"]修改时间结果:"+resultMsg);
}
return ResultBean.newOkResult(resultMap);
} catch (Exception e) {
......
......@@ -561,8 +561,8 @@ public class StorageDataController extends BaseController {
log.info("流水线["+cids+"]获取["+rfid+"]["+code+"]的入库库位");
Map<String,Object> resultMap = Maps.newHashMap();
if(dataCache.getSettings().isStopOut()){
lineMsg = "系统更新中,暂停出入库";
if(dataCache.getSettings().isStopIn()){
lineMsg = "系统已暂停入库";
resultMap.put("result","100");
resultMap.put("msg",lineMsg);
return resultMap;
......
......@@ -755,13 +755,14 @@ public class TaskService implements ITaskService {
}
}else{
//入库任务取消时,将库位置为不可用
log.info("库位["+task.getPosName()+"]料盘["+task.getBarcode()+"]入库任务取消,禁用库位");
log.info("库位["+task.getPosName()+"]料盘["+task.getBarcode()+"]入库任务取消,禁用库位,解除料盘锁定");
try {
StoragePos pos = storagePosManager.get(task.getPosId());
pos.setEnabled(false);
storagePosManager.save(pos);
Storage storage = dataCache.getStorage(task.getCid());
dataCache.reloadStorage(storage);
QisdaCache.removeReelLockPosInfo(task.getBarcode());
} catch (Exception e) {
log.error("入库任务取消时,禁用库位出错",e);
}
......@@ -816,18 +817,21 @@ public class TaskService implements ITaskService {
finishedTaskMap.remove(task.getBarcode());
if(prohibitePos){
log.info("库位["+task.getPosName()+"]料盘["+task.getBarcode()+"]空出,禁用库位");
task.setOutOrder(-task.getOutOrder());
try {
StoragePos pos = storagePosManager.get(task.getPosId());
pos.setEnabled(false);
storagePosManager.save(pos);
Storage storage = dataCache.getStorage(task.getCid());
dataCache.reloadStorage(storage);
} catch (ValidateException e) {
log.error("禁用库位出错:" , e);
//库位里面没有物料的不需禁用
if(!Strings.isNullOrEmpty(task.getBarcode())){
log.info("库位["+task.getPosName()+"]料盘["+task.getBarcode()+"]空出,禁用库位");
task.setOutOrder(-task.getOutOrder());
try {
StoragePos pos = storagePosManager.get(task.getPosId());
pos.setEnabled(false);
storagePosManager.save(pos);
Storage storage = dataCache.getStorage(task.getCid());
dataCache.reloadStorage(storage);
} catch (ValidateException e) {
log.error("禁用库位出错:" , e);
}
}
}
task.setStopSendToQisda(true);
......@@ -1402,12 +1406,12 @@ public class TaskService implements ITaskService {
resultStatus = statusBean;
} else if(statusBean.getOp() == StorageConstants.OP.PUT_IN){
if(!dataCache.getSettings().isStopOut()){
if(!dataCache.getSettings().isStopIn()){
log.debug("入库:"+mapper.writeValueAsString(statusBean));
resultStatus = putInLine(storage, statusBean);
}else {
resultStatus.setMsg("系统更新中,暂停出入库");
serverMsgs.put(cid,"系统更新中,暂停出入库");
resultStatus.setMsg("系统已暂停入库");
serverMsgs.put(cid,"系统已暂停入库");
}
}else {
......
......@@ -181,7 +181,11 @@
if(outInfo.reelCutAction){
executingHtml = executingHtml + infoHtml;
}else{
priorityHtml = priorityHtml + infoHtml;
if(priorityHtml == ""){
priorityHtml = priorityHtml + infoHtml;
}else{
waitHtml = waitHtml + infoHtml;
}
}
}else{
waitHtml = waitHtml + infoHtml;
......
......@@ -18,10 +18,6 @@
</style>
<c:if test="${stopOut}">
系统更新中,暂停出库,请稍后再试
</c:if>
<c:if test="${!stopOut}">
<!-- BEGIN PAGE HEADER-->
<h3 class="page-title">
......@@ -122,6 +118,11 @@
<display:column titleKey="需求时间" sortable="true" sortProperty="taskNeedOutDate">
<fmt:formatDate value="${outInfo.taskNeedOutDate}" pattern="yyyy-MM-dd HH:mm"/>
</display:column>
<display:column titleKey="状态" sortable="false" sortProperty="taskNeedOutDate">
<c:forEach var="eventItem" items="${outInfo.eventItems}">
<fmt:formatDate value="${eventItem.date}" pattern="yyyy-MM-dd HH:mm"/> ${eventItem.msg}</br>
</c:forEach>
</display:column>
<display:column titleKey="checkOut.operate" media="html" sortProperty="sendStatus" sortable="true">
<c:if test="${!outInfo.executing}">
......@@ -145,7 +146,6 @@
<!-- END EXAMPLE TABLE PORTLET-->
</div>
</div>
</c:if>
<div id="detail" class="modal fade" tabindex="-1" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog" style="margin-top: 10%;width:80%;margin-left:10%;">
......
......@@ -85,7 +85,7 @@
<display:column titleKey="storagePosFind.index">${pos_rowNum}</display:column>
<display:column property="posName" titleKey="checkOut.pos" sortProperty="posName" sortable="true"/>
<display:column titleKey="storage.enable" class="${enabledClass}">
<display:column titleKey="storage.enable" class="${enabledClass}" media="html">
<c:if test="${!pos.enabled}">
<fmt:message key="storage.enable.no"/>
[
......@@ -110,7 +110,7 @@
<fmt:formatDate value="${pos.updateDate}" pattern="yyyy-MM-dd HH:mm"/>
</display:column>
<display:column titleKey="">
<display:column titleKey="" media="html">
<button class="btn yellow" id="btn${pos.id}" onclick="checkoutPos('${pos.id}')">
<i class="fa fa-sign-out"></i><fmt:message key="button.checkout"/></button>
</display:column>
......
......@@ -73,7 +73,6 @@
</div>
</div>
<div class="portlet-title">
<div class="caption">
<i class="icon-bell font-green-haze"></i>
......@@ -83,7 +82,13 @@
<div class="portlet-body" style="padding-left: 30px;">
<div class="col-md-12">
<div class="input-group">
<label class="control-label"><fmt:message key="系统更新,暂停出入库"/> </label>
<label class="control-label"><fmt:message key="暂停入库"/> </label>
<form:checkbox path="stopIn" />
</div>
</div>
<div class="col-md-12">
<div class="input-group">
<label class="control-label"><fmt:message key="暂停出库"/> </label>
<form:checkbox path="stopOut"/>
</div>
</div>
......@@ -93,45 +98,8 @@
<form:checkbox path="stopJob"/>
</div>
</div>
</div>
<%--<div class="portlet-title">--%>
<%--<div class="caption">--%>
<%--<i class="icon-link font-green-haze"></i>--%>
<%--<span class="caption-subject bold uppercase font-green-haze"><fmt:message key="settings.api"/></span>--%>
<%--</div>--%>
<%--</div>--%>
<%--<div class="portlet-body" style="padding-left: 30px;">--%>
<%--<c:if test='<%=DataCache.isProductionFor("Pana") %>'>--%>
<%--<div class="form-group form-inline">--%>
<%--<div class="input-group margin-top-10"><fmt:message key="settings.api.checkBarcode"/>:</div>--%>
<%--<div class="input-group margin-top-10">--%>
<%--<form:input path="reelCheckApi" cssClass="form-control input-xlarge"/>--%>
<%--</div>--%>
<%--</div>--%>
<%--</c:if>--%>
<%--<div class="form-group form-inline">--%>
<%--<div class="input-group margin-top-10"><fmt:message key="settings.api.inNotifaction"/>:</div>--%>
<%--<div class="input-group margin-top-10">--%>
<%--<form:input path="inNotifyApi" cssClass="form-control input-xlarge"/>--%>
<%--</div>--%>
<%--</div>--%>
<%--<div class="form-group form-inline">--%>
<%--<div class="input-group margin-top-10"><fmt:message key="settings.api.outNotifaction"/>:</div>--%>
<%--<div class="input-group margin-top-10">--%>
<%--<form:input path="outNotifyApi" cssClass="form-control form-control input-xlarge"/>--%>
<%--</div>--%>
<%--</div>--%>
<%--<div class="form-group form-inline">--%>
<%--<div class="input-group margin-top-10"><fmt:message key="settings.api.orderFileDir"/>:</div>--%>
<%--<div class="input-group margin-top-10">--%>
<%--<form:input path="orderFileDir" cssClass="form-control form-control input-xlarge"/>--%>
<%--</div>--%>
<%--</div>--%>
<%--</div>--%>
</div>
<div class="form-actions">
<div class="row">
<div class="col-md-offset-5 col-md-12">
......
......@@ -12,6 +12,81 @@
<div class="row">
<div class="col-md-12">
<ul class="timeline">
<li class="timeline-blue">
<div class="timeline-time">
<span class="date">2021 </span>
<span class="time">05-06 </span>
</div>
<div class="timeline-icon">
<i class="fa fa-clock-o"></i>
</div>
<div class="timeline-body">
<h2>版本: V2021050610</h2>
<div class="timeline-content">
<ul>
<li>暂停入库和暂停出库开关,达到同一时间只入库或只出库的目的</li>
<li>手动对无物料库位出库时,不禁用库位</li>
</ul>
</div>
</div>
</li>
<li class="timeline-yellow">
<div class="timeline-time">
<span class="date">2021 </span>
<span class="time">04-25 </span>
</div>
<div class="timeline-icon">
<i class="fa fa-clock-o"></i>
</div>
<div class="timeline-body">
<h2>版本: V2021042516</h2>
<div class="timeline-content">
<ul>
<li>包装仓紧急料出到NG箱</li>
<li>修改需求单时间时,详细异常信息打印及返回</li>
<li>入库任务取消时,解除锁定库位</li>
</ul>
</div>
</div>
</li>
<li class="timeline-grey">
<div class="timeline-time">
<span class="date">2021</span>
<span class="time">04-20</span>
</div>
<div class="timeline-icon">
<i class="fa fa-clock-o"></i>
</div>
<div class="timeline-body">
<h2>版本: V2021042016</h2>
<div class="timeline-content">
<ul>
<li>需求单排队按必须出仓时间</li>
<li>允许修改已到必须出仓时间的需求单</li>
<li>优先队列里最多只展示一个需求单</li>
<li>记录需求单状态变化</li>
</ul>
</div>
</div>
</li>
<li class="timeline-purple">
<div class="timeline-time">
<span class="date">2021</span>
<span class="time">04-12</span>
</div>
<div class="timeline-icon">
<i class="fa fa-clock-o"></i>
</div>
<div class="timeline-body">
<h2>版本: V2021041213</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">2021</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: 2021.04.01</span>
<span class="right" style="color: #a3a3a3;">Version: 2021.05.06</span>
<div class="scroll-to-top">
<i class="icon-arrow-up"></i>
</div>
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!