施工人员文件处理
This commit is contained in:
		| @ -197,9 +197,9 @@ public class TransferDataController { | ||||
|     } | ||||
|  | ||||
|  | ||||
|     @GetMapping("/transferSpecialWorkPic") | ||||
|     private void handleFaceImage() { | ||||
|         transferDataService.handleSpecialWorkPic(); | ||||
|     @GetMapping("/handleFile") | ||||
|     private void handleFile() { | ||||
|         transferDataService.handleFile(); | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -0,0 +1,20 @@ | ||||
| package org.dromara.transferData.domain; | ||||
|  | ||||
| import lombok.Data; | ||||
|  | ||||
| @Data | ||||
| public class ConstructionUserNew { | ||||
|     private Long id; | ||||
|  | ||||
|     private Long sysUserId; | ||||
|  | ||||
|     private Long goId; | ||||
|  | ||||
|     private String yhkPic; | ||||
|  | ||||
|     private String sfzFrontPic; | ||||
|  | ||||
|     private String sfzBackPic; | ||||
|  | ||||
|     private String specialWorkPic; | ||||
| } | ||||
| @ -0,0 +1,21 @@ | ||||
| package org.dromara.transferData.domain; | ||||
|  | ||||
| import com.baomidou.mybatisplus.annotation.*; | ||||
| import lombok.Data; | ||||
|  | ||||
| import java.time.LocalDateTime; | ||||
|  | ||||
| @Data | ||||
| public class OldFile { | ||||
|  | ||||
|     private Long id; | ||||
|  | ||||
|     private Long userId; | ||||
|  | ||||
|     private String userImgType; | ||||
|  | ||||
|     private String name; | ||||
|  | ||||
|     private String path; | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,39 @@ | ||||
| package org.dromara.transferData.domain; | ||||
|  | ||||
| import com.baomidou.mybatisplus.annotation.TableId; | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
| import lombok.Data; | ||||
|  | ||||
| import java.io.Serial; | ||||
| import java.io.Serializable; | ||||
| import java.util.Date; | ||||
|  | ||||
| /** | ||||
|  * 施工人员文件存储对象 sub_construction_user_file | ||||
|  * | ||||
|  * @author lilemy | ||||
|  * @date 2025-04-01 | ||||
|  */ | ||||
| @Data | ||||
| public class UserFile { | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * 用户id | ||||
|      */ | ||||
|     private Long userId; | ||||
|  | ||||
|     /** | ||||
|      * 文件类型 | ||||
|      */ | ||||
|     private String fileType; | ||||
|  | ||||
|     /** | ||||
|      * 文件路径 | ||||
|      */ | ||||
|     private String path; | ||||
|  | ||||
|  | ||||
|     private Long goId; | ||||
|  | ||||
| } | ||||
| @ -1,13 +1,9 @@ | ||||
| package org.dromara.transferData.mapper; | ||||
|  | ||||
| import com.baomidou.dynamic.datasource.annotation.DS; | ||||
| import org.apache.ibatis.annotations.Insert; | ||||
| import org.apache.ibatis.annotations.Mapper; | ||||
| import org.apache.ibatis.annotations.Param; | ||||
| import org.apache.ibatis.annotations.Select; | ||||
| import org.apache.ibatis.annotations.*; | ||||
| import org.dromara.project.domain.BusAttendance; | ||||
| import org.dromara.transferData.domain.ConstructionUserCopy; | ||||
| import org.dromara.transferData.domain.OldAttendance; | ||||
| import org.dromara.transferData.domain.*; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| @ -40,4 +36,38 @@ public interface TransferDataMapper { | ||||
|         "</foreach>" + | ||||
|         "</script>") | ||||
|     int saveBatchCopy(@Param("list") List<BusAttendance> busAttendanceList); | ||||
|  | ||||
|  | ||||
|     @Select("select id,go_id,sfz_front_pic,sfz_back_pic,yhk_pic,special_work_pic from sub_construction_user_copy1") | ||||
|     List<ConstructionUserNew> getConstructionUserList(); | ||||
|  | ||||
|  | ||||
|     @DS("slave1") | ||||
|     @Select("<script>" + | ||||
|         "SELECT * FROM bus_construction_user_file " + | ||||
|         "WHERE user_id IN " + | ||||
|         "<foreach collection='userIds' item='userId' open='(' separator=',' close=')'>" + | ||||
|         "#{userId}" + | ||||
|         "</foreach>" + | ||||
|         "</script>") | ||||
|    List<OldFile> getOldFileList1(List<Long> userIds); | ||||
|  | ||||
|     @DS("slave") | ||||
|     @Select("<script>" + | ||||
|         "SELECT * FROM bus_construction_user_file " + | ||||
|         "WHERE user_id IN " + | ||||
|         "<foreach collection='userIds' item='userId' open='(' separator=',' close=')'>" + | ||||
|         "#{userId}" + | ||||
|         "</foreach>" + | ||||
|         "</script>") | ||||
|     List<OldFile> getOldFileList(List<Long> userIds); | ||||
|  | ||||
|     @Select("<script>" + | ||||
|         "SELECT * FROM sub_construction_user_file " + | ||||
|         "WHERE go_id IN " + | ||||
|         "<foreach collection='goIds' item='userId' open='(' separator=',' close=')'>" + | ||||
|         "#{userId}" + | ||||
|         "</foreach>" + | ||||
|         "</script>") | ||||
|     List<UserFile> getUserFileList(List<Long> goIds); | ||||
| } | ||||
|  | ||||
| @ -1,5 +1,11 @@ | ||||
| package org.dromara.transferData.service; | ||||
|  | ||||
| import cn.hutool.core.bean.BeanUtil; | ||||
| import cn.hutool.core.collection.CollectionUtil; | ||||
| import cn.hutool.core.util.StrUtil; | ||||
| import com.baomidou.mybatisplus.core.conditions.Wrapper; | ||||
| import com.baomidou.mybatisplus.core.conditions.query.Query; | ||||
| import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | ||||
| import com.baomidou.mybatisplus.core.toolkit.Wrappers; | ||||
| import jakarta.activation.MimetypesFileTypeMap; | ||||
| import jakarta.annotation.Resource; | ||||
| @ -15,6 +21,10 @@ import org.dromara.project.service.IBusAttendanceRuleService; | ||||
| import org.dromara.project.service.IBusAttendanceService; | ||||
| import org.dromara.system.domain.vo.SysOssVo; | ||||
| import org.dromara.system.service.ISysOssService; | ||||
| import org.dromara.transferData.domain.ConstructionUserNew; | ||||
| import org.dromara.transferData.domain.OldFile; | ||||
| import org.dromara.transferData.domain.UserFile; | ||||
| import org.dromara.transferData.mapper.TransferDataMapper; | ||||
| import org.springframework.beans.factory.annotation.Qualifier; | ||||
| import org.springframework.scheduling.annotation.Async; | ||||
| import org.springframework.stereotype.Service; | ||||
| @ -29,10 +39,13 @@ import java.nio.file.Paths; | ||||
| import java.time.Duration; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.concurrent.CompletableFuture; | ||||
| import java.util.concurrent.Executor; | ||||
| import java.util.stream.Collectors; | ||||
|  | ||||
| import static kotlin.reflect.jvm.internal.impl.builtins.StandardNames.FqNames.list; | ||||
|  | ||||
| /** | ||||
|  * @Author 铁憨憨 | ||||
|  * @Date 2025/9/14 10:53 | ||||
| @ -55,6 +68,8 @@ public class TransferDataService { | ||||
|     @Resource | ||||
|     @Qualifier("attendanceAsyncPool") // 对应之前 AsyncConfig 中定义的线程池Bean名 | ||||
|     private Executor attendanceAsyncExecutor; | ||||
|     @Resource | ||||
|     private TransferDataMapper transferDataMapper; | ||||
|  | ||||
|  | ||||
|     // 两个候选基础URL | ||||
| @ -62,8 +77,10 @@ public class TransferDataService { | ||||
|         "http://xny.yj-3d.com:7464", | ||||
|         "http://xny.yj-3d.com:7363" | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * 异步处理照片并批量保存(修复线程安全 + 性能优化) | ||||
|      * | ||||
|      * @param batchList 原始批量数据(浅拷贝) | ||||
|      */ | ||||
|     // 2. 修复后的照片批量异步处理逻辑 | ||||
| @ -164,7 +181,7 @@ public class TransferDataService { | ||||
|                     try (InputStream inputStream = httpClient.send(request, HttpResponse.BodyHandlers.ofInputStream()).body()) { | ||||
|                         // 从响应头获取真实Content-Type(比文件名解析更准确) | ||||
|                         HttpResponse<?> response = httpClient.send(request, HttpResponse.BodyHandlers.discarding()); | ||||
|                         if(response.statusCode() == 200){ | ||||
|                         if (response.statusCode() == 200) { | ||||
|                             contentType = response.headers().firstValue("Content-Type").orElse(contentType); | ||||
|                             long contentLength = response.headers().firstValueAsLong("Content-Length").orElse(-1); | ||||
|  | ||||
| @ -197,21 +214,21 @@ public class TransferDataService { | ||||
|         //获取到施工人员信息,然后处理图片 | ||||
|         List<SubConstructionUser> list1 = constructionUserService.list(); | ||||
|         for (SubConstructionUser subConstructionUser : list1) { | ||||
|             if(subConstructionUser.getFacePic()!=null){ | ||||
|             if (subConstructionUser.getFacePic() != null) { | ||||
|                 Long l = handleSinglePhoto1(subConstructionUser.getFacePic()); | ||||
|                 subConstructionUser.setFacePic(l==null?"":l.toString()); | ||||
|                 subConstructionUser.setFacePic(l == null ? "" : l.toString()); | ||||
|             } | ||||
|             if(subConstructionUser.getSfzFrontPic()!=null){ | ||||
|             if (subConstructionUser.getSfzFrontPic() != null) { | ||||
|                 Long l = handleSinglePhoto1(subConstructionUser.getSfzFrontPic()); | ||||
|                 subConstructionUser.setSfzFrontPic(l==null?"":l.toString()); | ||||
|                 subConstructionUser.setSfzFrontPic(l == null ? "" : l.toString()); | ||||
|             } | ||||
|             if(subConstructionUser.getSfzBackPic()!=null){ | ||||
|             if (subConstructionUser.getSfzBackPic() != null) { | ||||
|                 Long l = handleSinglePhoto1(subConstructionUser.getSfzBackPic()); | ||||
|                 subConstructionUser.setSfzBackPic(l==null?"":l.toString()); | ||||
|                 subConstructionUser.setSfzBackPic(l == null ? "" : l.toString()); | ||||
|             } | ||||
|             if(subConstructionUser.getYhkPic()!=null){ | ||||
|             if (subConstructionUser.getYhkPic() != null) { | ||||
|                 Long l = handleSinglePhoto1(subConstructionUser.getYhkPic()); | ||||
|                 subConstructionUser.setYhkPic(l==null?"":l.toString()); | ||||
|                 subConstructionUser.setYhkPic(l == null ? "" : l.toString()); | ||||
|             } | ||||
|             objects.add(subConstructionUser); | ||||
|         } | ||||
| @ -230,8 +247,8 @@ public class TransferDataService { | ||||
|                 String[] split = path.split(","); | ||||
|                 for (String s : split) { | ||||
|                     Long l = handleSinglePhoto1(s); | ||||
|                     if(l!=null){ | ||||
|                         subConstructionUser.setPath(subConstructionUser.getPath().replace(s,l.toString())); | ||||
|                     if (l != null) { | ||||
|                         subConstructionUser.setPath(subConstructionUser.getPath().replace(s, l.toString())); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| @ -243,7 +260,6 @@ public class TransferDataService { | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
|     private Long handleSinglePhoto1(String facePicRelativePath) { | ||||
|         if (facePicRelativePath == null || facePicRelativePath.isEmpty()) { | ||||
|             return null; | ||||
| @ -272,7 +288,7 @@ public class TransferDataService { | ||||
|                     try (InputStream inputStream = httpClient.send(request, HttpResponse.BodyHandlers.ofInputStream()).body()) { | ||||
|                         // 从响应头获取真实Content-Type(比文件名解析更准确) | ||||
|                         HttpResponse<?> response = httpClient.send(request, HttpResponse.BodyHandlers.discarding()); | ||||
|                         if(response.statusCode() == 200){ | ||||
|                         if (response.statusCode() == 200) { | ||||
|                             contentType = response.headers().firstValue("Content-Type").orElse(contentType); | ||||
|                             long contentLength = response.headers().firstValueAsLong("Content-Length").orElse(-1); | ||||
|  | ||||
| @ -291,7 +307,7 @@ public class TransferDataService { | ||||
|  | ||||
|         // 所有URL和重试都失败 | ||||
|         log.error("照片处理失败,所有URL重试完毕,relativePath={}", normalizedPath); | ||||
|        return null; | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -301,13 +317,127 @@ public class TransferDataService { | ||||
|         for (SubConstructionUser constructionUser : list) { | ||||
|             String facePicRelativePath = constructionUser.getSpecialWorkPic(); | ||||
|             Long l = handleSinglePhoto1(facePicRelativePath); | ||||
|             constructionUser.setSpecialWorkPic(l==null?"":l.toString()); | ||||
|             constructionUser.setSpecialWorkPic(l == null ? "" : l.toString()); | ||||
|         } | ||||
|  | ||||
|         constructionUserService.updateBatchById(list); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     public void handleFile() { | ||||
|         List<ConstructionUserNew> constructionUserList = transferDataMapper.getConstructionUserList(); | ||||
|         log.info("开始处理特殊图片,一共{}条数据", constructionUserList.size()); | ||||
|         List<Long> list1 = constructionUserList.stream().map(ConstructionUserNew::getGoId).toList(); | ||||
|         //zmkgprod | ||||
|         List<OldFile> oldFileList1 = transferDataMapper.getOldFileList1(list1); | ||||
|         // 将 oldFileList1 转换为 Map<Long, Map<String, String>> 结构 | ||||
|         Map<Long, Map<String, String>> resultMap1 = oldFileList1.stream() | ||||
|             .collect(Collectors.groupingBy( | ||||
|                 OldFile::getUserId, | ||||
|                 Collectors.toMap( | ||||
|                     OldFile::getUserImgType, | ||||
|                     OldFile::getPath, | ||||
|                     (existing, replacement) -> replacement // 如果有重复的 key,保留后面的值 | ||||
|                 ) | ||||
|             )); | ||||
|         //zmkgc | ||||
|         List<OldFile> oldFileList = transferDataMapper.getOldFileList(list1); | ||||
|  | ||||
|         // 将 oldFileList1 转换为 Map<Long, Map<String, String>> 结构 | ||||
|         Map<Long, Map<String, String>> resultMap = oldFileList.stream() | ||||
|             .collect(Collectors.groupingBy( | ||||
|                 OldFile::getUserId, | ||||
|                 Collectors.toMap( | ||||
|                     OldFile::getUserImgType, | ||||
|                     OldFile::getPath, | ||||
|                     (existing, replacement) -> replacement // 如果有重复的 key,保留后面的值 | ||||
|                 ) | ||||
|             )); | ||||
|         //本地文件 | ||||
|  | ||||
|         //身份证(正面),0 | ||||
|         //身份证(反面),1 | ||||
|         //银行卡,2 | ||||
|         //特种作业证,3 | ||||
|         //合同,4 | ||||
|         //体检报告,5 | ||||
|         //安全责任书,6 | ||||
|         //岗位危险告知书,7 | ||||
|         //安全技术交底,8 | ||||
|         //三级安全教育,10 | ||||
|  | ||||
|         for (ConstructionUserNew constructionUser : constructionUserList) { | ||||
|             Long goId = constructionUser.getGoId(); | ||||
|             Map<String, String> map = resultMap1.get(goId); | ||||
|             if (map != null) { | ||||
|                 handle0to3(map, constructionUser); | ||||
|                 handle4to10(map,goId); | ||||
|             } | ||||
|  | ||||
|             Map<String, String> map1 = resultMap.get(goId); | ||||
|             if (map1 != null) { | ||||
|                 handle0to3(map1, constructionUser); | ||||
|                 handle4to10(map1,goId); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|     private void handle0to3(Map<String, String> map, ConstructionUserNew constructionUser) { | ||||
|         String s = map.get("0"); | ||||
|         if (s != null) { | ||||
|             Long l = handleSinglePhoto1(s); | ||||
|             if (l != null) { | ||||
|                 constructionUser.setSfzFrontPic(l.toString()); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         String s1 = map.get("1"); | ||||
|         if (s1 != null) { | ||||
|             Long l = handleSinglePhoto1(s1); | ||||
|             if (l != null) { | ||||
|                 constructionUser.setSfzBackPic(l.toString()); | ||||
|             } | ||||
|         } | ||||
|         String s2 = map.get("2"); | ||||
|         if (s2 != null) { | ||||
|             Long l = handleSinglePhoto1(s2); | ||||
|             if (l != null) { | ||||
|                 constructionUser.setYhkPic(l.toString()); | ||||
|             } | ||||
|         } | ||||
|         String s3 = map.get("3"); | ||||
|         if (s3 != null) { | ||||
|             Long l = handleSinglePhoto1(s3); | ||||
|             if (l != null) { | ||||
|                 constructionUser.setSpecialWorkPic(l.toString()); | ||||
|             } | ||||
|         } | ||||
|         SubConstructionUser constructionUser1 = BeanUtil.copyProperties(constructionUser, SubConstructionUser.class); | ||||
|         constructionUserService.updateById(constructionUser1); | ||||
|     } | ||||
|  | ||||
|     private void handle4to10(Map<String, String> map,Long goId){ | ||||
|         List<SubConstructionUserFile> list1 = constructionUserFileService.list(Wrappers.<SubConstructionUserFile>lambdaQuery() | ||||
|             .eq(SubConstructionUserFile::getUserId, goId) | ||||
|         ); | ||||
|         for (SubConstructionUserFile subConstructionUserFile : list1) { | ||||
|             String s = map.get(subConstructionUserFile.getFileType()); | ||||
|             if (s != null) { | ||||
|                 String[] split = s.split(","); | ||||
|                 List<Long> path = new ArrayList<>(); | ||||
|                 for (String s1 : split) { | ||||
|                     Long l = handleSinglePhoto1(s1); | ||||
|                     if (l != null) { | ||||
|                         path.add(l); | ||||
|                     } | ||||
|                 } | ||||
|                 if (CollectionUtil.isNotEmpty(path)) { | ||||
|                     subConstructionUserFile.setPath(path.stream().map(String::valueOf).collect(Collectors.joining(","))); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         constructionUserFileService.updateBatchById(list1); | ||||
|     } | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 zt
					zt