package com.ld.igds.inout.service.impl; import com.bstek.dorado.data.entity.EntityUtils; import com.ld.igds.common.CoreCommonService; import com.ld.igds.constant.BizType; import com.ld.igds.constant.Constant; import com.ld.igds.constant.RedisConst; import com.ld.igds.data.CommonData; import com.ld.igds.data.Page; import com.ld.igds.inout.InoutConstant; import com.ld.igds.inout.dto.InoutCheckData; import com.ld.igds.inout.dto.InoutCheckParam; import com.ld.igds.inout.dto.InoutData; import com.ld.igds.inout.dto.InoutParam; import com.ld.igds.inout.mapper.InoutCheckMapper; import com.ld.igds.inout.mapper.InoutRecordMapper; import com.ld.igds.inout.service.InoutService; import com.ld.igds.models.InoutPrice; import com.ld.igds.util.ContextUtil; import com.ld.igds.util.DateUtil; import com.ld.igds.util.RedisUtil; import com.ld.igds.websocket.WebSocketServer; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.time.DateFormatUtils; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.util.*; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.FutureTask; @Slf4j @Component public class InoutServiceImpl implements InoutService { @Resource private InoutRecordMapper inoutMapper; @Resource private InoutCheckMapper inoutCheckMapper; @Resource private RedisUtil redisUtil; @Resource private CoreCommonService commonService; @Override public InoutData inoutProgressQuery(InoutParam param) throws Exception { if (StringUtils.isEmpty(param.getCompanyId())) { param.setCompanyId(ContextUtil.getCompanyId()); } // 首先从缓存中获取,如果没有则从数据库获取 InoutData result = this.getFromInoutCache(param); if (null != result) { return result; } List list = inoutMapper.inoutProgressQuery(param); if (null == list || list.size() == 0) return null; if (list.size() == 1) { return list.get(0); } else { throw new Exception("当前条件下存在多个满足条件的数据,请核查!!"); } } @Override public InoutData inoutQueryById(InoutParam param) { if (StringUtils.isEmpty(param.getCompanyId())) { param.setCompanyId(ContextUtil.getCompanyId()); } if (null == param.getId()) return null; // 首先从缓存中获取,如果没有则从数据库获取 InoutData result = this.getFromInoutCache(param); if (null != result) { return result; } result = inoutMapper.inoutQueryById(param); return result; } @Override public String deleteData(InoutParam param) throws Exception { if (StringUtils.isEmpty(param.getCompanyId())) { param.setCompanyId(ContextUtil.getCompanyId()); } if (StringUtils.isEmpty(param.getId())) { return "没有获取到被删除数据的ID,无法删除!"; } inoutMapper.deleteData(param); delFromCache(param.getDeptId(), param.getType(), param.getId()); return null; } @Override public String inoutStop(InoutParam param) throws Exception { if (StringUtils.isEmpty(param.getCompanyId())) { param.setCompanyId(ContextUtil.getDefaultCompanyId()); } param.setProgress(InoutConstant.PROGRESS_RECORD); param.setRecordStatus(InoutConstant.RECORD_STATUS_DEL); // 缓存中删除 delFromCache(param.getDeptId(), param.getType(), param.getId()); inoutMapper.inoutStop(param); return null; } @Override public String insertData(InoutData data) { try { data.setUpdateTime(new Date()); if (null == data.getDeptId()) { data.setDeptId(ContextUtil.subDeptId(null)); } String id = this.createId(data.getRegisterTime(), data.getCompanyId()); if (StringUtils.isEmpty(data.getId())) { if (InoutConstant.TYPE_IN.equals(data.getType())) { data.setId("R_" + id); } else if (InoutConstant.TYPE_OUT.equals(data.getType())) { data.setId("C_" + id); } else if (Constant.LOSS_OVER_OVER.equals(data.getType())) { data.setId("R_" + id); } else if (Constant.LOSS_OVER_LOSS.equals(data.getType())) { data.setId("C_" + id); } else { data.setId("M_" + id); } } if (StringUtils.isEmpty(data.getCheckId())) { data.setCheckId(id); } if (null == data.getUserName()) { data.setUserName(""); } inoutMapper.insertData(data); updateInoutCache(data); } catch (Exception e) { log.error("------------出入库执行保存出错---{}", e); return "后台异常:" + e.getMessage(); } return null; } @Override public String updateData(InoutData data) throws Exception { data.setUpdateTime(new Date()); if (StringUtils.isEmpty(data.getCompanyId())) { data.setCompanyId(ContextUtil.getCompanyId()); } InoutData newData; if (EntityUtils.isEntity(data)) { newData = new InoutData(); BeanUtils.copyProperties(data, newData, new String[]{"checkItems", "files"}); } else { newData = data; } inoutMapper.updateData(newData); //更新缓存 updateInoutCache(newData); return null; } @Override public String updateDataByHandle(InoutData data) { data.setUpdateTime(new Date()); if (StringUtils.isEmpty(data.getCompanyId())) { data.setCompanyId(ContextUtil.getCompanyId()); } InoutData newData; if (EntityUtils.isEntity(data)) { newData = new InoutData(); BeanUtils.copyProperties(data, newData, new String[]{"checkItems", "files"}); } else { newData = data; } inoutMapper.updateDataByHandle(newData); //更新缓存 updateInoutCache(newData); return null; } @Override public Page pageRecordData(InoutParam param) { if (StringUtils.isEmpty(param.getCompanyId())) { param.setCompanyId(ContextUtil.getCompanyId()); } Page page = new Page<>(param.getPage(), param.getLimit()); page.setSearchCount(true); if (null != param.getStart()) { param.setStart(DateUtil.getCurZero(param.getStart())); } if (null != param.getEnd()) { param.setEnd(DateUtil.getNextZero(param.getEnd())); } // 设置车牌的模糊查询条件 if (null != param.getPlateNum()) { param.setPlateNum("%" + param.getPlateNum() + "%"); } // 设置身份证号的模糊查询条件 if (null != param.getUserId()) { param.setUserId("%" + param.getUserId() + "%"); } if(null != param.getRecordStatus() && InoutConstant.RECORD_STATUS_NORMAL.equals(param.getRecordStatus())){ param.setRecordStatus(null); } List records = inoutMapper.pageRecordData(page, param); //判断入库重量是否为空,为空则赋值结算重量 if (records != null) { for (InoutData record : records) { if (record.getRecordWeight() == null || record.getRecordWeight() == 0.0) { record.setRecordWeight(record.getSettleWeight()); } } } page.setRecords(records); return page; } @Override public List listRecordData(InoutParam param) { if (StringUtils.isEmpty(param.getCompanyId())) { param.setCompanyId(ContextUtil.getCompanyId()); } List records = inoutMapper.listRecordData(param); return records; } @Override public String validate(String intelCard, String plateNum) { InoutParam param = new InoutParam(); param.setCompanyId(ContextUtil.getCompanyId()); param.setIntelCard(intelCard); param.setPlateNum(plateNum); int i = inoutMapper.validateInoutData(param); if (i > 0) { return "当前卡或者车辆出入库未完成!"; } return null; } @Override public String toComplete(InoutParam param) throws Exception { param.setUpdateTime(new Date()); if (null == param.getCompanyId()) { param.setCompanyId(ContextUtil.getDefaultCompanyId()); } // 清除缓存 this.delFromCache(param.getDeptId(), param.getType(), param.getId()); inoutMapper.toComplete(param); return null; } @Override public String quickComplete(InoutData data) throws Exception { if (null == data.getCompanyId()) { data.setCompanyId(ContextUtil.getDefaultCompanyId()); } if (null == data.getCompleteTime()) { data.setCompleteTime(new Date()); } if (null == data.getCompleteTime()) { data.setCompleteTime(new Date()); } if (null == data.getEmptyWeightTime()) { data.setEmptyWeightTime(new Date()); } //调整时间差 if (InoutConstant.TYPE_IN.equals(data.getType())) { if (data.getFullWeightTime().after(data.getEmptyWeightTime())) data.setFullWeightTime(DateUtil.getNewByMinute(data.getEmptyWeightTime(), -50)); if (data.getCompleteTime().before(data.getEmptyWeightTime())) data.setCompleteTime(DateUtil.getNewByMinute(data.getEmptyWeightTime(), 5)); } //调整时间差 if (InoutConstant.TYPE_OUT.equals(data.getType())) { if (data.getEmptyWeightTime().after(data.getFullWeightTime())) data.setEmptyWeightTime(DateUtil.getNewByMinute(data.getFullWeightTime(), -50)); if (data.getCompleteTime().before(data.getFullWeightTime())) data.setCompleteTime(DateUtil.getNewByMinute(data.getFullWeightTime(), 10)); } if (InoutConstant.STATUS_NONE.equals(data.getCheckStatus())) { data.setCheckStatus(InoutConstant.STATUS_PASS); } // 设置流程结束 data.setProgress(InoutConstant.PROGRESS_RECORD); //执行更新 inoutMapper.updateData(data); //更新缓存 updateInoutCache(data); return null; } @Override public void updateInoutCache(InoutData data) { data.setFiles(null); data.setCheckItems(null); if (InoutConstant.PROGRESS_RECORD.equals(data.getProgress())) { delFromCache(data.getDeptId(), data.getType(), data.getId()); setCompleteInoutCache(data.getDeptId(), data); } else { setInoutCache(data.getDeptId(), data); } } public void delFromCache(String deptId, String type, String id) { if (StringUtils.isEmpty(deptId)) { return; } if (StringUtils.isEmpty(type)) { return; } if (StringUtils.isEmpty(id)) { return; } //从未完成列表中删除 String key = this.buildInoutKey(deptId, InoutConstant.KEY_INOUT_LIST, type, id); redisUtil.del(key); } @Override public List getListInoutCache(String deptId) { String pattern = RedisConst.buildKey(deptId, InoutConstant.KEY_INOUT_LIST); Set keys = redisUtil.keys(pattern); if (null == keys || keys.isEmpty()) { return null; } List list = new ArrayList<>(); for (String key : keys) { list.add((InoutData) redisUtil.get(key)); } return list; } @Override public List getCompleteListInoutCache(String deptId) { String pattern = RedisConst.buildKey(deptId, InoutConstant.KEY_INOUT_COMPLETE_LIST); Set keys = redisUtil.keys(pattern); if (null == keys || keys.isEmpty()) { return null; } List list = new ArrayList<>(); for (String key : keys) { list.add((InoutData) redisUtil.get(key)); } return list; } @Override public InoutData getFromInoutCache(InoutParam param) { if (StringUtils.isEmpty(param.getDeptId())) { param.setDeptId(ContextUtil.subDeptId(null)); } List list = getListInoutCache(param.getDeptId()); if (null == list || list.isEmpty()) return null; String intelCard = param.getIntelCard(), plateNum = param.getPlateNum(), id = param.getId(), userId = param.getUserId(); for (InoutData data : list) { if (StringUtils.isNotEmpty(id) && data.getId().equals(id)) { return data; } if (StringUtils.isNotEmpty(intelCard) && data.getIntelCard().equals(intelCard)) { return data; } if (StringUtils.isNotEmpty(plateNum) && data.getPlateNum().equals(plateNum)) { return data; } if (StringUtils.isNotEmpty(userId) && data.getUserId().equals(userId)) { return data; } } return null; } @Override public Page pageUnCompleteData(InoutParam param) { if (StringUtils.isEmpty(param.getCompanyId())) { param.setCompanyId(ContextUtil.getCompanyId()); } Page page = new Page(param.getPage(), param.getLimit()); page.setSearchCount(true); if (null != param.getStart()) { param.setStart(DateUtil.getCurZero(param.getStart())); } if (null != param.getEnd()) { param.setEnd(DateUtil.getNextZero(param.getEnd())); } // 设置单据号模糊查询 if (null != param.getId()) { param.setId("%" + param.getId() + "%"); } // 设置往来单位名称的模糊查询条件 if (StringUtils.isNotEmpty(param.getCustomerName())) { param.setCustomerName("%" + param.getCustomerName() + "%"); } List records = inoutMapper.pageUnCompleteData(page, param); page.setRecords(records); return page; } @Override public InoutData getLastRecord(InoutParam param) { return inoutMapper.getLastRecord(param); } @Override public String addInoutDataByLossOver(InoutData data) { // 获取上一车的流水数据 // InoutData inoutData = this.getLastRecord(data.getCompanyId(), data.getDepotId()); // // 设置流水的库存 // if (InoutConstant.TYPE_IN.equals(inoutData.getType())) { // data.setCurStorage(inoutData.getCurStorage() // + inoutData.getSettleWeight()); // } else if (InoutConstant.TYPE_OUT.equals(inoutData.getType())) { // data.setCurStorage(inoutData.getCurStorage() // - inoutData.getSettleWeight()); // } // 添加补单数据 this.insertData(data); return data.getId(); } @Override public void delInoutDataByLossOver(InoutParam param) { inoutMapper.deleteData(param); } @Override public void setCheckCache(InoutData data) { String cacheKey = RedisConst.buildKey(data.getCompanyId(), data.getCheckId()); //化验结果存入缓存3天 redisUtil.set(cacheKey, data.getCheckItems(), 60 * 60 * 24 * 3); } /** * 出入库流程ID创建 202001030001 202001030001 * * @param registerTime 登记时间,和组织编码 * @return */ @Override public String createId(Date registerTime, String companyId) { // 时间戳标签 String timeKey = DateFormatUtils.format(registerTime, "yyyyMMdd"); // 从缓存中获取已有的组织编码 String cacheKey = RedisConst.buildKey(companyId, InoutConstant.CACHE_RECORD_ID); String cacheId = (String) redisUtil.get(cacheKey); if (null != cacheId && cacheId.indexOf(timeKey) >= 0) { String temp = cacheId.substring(cacheId.length() - 4); Integer i = Integer.valueOf(temp); i++; temp = String.valueOf(i); if (temp.length() == 1) { cacheId = timeKey + "000" + temp; } if (temp.length() == 2) { cacheId = timeKey + "00" + temp; } if (temp.length() == 3) { cacheId = timeKey + "0" + temp; } if (temp.length() == 4) { cacheId = timeKey + temp; } } else { Map result = inoutMapper.getMaxId("%_" + timeKey + "%", companyId); if (null == result) { cacheId = timeKey + "0001"; } else { String temp = (String) result.get("maxId"); // 获取最后四位 int i = Integer.valueOf(temp.substring(temp.length() - 4)); i++; temp = String.valueOf(i); if (temp.length() == 1) { cacheId = timeKey + "000" + temp; } if (temp.length() == 2) { cacheId = timeKey + "00" + temp; } if (temp.length() == 3) { cacheId = timeKey + "0" + temp; } if (temp.length() == 4) { cacheId = timeKey + temp; } } } // 更新缓存 redisUtil.set(cacheKey, cacheId); return cacheId; } @Override public double sumRecordWeight(InoutParam param) { CommonData result = inoutMapper.sumRecordWeight(param); return result.getNumValue1(); } @Override public int checkExist(InoutParam param) { return inoutMapper.checkExist(param); } /** * 未完成流程存入缓存 * * @param deptId * @param data */ private void setInoutCache(String deptId, InoutData data) { String key = this.buildInoutKey(deptId, InoutConstant.KEY_INOUT_LIST, data.getType(), data.getId()); redisUtil.set(key, data, InoutConstant.KEY_INOUT_LIST_TIME); } /** * 设置完成的流水存入缓存 * * @param deptId * @param data */ private void setCompleteInoutCache(String deptId, InoutData data) { String key = this.buildInoutKey(deptId, InoutConstant.KEY_INOUT_COMPLETE_LIST, data.getType(), data.getId()); //设置缓存到第二天凌晨(计算当前时间到第二天凌晨的时间差秒数) redisUtil.set(key, data, DateUtil.getNowToNextDaySeconds()); } /** * 推送到大屏,判断只有当大屏在线时候才处理当前逻辑,避免页面卡顿,调用子任务完成推送 * * @param companyId 组织编号 * @param deptId 分库编号 * @param progress 流转节点 */ public void notifyToScreen(String companyId, String deptId, String progress) { // 推送到大屏 List curList = this.getListInoutCache(deptId); List completeList = this.getCompleteListInoutCache(deptId); if (null == WebSocketServer.contextOnLineMap.get(BizType.SCREEN .getCode())) { WebSocketServer.contextOnLineMap.put(BizType.SCREEN.getCode(), false); } if (null == WebSocketServer.contextOnLineMap.get(BizType.SCREEN_INOUT .getCode())) { WebSocketServer.contextOnLineMap.put( BizType.SCREEN_INOUT.getCode(), false); } if (null == WebSocketServer.contextOnLineMap.get(BizType.SCREEN_CHECK .getCode())) { WebSocketServer.contextOnLineMap.put( BizType.SCREEN_CHECK.getCode(), false); } if (WebSocketServer.contextOnLineMap.get(BizType.SCREEN.getCode()) || WebSocketServer.contextOnLineMap.get(BizType.SCREEN_INOUT .getCode()) || WebSocketServer.contextOnLineMap.get(BizType.SCREEN_CHECK .getCode())) { // 创建一个子任务进行推送信息 FutureTask futureTask = new FutureTask<>(new NotifyScreenTask(curList, completeList, deptId)); ExecutorService executorService = Executors.newCachedThreadPool(); executorService.submit(futureTask); executorService.shutdown(); } } /** * 创建出入库key * * @param deptId * @param key * @param type * @param bizId * @return */ public String buildInoutKey(String deptId, String key, String type, String bizId) { return Constant.APP_NAME + ":" + deptId + ":" + key + ":" + type + ":" + bizId; } @Override public Page pageSampleData(InoutCheckParam param) { //设置起始和截止时间 if (null != param.getStart()) { param.setStart(DateUtil.getCurZero(param.getStart())); } if (null != param.getEnd()) { param.setEnd(DateUtil.getNextZero(param.getEnd())); } // 设置车牌和检验单据的模糊查询 if (StringUtils.isNotEmpty(param.getPlateNum())) { param.setPlateNum("%" + param.getPlateNum() + "%"); } if (StringUtils.isNotEmpty(param.getCheckId())) { param.setCheckId("%" + param.getCheckId() + "%"); } Page page = new Page<>(param.getPage(), param.getLimit()); page.setSearchCount(true); List records = inoutCheckMapper.pageSampleData(page, param); page.setRecords(records); return page; } @Override public String updateSampleData(InoutCheckData data) { if (StringUtils.isEmpty(data.getCompanyId())) { data.setCompanyId(ContextUtil.getCompanyId()); } if (StringUtils.isEmpty(data.getDeptId())) { data.setCompanyId(ContextUtil.subDeptId(null)); } inoutCheckMapper.updateSampleData(data); return null; } @Override public Page pageCheckData(InoutCheckParam param) { //设置起始和截止时间 if (null != param.getStart()) { param.setStart(DateUtil.getCurZero(param.getStart())); } if (null != param.getEnd()) { param.setEnd(DateUtil.getNextZero(param.getEnd())); } // 设置检验单据的模糊查询 if (StringUtils.isNotEmpty(param.getCheckId())) { param.setCheckId("%" + param.getCheckId() + "%"); } Page page = new Page<>(param.getPage(), param.getLimit()); page.setSearchCount(true); List records = inoutCheckMapper.pageCheckData(page, param); page.setRecords(records); return page; } @Override public String updateCheckData(InoutData data) { data.setUpdateTime(new Date()); inoutCheckMapper.updateCheckData(data); //更新缓存 updateInoutCache(data); return null; } @Override public List getPrice(InoutCheckParam param) { if (null == param.getStart()) { param.setStart(new Date()); } if (null == param.getEnd()) { param.setEnd(new Date()); } return inoutCheckMapper.getPrice(param); } }