| | |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.hutool.json.JSONObject; |
| | | import com.alibaba.excel.EasyExcel; |
| | | import com.alibaba.fastjson2.JSON; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; |
| | |
| | | import com.ruoyi.basic.mapper.StructureItemParameterMapper; |
| | | import com.ruoyi.basic.pojo.StructureItemParameter; |
| | | import com.ruoyi.common.core.domain.Result; |
| | | import com.ruoyi.common.core.domain.entity.SysDictData; |
| | | import com.ruoyi.common.core.domain.entity.SysDept; |
| | | import com.ruoyi.common.core.domain.entity.User; |
| | | import com.ruoyi.common.utils.QueryWrappers; |
| | | import com.ruoyi.device.dto.*; |
| | | import com.ruoyi.device.excel.upload.DeviceImport; |
| | | import com.ruoyi.device.mapper.CollectBridgeMapper; |
| | | import com.ruoyi.device.mapper.DeviceMaintenanceMapper; |
| | | import com.ruoyi.device.mapper.DeviceMapper; |
| | |
| | | import com.ruoyi.device.pojo.*; |
| | | import com.ruoyi.device.service.DataConfigService; |
| | | import com.ruoyi.device.service.DeviceService; |
| | | import com.ruoyi.device.service.DocumentService; |
| | | import com.ruoyi.device.service.DeviceDocumentsService; |
| | | import com.ruoyi.device.utils.DataAcquisition; |
| | | import com.ruoyi.framework.exception.ErrorException; |
| | | import com.ruoyi.inspect.mapper.InsSampleMapper; |
| | | import com.ruoyi.inspect.pojo.InsProduct; |
| | | import com.ruoyi.inspect.util.HackLoopTableRenderPolicy; |
| | | import com.ruoyi.system.mapper.SysDictDataMapper; |
| | | import com.ruoyi.system.mapper.SysDeptMapper; |
| | | import com.ruoyi.system.mapper.UserMapper; |
| | | import lombok.AllArgsConstructor; |
| | | import org.apache.logging.log4j.util.Strings; |
| | | import org.springframework.beans.BeanUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.io.InputStream; |
| | | import java.io.OutputStream; |
| | | import java.math.BigDecimal; |
| | | import java.net.URLEncoder; |
| | | import java.text.SimpleDateFormat; |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.*; |
| | |
| | | |
| | | private UserMapper userMapper; |
| | | |
| | | private SysDeptMapper sysDeptMapper; |
| | | |
| | | private SysDictDataMapper sysDictDataMapper; |
| | | |
| | | private StructureItemParameterMapper structureItemParameterMapper; |
| | | |
| | | private DataConfigService dataConfigService; |
| | | |
| | | private QrShowServiceImpl qrShowService; |
| | | |
| | | private InsSampleMapper insSampleMapper; |
| | | |
| | | private DocumentService documentService; |
| | | private DeviceDocumentsService documentService; |
| | | |
| | | private DeviceMetricRecordMapper deviceMetricRecordMapper; |
| | | |
| | |
| | | @Transactional(rollbackFor = Exception.class) |
| | | @Override |
| | | public int upDeviceParameter(Device itemParameter) { |
| | | // 删除数采集配置数据 |
| | | dataConfigService.deleteDataConfig(); |
| | | // 需要同时更改 device表 |
| | | |
| | | |
| | | return deviceMapper.updateById(itemParameter); |
| | | } |
| | |
| | | } |
| | | deviceDto.setAuthorizedPersonName(name); |
| | | //查询设备校准信息 |
| | | DeviceMetricRecord calibrate = qrShowService.getDeviceMetricRecord(id, "calibrate"); |
| | | DeviceMetricRecord calibrate = getDeviceMetricRecord(id, "calibrate"); |
| | | deviceDto.setCalibrateNo(calibrate.getCertificateSerialNumber()); |
| | | |
| | | // 到了停用日期,自动将状态改为停用 |
| | |
| | | } |
| | | } |
| | | return deviceDto; |
| | | } |
| | | |
| | | /** |
| | | * 查询设备校准/核查记录 |
| | | * @param deviceId |
| | | * @param type |
| | | * @return |
| | | */ |
| | | public DeviceMetricRecord getDeviceMetricRecord(int deviceId, String type){ |
| | | return Optional.ofNullable( |
| | | deviceMetricRecordMapper.selectOne(Wrappers.<DeviceMetricRecord>lambdaQuery() |
| | | .eq(DeviceMetricRecord::getDeviceId, deviceId) |
| | | .eq(DeviceMetricRecord::getType, type) |
| | | .orderByDesc(DeviceMetricRecord::getCreateTime) |
| | | .last("limit 1"))).orElse(new DeviceMetricRecord()); |
| | | } |
| | | |
| | | @Override |
| | |
| | | // 设备信息 |
| | | Device device = baseMapper.selectById(deviceId); |
| | | // 设备档案 |
| | | List<Document> documentList = documentService.list(Wrappers.<Document>lambdaQuery().eq(Document::getDeviceId, deviceId)); |
| | | List<DeviceDocuments> documentList = documentService.list(Wrappers.<DeviceDocuments>lambdaQuery().eq(DeviceDocuments::getDeviceId, deviceId)); |
| | | // 设备校准表 |
| | | List<DeviceMetricRecord> deviceMetricRecordList = deviceMetricRecordMapper.selectList(Wrappers.<DeviceMetricRecord>lambdaQuery().eq(DeviceMetricRecord::getDeviceId, deviceId)); |
| | | // 设备维修表 |
| | |
| | | template.write(os); |
| | | os.flush(); |
| | | os.close(); |
| | | inputStream.close(); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | throw new RuntimeException("导出失败"); |
| | |
| | | DeviceMaintenance deviceMaintenance = deviceMaintenanceList.get(i); |
| | | DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); |
| | | // 维修日期 |
| | | deviceMetricRecordAndMaintenanceDto.setMaintenanceDateString(deviceMaintenance.getDate().format(dateTimeFormatter)); |
| | | deviceMetricRecordAndMaintenanceDto.setMaintenanceDateString(deviceMaintenance.getMaintenanceDate().format(dateTimeFormatter)); |
| | | // 处理方法 |
| | | deviceMetricRecordAndMaintenanceDto.setHandlingMethod(deviceMaintenance.getContent()); |
| | | deviceMetricRecordAndMaintenanceDto.setHandlingMethod(deviceMaintenance.getMaintenanceContent()); |
| | | // 备注 |
| | | deviceMetricRecordAndMaintenanceDto.setComments(deviceMaintenance.getComments()); |
| | | deviceMetricRecordAndMaintenanceDto.setComments(deviceMaintenance.getRemark()); |
| | | } |
| | | |
| | | deviceMetricRecordAndMaintenanceDtoList.add(deviceMetricRecordAndMaintenanceDto); |
| | |
| | | * @param documentList 档案列表 |
| | | * @param documentExportWordDtoList 返回给word的数据列表 |
| | | */ |
| | | private static void extracted(List<Document> documentList, List<DocumentExportWordDto> documentExportWordDtoList) { |
| | | private static void extracted(List<DeviceDocuments> documentList, List<DocumentExportWordDto> documentExportWordDtoList) { |
| | | // 给档案加序号 并且分为左右两个列表在word中显示 |
| | | for (int i = 0; i < documentList.size(); i++) { |
| | | // 创建word表格中一行的数据对象 |
| | | DocumentExportWordDto documentExportWordDto = new DocumentExportWordDto(); |
| | | // 获取档案信息 |
| | | Document document = documentList.get(i); |
| | | DeviceDocuments document = documentList.get(i); |
| | | // 格式化日期 |
| | | DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); |
| | | // 根据序号 分别加入两个列表 |
| | |
| | | template.write(os); |
| | | os.flush(); |
| | | os.close(); |
| | | inputStream.close(); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | throw new RuntimeException("导出失败"); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void downloadImportTemplate(HttpServletResponse response) { |
| | | response.reset(); |
| | | response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); |
| | | response.setHeader("Access-Control-Expose-Headers", "Content-Disposition"); |
| | | try { |
| | | String fileName = URLEncoder.encode("设备导入模板.xlsx", "UTF-8"); |
| | | response.setHeader("Content-Disposition", "attachment;filename=" + fileName); |
| | | EasyExcel.write(response.getOutputStream(), DeviceImport.class) |
| | | .sheet("设备导入模板") |
| | | .doWrite(Collections.emptyList()); |
| | | } catch (Exception e) { |
| | | throw new RuntimeException("设备导入模板下载失败", e); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public int importDevice(org.springframework.web.multipart.MultipartFile file) { |
| | | if (file == null || file.isEmpty()) { |
| | | throw new RuntimeException("请选择需要导入的Excel文件"); |
| | | } |
| | | String fileName = file.getOriginalFilename(); |
| | | if (fileName == null || !fileName.toLowerCase(Locale.ROOT).endsWith(".xlsx")) { |
| | | throw new RuntimeException("仅支持.xlsx格式文件"); |
| | | } |
| | | |
| | | final List<DeviceImport> rows; |
| | | try { |
| | | rows = EasyExcel.read(file.getInputStream()) |
| | | .head(DeviceImport.class) |
| | | .sheet() |
| | | .doReadSync(); |
| | | } catch (Exception e) { |
| | | throw new RuntimeException("Excel解析失败,请使用下载的导入模板", e); |
| | | } |
| | | if (CollectionUtils.isEmpty(rows)) { |
| | | throw new RuntimeException("导入文件没有设备数据"); |
| | | } |
| | | |
| | | Set<String> fileKeys = new HashSet<>(); |
| | | for (int i = 0; i < rows.size(); i++) { |
| | | String managementNumber = required(rows.get(i).getManagementNumber(), i + 2, "管理编号"); |
| | | String deviceName = required(rows.get(i).getDeviceName(), i + 2, "仪器名称"); |
| | | String specificationModel = required(rows.get(i).getSpecificationModel(), i + 2, "规格型号"); |
| | | if (!fileKeys.add(deviceKey(deviceName, specificationModel, managementNumber))) { |
| | | throw new RuntimeException("第" + (i + 2) + "行:仪器名称+规格型号+管理编号在文件中重复"); |
| | | } |
| | | } |
| | | Set<String> existingKeys = baseMapper.selectList(Wrappers.<Device>lambdaQuery() |
| | | .select(Device::getDeviceName, Device::getSpecificationModel, Device::getManagementNumber)) |
| | | .stream().map(d -> deviceKey(d.getDeviceName(), d.getSpecificationModel(), d.getManagementNumber())).collect(Collectors.toSet()); |
| | | |
| | | Map<String, List<SysDept>> departmentMap = sysDeptMapper.selectDeptList(new SysDept()).stream() |
| | | .filter(item -> StringUtils.isNotBlank(item.getDeptName())) |
| | | .collect(Collectors.groupingBy(item -> item.getDeptName().trim())); |
| | | Map<String, List<User>> userMap = userMapper.selectList(Wrappers.<User>lambdaQuery() |
| | | .isNotNull(User::getName).select(User::getId, User::getName)) |
| | | .stream().collect(Collectors.groupingBy(item -> item.getName().trim())); |
| | | Map<String, String> statusMap = dictMap("device_status"); |
| | | Map<String, String> typeMap = dictMap("device_type"); |
| | | |
| | | List<Device> devices = new ArrayList<>(); |
| | | for (int i = 0; i < rows.size(); i++) { |
| | | int rowNumber = i + 2; |
| | | DeviceImport row = rows.get(i); |
| | | String managementNumber = required(row.getManagementNumber(), rowNumber, "管理编号"); |
| | | String deviceName = required(row.getDeviceName(), rowNumber, "仪器名称"); |
| | | String specificationModel = required(row.getSpecificationModel(), rowNumber, "规格型号"); |
| | | if (existingKeys.contains(deviceKey(deviceName, specificationModel, managementNumber))) { |
| | | throw new RuntimeException("第" + rowNumber + "行:仪器名称“" + deviceName + "”+规格型号“" + specificationModel + "”+管理编号“" + managementNumber + "”已存在"); |
| | | } |
| | | |
| | | String laboratoryName = required(row.getLaboratoryName(), rowNumber, "所属部门"); |
| | | List<SysDept> departments = departmentMap.get(laboratoryName); |
| | | if (CollectionUtils.isEmpty(departments) || departments.size() > 1) { |
| | | throw new RuntimeException("第" + rowNumber + "行:所属部门“" + laboratoryName + "”不存在或不唯一"); |
| | | } |
| | | |
| | | Device device = new Device(); |
| | | device.setDeviceName(deviceName); |
| | | device.setSpecificationModel(specificationModel); |
| | | device.setManagementNumber(managementNumber); |
| | | device.setActivationDate(parseDate(row.getActivationDate())); |
| | | device.setSubordinateDepartmentsId(departments.get(0).getDeptId().intValue()); |
| | | device.setDeviceStatus(Integer.valueOf(dictValue(statusMap, row.getDeviceStatus(), rowNumber, "当前状态", true))); |
| | | device.setCalibrationDate(required(row.getCalibrationDate(), rowNumber, "校准周期(月)")); |
| | | device.setEnDeviceName(trim(row.getEnDeviceName())); |
| | | device.setManufacturer(trim(row.getManufacturer())); |
| | | device.setFactoryNo(trim(row.getFactoryNo())); |
| | | device.setAssetCode(trim(row.getAssetCode())); |
| | | device.setOrigin(trim(row.getOrigin())); |
| | | device.setAcquisitionDate(parseDate(row.getAcquisitionDate())); |
| | | device.setStoragePoint(trim(row.getStoragePoint())); |
| | | device.setTechnicalIndicators(trim(row.getTechnicalIndicators())); |
| | | device.setCalibrationServices(trim(row.getCalibrationServices())); |
| | | device.setLastCalibrationDate(parseDate(row.getLastCalibrationDate())); |
| | | device.setNextCalibrationDate(parseDate(row.getNextCalibrationDate())); |
| | | device.setLargeCategory(dictValue(typeMap, row.getLargeCategory(), rowNumber, "设备类型", false)); |
| | | device.setUnitPrice(parseDecimal(row.getUnitPrice(), rowNumber, "单价(万元)")); |
| | | |
| | | String managerName = trim(row.getEquipmentManagerName()); |
| | | if (StringUtils.isNotBlank(managerName)) { |
| | | List<User> users = userMap.get(managerName); |
| | | if (CollectionUtils.isEmpty(users) || users.size() > 1) { |
| | | throw new RuntimeException("第" + rowNumber + "行:负责人“" + managerName + "”不存在或不唯一"); |
| | | } |
| | | device.setEquipmentManager(users.get(0).getId()); |
| | | } |
| | | devices.add(device); |
| | | } |
| | | saveBatch(devices); |
| | | return devices.size(); |
| | | } |
| | | |
| | | private Map<String, String> dictMap(String dictType) { |
| | | return sysDictDataMapper.selectDictDataByType(dictType).stream() |
| | | .collect(Collectors.toMap(item -> item.getDictLabel().trim(), SysDictData::getDictValue, (first, second) -> first)); |
| | | } |
| | | |
| | | private String dictValue(Map<String, String> values, String input, int rowNumber, String column, boolean required) { |
| | | String text = trim(input); |
| | | if (StringUtils.isBlank(text)) { |
| | | if (required) { |
| | | throw new RuntimeException("第" + rowNumber + "行:" + column + "不能为空"); |
| | | } |
| | | return null; |
| | | } |
| | | String value = values.get(text); |
| | | if (value == null && values.containsValue(text)) { |
| | | value = text; |
| | | } |
| | | if (value == null) { |
| | | throw new RuntimeException("第" + rowNumber + "行:" + column + "“" + text + "”不在系统字典中"); |
| | | } |
| | | return value; |
| | | } |
| | | |
| | | private LocalDateTime parseDate(String input) { |
| | | String text = trim(input); |
| | | if (StringUtils.isBlank(text)) { |
| | | return null; |
| | | } |
| | | String datePart = text.replace('/', '-').split("\\s+")[0]; |
| | | try { |
| | | return LocalDate.parse(datePart, DateTimeFormatter.ofPattern("yyyy-M-d")).atStartOfDay(); |
| | | } catch (Exception e) { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | private BigDecimal parseDecimal(String input, int rowNumber, String column) { |
| | | String text = trim(input); |
| | | if (StringUtils.isBlank(text)) { |
| | | return null; |
| | | } |
| | | try { |
| | | return new BigDecimal(text); |
| | | } catch (NumberFormatException e) { |
| | | throw new RuntimeException("第" + rowNumber + "行:" + column + "必须是数字", e); |
| | | } |
| | | } |
| | | |
| | | private String required(String input, int rowNumber, String column) { |
| | | String value = trim(input); |
| | | if (StringUtils.isBlank(value)) { |
| | | throw new RuntimeException("第" + rowNumber + "行:" + column + "不能为空"); |
| | | } |
| | | return value; |
| | | } |
| | | |
| | | private String deviceKey(String deviceName, String specificationModel, String managementNumber) { |
| | | return (deviceName == null ? "" : deviceName.trim()) + "|" |
| | | + (specificationModel == null ? "" : specificationModel.trim()) + "|" |
| | | + (managementNumber == null ? "" : managementNumber.trim()); |
| | | } |
| | | |
| | | private String trim(String value) { |
| | | return value == null ? null : value.trim(); |
| | | } |
| | | } |