Index: ssts-tousse/src/main/java/com/forgon/disinfectsystem/tousse/toussedefinition/service/TousseInstanceManager.java =================================================================== diff -u -r26083 -r26405 --- ssts-tousse/src/main/java/com/forgon/disinfectsystem/tousse/toussedefinition/service/TousseInstanceManager.java (.../TousseInstanceManager.java) (revision 26083) +++ ssts-tousse/src/main/java/com/forgon/disinfectsystem/tousse/toussedefinition/service/TousseInstanceManager.java (.../TousseInstanceManager.java) (revision 26405) @@ -317,9 +317,9 @@ * @param tousseType 器械包类型 * @param reason 废弃原因 * @param userName 废弃人-当前登录用户 - * @return + * @return long 处理数量 */ - public boolean deleteAllExpiredTousseGoods(String orgUnitCoding,String warningType,String tousseType,String reason,String userName); + public long deleteAllExpiredTousseGoods(String orgUnitCoding,String warningType,String tousseType,String reason,String userName); /** * 验证器械包是否被召回 Index: ssts-web/src/main/webapp/disinfectsystem/assestManagement/tousseGoods/tousseGoodsWarningView.js =================================================================== diff -u -r24817 -r26405 --- ssts-web/src/main/webapp/disinfectsystem/assestManagement/tousseGoods/tousseGoodsWarningView.js (.../tousseGoodsWarningView.js) (revision 24817) +++ ssts-web/src/main/webapp/disinfectsystem/assestManagement/tousseGoods/tousseGoodsWarningView.js (.../tousseGoodsWarningView.js) (revision 26405) @@ -57,14 +57,25 @@ var warningType = Ext.getCmp('warningType').getValue(); var tousseType = Ext.getCmp('tousseType').getValue(); var remark = showSelectTousseDiscardCauseWin(); + Ext.getBody().mask("正在处理,请稍候..."); Ext.Ajax.request({ + timeout:30 * 60 * 1000,//半小时 url : WWWROOT + '/disinfectSystem/tousseInstanceAction!deleteAllTousseGoods.do', params : {reason:remark,warningType : warningType , tousseType : tousseType,department:department}, success : function(response, options) { - showResult("废弃成功!"); - grid.dwrReload(); + Ext.getBody().unmask(); + var result = Ext.decode(response.responseText); + if(result.success){ + showResult("废弃完成,废弃的器械包总数量为" + result.amount); + grid.dwrReload(); + }else{ + showResult("废弃失败,原因为:" + result.message); + } }, - failure : function(response, options) {} + failure : function(response, options) { + Ext.getBody().unmask(); + showResult("废弃失败,请稍后再试..."); + } }); } } @@ -619,8 +630,8 @@ title : '器械包物品告警列表', tbar : tbarForFirstRow, pageSize : 20, - defaultSortField : 'validUntil', - defaultSortDirection : 'ASC', +// defaultSortField : 'validUntil',//排序性能很慢,先去掉 +// defaultSortDirection : 'ASC', isCheckboxSelectionModel : true, rememberSelected : false, isShowSearchField : true, Index: ssts-packing/src/main/java/com/forgon/disinfectsystem/packing/action/TousseInstanceAction.java =================================================================== diff -u -r26367 -r26405 --- ssts-packing/src/main/java/com/forgon/disinfectsystem/packing/action/TousseInstanceAction.java (.../TousseInstanceAction.java) (revision 26367) +++ ssts-packing/src/main/java/com/forgon/disinfectsystem/packing/action/TousseInstanceAction.java (.../TousseInstanceAction.java) (revision 26405) @@ -1057,7 +1057,10 @@ out.close(); } - // 废弃器械包物品 + /** + * 废弃器械包物品(页面选中的器械包实例id(多个用分号分隔)作为request请求参数传至后台) + * 对应系统告警-器械包告警页面的"废弃"按钮 + */ public void deleteTousseGood() { String wasteReason = StrutsParamUtils.getPraramValue("reason", @@ -1116,8 +1119,17 @@ StrutsResponseUtils.output(jobj); } - // 废弃全部器械包物品 + /** + * 废弃全部符合条件的器械包物品 + * request请求参数有以下: + * warningType 告警类型 + * tousseType 器械包类型 + * reason 理由 + * department 所选科室编码 + * 对应系统告警-器械包告警页面的"全部废弃"按钮 + */ public void deleteAllTousseGoods() { + JSONObject result = JSONUtil.buildJsonObject(false); //当前用户所属科室编码 String departCodeOfCurrentUser = AcegiHelper.getCurrentOrgUnitCode(); //所选择的科室编码 @@ -1129,8 +1141,16 @@ String reason = StrutsParamUtils.getPraramValue("reason", ""); String userName = AcegiHelper.getLoginUser() .getUserFullName(); - tousseInstanceManager.deleteAllExpiredTousseGoods(queryDepartCode, - warningType , tousseType,reason,userName); + try{ + long amount = tousseInstanceManager.deleteAllExpiredTousseGoods(queryDepartCode, + warningType , tousseType,reason,userName); + JSONUtil.addSuccess(result, true); + result.put("amount", amount); + }catch(Exception e){ + e.printStackTrace(); + JSONUtil.addMessage(result, e.getMessage()); + } + StrutsResponseUtils.output(result); } @SuppressWarnings({ "static-access"}) Index: ssts-tousse/src/main/java/com/forgon/disinfectsystem/tousse/toussedefinition/service/TousseInstanceManagerImpl.java =================================================================== diff -u -r26367 -r26405 --- ssts-tousse/src/main/java/com/forgon/disinfectsystem/tousse/toussedefinition/service/TousseInstanceManagerImpl.java (.../TousseInstanceManagerImpl.java) (revision 26367) +++ ssts-tousse/src/main/java/com/forgon/disinfectsystem/tousse/toussedefinition/service/TousseInstanceManagerImpl.java (.../TousseInstanceManagerImpl.java) (revision 26405) @@ -19,6 +19,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import java.util.stream.Collector; import java.util.stream.Collectors; import jxl.Workbook; @@ -35,6 +36,7 @@ import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import org.hibernate.Query; +import org.hibernate.Session; import com.forgon.Constants; import com.forgon.databaseadapter.service.DateQueryAdapter; @@ -263,9 +265,33 @@ */ @Override public void autoWasteOutdateTousseInstances(){ - List outdateTousseInstanceList = - objectDao.getHibernateSession().createQuery("from TousseInstance where status not in ('"+TousseInstance.STATUS_USED+"','"+TousseInstance.STATUS_RECYCLED+"','"+TousseInstance.STATUS_DISCARD+"') and validUntil < :validUntil").setDate("validUntil", new java.sql.Timestamp(new Date().getTime())).list(); - discardTousseInstance(outdateTousseInstanceList,"系统定时器","失效期过期定时废弃处理"); + logger.debug("autoWasteOutdateTousseInstances start..." + System.currentTimeMillis()); + //每次处理的数据量 + int processAmount = 1000; + Session session = objectDao.getHibernateSession(); + //废弃循环次数 + int times = 0; + //已废弃数量 + int wastedAmount = 0; + do{ + logger.debug("autoWasteOutdateTousseInstances times=" + times++ + ",start..." + System.currentTimeMillis()); + Query query = session.createQuery("from "+ TousseInstance.class.getSimpleName() +" where status not in ('"+TousseInstance.STATUS_USED+"','"+TousseInstance.STATUS_RECYCLED+"','"+TousseInstance.STATUS_DISCARD+"') and validUntil < :validUntil"); + query.setDate("validUntil", new java.sql.Timestamp(new Date().getTime())); + query.setFirstResult(0); + query.setMaxResults(processAmount); + @SuppressWarnings("unchecked") + List outdateTousseInstanceList = query.list(); + logger.debug("autoWasteOutdateTousseInstances after query..." + System.currentTimeMillis()); + if(CollectionUtils.isNotEmpty(outdateTousseInstanceList)){ + discardTousseInstance(outdateTousseInstanceList,"系统定时器","失效期过期定时废弃处理"); + logger.debug("autoWasteOutdateTousseInstances waste tousse amount = " + outdateTousseInstanceList.size()); + wastedAmount += outdateTousseInstanceList.size(); + }else{ + break; + } + }while(true); + logger.debug("autoWasteOutdateTousseInstances end..." + System.currentTimeMillis()); + logger.debug("autoWasteOutdateTousseInstances wastedAmount=" + wastedAmount); } @Override @@ -2376,66 +2402,102 @@ } @Override - public boolean deleteAllExpiredTousseGoods(String orgUnitCoding, + public long deleteAllExpiredTousseGoods(String orgUnitCoding, String warningType,String tousseType ,String reason,String userName) { - boolean isCommandExecutedSuccessfully = true; + //每次处理的数据量 + int processAmount = 1000; + //废弃循环次数 + int times = 0; + //已废弃数量 + long wastedAmount = 0; + do{ + logger.debug("deleteAllExpiredTousseGoods times = " + times++); + logger.debug("deleteAllExpiredTousseGoods while start = " + System.currentTimeMillis()); + JSONObject result = deleteAllExpiredTousseGoods(orgUnitCoding, + warningType, tousseType , reason, userName , processAmount); + logger.debug("deleteAllExpiredTousseGoods while end = " + System.currentTimeMillis()); + if(!result.optBoolean(JSONUtil.JSON_KEY_SUCCESS)){ + break; + } + wastedAmount += result.optInt("amount"); + }while(true); + logger.debug("deleteAllExpiredTousseGoods method end = " + System.currentTimeMillis()); + logger.debug("deleteAllExpiredTousseGoods wastedAmount = " + wastedAmount); + throw new RuntimeException("test"); +// return true; + } + + /** + * 废弃器械包 + * @param orgUnitCoding 科室编码 + * @param warningType 告警类型 + * @param tousseType 器械包类型 + * @param reason 理由 + * @param userName 废弃人 + * @param processAmount 处理数据量 + * @return + */ + private JSONObject deleteAllExpiredTousseGoods(String orgUnitCoding, + String warningType,String tousseType ,String reason,String userName , int processAmount) { + JSONObject result = JSONUtil.buildJsonObject(false); String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); - String wasteUpdateSql = "update TousseInstance set status = '" - + TousseInstance.STATUS_DISCARD + "',wasteReason = '"+reason+"',operateUser = '"+userName+"'," -// +"wasteDate = '"+date+"'"; - +"wasteDate = "+dateQueryAdapter.dateAdapter(date); - - String sqlCondition = " where 1=1 "; + String condition = " where 1=1 "; //状态为已发货或已签收时,包所在位置为当前用户所属科室 - sqlCondition +=" and ((" + SqlBuilder.build_IN_Statement("status", SqlBuilder.IN, + condition +=" and ((" + SqlBuilder.build_IN_Statement("status", SqlBuilder.IN, TousseInstance.STATUS_SHIPPED, TousseInstance.STATUS_SIGNED) + " and location = '" + orgUnitCoding + "')"; //或状态为已灭菌时,当前用户所属科室装配的包 - sqlCondition += " or (orgUnitCoding ='"+orgUnitCoding+"'"; - sqlCondition += " and " + SqlBuilder.build_IN_Statement("status", SqlBuilder.IN, + condition += " or (orgUnitCoding ='"+orgUnitCoding+"'"; + condition += " and " + SqlBuilder.build_IN_Statement("status", SqlBuilder.IN, TousseInstance.STATUS_STERILED) + "))"; String dateSqlCondition = dateQueryAdapter.dateAdapter(date); //已过期的器械包 if (SystemWarningItemVO.WARNING_TYPE_DISABLED_TOUSSE .equals(warningType)) { - sqlCondition += " and validUntil < " + dateSqlCondition; + condition += " and validUntil < " + dateSqlCondition; } else if (SystemWarningItemVO.WARNING_TYPE_TOUSSE .equals(warningType)){//即将过期的器械包 - sqlCondition += " and validUntil > " + dateSqlCondition + " and warningUntil < " + dateSqlCondition; + condition += " and validUntil > " + dateSqlCondition + " and warningUntil < " + dateSqlCondition; }else{ //为全部时:含已过期的器械包与即将过期的器械包 - sqlCondition += " and (validUntil < " + dateSqlCondition; - sqlCondition += " or (validUntil > " + dateSqlCondition + " and warningUntil < " + dateSqlCondition + ")" + condition += " and (validUntil < " + dateSqlCondition; + condition += " or (validUntil > " + dateSqlCondition + " and warningUntil < " + dateSqlCondition + ")" + ")"; } - //hql语法的条件 - String hqlCondition = sqlCondition; //器械包类型 if(StringUtils.isNotBlank(tousseType)){ - sqlCondition += " and tousseDefinition_id in (select id from TousseDefinition where tousseType = '" + tousseType + "')"; - hqlCondition += " and tousseDefinition.tousseType = '" + tousseType + "'"; + condition += " and tousseDefinition.tousseType = '" + tousseType + "'"; } try { - List waitWasteTousseInstanceList = - objectDao.findBySql(TousseInstance.class.getSimpleName(),hqlCondition); + @SuppressWarnings("unchecked") + List waitWasteTousseInstanceList = + objectDao.findBySql(TousseInstance.class.getSimpleName(),condition , 0 , processAmount , null); if(CollectionUtils.isNotEmpty(waitWasteTousseInstanceList)){ List goodsStockList = new ArrayList<>(); //更新器械包库存 goodsStockManager.addToList(goodsStockList, waitWasteTousseInstanceList); -// goodsStockList = TousseInstanceUtils.newGoodsStock(waitWasteTousseInstanceList); + String wasteUpdateSql = "update TousseInstance set status = '" + + TousseInstance.STATUS_DISCARD + "',wasteReason = '"+reason+"',operateUser = '"+userName+"'," + +"wasteDate = "+dateQueryAdapter.dateAdapter(date); + List tousseInstanceIdList = + waitWasteTousseInstanceList.stream().map(p -> p.getId()).collect(Collectors.toList()); + logger.debug("deleteAllExpiredTousseGoods tousseInstanceIdList=" + tousseInstanceIdList); //需要先更新包实例状态为废弃,再扣减库存.如果库存不够,这样校验机制才会是正确的 - objectDao.excuteSQL(wasteUpdateSql + sqlCondition); + objectDao.excuteSQL(wasteUpdateSql + " where " + SqlUtils.getNonStringFieldInLargeCollectionsPredicate("id", + tousseInstanceIdList)); goodsStockManager.saveOrUpdateGoodsStock(goodsStockList, GoodsStockManager.MODE_OUTSTOCK); + JSONUtil.addSuccess(result, true); + result.put("amount", waitWasteTousseInstanceList.size()); } } catch (Exception e) { e.printStackTrace(); - isCommandExecutedSuccessfully = false; + throw new RuntimeException(e); } - return isCommandExecutedSuccessfully; + return result; } @Override