| 
					
				 | 
			
			
				@@ -1,6 +1,7 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 package com.fs.qw.service.impl; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.fs.common.core.domain.R; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.fs.common.utils.DateUtils; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.fs.qw.domain.QwMaterial; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -11,6 +12,7 @@ import com.fs.qw.vo.QwMaterialVO; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.fs.qwApi.Result.QwUploadResult; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.fs.qwApi.service.QwApiService; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.fs.voice.utils.StringUtil; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import lombok.extern.log4j.Log4j2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import org.springframework.beans.factory.annotation.Autowired; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import org.springframework.stereotype.Service; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -19,8 +21,14 @@ import java.io.File; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import java.io.FileOutputStream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import java.io.IOException; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import java.net.URL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.util.ArrayList; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import java.util.Date; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import java.util.List; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.util.concurrent.CompletableFuture; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.util.concurrent.ConcurrentLinkedQueue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.util.concurrent.ExecutorService; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.util.concurrent.Executors; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.util.stream.Collectors; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  * 素材库Service业务层处理 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -28,8 +36,9 @@ import java.util.List; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  * @author fs 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  * @date 2024-06-20 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@Log4j2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 @Service 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-public class QwMaterialServiceImpl implements IQwMaterialService 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+public class QwMaterialServiceImpl extends ServiceImpl<QwMaterialMapper, QwMaterial> implements IQwMaterialService 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     @Autowired 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     private QwMaterialMapper qwMaterialMapper; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -73,14 +82,62 @@ public class QwMaterialServiceImpl implements IQwMaterialService 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         //调用企业微信接口 上次临时图片 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        File fileImage = urlToFile(qwMaterial.getMaterialUrl()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        QwUploadResult imageResult = qwApiService.upload(fileImage, "image", qwMaterial.getCorpId()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (imageResult.getErrCode()==0){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            qwMaterial.setMaterialMediaId(imageResult.getMediaId()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if ("text".equals(qwMaterial.getMaterialType())){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             qwMaterialMapper.insertQwMaterial(qwMaterial); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return R.ok(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return R.error("上传图片失败:"+imageResult.getErrMsg()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }else if ("image".equals(qwMaterial.getMaterialType()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ||"video".equals(qwMaterial.getMaterialType()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ||"file".equals(qwMaterial.getMaterialType())){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return uploadAndSaveQwMaterial(qwMaterial); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return R.ok(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public R uploadAndSaveQwMaterial(QwMaterial qwMaterial){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 将URL转换为文件 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            File materialFile = urlToFile(qwMaterial.getMaterialUrl()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 上传素材到企业微信 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            QwUploadResult uploadResult = qwApiService.upload(materialFile, qwMaterial.getMaterialType(), qwMaterial.getCorpId()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (uploadResult.getErrCode() == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // 设置素材信息并保存到数据库 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                qwMaterial.setMaterialMediaId(uploadResult.getMediaId()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                qwMaterial.setCreatedAt(Long.valueOf(uploadResult.getCreatedAt())); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                qwMaterialMapper.insertQwMaterial(qwMaterial); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return R.ok(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return R.error("上传"+qwMaterial.getMaterialType()+"失败:" + uploadResult.getErrMsg()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } catch (Exception e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return R.error("处理"+qwMaterial.getMaterialType()+"时发生异常:" + e.getMessage()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public QwMaterial uploadAndSaveQwMaterialByDTO(QwMaterial qwMaterial){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 将URL转换为文件 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            File materialFile = urlToFile(qwMaterial.getMaterialUrl()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 上传素材到企业微信 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            QwUploadResult uploadResult = qwApiService.upload(materialFile, qwMaterial.getMaterialType(), qwMaterial.getCorpId()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (uploadResult.getErrCode() == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // 设置素材信息并保存到数据库 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                qwMaterial.setMaterialMediaId(uploadResult.getMediaId()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                qwMaterial.setCreatedAt(Long.valueOf(uploadResult.getCreatedAt())); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                qwMaterialMapper.insertQwMaterial(qwMaterial); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return qwMaterial; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                log.error("上传DTO"+qwMaterial.getMaterialType()+"失败:" + uploadResult.getErrMsg()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } catch (Exception e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            log.error("处理DTO"+qwMaterial.getMaterialType()+"时发生异常:" + e.getMessage()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -188,6 +245,89 @@ public class QwMaterialServiceImpl implements IQwMaterialService 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     @Override 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     public int deleteQwMaterialByMaterialId(Long materialId) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        log.info("删除素材库中信息:{}",qwMaterialMapper.selectQwMaterialByMaterialId(materialId)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return qwMaterialMapper.deleteQwMaterialByMaterialId(materialId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @Override 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public void updateQwMaterialByQw() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        List<QwMaterial> qwMaterials = qwMaterialMapper.selectQwMaterialListByMediaIdList(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 创建线程安全的集合用于存储处理结果 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ConcurrentLinkedQueue<QwMaterial> successQueue = new ConcurrentLinkedQueue<>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 创建线程池 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int threadPoolSize = Math.min(8, Runtime.getRuntime().availableProcessors() * 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ExecutorService executor = Executors.newFixedThreadPool(threadPoolSize); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 创建并执行所有异步任务 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            List<CompletableFuture<Void>> futures = qwMaterials.stream() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    .filter(item -> "image".equals(item.getMaterialType()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            || "video".equals(item.getMaterialType()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            || "file".equals(item.getMaterialType())) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    .map(item -> CompletableFuture.runAsync(() -> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            // 将URL转换为文件 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            File materialFile = urlToFile(item.getMaterialUrl()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            // 上传素材到企业微信 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            QwUploadResult uploadResult = qwApiService.upload( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    materialFile, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    item.getMaterialType(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    item.getCorpId() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            if (uploadResult.getErrCode() == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                // 设置素材信息 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                item.setMaterialMediaId(uploadResult.getMediaId()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                item.setCreatedAt(Long.valueOf(uploadResult.getCreatedAt())); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                successQueue.add(item); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                log.error("上传失败:{},{}", uploadResult.getErrMsg(), item); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        } catch (Exception e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            log.error("上传失败异常:{},{}", e.getMessage(), item); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    }, executor)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    .collect(Collectors.toList()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 等待所有任务完成 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 批量更新成功的记录 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!successQueue.isEmpty()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                super.saveOrUpdateBatch(new ArrayList<>(successQueue),300); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } finally { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 关闭线程池 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            executor.shutdown(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @Override 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public QwMaterial selectQwMaterialByMaterialIdByTime(Long materialId) throws Exception { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return uploadAndSaveQwMaterialByDTO(qwMaterialMapper.selectQwMaterialByMaterialId(materialId)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @Override 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public QwMaterial selectQwMaterialByMaterialIdByTimeTwo(Long materialId) throws Exception { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        QwMaterial qwMaterial = qwMaterialMapper.selectQwMaterialByMaterialId(materialId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Long createdAt = qwMaterial.getCreatedAt(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        boolean isOver48h = createdAt != null 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                && (System.currentTimeMillis() / 1000 - createdAt) > 172800; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (qwMaterial.getMaterialType() != null && isOver48h) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return uploadAndSaveQwMaterialByDTO(qwMaterial); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return qwMaterial; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 |