src/main/java/com/nanometer/smartlab/controller/WarehouseStockMngController.java
@@ -6,10 +6,12 @@ import com.nanometer.smartlab.entity.*; import com.nanometer.smartlab.entity.dto.ApplyListDto; import com.nanometer.smartlab.entity.enumtype.ApplyStatusVo; import com.nanometer.smartlab.entity.enumtype.ApplyStatus; import com.nanometer.smartlab.entity.enumtype.ArrivalStatus; import com.nanometer.smartlab.entity.enumtype.SeeFlag; import com.nanometer.smartlab.entity.enumtype.ValidFlag; import com.nanometer.smartlab.exception.BusinessException; import com.nanometer.smartlab.exception.ExceptionEnumCode; import com.nanometer.smartlab.service.*; import com.nanometer.smartlab.util.*; import org.apache.commons.lang.StringUtils; @@ -27,6 +29,7 @@ import org.springframework.context.annotation.PropertySource; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Controller; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import javax.faces.context.ExternalContext; @@ -38,6 +41,7 @@ import java.math.BigDecimal; import java.math.BigInteger; import java.net.URLEncoder; import java.sql.Timestamp; import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; @@ -67,6 +71,8 @@ private SysUserService sysUserService; @Resource private SysSupplierService sysSupplierService; @Resource private OpeOrderService opeOrderService; @Resource private MenuController menuController; @@ -84,6 +90,8 @@ @Resource(name = "opeReagentStatusDao") OpeReagentStatusDao opeReagentStatusDao; @Resource OpeUseFlowService opeUseFlowService; @Resource OpeWarehouseReserveDao opeWarehouseReserveDao; @@ -238,7 +246,20 @@ private List<OpeApplyReserve> selectedListForPerson; private List<OpeApplyReserve> selectedTmpOrderList; private List<OpeApplyReserve> trulySelectedOrderList; /** * 入库车 */ private List<OpeApplyReserve> selectedInputStorageTmpOrderList; private List<OpeApplyReserve> trulyInputStorageTmpSelectedOrderList; /** * 订单入库变量 */ //到货时间 private Timestamp arrivalTime; //收货人 private String consigneeId; //OpeApply private List<OpeApplyReserve> opeApplyList; /** * 条形码对话框中选择的条形码集合 */ @@ -301,6 +322,33 @@ } this.onWarehouseSelectChange(null); } public void initInputWarehouse() { logger.info("WarehouseStockMngController initInputWarehouse start"); this.warehouseList = this.sysWarehouseService.getSysWarehouseList(null, null, null, null); this.warehouseNameMap = new HashMap<String, String>(); if (this.warehouseList != null && this.warehouseList.size() > 0) { for (SysWarehouse house : this.warehouseList) { this.warehouseNameMap.put(house.getId(), house.getName()); } } this.warehouseContainerMap = new HashMap<String, SysWarehouseContainer>(); this.warehouseIdContainerMap = new HashMap<String, List<SysWarehouseContainer>>(); List<SysWarehouseContainer> warehouseContainerList = this.sysWarehouseContainerService.getSysWarehouseContainerList(null, null, null, null, null); if (warehouseContainerList != null && warehouseContainerList.size() > 0) { for (SysWarehouseContainer container : warehouseContainerList) { warehouseContainerMap.put(container.getId(), container); if (!warehouseIdContainerMap.containsKey(container.getWarehouseId()) || warehouseIdContainerMap.get(container.getWarehouseId()) == null) { warehouseIdContainerMap.put(container.getWarehouseId(), new ArrayList<SysWarehouseContainer>()); } warehouseIdContainerMap.get(container.getWarehouseId()).add(container); } } this.onWarehouseSelectChange(null); } private void initReagentSelectList() { @@ -423,6 +471,40 @@ } } public void addInputStorageOrder() { if (this.selectedListForPerson == null || this.selectedListForPerson.size() == 0) { FacesUtils.warn("请选择数据。"); return; } //1.判断非状态为确认的申购单不能入库 for (OpeApplyReserve opeApplyReserve : this.selectedListForPerson) { if (opeApplyReserve.getStatus() != ApplyStatus.SUPPLIER_CONFIRM) { FacesUtils.warn("非已确认的数据不能入库。"); return; } } //2.加入暂存 if (selectedInputStorageTmpOrderList !=null && selectedInputStorageTmpOrderList.size()>0){ ArrayList<OpeApplyReserve> tmp = new ArrayList<>(); selectedListForPerson.forEach(opeApplyReserve -> { AtomicBoolean flag = new AtomicBoolean(false); selectedInputStorageTmpOrderList.forEach(opeApplyReserve1 -> { if (opeApplyReserve.getId().equals(opeApplyReserve1.getId())){ flag.set(true); } }); if(!flag.get()) { tmp.add(opeApplyReserve); } }); selectedInputStorageTmpOrderList.addAll(tmp); }else{ selectedInputStorageTmpOrderList = new ArrayList<>(); selectedInputStorageTmpOrderList.addAll(selectedListForPerson); } } public void clear(){ selectedTmpList = null; @@ -430,6 +512,10 @@ public void clearOrderTmp(){ selectedTmpOrderList = null; } public void clearInputStorageTmp(){ selectedInputStorageTmpOrderList = null; } public void cancel(){ @@ -488,6 +574,34 @@ } public void cancelInputStorageTmp(){ if (trulyInputStorageTmpSelectedOrderList == null || trulyInputStorageTmpSelectedOrderList.size()<=0){ FacesUtils.info("至少选择一个"); return; } if (selectedInputStorageTmpOrderList == null || selectedInputStorageTmpOrderList.size()<=0){ FacesUtils.info("至少选择一个"); return; } ArrayList<Object> indexs = new ArrayList<>(); for (OpeApplyReserve opeApplyReserve : trulyInputStorageTmpSelectedOrderList) { for (OpeApplyReserve applyReserve : selectedInputStorageTmpOrderList) { if (opeApplyReserve.getId().equals(applyReserve.getId())) { indexs.add(opeApplyReserve); } } } if (indexs.size()>0){ indexs.forEach(obj -> { selectedInputStorageTmpOrderList.remove(obj); }); } } public void onUseBtnClick(){ if (selectedTmpList == null || selectedTmpList.size()<=0){ FacesUtils.info("至少选择一个"); @@ -504,6 +618,21 @@ } this.menuController.goToPage(Constants.PAGE_WAREHOUSE_REAGENT_USE_NEW_PERSON, Constants.PAGE_WAREHOUSE_STOCK_MNG); } public void onUseBtnClickInputStorageTmp(){ if (selectedInputStorageTmpOrderList == null || selectedInputStorageTmpOrderList.size()<=0){ FacesUtils.info("至少选择一个"); return; } opeApplyList = new ArrayList<>(); selectedInputStorageTmpOrderList.forEach(opeApplyReserve -> { OpeApplyReserve applyDetail = opeApplyService.getOpeApplyDetail(opeApplyReserve.getId()); opeApplyList.add(applyDetail); }); //跳转编辑页面 this.menuController.goToPage(Constants.PAGE_ORDER_INPUT_WAREHOUSE, Constants.PAGE_WAREHOUSE_STOCK_MNG); } public void onUseBtnClickForPerson() { @@ -828,6 +957,7 @@ public void onCancelBtnClick() { this.selectedTmpOrderList = null; this.selectedTmpList = null; this.selectedInputStorageTmpOrderList = null; this.menuController.backToPage(); } @@ -1197,6 +1327,52 @@ logger.error(e.getMessage(), e); FacesUtils.warn("操作失败。"); } } /** * @Description: 订单入库保存 */ public void onSaveInputWarehouseClick(){ try{ //用来检验提交表单得试剂条码是否重复 Map<String,Boolean> checkTable= new HashMap<>(); if (opeApplyList != null && opeApplyList.size() > 0) { for (OpeApplyReserve opeApplyReserve:opeApplyList) { //0.1获取该申购单的订单 OpeOrder oo = opeOrderService.getOrder(opeApplyReserve.getId()); if (oo == null) { throw new BusinessException(ExceptionEnumCode.ORDER_ERROR,"订单不存在"); } //0.2检查条码->得到试剂条码列表 List<String> codeList = opeReagentStatusService .checkReagentCode(opeApplyReserve.getStartReagentCode2(), opeApplyReserve.getEndReagentCode2(), opeApplyReserve.getArrivalNum()); if (codeList != null && codeList.size() > 0) { for (String code:codeList) { if (checkTable.get(code) == null) { checkTable.put(code, true); }else{ throw new BusinessException(ExceptionEnumCode.PARAM_EXIST, "当前订单条码重复,"+code); } } } } checkTable = null; opeApplyService.orderInputWarehouse(opeApplyList,consigneeId,arrivalTime); } FacesUtils.info("入库完成"); //返回 this.onCancelBtnClick(); }catch (BusinessException e){ e.printStackTrace(); FacesUtils.warn(e.getMessage()); } catch (Exception e) { e.printStackTrace(); FacesUtils.warn("系统异常,操作失败"); } } @SuppressWarnings("serial") @@ -2360,6 +2536,118 @@ this.tabValue = tabValue; } public List<OpeApplyReserve> getSelectedInputStorageTmpOrderList() { return selectedInputStorageTmpOrderList; } public void setSelectedInputStorageTmpOrderList(List<OpeApplyReserve> selectedInputStorageTmpOrderList) { this.selectedInputStorageTmpOrderList = selectedInputStorageTmpOrderList; } public List<OpeApplyReserve> getTrulyInputStorageTmpSelectedOrderList() { return trulyInputStorageTmpSelectedOrderList; } public void setTrulyInputStorageTmpSelectedOrderList(List<OpeApplyReserve> trulyInputStorageTmpSelectedOrderList) { this.trulyInputStorageTmpSelectedOrderList = trulyInputStorageTmpSelectedOrderList; } public Timestamp getArrivalTime() { return arrivalTime; } public void setArrivalTime(Timestamp arrivalTime) { this.arrivalTime = arrivalTime; } public String getConsigneeId() { return consigneeId; } public void setConsigneeId(String consigneeId) { this.consigneeId = consigneeId; } public List getConsignee() { List<SysUser> dataList = this.sysUserService.getSysUserList(null, null, null, null, null); //将admin置于首位 for (int i = 0; i < dataList.size(); i++) { if ("admin".equals(dataList.get(i).getAccount())){ dataList.add(0, dataList.remove(i)); } } return dataList; } public List<OpeApplyReserve> getOpeApplyList() { return opeApplyList; } public void setOpeApplyList(List<OpeApplyReserve> opeApplyList) { this.opeApplyList = opeApplyList; } public void setArrival(OpeApplyReserve oar) { //强制-》全到货 oar.setArrivalNum(oar.getNum()); } public void reagentStartCodeChange(OpeApplyReserve oar) { //先输入条形码,到货数量帮填 oar.setArrivalNum(oar.getNum()); String startReagentCode2 = oar.getStartReagentCode2(); String endReagentCode2 = oar.getEndReagentCode2(); //1.如果开始条码为空,条码就为空,或者没有到货 if (StringUtils.isBlank(startReagentCode2) || oar.getArrivalNum() == null || oar.getArrivalNum() < 1) { oar.setStartReagentCode2(""); oar.setEndReagentCode2(""); return; } //2如果开始条码不为空 //2.0如果包含字母不等于24位的直接不管 if (startReagentCode2.matches(".*[A-F]+.*")) { if (startReagentCode2.length() ==24){ //2.2长度为24位编码的 BigInteger arrNum = BigInteger.valueOf(oar.getArrivalNum().longValue()); //后5位随机码 String randomCode = startReagentCode2.substring(startReagentCode2.length() - 5); String reagentCodePrefix = startReagentCode2.substring(0,startReagentCode2.length() - 5); BigInteger startReagentCodeSuffix = new BigInteger(randomCode); BigInteger endReagentCodeSuffix = startReagentCodeSuffix.add(arrNum).subtract((new BigInteger("1"))); String reagentCodeSuffix= autoGenericCode(randomCode, endReagentCodeSuffix); oar.setEndReagentCode2(reagentCodePrefix + reagentCodeSuffix); }else{ oar.setEndReagentCode2(""); } }else{ BigInteger startReagentCode = new BigInteger(startReagentCode2); //2.1长度不为24位编码 //数据1 BigInteger arrNum = BigInteger.valueOf(oar.getArrivalNum().longValue()); BigInteger code1 = startReagentCode.add(arrNum).subtract(BigInteger.ONE); oar.setEndReagentCode2(autoGenericCode(startReagentCode2, code1)); } } private String autoGenericCode(String code, BigInteger code1) { String result = ""; //补充位数 result = String.format("%0" + code.length() + "d", code1); return result; } public void setProductSn(String productSn) { this.productSn = productSn; } src/main/java/com/nanometer/smartlab/dao/OpeApplyDao.java
@@ -2,6 +2,7 @@ import com.nanometer.smartlab.entity.OpeApply; import com.nanometer.smartlab.entity.OpeApplyReserve; import com.nanometer.smartlab.entity.OpeOrder; import com.nanometer.smartlab.entity.OpeWarehouseReserve; import org.springframework.dao.DataAccessException; @@ -50,4 +51,8 @@ List<OpeApply> selectByReId(String id); public int updateByReId(Map params); OpeApplyReserve getOpeApplyDetail(String id); void updateOpeApplyInfo(Map params); } src/main/java/com/nanometer/smartlab/dao/OpeApplyDao.xml
@@ -60,8 +60,10 @@ <result property="applyCode" column="apply_code"></result> <result property="num" column="num"></result> <result property="used" column="used"></result> <result property="status" column="status" typeHandler="com.nanometer.smartlab.entity.handler.ApplyStatusHandler"></result> <result property="arrivalNum" column="arrival_num"></result> <result property="status" column="status" typeHandler="com.nanometer.smartlab.entity.handler.ApplyStatusHandler"></result> <result property="applyUserId" column="apply_user_id"></result> <result property="arrivalTime" column="arrival_time"></result> <result property="projectManage" column="projectManage"/> <result property="project" column="project"/> <association property="reagent" javaType="com.nanometer.smartlab.entity.SysReagent"> @@ -398,7 +400,8 @@ oa.used, su.`name` apply_user_id, su.project, su1.`name` as projectManage su1.`name` as projectManage, oa.arrival_time FROM ope_apply AS oa LEFT JOIN sys_reagent sr ON sr.id = oa.reagent_id @@ -429,6 +432,36 @@ <select id="selectByReId" resultMap="OpeApply"> select * from ope_apply where reagent_id=#{id} </select> <select id="getOpeApplyDetail" resultMap="OpeApplyReserve"> select oa.id, oa.apply_code, sr.id reagent_id, oa.status, sr.product_sn reagentProductSn, sr.`name` reagentName, bm2.meta_value controlProducts, bm3.meta_value reagentFormat, sr.main_metering reagentMainMetering, sr.price reagentPrice, sr.cas reagentCas, oa.article_number articleNumber, bm4.meta_value reagentCharacter, bm1.meta_value productHome, sr.dangerous_flag, oa.num, oa.used, oa.arrival_num, su.id apply_user_id from ope_apply as oa left JOIN sys_reagent sr on sr.id = oa.reagent_id left JOIN sys_user su on su.id = oa.apply_user_id left join base_meta as bm2 on sr.control_products = bm2.id left join base_meta as bm3 on sr.reagent_format = bm3.id left join base_meta as bm4 on sr.reagent_character = bm4.id left join base_meta as bm1 on sr.product_home = bm1.id where oa.valid_flag = 1 and oa.id = #{0} </select> <update id="updateByReId" parameterType="java.util.Map"> update ope_apply set reagent_id=#{newReId} where reagent_id=#{oldReId} src/main/java/com/nanometer/smartlab/dao/OpeOrderDao.java
@@ -21,4 +21,8 @@ public void insertOpeOrder(OpeOrder opeOrder) throws DataAccessException; public int updateOpeOrder(OpeOrder opeOrder) throws DataAccessException; public int deleteOpeOrder(List<String> ids) throws DataAccessException; OpeOrder selectParentOrder(String id); void updateOpeOrderStatus(OpeOrder oo); } src/main/java/com/nanometer/smartlab/dao/OpeOrderDao.xml
@@ -93,4 +93,25 @@ #{item} </foreach> </update> <update id="updateOpeOrderStatus" parameterType="com.nanometer.smartlab.entity.OpeOrder"> update ope_order set status = #{status}, arrival_time = #{arrivalTime}, consignee_user_id = #{consigneeUserId} where id = #{id} </update> <select id="selectParentOrder" resultType="com.nanometer.smartlab.entity.OpeOrder"> select oo.id, oo.status, oo.order_code orderCode, oo.order_name orderName, oo.order_user_id orderUserId from ope_apply_order oao left join ope_order oo on oo.id = oao.ope_order_id where oo.valid_flag = 1 and oao.ope_apply_id = #{0} </select> </mapper> src/main/java/com/nanometer/smartlab/dao/OpeReagentStatusDao.java
@@ -51,4 +51,6 @@ public int updateByReId(Map params); List<String> selectReagentCodesByReId(String reagentId); void insertOpeReagentStatus2(OpeReagentStatus ors); } src/main/java/com/nanometer/smartlab/dao/OpeReagentStatusDao.xml
@@ -281,6 +281,10 @@ insert into ope_reagent_status(id, reagent_id, article_number, reagent_code, status, house_id, container_id, user_id, remainder, place, store_type, valid_flag, update_time,project_num) values (#{id}, #{reagentId}, #{articleNumber}, #{reagentCode}, #{status}, #{houseId}, #{containerId}, #{userId}, #{remainder}, #{place}, #{storeType}, 1, now(),#{projectNum}) </insert> <insert id="insertOpeReagentStatus2" parameterType="com.nanometer.smartlab.entity.OpeReagentStatus"> insert into ope_reagent_status(id, reagent_id, article_number, reagent_code, status, house_id, container_id, user_id, remainder, place, store_type, valid_flag, update_time,project_num,apply_code,order_code) values (#{id}, #{reagentId}, #{articleNumber}, #{reagentCode}, #{status}, #{houseId}, #{containerId}, #{userId}, #{remainder}, #{place}, #{storeType}, 1, now(),#{projectNum},#{applyCode},#{orderCode}) </insert> <select id="getOpeReagentStatusByReagentCode" parameterType="java.lang.String" resultMap="OpeReagentStatus"> select * src/main/java/com/nanometer/smartlab/dao/OpeWarehouseReserveDao.java
@@ -29,4 +29,6 @@ //仓库指定试剂自加1 void updateCount(Map<String ,Object> params); void insertOpeWarehouseReserve2(OpeWarehouseReserve ope); } src/main/java/com/nanometer/smartlab/dao/OpeWarehouseReserveDao.xml
@@ -105,6 +105,10 @@ insert into ope_warehouse_reserve(id, reagent_id, article_number, reserve, valid_flag, update_time,warehouseId) values (#{id}, #{reagentId}, #{articleNumber}, #{reserve}, 1, now(),#{warehouseId}) </insert> <insert id="insertOpeWarehouseReserve2" parameterType="com.nanometer.smartlab.entity.OpeWarehouseReserve"> insert into ope_warehouse_reserve(id, reagent_id, article_number, reserve, valid_flag, update_time,warehouseId,apply_code,order_code) values (#{id}, #{reagentId}, #{articleNumber}, #{reserve}, 1, now(),#{warehouseId},#{applyCode},#{orderCode}) </insert> <update id="updateOpeWarehouseReserve" parameterType="com.nanometer.smartlab.entity.OpeWarehouseReserve"> update ope_warehouse_reserve set reagent_id=#{reagentId},warehouseId=#{warehouseId}, article_number=#{articleNumber}, reserve=#{reserve}, update_time=now() src/main/java/com/nanometer/smartlab/dao/SysReagentDao.java
@@ -3,6 +3,7 @@ import com.nanometer.smartlab.entity.SysReagent; import org.springframework.dao.DataAccessException; import java.math.BigDecimal; import java.util.List; import java.util.Map; src/main/java/com/nanometer/smartlab/entity/OpeApplyReserve.java
@@ -31,6 +31,10 @@ private Integer flag; private ApplyStatus status; private Integer arrivalNum; private String containerId; private String houseId; private Timestamp arrivalTime; private String project; private String projectManage; @@ -169,19 +173,51 @@ this.selectNum = selectNum; } public String getProject() { return project; public Integer getArrivalNum() { return arrivalNum; } public void setProject(String project) { this.project = project; public void setArrivalNum(Integer arrivalNum) { this.arrivalNum = arrivalNum; } public String getProjectManage() { return projectManage; public String getContainerId() { return containerId; } public void setProjectManage(String projectManage) { this.projectManage = projectManage; public void setContainerId(String containerId) { this.containerId = containerId; } public String getHouseId() { return houseId; } public void setHouseId(String houseId) { this.houseId = houseId; } public Timestamp getArrivalTime() { return arrivalTime; } public void setArrivalTime(Timestamp arrivalTime) { this.arrivalTime = arrivalTime; } public String getProject() { return project; } public void setProject(String project) { this.project = project; } public String getProjectManage() { return projectManage; } public void setProjectManage(String projectManage) { this.projectManage = projectManage; } } src/main/java/com/nanometer/smartlab/entity/OpeReagentStatus.java
@@ -31,6 +31,8 @@ private String place; private StoreType storeType; private String projectNum; private String applyCode; private String orderCode; private String houseName; private String containerCode; @@ -215,4 +217,20 @@ public void setStoreType(StoreType storeType) { this.storeType = storeType; } public String getApplyCode() { return applyCode; } public void setApplyCode(String applyCode) { this.applyCode = applyCode; } public String getOrderCode() { return orderCode; } public void setOrderCode(String orderCode) { this.orderCode = orderCode; } } src/main/java/com/nanometer/smartlab/entity/OpeWarehouseReserve.java
@@ -28,6 +28,9 @@ private String warehouseName; private String startReagentCode2; private String endReagentCode2; private String applyCode; private String orderCode; public String getWarehouseId() { return warehouseId; @@ -158,4 +161,20 @@ public void setSelectNum(Integer selectNum) { this.selectNum = selectNum; } public String getApplyCode() { return applyCode; } public void setApplyCode(String applyCode) { this.applyCode = applyCode; } public String getOrderCode() { return orderCode; } public void setOrderCode(String orderCode) { this.orderCode = orderCode; } } src/main/java/com/nanometer/smartlab/exception/ExceptionEnumCode.java
@@ -11,7 +11,10 @@ PARAM_NO_EXIST("1003"), PARAM_EXIST("1004"), REAGENT_CODE_EXIST("2001"), MAIL_SEND_FAIL("3001"); REAGENT_CODE_INVALID("2002"), MAIL_SEND_FAIL("3001"), ORDER_ERROR("4001"); private String code; src/main/java/com/nanometer/smartlab/service/OpeApplyService.java
@@ -2,8 +2,10 @@ import com.nanometer.smartlab.entity.OpeApply; import com.nanometer.smartlab.entity.OpeApplyReserve; import com.nanometer.smartlab.entity.OpeOrder; import com.nanometer.smartlab.entity.OpeWarehouseReserve; import com.nanometer.smartlab.entity.enumtype.ApplyStatus; import com.nanometer.smartlab.exception.BusinessException; import java.math.BigDecimal; import java.sql.Timestamp; @@ -62,4 +64,11 @@ public List<OpeApply> selectByReId(String id); public void updateByReId(String newReId,String oldReId); OpeApplyReserve getOpeApplyDetail(String applyCode); void updateOpeApplyInfo(ApplyStatus storage, String consigneeId, Timestamp arrivalTime, String applyId); void orderInputWarehouse(List<OpeApplyReserve> opeApplyList,String consigneeId,Timestamp arrivalTime) throws BusinessException,Exception; } src/main/java/com/nanometer/smartlab/service/OpeApplyServiceImpl.java
@@ -3,6 +3,7 @@ import com.nanometer.smartlab.dao.OpeApplyDao; import com.nanometer.smartlab.entity.OpeApply; import com.nanometer.smartlab.entity.OpeApplyReserve; import com.nanometer.smartlab.entity.OpeOrder; import com.nanometer.smartlab.entity.SysUser; import com.nanometer.smartlab.entity.enumtype.ApplyStatus; import com.nanometer.smartlab.entity.enumtype.SeeFlag; @@ -40,6 +41,12 @@ @Resource(name = "opeApplyDao") OpeApplyDao opeApplyDao; @Resource OpeOrderService opeOrderService; @Resource OpeReagentStatusService opeReagentStatusService; @Resource OpeWarehouseReserveService opeWarehouseReserveService; @Resource private SysUserService sysUserService; @@ -639,4 +646,66 @@ params.put("oldReId",oldReId); this.opeApplyDao.updateByReId(params); } @Override public OpeApplyReserve getOpeApplyDetail(String id) { return opeApplyDao.getOpeApplyDetail(id); } @Override public void updateOpeApplyInfo(ApplyStatus storage, String consigneeId, Timestamp arrivalTime, String applyId) { Map<String,Object> params = new HashMap(); params.put("status", storage); params.put("consigneeId", consigneeId); params.put("arrivalTime", arrivalTime); params.put("applyId", applyId); opeApplyDao.updateOpeApplyInfo(params); } @Override @Transactional public void orderInputWarehouse(List<OpeApplyReserve> opeApplyList,String consigneeId,Timestamp arrivalTime) { for (OpeApplyReserve opeApplyReserve:opeApplyList) { //0.1获取该申购单的订单 OpeOrder oo = opeOrderService.getOrder(opeApplyReserve.getId()); if (oo == null) { throw new BusinessException(ExceptionEnumCode.ORDER_ERROR,"订单不存在"); } //0.2检查条码->得到试剂条码列表 List<String> codeList = opeReagentStatusService .checkReagentCode(opeApplyReserve.getStartReagentCode2(), opeApplyReserve.getEndReagentCode2(), opeApplyReserve.getArrivalNum()); //1.入库 if (codeList == null){ //无条码入库 不需要增加状态和流向 //1.1库存表增加 opeWarehouseReserveService.insertOpeWarehouseReserve2(opeApplyReserve, oo); }else{ //条码入库 assert codeList.size() > 0; //1.1入库(库存表增加) opeWarehouseReserveService.insertOpeWarehouseReserve2(opeApplyReserve, oo); //1.2试剂状态表增加,流向增加 opeReagentStatusService.orderInputWarehouseReagentStatusAndUseFlow(opeApplyReserve,consigneeId,codeList,oo); } //2.更改申购单所属订单状态(判断子订单是否全部完成) //2.1更改该申购单的状态,收货人和到货时间 this.updateOpeApplyInfo(ApplyStatus.STORAGE,consigneeId,arrivalTime, opeApplyReserve.getId()); //2.2更改订单状态 List<OpeApply> oas = opeOrderService.getOpeApplyListByOrder(oo.getId()); assert oas.size() > 0; //子订单是否全部入库,是则父单为完成,否则未完成 boolean flag = oas.stream().allMatch(oa -> oa.getStatus() == ApplyStatus.STORAGE); oo.setConsigneeUserId(consigneeId); oo.setArrivalTime(arrivalTime); if (flag){ oo.setStatus(ApplyStatus.FINISHED); opeOrderService.updateOpeOrderStatus(oo); }else{ oo.setStatus(ApplyStatus.UNCOMPLETED); opeOrderService.updateOpeOrder(oo); } } } } src/main/java/com/nanometer/smartlab/service/OpeOrderService.java
@@ -33,4 +33,8 @@ public List<EmailStatus> selectByReId(String id); public void updateByReId(String newReId,String oldReId); OpeOrder getOrder(String id); void updateOpeOrderStatus(OpeOrder oo); } src/main/java/com/nanometer/smartlab/service/OpeOrderServiceImpl.java
@@ -478,4 +478,15 @@ this.emailStatusDao.updateByReId(params); } @Override public OpeOrder getOrder(String id) { return opeOrderDao.selectParentOrder(id); } @Override @Transactional public void updateOpeOrderStatus(OpeOrder oo) { opeOrderDao.updateOpeOrderStatus(oo); } } src/main/java/com/nanometer/smartlab/service/OpeReagentStatusService.java
@@ -1,8 +1,6 @@ package com.nanometer.smartlab.service; import com.nanometer.smartlab.entity.OpeApply; import com.nanometer.smartlab.entity.OpeReagentStatus; import com.nanometer.smartlab.entity.SysUser; import com.nanometer.smartlab.entity.*; import java.util.Date; import java.util.LinkedHashMap; @@ -94,6 +92,11 @@ List<String> getReagentCodes(String reagentId); //订单入库 新增试剂状态表 和流向 void orderInputWarehouseReagentStatusAndUseFlow(OpeApplyReserve opeApplyReserve, String userId, List<String> reagentCodeList , OpeOrder opeOrder); List<String> checkReagentCode(String startReagentCode2, String endReagentCode2,Integer arrivalNum) throws BusinessException; void updateOpeReagentStatus(OpeReagentStatus opeReagentStatus); } src/main/java/com/nanometer/smartlab/service/OpeReagentStatusServiceImpl.java
@@ -1,5 +1,7 @@ package com.nanometer.smartlab.service; import java.math.BigInteger; import java.sql.Timestamp; import java.util.*; import javax.annotation.Resource; @@ -807,6 +809,138 @@ } @Override /** * @Description: 订单入库时 的更新试剂状态和更新试剂流向 */ @Transactional public void orderInputWarehouseReagentStatusAndUseFlow (OpeApplyReserve opeApplyReserve,String userId,List<String> reagentCodeList,OpeOrder opeOrder) { for (String reagentCode : reagentCodeList) { //1.新增试剂状态:在仓库有 OpeReagentStatus ors = new OpeReagentStatus(); ors.setId(IDUtils.uuid()); //状态和用户 ors.setStatus(ArrivalStatus.WAREHOUSE); ors.setUserId(userId); //入库场所 ors.setHouseId(opeApplyReserve.getHouseId()); ors.setContainerId(opeApplyReserve.getContainerId()); //试剂编码 id和批号 ors.setReagentCode(reagentCode); ors.setReagentId(opeApplyReserve.getReagent().getId()); ors.setArticleNumber(opeApplyReserve.getArticleNumber()); //订单和申购单 ors.setApplyCode(opeApplyReserve.getApplyCode()); ors.setOrderCode(opeOrder.getOrderCode()); opeReagentStatusDao.insertOpeReagentStatus2(ors); //2.更新试剂流向 OpeUseFlow ouf = new OpeUseFlow(); ouf.setId(IDUtils.uuid()); //持有者 ouf.setUserId(userId); //在仓库状态 ouf.setStatus(ArrivalStatus.WAREHOUSE); //操作状态->仓库入库 Map<String, String> metaMap = new HashMap<>(); metaMap.put("groupId", "operate_status"); metaMap.put("metaKey", String.valueOf(OperateStatus.WAREHOUSEIN.getKey())); List<BaseMeta> baseMetaList = baseMetaDao.getBaseMetaList(metaMap); ouf.setOperateState(baseMetaList.get(0).getId()); //地点 ouf.setHouseId(opeApplyReserve.getHouseId()); ouf.setContainerId(opeApplyReserve.getContainerId()); //试剂条码 ouf.setReagentCode(reagentCode); //创建时间 ouf.setCreateTime(new Timestamp(new Date().getTime())); opeUseFlowDao.insertOpeUseFlow(ouf); } } /** * @Description: 校验条码在试剂状态中是否存在 */ @Override public List<String> checkReagentCode(String startReagentCode2, String endReagentCode2,Integer arrivalNum) throws BusinessException { if (startReagentCode2 == null || startReagentCode2.length() < 1) { return null; } if (endReagentCode2 == null || endReagentCode2.length() < 1) { return null; } List<String> codeList= new ArrayList<>(); //1.做24位的字母判断否则就是纯数字 if (startReagentCode2.matches(".*[A-F]+.*")) { //长度为24并且后5位随机码得是数字 if (startReagentCode2.length() == 24 && endReagentCode2.length() == 24 && startReagentCode2.substring(startReagentCode2.length()-5).matches("/d{5}")) { //24位指定编码生成 Integer randomStart = Integer.valueOf(startReagentCode2.substring(startReagentCode2.length() - 5)); Integer randomEnd = Integer.valueOf(endReagentCode2.substring(endReagentCode2.length() - 5)); String regentPrefix = startReagentCode2.substring(0, startReagentCode2.length() - 5); String regentPrefix2 = endReagentCode2.substring(0, endReagentCode2.length() - 5); //如果距离不是 到货数量或者非后5位得前缀有问题,则说明输入有问题 if (randomEnd - randomStart + 1 != arrivalNum||!regentPrefix2.equals(regentPrefix)) { throw new BusinessException(ExceptionEnumCode.PARAM_EXIST,"试剂的开始结束条码有问题"); } for (int random = randomStart; random < randomEnd; random++) { String random5 = String.format("%0" + 5 + "d", random); String reagentCode = regentPrefix + random5; OpeReagentStatus opeReagentStatus = this.getOpeReagentStatusByReagentCode(reagentCode); if (opeReagentStatus != null) { throw new BusinessException(ExceptionEnumCode.PARAM_EXIST, MessageUtil.getMessageByCode(ExceptionEnumCode.PARAM_EXIST.getCode(), "试剂条码", reagentCode)); }else{ codeList.add(reagentCode); } } return codeList; }else{ throw new BusinessException(ExceptionEnumCode.REAGENT_CODE_INVALID,"输入的试剂条码不合法"); } } //2.纯数字编码列表生成 BigInteger reagentCode= new BigInteger(startReagentCode2); BigInteger endReagentCode = new BigInteger(endReagentCode2); //条码得距离 如果和到货数量不等 则输入有问题 if (!endReagentCode.subtract(reagentCode).add(BigInteger.ONE).equals(new BigInteger(String.valueOf(arrivalNum)))) { throw new BusinessException(ExceptionEnumCode.REAGENT_CODE_INVALID,"试剂的开始结束条码有问题"); } while (reagentCode.compareTo(endReagentCode) <= 0) { String reagentCodeStr = String.format("%0" + startReagentCode2.length() + "d", reagentCode); OpeReagentStatus opeReagentStatus = this.getOpeReagentStatusByReagentCode(reagentCodeStr); if (opeReagentStatus != null) { throw new BusinessException(ExceptionEnumCode.PARAM_EXIST, MessageUtil.getMessageByCode(ExceptionEnumCode.PARAM_EXIST.getCode(), "试剂条码", reagentCodeStr)); }else{ codeList.add(reagentCodeStr); } reagentCode = reagentCode.add(BigInteger.ONE); } return codeList; } @Override public void updateOpeReagentStatus(OpeReagentStatus opeReagentStatus) { opeReagentStatusDao.updateOpeReagentStatusDao(opeReagentStatus); } src/main/java/com/nanometer/smartlab/service/OpeWarehouseReserveService.java
@@ -4,6 +4,7 @@ import com.nanometer.smartlab.entity.OpeApply; import com.nanometer.smartlab.entity.OpeApplyReserve; import com.nanometer.smartlab.entity.OpeOrder; import com.nanometer.smartlab.entity.OpeWarehouseReserve; /** @@ -30,4 +31,6 @@ public List<OpeWarehouseReserve> selectByReId(String id); public void updateByReId(String newReId,String oldReId); void insertOpeWarehouseReserve2(OpeApplyReserve opeApplyReserve, OpeOrder oo); } src/main/java/com/nanometer/smartlab/service/OpeWarehouseReserveServiceImpl.java
@@ -8,6 +8,7 @@ import com.nanometer.smartlab.dao.OpeApplyDao; import com.nanometer.smartlab.entity.*; import com.nanometer.smartlab.entity.enumtype.ValidFlag; import com.nanometer.smartlab.exception.AlarmCode; import com.nanometer.smartlab.exception.AlarmException; import com.nanometer.smartlab.util.IDUtils; @@ -432,7 +433,29 @@ this.opeWarehouseReserveDao.updateByReId(params); } @Transactional(propagation = Propagation.REQUIRED) @Override @Transactional public void insertOpeWarehouseReserve2(OpeApplyReserve opeApplyReserve, OpeOrder oo) { OpeWarehouseReserve ope = new OpeWarehouseReserve(); //库存为到货数量 ope.setReserve(opeApplyReserve.getArrivalNum()); //仓库 ope.setWarehouseId(opeApplyReserve.getHouseId()); //试剂 ope.setReagentId(opeApplyReserve.getReagent().getId()); //订单编号 ope.setOrderCode(oo.getOrderCode()); // 申购编号 ope.setApplyCode(opeApplyReserve.getApplyCode()); //批号 ope.setArticleNumber(opeApplyReserve.getArticleNumber()); ope.setId(IDUtils.uuid()); opeWarehouseReserveDao.insertOpeWarehouseReserve2(ope); } @Transactional(propagation = Propagation.REQUIRED) public void reagentDStore(List<OpeApply> reagentDStoreList, String loginUserId) { if (reagentDStoreList == null) { src/main/java/com/nanometer/smartlab/util/Constants.java
@@ -50,6 +50,7 @@ public static final String PAGE_VIEW_ORDER_MNG = "view_order_mng"; public static final String PAGE_CANCEL_ORDER_MNG = "cancel_order_mng"; public static final String PAGE_WAREHOUSE_REAGENT_DIRECT_STORE = "warehouse_reagent_direct_store"; public static final String PAGE_ORDER_INPUT_WAREHOUSE = "order_input_warehouse"; // -----页面名称(以xhtml文件名为准)end----- src/main/webapp/WEB-INF/spring-menu.xml
@@ -153,6 +153,15 @@ </bean> <bean class="com.nanometer.smartlab.model.MenuModel"> <property name="id" value="order_input_warehouse"></property> <property name="title" value="仓库订单领用"></property> <property name="page" value="order_input_warehouse"></property> <property name="dispInMenuList" value="false"></property> <property name="initClazz" value="warehouseStockMngController"></property> <property name="initMethod" value="initInputWarehouse"></property> </bean> <bean class="com.nanometer.smartlab.model.MenuModel"> <property name="id" value="warehouse_reagent_direct_store"></property> <property name="title" value="试剂直接入库"></property> <property name="page" value="warehouse_reagent_direct_store"></property> src/main/webapp/order_input_warehouse.xhtml
对比新文件 @@ -0,0 +1,202 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:p="http://primefaces.org/ui" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:c="http://java.sun.com/jsp/jstl/core"> <head></head> <ui:composition> <h:form id="orderMngRukuForm"> <p:panel styleClass="center-header"> <p:outputLabel styleClass="title" value="订单入库"/> </p:panel> <p:panel styleClass="center-body"> <p:panel styleClass="apply-mng-new-body"> <p:panelGrid styleClass="info grid-padding-bottom2" columns="2"> <p:outputLabel value="到货时间:"/> <p:calendar value="#{warehouseStockMngController.arrivalTime}" converter="timestampConvert" pattern="yyyy-MM-dd" locale="zh_CN" required="true" requiredMessage="请选择到货时间"/> <p:outputLabel value="收货人:"/> <p:selectOneMenu value="#{warehouseStockMngController.consigneeId}" filter="true" filterMatchMode="startsWith" required="true" requiredMessage="请选择收货人"> <f:selectItems value="#{warehouseStockMngController.getConsignee()}" var="item" itemValue="#{item.id}" itemLabel="#{item.name}"/> </p:selectOneMenu> </p:panelGrid> <p:panel styleClass="btn"> <p:commandButton value="取消" process="@this" update=":centerRootPanel" actionListener="#{warehouseStockMngController.onCancelBtnClick}" styleClass="cancel-btn"/> <p:commandButton value="确定" process="@form" update=":centerRootPanel" actionListener="#{warehouseStockMngController.onSaveInputWarehouseClick}" styleClass="save-btn"> <p:confirm header="确认" message="确认操作?"/> </p:commandButton> </p:panel> </p:panel> <p:dataTable styleClass="data-table" paginator="true" paginatorAlwaysVisible="false" paginatorPosition="bottom" value="#{warehouseStockMngController.opeApplyList}" var="row" rowKey="#{row.id}" emptyMessage="无数据" editable="true" rows="20" pageLinks="5"> <p:column width="100"> <p:rowEditor/> </p:column> <p:column headerText="申购编号" width="120"> <h:outputText value="#{row.applyCode}"/> </p:column> <p:column headerText="试剂名称" width="120"> <h:outputText value="#{row.reagent!=null?row.reagent.name:''}"/> </p:column> <p:column headerText="包装" width="80"> <h:outputText value="#{row.reagent!=null?(''.concat(row.reagent.mainMetering).concat(baseMetaService.getBaseMetaValue(row.reagent.reagentUnit))):''}"/> </p:column> <p:column headerText="CAS" width="80"> <h:outputText value="#{row.reagent!=null?row.reagent.cas:''}"/> </p:column> <p:column headerText="厂家" width="80"> <h:outputText value="#{row.reagent.productHome}"/> </p:column> <p:column headerText="申购数量" width="80"> <h:outputText value="#{row.num}"/> </p:column> <p:column headerText="申购人" width="80"> <h:outputText value="#{sysUserService.getSysUser(row.applyUserId).getName()}"/> </p:column> <p:column headerText="到货数量" width="80"> <p:cellEditor> <f:facet name="output"> <h:outputText value="#{row.arrivalNum}" /> </f:facet> <f:facet name="input"> <p:inputText value="#{row.arrivalNum}" styleClass="arrivalNum" minValue="0" required="true" requiredMessage="请输入到货数量" onkeyup="this.value = #{row.num}"> <p:ajax event="keyup" listener="#{warehouseStockMngController.setArrival(row)}"/> </p:inputText> </f:facet> </p:cellEditor> </p:column> <p:column headerText="批号" width="100"> <p:cellEditor> <f:facet name="output"> <h:outputText value="#{row.articleNumber}" /> </f:facet> <f:facet name="input"> <p:inputText value="#{row.articleNumber}" maxlength="32" style="width: 100%" required="true" requiredMessage="请输入到批号"/> </f:facet> </p:cellEditor> </p:column> <p:column headerText="条形码开始" width="200"> <p:cellEditor> <f:facet name="output"> <h:outputText value="#{row.startReagentCode2}"/> </f:facet> <f:facet name="input"> <p:inputText value="#{row.startReagentCode2}" maxlength="24" size="24" styleClass="reagentCodeStart" onkeyup="this.value = this.value.replace(/[^0-9A-F]/,'')"> <p:ajax event="change" listener="#{warehouseStockMngController.reagentStartCodeChange(row)}" update="@this,@(.reagentCodeEnd),@(.arrivalNum)"/> </p:inputText> </f:facet> </p:cellEditor> </p:column> <p:column headerText="条形码结束" width="200"> <p:cellEditor> <f:facet name="output"> <h:outputText value="#{row.endReagentCode2}" /> </f:facet> <f:facet name="input"> <p:inputText value="#{row.endReagentCode2}" maxlength="24" size="24" onkeyup="this.value = this.value.replace(/\D/g,'')" styleClass="reagentCodeEnd"> </p:inputText> </f:facet> </p:cellEditor> </p:column> <p:column headerText="仓库名" width="120"> <p:cellEditor> <f:facet name="output"> <h:outputText value="#{warehouseStockMngController.formatWarehouseName(row.houseId)}"/> </f:facet> <f:facet name="input"> <p:selectOneMenu value="#{row.houseId}" style="width: 110px"> <p:ajax event="change" process="@this" listener="#{warehouseStockMngController.onWarehouseSelectChange(row.houseId)}" update="containerSelect"/> <f:selectItems value="#{warehouseStockMngController.warehouseList}" var="item" itemValue="#{item.id}" itemLabel="#{item.name}"/> </p:selectOneMenu> </f:facet> </p:cellEditor> </p:column> <p:column headerText="货柜名" width="120"> <p:cellEditor> <f:facet name="output"> <h:outputText value="#{warehouseStockMngController.formatWarehouseContainerName(row.containerId)}" /> </f:facet> <f:facet name="input"> <p:selectOneMenu id="containerSelect" value="#{row.containerId}" style="width: 110px"> <f:selectItems value="#{warehouseStockMngController.warehouseContainerList}" var="item" itemValue="#{item.id}" itemLabel="#{item.containerCode}"/> </p:selectOneMenu> </f:facet> </p:cellEditor> </p:column> </p:dataTable> </p:panel> </h:form> </ui:composition> </html> src/main/webapp/resources/css/default.css
@@ -1102,4 +1102,9 @@ vertical-align: baseline; border-radius: .25em; background-color: #d9534f; } #tabView\:putInStorageTmpOrder th{ background: #1c427b !important; } src/main/webapp/warehouse_stock_mng.xhtml
@@ -254,6 +254,95 @@ </p:panel> </h:form> </div> <div id ="putInStorage" style="display: none"> <h:form id="putInStorageTmpOrder" styleClass="inputStorageTmp"> <p:panel styleClass="center-body"> <p:panelGrid columns="3" styleClass="btn"> <p:commandButton value="删除" styleClass="del-btn" process="@form" actionListener="#{warehouseStockMngController.cancelInputStorageTmp}" update="@(.inputStorageTmp)" /> <p:commandButton value="清空" styleClass="del-btn" process="@form" actionListener="#{warehouseStockMngController.clearInputStorageTmp}" update="@(.inputStorageTmp)" /> <p:commandButton value="提交" styleClass="edit-btn" process="@form" actionListener="#{warehouseStockMngController.onUseBtnClickInputStorageTmp}" update=":centerRootPanel"/> </p:panelGrid> <p:dataTable id="putInStorageTmpOrderTable" styleClass="data-table" paginator="true" paginatorAlwaysVisible="false" paginatorPosition="bottom" lazy="true" value="#{warehouseStockMngController.selectedInputStorageTmpOrderList}" var="row" selection="#{warehouseStockMngController.trulyInputStorageTmpSelectedOrderList}" rowKey="#{row.id}" emptyMessage="无数据" rows="20" pageLinks="5"> <p:column selectionMode="multiple" style="width: 30px;text-align: center;" /> <p:column headerText="申购编号" width="170"> <h:outputText value="#{row.applyCode}"/> </p:column> <p:column headerText="产品编号"> <h:outputText value="#{row.reagent.productSn}"/> </p:column> <p:column headerText="试剂名称"> <h:outputText value="#{row.reagent.name}"/> </p:column> <p:column headerText="管制品"> <h:outputText value="#{row.reagent.controlProducts}"/> </p:column> <p:column headerText="规格"> <h:outputText value="#{row.reagent.reagentFormat}"/> </p:column> <p:column headerText="包装"> <h:outputText value="#{''.concat(row.reagent.mainMetering).concat(baseMetaService.getBaseMetaValue(row.reagent.reagentUnit))}"/> </p:column> <p:column headerText="价格"> <h:outputText value="#{row.reagent.price}"/> </p:column> <p:column headerText="CAS"> <h:outputText value="#{row.reagent.cas}"/> </p:column> <p:column headerText="危险性质"> <h:outputText value="#{row.reagent.reagentCharacter}"/> </p:column> <p:column headerText="厂商"> <h:outputText value="#{row.reagent.productHome}"/> </p:column> <p:column headerText="申请数量"> <h:outputText value="#{row.num}"/> </p:column> <p:column headerText="已领用数量"> <h:outputText value="#{row.used}"/> </p:column> <p:column headerText="申领人"> <h:outputText value="#{row.applyUserId}"/> </p:column> <p:column headerText="订单状态"> <h:outputText value="#{row.status.getText()}"/> </p:column> </p:dataTable> </p:panel> </h:form> </div> <h:form id="warehouseStockMngFormForPerson"> <p:panel styleClass="center-header" style="border-bottom:none;"> <p:panelGrid styleClass="filter" columns="12"> @@ -280,11 +369,16 @@ <p:panel styleClass="center-body"> <p:panelGrid columns="2" styleClass="btn" rendered="#{warehouseStockMngController.editFlag==1}"> <p:commandButton value="入库" styleClass="edit-btn" process="@form" actionListener="#{warehouseStockMngController.addInputStorageOrder}" disabled="#{warehouseStockMngController.editFlag==0}" oncomplete="$('#putInStorage').css('display','block');$('#showTabOrder').css('display','none');" update="@(.inputStorageTmp)" ></p:commandButton> <p:commandButton value="领用" styleClass="edit-btn" process="@form" actionListener="#{warehouseStockMngController.addOrder}" disabled="#{warehouseStockMngController.editFlag==0}" oncomplete="$('#showTabOrder').css('display','block');" oncomplete="$('#showTabOrder').css('display','block');$('#putInStorage').css('display','none');" update="@(.tmpOrder)" ></p:commandButton> <p:commandButton update=":centerRootPanel" actionListener="#{warehouseStockMngController.onExportFileBtnClickOrder}" @@ -354,6 +448,11 @@ <p:column headerText="订单状态"> <h:outputText value="#{row.status!=null?row.status.text:''}"></h:outputText> </p:column> <p:column headerText="到货时间"> <h:outputText value="#{row.arrivalTime}"> <f:convertDateTime pattern="yyyy-MM-dd" locale="zh_CN"/> </h:outputText> </p:column> <p:column headerText="课题组"> <h:outputText value="#{row.project}" /> </p:column>