Index: ssts-packing/src/main/java/com/forgon/disinfectsystem/packing/service/PackingManagerImpl.java =================================================================== diff -u -r40649 -r40663 --- ssts-packing/src/main/java/com/forgon/disinfectsystem/packing/service/PackingManagerImpl.java (.../PackingManagerImpl.java) (revision 40649) +++ ssts-packing/src/main/java/com/forgon/disinfectsystem/packing/service/PackingManagerImpl.java (.../PackingManagerImpl.java) (revision 40663) @@ -41,6 +41,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; +import com.forgon.disinfectsystem.entity.basedatamanager.container.ContainerBinding; import com.forgon.disinfectsystem.packing.vo.*; import net.sf.json.JSONArray; import net.sf.json.JSONException; @@ -5699,9 +5700,16 @@ int foreignTousseSplitPriceType = ConfigUtils.getSystemSetConfigByNameInt("foreignTousseSplitPriceType", TousseDefinition.FOREIGNTOUSSE_SPLIT_PRICE_TYPE_TD); Set departCodings = new HashSet(); boolean enableTraceableToussesShippedBackToTheOriginalApplyInfoFunction = CssdUtils.getSystemSetConfigByNameBool("enableTraceableToussesShippedBackToTheOriginalApplyInfoFunction", false); + boolean enbaleLoadAutomaticallyIntoBasketsAfterAssembly = CssdUtils.getSystemSetConfigByNameBool("enbaleLoadAutomaticallyIntoBasketsAfterAssembly",false); + Set cleaningContainerIds = new HashSet<>(); for (PackingTask packingTask : packingTasks) { tdOfPackingTask = packingTask.getTousseDefinition(); + //启用装配后自动装载到篮筐 整包清洗 并且 只入到一个篮筐 + if(enbaleLoadAutomaticallyIntoBasketsAfterAssembly && tdOfPackingTask.cleanedEntirely() + && packingTask.getClassifyBasket_id() != null) { + cleaningContainerIds.add(packingTask.getClassifyBasket_id()); + } // 判断包定义的配置是否需要打印材料 if(TousseDefinition.STR_YES.equals(tdOfPackingTask.getIsPrint()) && TousseDefinition.STR_YES.equals(tdOfPackingTask.getIsPrintMaterialForPacking())){ // json.put("tousseDefinition", JSONObject.fromObject(td , cfg));//会报json异常(net.sf.json.JSONException: There is a cycle in the hierarchy) @@ -5723,6 +5731,7 @@ if(ancestorTd == null && DatabaseUtil.isPoIdValid(tdOfPackingTask.getAncestorID())){ ancestorTd = tousseDefinitionManager.get(tdOfPackingTask.getAncestorID()); } + if(ancestorTd != null && Constants.STR_YES.equals(ancestorTd.getShipBackToOriginalApply())){ throw new SystemException("【"+ ancestorTd.getName() +"】设置了需要发货回原申请单,无法进行聚合包、操作。"); } @@ -5736,6 +5745,7 @@ } } } + Map containerBindingInfo = getContainerBindingInfo(cleaningContainerIds); if(packingPara.getCreateSetCode() && departCodings.size() > 1){ throw new SystemException("只支持同科室物品合并生成器械包集合码,请检查物品后重新操作。"); } @@ -6295,6 +6305,11 @@ bindImageVideoWithTousseInstance(packingTaskIdToTousseInstanceIdMap); //生成器械包集合码 createSetCode(packingPara, tousseNameAmountMap, toussesArray, json); + JSONObject autoResult = autobasketInsertion(tousseInstanceList, containerBindingInfo); + if(autoResult != null){ + json.put("containerStatusMsgs", autoResult.optString("containerStatusMsgs")); + json.put("successIntoBasket", autoResult.optString("successIntoBasket")); + } }else{ batchLoadToVirtaulBasket = false;//器械包批量装入虚拟篮筐是否成功 batchLoadMsg = "装配任务id为空"; @@ -6338,7 +6353,357 @@ //if(true){throw new RuntimeException("装配速度测试 ");} return json.toString(); } + @Override + public JSONObject autobasketInsertion(List tousseInstances, Map cntainerBindingInfo) { + if(CollectionUtils.isEmpty(tousseInstances) || MapUtils.isEmpty(cntainerBindingInfo)){ + return null; + } + try{ + //先按篮筐分组 + Map> groups = new HashMap<>(); + Set packageTypes = new HashSet(); + for (TousseInstance tousseInstance : tousseInstances) { + TousseDefinition td = tousseInstance.getTousseDefinition(); + if(tousseInstance.getClassifyBasket_id() != null && td.cleanedEntirely()) { + Long stContainerId = cntainerBindingInfo.get(tousseInstance.getClassifyBasket_id()); + if(!DatabaseUtil.isPoIdValid(stContainerId)){ + continue; + } + if(StringUtils.isNotBlank(tousseInstance.getPackageType())){ + packageTypes.add(tousseInstance.getPackageType()); + } + List tis = null; + if(groups.containsKey(stContainerId)){ + tis = groups.get(stContainerId); + }else{ + tis = new ArrayList<>(); + groups.put(stContainerId, tis); + } + tis.add(tousseInstance); + } + } + List statusLogMsgs = new ArrayList(); + List containerStatusMsgs = new ArrayList(); + boolean haveSuccessMsgs = false; + if(MapUtils.isNotEmpty(groups)){ + String databaseNowTime = DatabaseUtil.getSqlNowDateTimeExpress(dbConnection); + Map expirationDateInfoMap = getExpirationDateInfoMap(packageTypes); + LoginUserData loginUser = AcegiHelper.getLoginUser(); + boolean enableFlexiblePriceCalculationOfDisinfectionGoodsFunction = CssdUtils.getSystemSetConfigByNameBool("enableFlexiblePriceCalculationOfDisinfectionGoodsFunction", false); + int expirationDateValueMode = ConfigUtils.getSystemSetConfigByNameInt("expirationDateValueMode", 0); + String reviewerName = loginUser.getUserFullName(); + String reviewerCode = loginUser.getUserName(); + Date sterileDate = new Date(); + // 灭菌开始时间 + String sterileStartTime = TousseInstanceUtils.buildSterileStartTime(sterileDate); + Date now = new Date(); + String coding = loginUser.getCurrentOrgUnitCode(); + WareHouse wareHouse = wareHouseManager.getDefaultWareHouseByUnitCode(coding); + SupplyRoomConfig supplyRoomConfig = supplyRoomConfigManager + .getSupplyRoomConfigByOrgUnitCoding(coding); + // 读取配置:是否在审核时打印标签,决定是否需要修改灭菌开始时间 + boolean needToModifySterileDate = CssdUtils.getSystemSetConfigByNameBool("printLabelWhenReviewing", false); + for (Entry> entry : groups.entrySet()) { + Long stContainerId = entry.getKey(); + Container container = containerManager.get(stContainerId); + if(!Container.CONTAINER_STATUS_FREE.equals(container.getStatus()) + && !Container.CONTAINER_STATUS_STERILIZELOADING.equals(container.getStatus())){ + statusLogMsgs.add("装配后自动审核入筐异常:" + container.getContainerName() + "状态不为空闲或灭菌装载"); + containerStatusMsgs.add(container.getContainerName() + "的篮筐状态不为空闲,无法自动放入物品,请手动装载相关物品。"); + continue; + } + ReviewedBasket reviewedBasket = reviewedBasketManager.getReviewedBasketButNew(container); + reviewedBasketManager.saveOrUpdate(reviewedBasket); + List tis = entry.getValue(); + Collection ids = new ArrayList(); + for (TousseInstance ti : tis) { + ids.add(ti.getId()); + } + Map tousseInstanceAdditionalInfoMap = null; + if(enableFlexiblePriceCalculationOfDisinfectionGoodsFunction){ + @SuppressWarnings("unchecked") + List tousseInstanceAdditionalInfos = objectDao.findByHql("select po from " + TousseInstanceAdditionalInfo.class.getSimpleName() + " po where " + SqlUtils.getNonStringFieldInLargeCollectionsPredicate("po.tousseInstanceId", ids)); + tousseInstanceAdditionalInfoMap = new HashMap(); + if(!CollectionUtils.isEmpty(tousseInstanceAdditionalInfos)){ + for (TousseInstanceAdditionalInfo info : tousseInstanceAdditionalInfos) { + tousseInstanceAdditionalInfoMap.put(info.getTousseInstanceId(), info); + } + } + } + //获取器械包审核前所在的虚拟篮筐集合 + List virtualBasketNameList = new ArrayList(); + + Set idsForUpdateReviewer = new HashSet(); + if(reviewedBasket != null + && reviewedBasket.getContainer() != null + && Container.CONTAINER_PURPOSE_VIRTUAL.equals(reviewedBasket.getContainer().getPurpose()) + && StringUtils.isNotBlank(reviewedBasket.getContainer().getContainerName())){ + virtualBasketNameList.add(reviewedBasket.getContainer().getContainerName()); + } + Set oldReviewBasketIds = new HashSet();//包实例中VirtualBasketSeqNum为空的篮筐id 数据中是有这种虚拟筐的 + + List tousses = new ArrayList();//拷贝数据,批量进行修改提高效率 对查询出来的tousses2的修改不是批量修改 速度较慢 + + + for (TousseInstance tousseInstance : tis) { + try { + tousses.add(tousseInstance.clone()); + } catch (Exception e) { + logger.error(e.getMessage()); + } + } + Map increaseStockByTousseNameMap = new HashMap(); + + for (TousseInstance tousseInstance : tousses) { + TousseDefinition td = tousseInstance + .getTousseDefinition(); + + if (!TousseDefinition.STR_NO.equals(td.getIsReview())){ + tousseInstance.setReviewer(reviewerName); + tousseInstance.setReviewerCode(reviewerCode); + tousseInstance.setReviewTime(now); + if(needToModifySterileDate){ + tousseInstance.setSterileStartTime(sterileStartTime); + } + if(DatabaseUtil.isPoIdValid(tousseInstance.getPackingRecord_id())){ + idsForUpdateReviewer.add(tousseInstance.getPackingRecord_id()); + } + } + //获取审核前虚拟篮筐 + String virtualBasketSeqNum = tousseInstance.getVirtualBasketSeqNum(); + if(StringUtils.isNotBlank(virtualBasketSeqNum) && !virtualBasketNameList.contains(virtualBasketSeqNum)){ + virtualBasketNameList.add(virtualBasketSeqNum); + }else if(DatabaseUtil.isPoIdValid(tousseInstance.getReviewBasket_id())){ + oldReviewBasketIds.add(tousseInstance.getReviewBasket_id()); + } + // 审核的是消毒物品 + if (td.isDisinfection()) { + // 更新包状态 + //如果为需要灭菌,则更改其状态为已审核(针对省医的高水平消毒的需求增加的处理,since 2016-01-20 SYF) + TousseInstanceAdditionalInfo info = null; + if(enableFlexiblePriceCalculationOfDisinfectionGoodsFunction){ + info = tousseInstanceAdditionalInfoMap.get(tousseInstance.getId()); + } + boolean sterilizedThisTime = false; + if(info != null){ + sterilizedThisTime = info.getSterilizedThisTime(); + } + if(td.isSterile(sterilizedThisTime)){ + tousseInstance.setStatus(TousseInstance.STATUS_REVIEWED); + //对应器械包实例的篮筐实例编号需要赋值 + if (reviewedBasket != null) { + tousseInstance.setReviewBasket_id(reviewedBasket.getId()); + tousseInstance.setVirtualBasketSeqNum(null);//需要将虚拟篮筐的别名字段也删除,防止还能通过别名查到 + tousseInstance.setSterilizationBasket(container.getContainerName()); + } + }else{ + if (supplyRoomConfig != null){ + int supplyRoomType = supplyRoomConfig.getSupplyRoomType(); + if(wareHouse != null && TousseInstance.STATUS_DISINFECTED.equals(tousseInstance.getStatus()) + || TousseInstance.STATUS_STERILED.equals(tousseInstance.getStatus())){ + tousseInstance.setWareHouseId(wareHouse.getId()); + tousseInstance.setWareHouseName(wareHouse.getName()); + } + if (supplyRoomType == SupplyRoomConfig.SUPPLYROOM_TYPE_FIRST_SUPPLYROOM) { + // 更新消毒物品的库存 + + boolean isTraceable = tousseInstance.getUnTraceableTousse(); + + String name = tousseInstance.getTousseDefinitionName(); + + // 如果不追溯,则库存的名字不需要带下划线 + if (!isTraceable){ + name = CssdUtils.filterDisinfectGoodsName(name); + } + increaseStockByTousseNameMap.put(name, MathTools.add(1, increaseStockByTousseNameMap.get(name)).intValue()); + } + } + } + + } + // 非消毒物品(器械包或者外来器械包等) + else{ + tousseInstance.setStatus(TousseInstance.STATUS_REVIEWED); + + //如果灭菌篮筐不为空,则将审核篮筐实例的id设置为传入的灭菌篮筐的id,再将其虚拟篮筐的名称置空 + if (reviewedBasket != null) { + tousseInstance.setReviewBasket_id(reviewedBasket.getId()); + tousseInstance.setVirtualBasketSeqNum(null);//需要将虚拟篮筐的别名字段也删除,防止还能通过别名查到 + if (reviewedBasket.getContainer() != null) { + tousseInstance.setSterilizationBasket(reviewedBasket.getContainer().getContainerName()); + } + } + //改为批量修改了 所以注释掉 + //tousseInstanceManager.save(tousseInstance); + + //如果审核的是聚合包时,包内的包实例也需要赋值 + if(tousseInstance.isComboTousse()){ + String reviewedBasketIdUpdateValue = tousseInstance.getReviewBasket_id() == null ? "null" : String.valueOf(tousseInstance.getReviewBasket_id()); + String sterilizationBasketUpdateValue = StringUtils.isBlank(tousseInstance.getSterilizationBasket()) ? "null" : "'" + String.valueOf(tousseInstance.getSterilizationBasket()) + "'"; + + String sterileStartTimeSql = ""; + // 如果需要修改灭菌开始时间 + if(needToModifySterileDate){ + sterileStartTimeSql = "sterileStartTime='" + sterileStartTime + "',"; + } + String reviewerUpdateValue = StringUtils.isBlank(tousseInstance.getReviewer()) ? "null" : "'" + String.valueOf(tousseInstance.getReviewer()) + "'"; + String reviewerCodeUpdateValue = StringUtils.isBlank(tousseInstance.getReviewerCode()) ? "null" : "'" + String.valueOf(tousseInstance.getReviewerCode()) + "'"; + objectDao.excuteSQL(String.format("update TousseInstance set status=%s, reviewTime=%s, %s reviewBasket_id=%s, sterilizationBasket=%s, reviewer=%s, reviewerCode=%s where comboTousseInstanceId=%d", + "'"+ TousseInstance.STATUS_REVIEWED +"'",databaseNowTime,sterileStartTimeSql,reviewedBasketIdUpdateValue,sterilizationBasketUpdateValue,reviewerUpdateValue,reviewerCodeUpdateValue,tousseInstance.getId())); + } + } + + String packageType = tousseInstance.getPackageType(); + + // 失效期和预警期计算 + JSONObject expirationObj = expirationDateInfoManager.getExpirationDate(sterileDate, packageType,expirationDateInfoMap); + + boolean isDefined = expirationObj.optBoolean("isDefined"); + if (isDefined){ + Date validUntil = (Date)JSONObject.toBean(expirationObj.optJSONObject("validUntil"), Date.class); + Date warningUntil = (Date)JSONObject.toBean(expirationObj.optJSONObject("warningUntil"), Date.class); + + if(expirationDateValueMode == 1){ + if(tousseInstance.getValidUntil() != null){ + if(tousseInstance.getValidUntil().before(validUntil)){ + //装配失效期早于审核失效期,则不修改失效期NYSY-68 + validUntil = tousseInstance.getValidUntil(); + } + } + if(tousseInstance.getWarningUntil() != null){ + if(tousseInstance.getWarningUntil().before(warningUntil)){ + //装配预警期早于审核预警期,则不修改预警期NYSY-68 + warningUntil = tousseInstance.getWarningUntil(); + } + } + } + tousseInstance.setValidUntil(validUntil); + tousseInstance.setWarningUntil(warningUntil); + } + } + if(increaseStockByTousseNameMap.size() > 0){ + tousseStockManager.increaseStockByTousseNameAmoutMap(increaseStockByTousseNameMap); + } + //联动需改装配记录的审核人 + Set idsWithoutReviewer = new HashSet(); + + List packRecords = objectDao.findByIds(PackingRecord.class.getSimpleName(), new ArrayList(idsForUpdateReviewer)); + for (PackingRecord packingRecord : packRecords) { + //审核每一个消毒包时,需要检查这个包所关联的装配记录的审核人是否为空,如果为空,则需要进行赋值;如果不为空,不进行赋值。 + if(StringUtils.isBlank(packingRecord.getReviewer()) || StringUtils.isNotBlank(reviewerName)){ + idsWithoutReviewer.add(packingRecord.getId()); + } + } + updateReviewersOfPackingRecordByTousseInstanceIds( + StringUtils.isBlank(reviewerName) ? loginUser.getUserFullName() : reviewerName, idsWithoutReviewer); + + StringBuffer batchSql = new StringBuffer(); + batchSql.append("update "); + batchSql.append(TousseInstance.class.getSimpleName()); + batchSql.append(" set reviewBasket_id=?,reviewTime=?,sterilizationBasket=?,validUntil=?,warningUntil=?" + + ",status=?,sterileStartTime=?,reviewer=?,reviewerCode=?,virtualBasketSeqNum=?" + + ",Location=?,LocationForDisplay=?,settleAccountsDepartCode=?,settleAccountsDepart=?,Invoice_id=?" + + ",wareHouseId=?,wareHouseName=?" + + " where id=?"); + Timestamp newDate = new Timestamp(new Date().getTime()); + jdbcTemplate.batchUpdate(batchSql.toString(), new BatchPreparedStatementSetter() { + + @Override + public void setValues(PreparedStatement ps, int i) throws SQLException { + TousseInstance ti = tousses.get(i); + if(DatabaseUtil.isPoIdValid(ti.getReviewBasket_id())){ + ps.setLong(1, ti.getReviewBasket_id()); + }else{ + ps.setObject(1, null); + } + ps.setTimestamp(2, newDate); + ps.setString(3, ti.getSterilizationBasket()); + if(ti.getValidUntil() != null){ + ps.setTimestamp(4, new Timestamp(ti.getValidUntil().getTime())); + }else{ + ps.setTimestamp(4, null); + } + if(ti.getWarningUntil() != null){ + ps.setTimestamp(5, new Timestamp(ti.getWarningUntil().getTime())); + }else{ + ps.setTimestamp(5, null); + } + ps.setString(6, ti.getStatus()); + ps.setString(7, ti.getSterileStartTime()); + ps.setString(8, ti.getReviewer()); + ps.setString(9, ti.getReviewerCode()); + ps.setString(10, ti.getVirtualBasketSeqNum()); + ps.setString(11, ti.getLocation()); + ps.setString(12, ti.getLocationForDisplay()); + ps.setString(13, ti.getSettleAccountsDepartCode()); + ps.setString(14, ti.getSettleAccountsDepart()); + if(DatabaseUtil.isPoIdValid(ti.getInvoice_id())){ + ps.setLong(15, ti.getInvoice_id()); + }else{ + ps.setObject(15, null); + } + if(DatabaseUtil.isPoIdValid(ti.getWareHouseId())){ + ps.setLong(16, ti.getWareHouseId()); + }else{ + ps.setObject(16, null); + } + ps.setString(17, ti.getWareHouseName()); + ps.setLong(18, ti.getId()); + } + + @Override + public int getBatchSize() { + return tousses.size(); + } + }); + if(oldReviewBasketIds.size() > 0){ + //查询篮筐id中的虚拟筐 + StringBuffer sql = new StringBuffer(); + sql.append("select containerName from ") + .append(Container.class.getSimpleName()) + .append(" c join ") + .append(ReviewedBasket.class.getSimpleName()) + .append(" rb on rb.container_id=c.id where c.purpose='") + .append(Container.CONTAINER_PURPOSE_VIRTUAL) + .append("' and c.containerType='") + .append(Container.CONTAINERTYPE_BASKET) + .append("' and ") + .append(SqlUtils.getNonStringFieldInLargeCollectionsPredicate("rb.id", oldReviewBasketIds)); + Set containerNames = objectDao.getStringSet(sql.toString(), null); + if(CollectionUtils.isNotEmpty(containerNames)){ + for (String containerName : containerNames) { + if(StringUtils.isNotBlank(containerName) && !virtualBasketNameList.contains(containerName)){ + virtualBasketNameList.add(containerName); + } + } + } + } + if(CollectionUtils.isNotEmpty(virtualBasketNameList)){ + //重新计算虚拟篮筐状态 + tousseInstanceManager.countVirtualContainerStatus(virtualBasketNameList); + } + if(!haveSuccessMsgs){//有成功只提示一次 + haveSuccessMsgs = true; + } + } + } + JSONObject obj = new JSONObject(); + if(CollectionUtils.isNotEmpty(containerStatusMsgs)){ + obj.put("containerStatusMsgs", containerStatusMsgs); + } + if(haveSuccessMsgs){ + obj.put("successIntoBasket", "装配成功,已自动装载到灭菌篮筐中。"); + } + appLogManager.batchSaveLog(AcegiHelper.getLoginUser(), Log.MODEL_PACKING, Log.TYPE_UPDATE, statusLogMsgs); + } catch (Exception e) { + logger.error(e); + appLogManager.saveLog(AcegiHelper.getLoginUser(), Log.MODEL_PACKING, Log.TYPE_UPDATE, "装配后自动审核入筐异常" + e.getMessage()); + } + return null; + } + + @Override public void updateDeliverStatusOfInvoicePlanWhenPackingSplit(ForeignTousseApplication foreignTousseApplication, Long ipIdOffirstSplit, Long tdId){ ForeignTousseApplication ip = null; if(foreignTousseApplication != null && DatabaseUtil.isPoIdValid(foreignTousseApplication.getId())){ @@ -12241,6 +12606,54 @@ return toussesArray; } + + @Override + public Map getContainerBindingInfo(Set classifyBasketIDs) { + // 参数校验 + if (CollectionUtils.isEmpty(classifyBasketIDs)) { + return Collections.emptyMap(); + } + + // 构建SQL查询 + String sql = buildContainerBindingQuery(classifyBasketIDs); + + // 执行查询并处理结果 + return executeContainerBindingQuery(sql); + } + + /** + * 构建容器绑定查询SQL + */ + private String buildContainerBindingQuery(Set classifyBasketIDs) { + return "SELECT distinct cb.id AS classifyBasketId, gb.sterilizationContainerId " + + "FROM ContainerBinding gb " + + "JOIN Container rc ON rc.id = gb.cleaningContainerId " + + "JOIN BarcodeDevice bd ON bd.id=rc.id "+ + "JOIN ClassifyBasket cb ON cb.containerBarcode=bd.barcode "+ + "WHERE 1=1 " + + SqlUtils.getInLongListSql("cb.id", classifyBasketIDs); + } + + /** + * 执行容器绑定查询 + */ + private Map executeContainerBindingQuery(String sql) { + Map resultMap = new HashMap<>(); + + try (ResultSet rs = objectDao.executeSql(sql)) { + while (rs != null && rs.next()) { + long classifyBasketId = rs.getLong("classifyBasketId"); + long sterilizationContainerId = rs.getLong("sterilizationContainerId"); + resultMap.put(classifyBasketId, sterilizationContainerId); + } + } catch (SQLException e) { + logger.error("查询容器绑定信息时发生异常", e); + throw new SystemException("获取容器绑定信息失败", e); + } + + return resultMap; + } + // 预收集数据方法 private PreCollectPrintData preCollectData(List tousseInstances) { PreCollectPrintData data = new PreCollectPrintData(); Index: ssts-basedata/src/main/java/com/forgon/disinfectsystem/basedatamanager/container/service/ContainerManager.java =================================================================== diff -u -r38389 -r40663 --- ssts-basedata/src/main/java/com/forgon/disinfectsystem/basedatamanager/container/service/ContainerManager.java (.../ContainerManager.java) (revision 38389) +++ ssts-basedata/src/main/java/com/forgon/disinfectsystem/basedatamanager/container/service/ContainerManager.java (.../ContainerManager.java) (revision 40663) @@ -8,7 +8,10 @@ import com.forgon.disinfectsystem.entity.basedatamanager.container.Container; import com.forgon.disinfectsystem.entity.basedatamanager.supplyroomconfig.SupplyRoomConfig; import com.forgon.disinfectsystem.entity.packing.ReviewedBasket; +import com.forgon.tools.StrutsParamUtils; import com.forgon.tools.hibernate.BasePoManager; +import net.sf.json.JSONArray; +import net.sf.json.JSONObject; /** @@ -17,7 +20,13 @@ public interface ContainerManager extends BasePoManager { public void saveOrUpdate(Container container); - + + /** + * 保存容器和容器绑定关系 + * @param container 容器 + * @param cleaningContainerIds 绑定清洗筐 + */ + public void saveOrUpdate(Container container, String cleaningContainerIds); public Container getContainerById(String id); public void deleteContainerById(String id); @@ -124,5 +133,19 @@ * @return key 篮筐条码 value Container */ public Map getBarcodeToContainerMap(Set basketBarcodes); - + + /** + * 绑定容器 + * @param sterilizationContainer 灭菌容器 + * @param cleaningContainerIds 清洗容器 + * @param isNew 是否新建的灭菌容器 + */ + public JSONObject bindingContainer(Container sterilizationContainer, String cleaningContainerIds, boolean isNew); + + /** + * 获取绑定的容器 + * @param sterilizationContainerId 灭菌容器 + * @return + */ + public JSONArray getContainerBindingInfo(Long sterilizationContainerId); } Index: ssts-basedata/src/main/java/com/forgon/disinfectsystem/basedatamanager/container/action/ContainerAction.java =================================================================== diff -u -r37070 -r40663 --- ssts-basedata/src/main/java/com/forgon/disinfectsystem/basedatamanager/container/action/ContainerAction.java (.../ContainerAction.java) (revision 37070) +++ ssts-basedata/src/main/java/com/forgon/disinfectsystem/basedatamanager/container/action/ContainerAction.java (.../ContainerAction.java) (revision 40663) @@ -9,6 +9,10 @@ import javax.servlet.http.HttpServletResponse; +import com.forgon.disinfectsystem.common.CssdUtils; +import com.forgon.exception.SystemException; +import com.forgon.tools.db.DatabaseUtil; +import com.forgon.tools.util.SqlUtils; import net.sf.json.JSONArray; import net.sf.json.JSONObject; import net.sf.json.JsonConfig; @@ -170,6 +174,7 @@ JSONObject obj = new JSONObject(); obj.put("containerName", container.getContainerName()); + obj.put("id", container.getId()); obj.put("status", container.getStatus()); obj.put("isCurrent", container.getIsCurrent()); obj.put("barcode", container.getBarcode()); @@ -267,26 +272,30 @@ */ public String saveContainer() { if (container != null) { - if(container.getId() == 0){ - container.setId(null); - } - container.setType(BarcodeDevice.BARCODE_TYPE_CONTAINER); - //设置条码 + JSONObject result = new JSONObject(); String barcode = container.getBarcode(); - if(StringUtils.isBlank(container.getBarcode())){ - barcode = serialNumManager.getSerialNumberStr(SerialNum.TYPE_BARCODE); - container.setBarcode(barcode); + try{ + if(container.getId() == 0){ + container.setId(null); + } + container.setType(BarcodeDevice.BARCODE_TYPE_CONTAINER); + //设置条码 + if(StringUtils.isBlank(container.getBarcode())){ + barcode = serialNumManager.getSerialNumberStr(SerialNum.TYPE_BARCODE); + container.setBarcode(barcode); + } + //清洗容器 + String cleaningContainerIds = StrutsParamUtils.getPraramValue("cleaningContainerIds", ""); + + SqlUtils.checkInputParam(cleaningContainerIds); + containerManager.saveOrUpdate(container, cleaningContainerIds); + result.put("success", true); + } catch (Exception e) { + result.put("success", false); + result.put("message", e.getMessage()); + result.put("barcode", barcode); } - containerManager.saveOrUpdate(container); - - //返回条码、供页面打印 - HttpServletResponse httpServletResponse = StrutsParamUtils - .getResponse(); - try { - httpServletResponse.getWriter().print("{success:true,barcode:'"+barcode+"'}"); - } catch (IOException e) { - e.printStackTrace(); - } + StrutsResponseUtils.output(result); } return null; } @@ -325,6 +334,14 @@ Map map = new HashMap(); map.put("success", true); map.put("data", container); + boolean enbaleLoadAutomaticallyIntoBasketsAfterAssembly = CssdUtils.getSystemSetConfigByNameBool("enbaleLoadAutomaticallyIntoBasketsAfterAssembly",false); + if(enbaleLoadAutomaticallyIntoBasketsAfterAssembly){ + if(Container.CONTAINER_PURPOSE_VIRTUAL.equals(container.getPurpose()) + || Container.CONTAINER_PURPOSE_DISINFECTION.equals(container.getPurpose()) + || Container.CONTAINERTYPE_SHELF.equals(container.getPurpose())){ + map.put("containerBindingInfo", containerManager.getContainerBindingInfo(container.getId())); + } + } JSONObject jsonObject = JSONObject.fromObject(map, config); String jsonStr = jsonObject.toString(); try { Index: ssts-basedata/src/main/java/com/forgon/disinfectsystem/basedatamanager/container/service/ContainerManagerImpl.java =================================================================== diff -u -r39513 -r40663 --- ssts-basedata/src/main/java/com/forgon/disinfectsystem/basedatamanager/container/service/ContainerManagerImpl.java (.../ContainerManagerImpl.java) (revision 39513) +++ ssts-basedata/src/main/java/com/forgon/disinfectsystem/basedatamanager/container/service/ContainerManagerImpl.java (.../ContainerManagerImpl.java) (revision 40663) @@ -2,13 +2,14 @@ import java.sql.ResultSet; import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; +import java.util.stream.Collectors; +import com.forgon.Constants; +import com.forgon.disinfectsystem.entity.basedatamanager.container.ContainerBinding; +import com.forgon.exception.SystemException; +import com.forgon.tools.StrutsParamUtils; +import net.sf.json.JSONArray; import net.sf.json.JSONObject; import org.apache.commons.collections.CollectionUtils; @@ -62,6 +63,25 @@ } @Override + public void saveOrUpdate(Container container, String cleaningContainerIds) { + boolean isNew = !DatabaseUtil.isPoIdValid(container.getId()); + if(Container.CONTAINER_PURPOSE_VIRTUAL.equals(container.getPurpose()) + || Container.CONTAINER_PURPOSE_DISINFECTION.equals(container.getPurpose()) + || Container.CONTAINERTYPE_SHELF.equals(container.getPurpose())){ + JSONObject bindingResult = bindingContainer(container, cleaningContainerIds, isNew); + if(bindingResult != null && !bindingResult.optBoolean("success", true)){ + if(!bindingResult.optBoolean("success", true)){ + throw new SystemException(bindingResult.optString("messages", "")); + } + } + }else if(StringUtils.isNotBlank(cleaningContainerIds)){ + throw new SystemException(container.getContainerName() + "("+ container.getPurpose() +")不是灭菌容器,不能绑定清洗筐"); + } + objectDao.saveOrUpdate(container); + + } + + @Override public Container getContainerById(String id) { return (Container) objectDao.getByProperty( Container.class.getSimpleName(), "id", Long @@ -762,4 +782,132 @@ } return resultMap; } + + @Override + public JSONObject bindingContainer(Container sterilizationContainer, String cleaningContainerIds , boolean isNew) { + // 参数校验 + JSONObject result = new JSONObject(); + //如果没传 那么就是清空关系 + if(StringUtils.isBlank(cleaningContainerIds) && !isNew){//如果是空的 + objectDao.excuteSQL("delete from " + ContainerBinding.class.getSimpleName() + " where sterilizationContainerId = " + sterilizationContainer.getId()); + result.put("success", true); + result.put("message", "删除成功"); + return result; + } + + // 解析清洗容器ID集合 + Set cleaningContainerIdSet = SqlUtils.splitLongToSet(cleaningContainerIds, Constants.IDS_SEPARATOR, false); + if (CollectionUtils.isEmpty(cleaningContainerIdSet)) { + throw new SystemException("No valid cleaning container IDs provided"); + } + + // 校验清洗容器是否已经绑定了其他灭菌容器 + + List bindInfo = checkExistingBindings(cleaningContainerIdSet, sterilizationContainer.getId()); + if (CollectionUtils.isNotEmpty(bindInfo)) { + result.put("success", false); + result.put("messages", bindInfo); + return result; + } + + // 处理绑定关系 + processContainerBindings(sterilizationContainer.getId(), cleaningContainerIdSet); + + result.put("success", true); + result.put("message", "Container binding updated successfully"); + return result; + } + + /** + * 验证清洗容器是否已经绑定了灭菌容器 + * @param cleaningContainerIdSet 验证的清洗容器id + * @param sterilizationContainerId 灭菌容器id + * @return List<错误提示的字符> + */ + private List checkExistingBindings(Set cleaningContainerIdSet, Long sterilizationContainerId) { + List bindInfo = new ArrayList<>(); + String sql = "SELECT DISTINCT sc.containerName AS scContainerName, rc.containerName AS rcContainerName FROM " + + ContainerBinding.class.getSimpleName() + +" gb JOIN " + + Container.class.getSimpleName() + +" sc ON sc.id = gb.sterilizationContainerId " + + "JOIN "+ Container.class.getSimpleName() + +" rc ON rc.id = gb.cleaningContainerId " + + "WHERE sc.id<> " + sterilizationContainerId + SqlUtils.getInLongListSql("rc.id", cleaningContainerIdSet); + + try (ResultSet rs = objectDao.executeSql(sql)) { + while (rs != null && rs.next()) { + bindInfo.add(rs.getString("rcContainerName") + "已经被绑定到" + + rs.getString("scContainerName") + "中,不能重复绑定"); + } + } catch (SQLException e) { + throw new SystemException("Error checking existing bindings", e); + } + return bindInfo; + } + + /** + * 处理绑定关系 + * @param sterilizationContainerId 灭菌容器id + * @param newCleaningContainerIds 新的清洗容器ids + */ + private void processContainerBindings(Long sterilizationContainerId, Set newCleaningContainerIds) { + // 查询现有的绑定关系 + List existingBindings = objectDao.findByHql( + "select po FROM "+ ContainerBinding.class.getSimpleName() +" po WHERE sterilizationContainerId = "+ sterilizationContainerId); + + Set existingIds = existingBindings.stream() + .map(ContainerBinding::getCleaningContainerId) + .collect(Collectors.toSet()); + + // 计算需要新增和删除的ID + Set idsToAdd = new HashSet<>(newCleaningContainerIds); + idsToAdd.removeAll(existingIds); + + Set idsToRemove = new HashSet<>(existingIds); + idsToRemove.removeAll(newCleaningContainerIds); + + // 执行删除操作 + if (!idsToRemove.isEmpty()) { + String deleteHql = "DELETE FROM "+ + ContainerBinding.class.getSimpleName() + + " WHERE sterilizationContainerId = " + + sterilizationContainerId + + SqlUtils.getInLongListSql("cleaningContainerId", idsToRemove); + objectDao.executeUpdate(deleteHql); + } + + // 执行新增操作 + for (Long cleaningContainerId : idsToAdd) { + ContainerBinding binding = new ContainerBinding(); + binding.setCleaningContainerId(cleaningContainerId); + binding.setSterilizationContainerId(sterilizationContainerId); + objectDao.save(binding); + } + } + + @Override + public JSONArray getContainerBindingInfo(Long sterilizationContainerId) { + String sql = "SELECT distinct rc.id, rc.containerName ,rbd.barcode FROM " + + ContainerBinding.class.getSimpleName() + +" gb JOIN " + + Container.class.getSimpleName() + +" rc ON rc.id = gb.cleaningContainerId join " + + BarcodeDevice.class.getSimpleName() + + " rbd on rbd.id=rc.id WHERE gb.sterilizationContainerId= " + + sterilizationContainerId; + JSONArray containerBindingInfos = new JSONArray(); + try (ResultSet rs = objectDao.executeSql(sql)) { + while (rs != null && rs.next()) { + JSONObject containerBindingInfo = new JSONObject(); + containerBindingInfo.put("id", rs.getLong("id")); + containerBindingInfo.put("containerName", rs.getString("containerName")); + containerBindingInfo.put("barcode", rs.getString("barcode")); + containerBindingInfos.add(containerBindingInfo); + } + } catch (SQLException e) { + throw new SystemException("Error getContainerBindingInfo", e); + } + return containerBindingInfos; + } } Index: ssts-basedata/src/main/java/com/forgon/disinfectsystem/entity/basedatamanager/container/ContainerBinding.java =================================================================== diff -u --- ssts-basedata/src/main/java/com/forgon/disinfectsystem/entity/basedatamanager/container/ContainerBinding.java (revision 0) +++ ssts-basedata/src/main/java/com/forgon/disinfectsystem/entity/basedatamanager/container/ContainerBinding.java (revision 40663) @@ -0,0 +1,55 @@ +package com.forgon.disinfectsystem.entity.basedatamanager.container; + +import org.hibernate.annotations.CacheConcurrencyStrategy; +import org.hibernate.annotations.DynamicInsert; +import org.hibernate.annotations.DynamicUpdate; + +import javax.persistence.*; + +/** + * 菌容器绑定清洗容器中间关系表 + * GDSKQYY-8 灭菌容器多对1清洗容器 + */ +@Entity +@DynamicInsert(false) +@DynamicUpdate(true) +@Table(name = "ContainerBinding") +@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) +public class ContainerBinding { + protected Long id; + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + /** + * 清洗容器id + */ + public Long cleaningContainerId; + /** + * 灭菌容器id + */ + public Long sterilizationContainerId; + + public Long getSterilizationContainerId() { + return sterilizationContainerId; + } + + public void setSterilizationContainerId(Long sterilizationContainerId) { + this.sterilizationContainerId = sterilizationContainerId; + } + + public Long getCleaningContainerId() { + return cleaningContainerId; + } + + public void setCleaningContainerId(Long cleaningContainerId) { + this.cleaningContainerId = cleaningContainerId; + } +} Index: ssts-packing/src/main/java/com/forgon/disinfectsystem/packing/service/PackingManager.java =================================================================== diff -u -r40439 -r40663 --- ssts-packing/src/main/java/com/forgon/disinfectsystem/packing/service/PackingManager.java (.../PackingManager.java) (revision 40439) +++ ssts-packing/src/main/java/com/forgon/disinfectsystem/packing/service/PackingManager.java (.../PackingManager.java) (revision 40663) @@ -477,5 +477,18 @@ * @return */ public JSONArray getTousseinstanceJSONArrayForPrint(List tousseInstances, String printCause); - + + /** + * 获取清洗筐绑定的篮筐条码 + * @param classifyBasketIDs ClassifyBasket ids + * @return + */ + public Map getContainerBindingInfo(Set classifyBasketIDs); + + /** + * 自动入筐 + * @param tis + * @param cntainerBindingInfo + */ + public JSONObject autobasketInsertion(List tis, Map cntainerBindingInfo); }