建档
手操器
- 密封点信息的采集
一个标签号(L-00001)
- 标签号的上一级对应的是一个采集任务(手操器 EnvCheckData/photos下的目录文件)
- 对应一个现场采集照片
- 其所对应的采集的基本信息(对应手操器上添加照片的界面)
- 标签号
- 装置
- 区域。。。。。
- 一个标签号下会有许多个密封点(照片中的一个标记点)
- 一个密封点对应的基本信息为 : 所属标签号的基本信息 + 插入密封点时的3个参数(组件类型。。。)
系统中基本单位为 : 密封点
- 将采集的密封点信息抽取成Excel
一个标签号信息的采集结果,在手抄器上对应为一个标签号文件夹,一个标签号文件夹下有
- handle.jpg 标记了的图片, 导入到系统主要是查看使用,到底这个标签号(照片)下标了多少点
- unhandle.jpg 左上角带了标签号的图片。
- 在Android中主要用作底图
- 在服务器 查看->图片信息 下 会显示这张图片
- original.jpg 用来生成以上两张图片。
- json.txt
- 里面使用json持久化了一个对象: SceneCollectTask, 该对象描述了一个标签号(照片)中所有密封点的采集信息
生成Excel
- 将所有任务目录从手操器中拿出来
- 对每一个任务目录使用 Excel工具
- 经过该工具的操作,
- 对每一个任务可以生成一个Excel文件,改Excel文件中每一行都是一个密封点的基本信息
- 对于每一个标签号都会在 任务目录下,创建该标签号对应的目录,并保存 handle.jpg 和 unhandle.jpg 两张图片
- 工具的大体工作原理
- 以每一个目录下的标签号目录为基本文件操作单位, 对于该目录下的文件
- 将handle.jpg 和 unhandle.jpg,放置到对应的标签号的文件夹下
- json.txt 对 其中的SceneCollectTask对象解析, 将其中的每个密封点的信息解析出来, 并插入到Excel文件中
- 以每一个目录下的标签号目录为基本文件操作单位, 对于该目录下的文件
服务端将手操器采集的信息导入到该厂对应的数据库中
- 导入密封点
参数设置 -> 装置管理 和区域管理
- 在进行导入组件操作前,必须检索Excel文件中的所有 装置、区域 将其信息设置到系统参数中
- 设置这两个参数的原因
- 每个密封点编码需要由这两个参数构成: 装置编号 区域编号
- 如果没有设置这两个参数,那么导入无法生成密封点编码,即将会造成导入组件失败
StringBuilder builder = new StringBuilder();
//装置名称和套数
QueryHelper deviceHelper = new QueryHelper(DeviceInfo.class, “d”);
deviceHelper.addConditions(“d.deviceName = ?”, module.getDevice());
DeviceInfo deviceInfo = deviceInfoService.findDeviceByDeviceName(deviceHelper);
if(deviceInfo == null){
throw new RuntimeException(“无对应装置信息”);
}
工具 -> 导入密封点, 选择生成的Excel文件, 进行导入操作, 导入的大体过程
- 解析整个Excel文件,读取Excel中的每一行(密封点的基本信息), 将其插入到系统数据库中
工具 -> 导入图片
- 首先将一个厂的图片放入到服务器 images/ 目录下
- 图片路径: 即通过Excel工具生成的任务目录, 其下都是标签号文件夹。
- 导入的大体原理 :
- 根据标签号文件夹的名称, 将图片与密封点建立联系
- 联系体现在: ImportPictureHistory (该对象记录导入一个标签号的图片信息)
- 每一个密封点的 picture_path(unhandle.jpg的绝对路径), 即导入的时候要给每个密封点设置上
验证法规
- 何为法规
- 规定每个组件的泄露阈值和检测周期(目前的作用)
- 每个地方的法规可能不同,即对于同一 类型&&介质状态 的密封点 泄露阈值可能不同
- 法规的完整性: 要包含所有的密封点的 类型+介质状态 的组合
- 法规代码 长度不能超过 20个英文字符 (原因在后面)
- 验证法规
- 当前法规
- 现在在验证一个厂的法规时, 首先要确定该厂对应的法规,并将系统的当前法规设置为这个法规,然后进行验证法规
- 大致过程: 检索系统中的每一个密封点,将其法规代码设置为系统当前法规的法规代码
分配任务
- 分配的任务谁可以下载? 当前登陆这个厂的人! 即自己给自己分配任务 —>创建人
- 首先创建任务,确定任务的基本信息
- 开始日期: 即任务的开始日期,在生成任务的压缩文件时会作为压缩文件名称的一部分
- 任务名称: 系统中显示的名称 和 Android手操器下载的任务名称
- 检测类型
常规检测,符合条件的组件为
if(checkType.equals(Constant.TASK_TYPE_COMMON_CHECK)){ //常规检测 qh.addConditions("m.hasCheck = ?", false); qh.addConditions("m.taskId <> ?", task.getId()); qh.addConditions("m.hasAllocate = ?", false); qh.addConditions("m.diffToCheck = ?", "否"); }
目视检测,符合条件的组件为
if(checkType.equals(Constant.TASK_TYPE_EYE_CHECK)){ //目视检测 qh.addConditions("m.hasCheck = ?", false); qh.addConditions("m.taskId <> ?", task.getId()); qh.addConditions("m.hasAllocate = ?", false); qh.addConditions("m.diffToCheck = ?", "是"); }
泄露检测,符合条件的组件为
if(checkType.equals(Constant.TASK_TYPE_REPEATE_CHECK)){ //泄露检测 qh.addConditions("m.taskId <> ?", task.getId()); // qh.addConditions("m.hasAllocate = ?", false); 即使分配了, 如果泄露, 还是可以去复检 qh.addConditions("m.leak = ?", true); qh.addConditions("m.diffToCheck = ?", "否"); }
- 创建任务后生成的具体文件
- ExtraInfo文件夹下的各种文件
- task.txt
- 用来描述任务信息的文件,对应现场管理->分配任务 中的一条任务记录
- 客户端会操作这个文件中的json对象, 比如任务的 已检点 和 泄漏点 数目
- calibration.txt, weather.txt 这两个文件中以json持久化着两个对象
- CalibrationListFromServer 和 WeatherListFromServer
- 这个对象打到客户端和, 工作人员在记录 校准信息 和 天气信息时, 会把记录的内容持久化到这两个对象中, 即对应的json文件中
- 在接下来任务上传时,服务端会解析这两个对象,并把客户端记录的信息持久化到系统数据库中
- checkapparatus.txt law.txt mincheckTime.txt
- 这三个文件中同样存储着一些对象: MincheckTime CheckApparatusListFromServer Law
- 这些对象在服务端都是有信息的
- MincheckTime: 客户端和解析这个对象, 当检测一个密封点时根据密封点的尺寸, 在这个对象中找到应该检测的时间
- CheckApparatusListFromServer: 工作人员在填写校准参数时,仪器的选择就是来自于这个对象
- Law: 客户端在对每一个密封点进行检测时,寻找组件对应的法规也是来自于这个对象
- 服务端确定该任务应使用的法规为?Module representModule = moduleService.(); String lawCode = representModule.getLaws(); Law law = lawService.getLawByLawCode(lawCode);
- 向任务中添加密封点
- 根据任务类型筛选出符合条件的密封点,添加到任务中
- 即在任务目录下创建密封点对应的标签号目录,其下有两个文件: unhandle.jpg 和 标签号名.txt
- unhandle.jpg 用作检测时的地图
- 标签号名.txt 添加到任务中的密封点
- 使用标签号来组织更简单,
- 该文件中存储的对象为: CheckTaskForLabel
- 对于每一个密封点,标签其分配和检测有三个 字段
- hasAllocate : 如果将一个密封点添加到任务中,那该字段设置为true
- taskId: 如果已经分配, 该字段存储的为该密封点所属任务的任务id
- hasCheck: 客户端检测一个点,会把该字段设置为true
客户端上传任务
- 客户端上传的内容
- 客户端在上传时会将任务中的所有unhandle.jpg图片剔除,然后将整个文件夹压缩,然后上传到服务端
服务端解压缩该文件, 按照目录组织,对任务文件进行解析
- 首先解析 ExtraInfo文件夹下的内容, 把校准信息、天气参数存储到数据库中
解析每一个标签号文件夹下的密封点,并保存到数据库中
- 如果该点已经被检测,则、
- 将点的基本信息(ModuleCheck / ModuleRepairRecord)保存到数据库中
- 维护 密封点的PPM 记录集合
- 第一次检测,将检测的值插入到这个集合中, 如果是多次上传,则判断有没有必要更新这个点PPM集合中的值
- 泄露复检, 将泄露复检的值添加到集合中
- 多次复检, 就继续添加
如果该点没有检测,则
释放点,使之可以继续被分配
for (CheckTaskForModule checkTaskForModule : moduleTasks) { ModuleCheck moduleCheck = checkTaskForModule.getModuleCheck(); Module module = checkTaskForModule.getModule(); //没有进行检测 则把modulecheck对象清除, 释放任务,并使之可以重新分配 if (!module.isHasCheck()) { module.setTaskId("-1"); module.setHasAllocate(false); module.setModuleCheck(null); moduleService.update(module); moduleCheckService.delete(moduleCheck.getId()); } else { if (Constant.TASK_TYPE_COMMON_CHECK.equals(task.getCheckType())) { //维护 排放相关信息 DischargeForPPMRecord record = new DischargeForPPMRecord(); record.setCheckTime(moduleCheck.getStartTime()); record.setCleanPPMValue(moduleCheck.getPPMNumber()); record.setEndPeriodRecord(false); Set<DischargeForPPMRecord> dischargeForPPMRecords = module.getDischargeForPPMRecords(); if(recordNotInPPMRecords(record, dischargeForPPMRecords)){ dischargeForPPMRecords.add(record); } } if(task.getCheckType().equals(Constant.TASK_TYPE_REPEATE_CHECK)){ ModuleRepairRecord moduleRepairRecord = checkTaskForModule.getModuleRepairRecord(); module.setModuleRepairRecord(moduleRepairRecord); DischargeForPPMRecord record = new DischargeForPPMRecord(); ModuleRepairUnit unit = TaskUtils.findLatestModuleRepairUnit(moduleRepairRecord); if(unit != null){ record.setCleanPPMValue(unit.getRepeateCheckValue()); record.setCheckTime(unit.getRepeateCheckDate()); Set<DischargeForPPMRecord> dischargeForPPMRecords = module.getDischargeForPPMRecords(); if(recordNotInPPMRecords(record, dischargeForPPMRecords)){ dischargeForPPMRecords.add(record); } } moduleRepairRecord.setModule(module); moduleRepairRecordService.update(moduleRepairRecord); } module.setModuleCheck(moduleCheck); moduleService.update(module); //上传代码 moduleCheck.setModule(module); moduleCheckService.update(moduleCheck); //上传代码 } }
- 如果该点已经被检测,则、
密封点排放集合 DischargeForPPMRecord
如何计算排放量??
- 查看排放量算法
- 计算排放量的算法位于: com\envcheck\report\statistics\letnumberstatistics\utils\DisChargeUtils.java
public class DischargeForPPMRecord {private String id; private int cleanPPMValue; private Date checkTime; private boolean endPeriodRecord; ---> 表示是否为周期检测点
}
导出各种报告
- 查询, 利用各种查询语句, 查询出符合条件的对象
- 利用POI, 将这些对象导出到Excel中
- 动态选择导出的列: 使用反射
关于统计图表
- 构造eChart显示图标时所需要的对象, 服务端从数据库查询出来相关数据,构造这个对象,然后以json字符串的形式打给前台界面
动态数据库的切换
利用Spring AbstractRoutingDataSource 动态在操作数据库前确定数据源的 key
具体是利用 Servlet Filter 和 用户对应的公司信息 session 实现动态确定key
对于 装置类型、 法规、 最小检测时间, 在可以切换数据源的基础上, 这些都是使用的顶级数据库的信息,即 liept
对于全部厂区的检测点的统计实现方法
- 利用动态数据源切换,一个库一个的方式 select count(*), 最后输入统计结果