basic-server/src/main/java/com/ruoyi/basic/mapper/LaboratoryMapper.java
@@ -7,6 +7,9 @@ import com.ruoyi.basic.pojo.Laboratory; import org.apache.ibatis.annotations.Param; import java.util.List; import java.util.Set; /** * å®éªå®¤ç®¡ç(Laboratory)è¡¨æ°æ®åºè®¿é®å± */ @@ -16,5 +19,6 @@ Object obtainItemParameterList(@Param("page") Page page, @Param("ew") QueryWrapper<Laboratory> ew); List<Laboratory> selectByName(@Param("names") Set<String> names); } basic-server/src/main/resources/mapper/LaboratoryMapper.xml
@@ -39,4 +39,12 @@ left join user u1 on l.create_user = u1.id ) a </select> <select id="selectByName" resultType="com.ruoyi.basic.pojo.Laboratory"> SELECT id, laboratory_name FROM laboratory WHERE laboratory_name IN <foreach collection="names" item="name" open="(" separator="," close=")"> #{name} </foreach> </select> </mapper> cnas-device/src/main/java/com/ruoyi/device/controller/DeviceController.java
@@ -3,9 +3,8 @@ import com.alibaba.excel.EasyExcel; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.basic.excel.StructureTestObjectData; import com.ruoyi.basic.excel.StructureTestObjectListener; import com.ruoyi.common.core.domain.Result; import com.ruoyi.common.utils.LocalDateTimeStringConverters; import com.ruoyi.device.dto.DataConfigDto; import com.ruoyi.device.dto.DeviceCollectionDto; import com.ruoyi.device.dto.DeviceDto; @@ -16,7 +15,6 @@ import com.ruoyi.device.service.DeviceService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.apache.commons.codec.digest.DigestUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.*; @@ -27,7 +25,6 @@ import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; @@ -209,7 +206,9 @@ @PostMapping("/importDevice") public Result importDevice(@RequestParam("file") MultipartFile file){ try { EasyExcel.read(file.getInputStream(), Device.class, new DeviceListener(deviceService)).sheet().doRead(); EasyExcel.read(file.getInputStream(), Device.class, new DeviceListener(deviceService)) .registerConverter(new LocalDateTimeStringConverters()) .sheet().doRead(); } catch (IOException e) { // è¿éå¯ä»¥æ ¹æ®å®é æ åµè¿è¡æ´å®åçé误å¤çï¼æ¯å¦è®°å½æ¥å¿ç System.err.println("读åæä»¶æ¶åçé误: " + e.getMessage()); cnas-device/src/main/java/com/ruoyi/device/dto/DeviceDto.java
@@ -6,7 +6,6 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.time.LocalDateTime; @Data @@ -39,5 +38,14 @@ @ApiModelProperty(value = "䏿¬¡æ ¡åæ¥æ") private LocalDateTime nextCalibrationDateTwo; private String deviceName; private String specModel; private String manageNumber; // å ¨åæé 彿° public DeviceDto(String deviceName, String specModel, String manageNumber) { this.deviceName = deviceName; this.specModel = specModel; this.manageNumber = manageNumber; } } cnas-device/src/main/java/com/ruoyi/device/excel/upload/DeviceListener.java
@@ -3,12 +3,8 @@ import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import com.ruoyi.basic.excel.StructureTestObjectData; import com.ruoyi.basic.service.ProductService; import com.ruoyi.device.pojo.Device; import com.ruoyi.device.service.DeviceService; import com.ruoyi.performance.dto.AuxiliaryCorrectionHoursDto; import com.ruoyi.performance.service.AuxiliaryCorrectionHoursService; import java.util.ArrayList; import java.util.List; cnas-device/src/main/java/com/ruoyi/device/mapper/DeviceMapper.java
@@ -10,6 +10,7 @@ import java.util.List; import java.util.Map; import java.util.Set; /** * 设å¤(Device)è¡¨æ°æ®åºè®¿é®å± @@ -36,5 +37,7 @@ List<Map<String, Object>> treeDevice(@Param("deviceName") String deviceName); DeviceDto selectDeviceByCode(Integer id); List<Device> selectByKeys(@Param("keys") Set<DeviceDto> keys); } cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceServiceImpl.java
@@ -1,9 +1,10 @@ package com.ruoyi.device.service.impl; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONObject; import com.alibaba.fastjson2.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; @@ -34,16 +35,14 @@ import com.ruoyi.inspect.mapper.InsSampleMapper; import com.ruoyi.inspect.pojo.InsProduct; import com.ruoyi.inspect.util.HackLoopTableRenderPolicy; import com.ruoyi.performance.dto.AuxiliaryCorrectionHoursDto; import com.ruoyi.performance.pojo.AuxiliaryCorrectionHours; import com.ruoyi.system.mapper.SysDictDataMapper; import com.ruoyi.system.mapper.UserMapper; import lombok.AllArgsConstructor; import org.apache.logging.log4j.util.Strings; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -54,7 +53,7 @@ import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.regex.Pattern; import java.util.function.Function; import java.util.stream.Collectors; /** @@ -509,49 +508,113 @@ } } //å¯¼å ¥è®¾å¤ @Override public void importExcel(List<Device> list){ if (CollectionUtil.isEmpty(list)) { @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class) public void importExcel(List<Device> batch) { if (CollectionUtils.isEmpty(batch)) { return; } List<Device> deviceList = new ArrayList<>(); List<Device> devices = new ArrayList<>(); for (Device device : list) { Device device1 = deviceMapper.selectOne(Wrappers.<Device>lambdaQuery() .eq(Device::getDeviceName, device.getDeviceName()) .eq(Device::getSpecificationModel, device.getSpecificationModel()) .eq(Device::getManagementNumber, device.getManagementNumber())); //管ç人 if (ObjectUtils.isNotEmpty(device.getEquipmentManagerName())){ //æ¥å¯¹åºç®¡ç人 User user = userMapper.selectOne(Wrappers.<User>lambdaQuery() .eq(User::getName, device.getEquipmentManagerName())); device.setEquipmentManager(user.getId()); } //æå±é¨é¨ if (ObjectUtils.isNotEmpty(device.getSubordinateDepartments())){ //æ¥å¯¹åºæå±é¨é¨ Laboratory laboratory = laboratoryMapper.selectOne(Wrappers.<Laboratory>lambdaQuery() .eq(Laboratory::getLaboratoryName,device.getSubordinateDepartments())); device.setSubordinateDepartmentsId(laboratory.getId()); } // 1. æ¹éæ¥è¯¢å ³èæ°æ®ï¼ç¨æ·ãå®éªå®¤ï¼ Map<String, Integer> userMap = queryUserMap(batch); Map<String, Integer> labMap = queryLabMap(batch); // 2. å åå¤çï¼è½¬æ¢å ³èåæ®µå¹¶å»é processBatch(batch, userMap, labMap); // 3. æ¹éæä½æ°æ®åº batchOperate(batch); } private Map<String, Integer> queryUserMap(List<Device> batch) { Set<String> managerNames = batch.stream() .map(Device::getEquipmentManagerName) .filter(Objects::nonNull) .collect(Collectors.toSet()); if (CollUtil.isEmpty(managerNames)) { return Collections.emptyMap(); } return userMapper.selectList( new LambdaQueryWrapper<User>().in(User::getName, managerNames) ).stream().collect(Collectors.toMap(User::getName, User::getId)); } private Map<String, Integer> queryLabMap(List<Device> batch) { Set<String> labNames = batch.stream() .map(Device::getSubordinateDepartments) .filter(Objects::nonNull) .collect(Collectors.toSet()); if (CollUtil.isEmpty(labNames)) { return Collections.emptyMap(); } return laboratoryMapper.selectList( new LambdaQueryWrapper<Laboratory>().in(Laboratory::getLaboratoryName, labNames) ).stream().collect(Collectors.toMap(Laboratory::getLaboratoryName, Laboratory::getId)); } private void processBatch(List<Device> batch, Map<String, Integer> userMap, Map<String, Integer> labMap) { // é¢è®¡ç®å¯ä¸é®ï¼è®¾å¤åç§°+åå·+管çç¼å·ï¼ Map<String, Device> existDevices = deviceMapper.selectList( new LambdaQueryWrapper<Device>() .in(Device::getDeviceName, batch.stream().map(Device::getDeviceName).collect(Collectors.toSet())) .in(Device::getSpecificationModel, batch.stream().map(Device::getSpecificationModel).collect(Collectors.toSet())) .in(Device::getManagementNumber, batch.stream().map(Device::getManagementNumber).collect(Collectors.toSet())) ).stream().collect(Collectors.toMap( d -> d.getDeviceName() + "|" + d.getSpecificationModel() + "|" + d.getManagementNumber(), Function.identity() )); List<Device> toInsert = new ArrayList<>(); List<Device> toUpdate = new ArrayList<>(); for (Device device : batch) { // 转æ¢å ³èåæ®µ device.setEquipmentManager(userMap.get(device.getEquipmentManagerName())); device.setSubordinateDepartmentsId(labMap.get(device.getSubordinateDepartments())); //设å¤ç¶æ if (ObjectUtils.isNotEmpty(device.getDeviceStatusName())){ //æ¥åå ¸å¯¹åºçå¼ String status = sysDictDataMapper.selectDictValue("device_status", device.getDeviceStatusName()); device.setDeviceStatus(Integer.parseInt(status)); } if (ObjectUtils.isNotEmpty(device1)) { devices.add(device1); // çæå¯ä¸é® String key = device.getDeviceName() + "|" + device.getSpecificationModel() + "|" + device.getManagementNumber(); if (existDevices.containsKey(key)) { Device exist = existDevices.get(key); BeanUtils.copyProperties(device, exist, "id"); toUpdate.add(exist); } else { deviceList.add(device); toInsert.add(device); } } //æ¹éæ°å¢ saveBatch(deviceList); //æ¹éä¿®æ¹ updateBatchById(devices); batch.clear(); batch.addAll(toInsert); batch.addAll(toUpdate); } private void batchOperate(List<Device> batch) { // æåæå ¥åæ´æ°å表 List<Device> toInsert = new ArrayList<>(); List<Device> toUpdate = new ArrayList<>(); for (Device device : batch) { if (device.getId() == null) { toInsert.add(device); } else { toUpdate.add(device); } } // æ¹éæå ¥ï¼ä½¿ç¨MyBatis-PlusçinsertBatchï¼é»è®¤batchSize=1000ï¼ if (CollUtil.isNotEmpty(toInsert)) { saveOrUpdateBatch(toInsert); } // æ¹éæ´æ°ï¼ä½¿ç¨MyBatis-PlusçupdateBatchByIdï¼é»è®¤batchSize=1000ï¼ if (CollUtil.isNotEmpty(toUpdate)) { updateBatchById(toUpdate); } } } cnas-device/src/main/resources/mapper/DeviceMapper.xml
@@ -181,4 +181,20 @@ u1.name, u2.name </select> <select id="selectByKeys" resultType="com.ruoyi.device.pojo.Device"> SELECT id, device_name, specification_model, management_number, manufacturer, factory_no, technical_indicators, acquisition_date, activation_date, equipment_manager, storage_point, subordinate_departments_id, calibration_services, last_calibration_date, next_calibration_date, large_category, unit_price, device_status, calibration_date, image_upload, image_name FROM device WHERE <foreach collection="keys" item="key" separator=" OR " open="(" close=")"> (device_name = #{key.deviceName} AND specification_model = #{key.specModel} AND management_number = #{key.manageNumber}) </foreach> </select> </mapper> ruoyi-common/src/main/java/com/ruoyi/common/utils/LocalDateTimeStringConverters.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,84 @@ package com.ruoyi.common.utils; import com.alibaba.excel.converters.Converter; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.GlobalConfiguration; import com.alibaba.excel.metadata.data.ReadCellData; import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.ruoyi.common.exception.base.BaseException; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import java.util.Arrays; import java.util.Date; import java.util.List; public class LocalDateTimeStringConverters implements Converter<LocalDateTime> { // æ¯æçææ¬æ¥ææ ¼å¼ï¼æä¼å 级å°è¯ï¼ private static final List<DateTimeFormatter> STRING_FORMATTERS = Arrays.asList( DateTimeFormatter.ofPattern("yyyy.MM.dd"), DateTimeFormatter.ofPattern("yyyy.M.d"), DateTimeFormatter.ofPattern("yyyy/MM/dd"), DateTimeFormatter.ofPattern("yyyy-MM-dd"), DateTimeFormatter.ofPattern("yyyyMMdd") ); @Override public Class<LocalDateTime> supportJavaTypeKey() { return LocalDateTime.class; // ç®æ Java ç±»å } @Override public CellDataTypeEnum supportExcelTypeKey() { return CellDataTypeEnum.STRING; // é»è®¤æ¯æç Excel åå æ ¼ç±»å } @Override public LocalDateTime convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { // æ£æ¥åå æ ¼æ¯å¦ä¸ºç©ºææ æå¼ if (cellData == null || cellData.getType() == null || (cellData.getType() == CellDataTypeEnum.EMPTY)) { return null; } // æ ¹æ®åå æ ¼ç±»åè¿è¡å¤ç switch (cellData.getType()) { case STRING: // å符串类å String dateString = cellData.getStringValue().trim(); if (dateString.isEmpty() || "/".equals(dateString)) { return null; // ç¹æ®å¼å¤ç } // å°è¯æææ¯æçæ¥ææ ¼å¼ for (DateTimeFormatter formatter : STRING_FORMATTERS) { try { LocalDate localDate = LocalDate.parse(dateString, formatter); LocalDateTime localDateTime = localDate.atStartOfDay(); return localDateTime; // 设置é»è®¤æ¶é´ä¸º 00:00:00 } catch (DateTimeParseException ignored) { // 忽ç¥åä¸ªæ ¼å¼çè§£æå¤±è´¥ï¼ç»§ç»å°è¯ä¸ä¸ä¸ªæ ¼å¼ } } // å¦ææææ ¼å¼å失败ï¼åæåºå¼å¸¸ throw new BaseException("æ æ³è§£æåç¬¦ä¸²æ¥æ: " + dateString); case NUMBER: // æ°å¼ç±»åï¼Excel æ¥ææ ¼å¼ï¼ try { double excelNumber = cellData.getNumberValue().doubleValue(); Date date = org.apache.poi.ss.usermodel.DateUtil.getJavaDate(excelNumber, false); return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(); } catch (Exception e) { throw new BaseException("æ æ³è§£ææ°å¼æ¥æ: " + cellData.getNumberValue()); } case BOOLEAN: // å¸å°ç±»å throw new BaseException("å¸å°ç±»å䏿¯æä½ä¸ºæ¥æå段"); default: throw new BaseException("䏿¯æçåå æ ¼ç±»å: " + cellData.getType()); } } } ruoyi-system/src/main/java/com/ruoyi/system/mapper/UserMapper.java
@@ -8,6 +8,7 @@ import java.util.List; import java.util.Map; import java.util.Set; /** * ç¨æ·ä¿¡æ¯è¡¨ @@ -60,5 +61,6 @@ List<User> selectDepartmentLimsUserList(@Param("userId") Integer userId); List<User> selectByNames(@Param("names") Set<String> names); } ruoyi-system/src/main/resources/mapper/system/UserMapper.xml
@@ -94,5 +94,11 @@ from user u2 where u2.id = #{userId}) </select> <select id="selectByNames" resultType="com.ruoyi.common.core.domain.entity.User"> SELECT id, name FROM user WHERE name IN <foreach item="name" collection="names" open="(" separator="," close=")"> #{name} </foreach> </select> </mapper>