package com.celnet.datadump.service.impl; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson2.JSON; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.celnet.datadump.config.SalesforceExecutor; import com.celnet.datadump.global.Const; import com.celnet.datadump.mapper.CustomMapper; import com.celnet.datadump.param.DataDumpParam; import com.celnet.datadump.service.FileManagerService; import com.celnet.datadump.util.EmailUtil; import com.celnet.datadump.util.HttpUtil; import com.celnet.datadump.vo.FileManageVo; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import lombok.extern.slf4j.Slf4j; import okhttp3.Response; import org.apache.commons.codec.binary.Base64; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPatch; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; import org.apache.ibatis.util.MapUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import java.io.*; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; @Service @Slf4j public class FileManagerServiceImpl implements FileManagerService { @Autowired private CustomMapper customMapper; @Autowired private SalesforceExecutor salesforceExecutor; @Override public Page getDocFileList(Integer isDump, Integer isUpload, String Name, Integer page, Integer pageSize) { String sql = ""; if (isDump != null) { sql += " and is_dump = " + isDump; } if (isUpload != null) { sql += " and is_upload = " + isUpload; } if (Name != null) { sql += " and Title like '%" + Name + "%'"; } sql += " order by CreatedDate desc"; if (page != null && pageSize != null) { sql += " limit " + (page - 1) * pageSize + "," + pageSize; } List> list = customMapper.list("Id,CreatedDate,LastModifiedDate,Title,is_upload,is_dump,new_id,url","ContentVersion","IsLatest = 1" + sql); List fileManageVos = new ArrayList<>(); for (Map map : list) { FileManageVo fileManageVo = new FileManageVo(); fileManageVo.setId(map.get("Id").toString()); fileManageVo.setNewId(map.get("new_id").toString()); fileManageVo.setFileName(map.get("Title").toString()); fileManageVo.setUrl(map.get("url").toString()); fileManageVo.setIsUpload(Boolean.valueOf(map.get("is_upload").toString()) == true ? 1 : 0); fileManageVo.setIsDump(Boolean.valueOf(map.get("is_dump").toString()) == true ? 1 : 0); fileManageVos.add(fileManageVo); } Page fileManageVoPage = new Page<>(); fileManageVoPage.setRecords(fileManageVos); fileManageVoPage.setTotal(fileManageVos.size()); fileManageVoPage.setCurrent(page); fileManageVoPage.setSize(pageSize); return fileManageVoPage; } @Override public Page getAttachmentFileList(Integer isDump, Integer isUpload, String Name, Integer page, Integer pageSize) { String sql = ""; if (isDump != null) { sql += " and is_dump = " + isDump; } if (isUpload != null) { sql += " and is_upload = " + isUpload; } if (Name != null) { sql += " and Name like '%" + Name + "%'"; } sql += " order by CreatedDate desc"; if (page != null && pageSize != null) { sql += " limit " + (page - 1) * pageSize + "," + pageSize; } List> list = customMapper.list("Id,CreatedDate,LastModifiedDate,`Name`,is_upload,is_dump,new_id,url","Attachment",sql); List fileManageVos = new ArrayList<>(); for (Map map : list) { FileManageVo fileManageVo = new FileManageVo(); fileManageVo.setId(map.get("Id").toString()); fileManageVo.setNewId(map.get("new_id").toString()); fileManageVo.setFileName(map.get("Name").toString()); fileManageVo.setUrl(map.get("url").toString()); fileManageVo.setIsUpload(Boolean.valueOf(map.get("is_upload").toString()) == true ? 1 : 0); fileManageVo.setIsDump(Boolean.valueOf(map.get("is_dump").toString()) == true ? 1 : 0); fileManageVos.add(fileManageVo); } Page fileManageVoPage = new Page<>(); fileManageVoPage.setRecords(fileManageVos); fileManageVoPage.setTotal(fileManageVos.size()); fileManageVoPage.setCurrent(page); fileManageVoPage.setSize(pageSize); return fileManageVoPage; } @Override public Object dumpImg(String token) { List> list = customMapper.list("Id,record_id,object_api,file_name,field_id,field_api","object_rich_text","is_dump = 0"); if (list.size() <= 0) { return "没有需要转储的图片"; } List> futures = Lists.newArrayList(); try { for (Map map : list) { Future future = salesforceExecutor.execute(() -> { List> maps = Lists.newArrayList(); String id = map.get("Id").toString(); String recordId = map.get("record_id").toString(); String objectApi = map.get("object_api").toString(); String fileName = map.get("file_name").toString(); String fieldId = map.get("field_id").toString(); String fieldApi = map.get("field_api").toString(); Map objectMap = customMapper.getById("Id", objectApi, recordId); if (objectMap.isEmpty()) { throw new RuntimeException("找不到对应主数据"); } // 检测路径是否存在 不存在则创建 File excel = new File(Const.SERVER_FILE_PATH + "/" + "richText"); if (!excel.exists()) { boolean mkdir = excel.mkdir(); } String filePath = "richText" + "/" + System.currentTimeMillis() + "_" + fileName; Map headers = Maps.newHashMap(); headers.put("Authorization", "Bearer " + token); headers.put("connection", "keep-alive"); String downloadUrl = null; List> poll = customMapper.list("code,value","org_config",null); for (Map map1 : poll) { if ("FILE_DOWNLOAD_URL".equals(map1.get("code"))) { downloadUrl = (String) map1.get("value"); } } if (StringUtils.isBlank(downloadUrl)) { EmailUtil.send("DumpFile ERROR", "文件下载失败!下载地址未配置"); return; } String url = downloadUrl + String.format(Const.SF_RICH_TEXT_FILE_URL, objectApi, recordId, fieldApi, fieldId); try { Response response = HttpUtil.doGet(url, null, headers); if (response.body() != null && response.code() == 200) { InputStream inputStream = response.body().byteStream(); String path = Const.SERVER_FILE_PATH + "/" + filePath; long offset = 0L; RandomAccessFile accessFile = new RandomAccessFile(path, "rw"); while (true) { try { // 保存到本地 byte[] buf = new byte[8192]; int len = 0; if (offset > 0) { inputStream.skip(offset); accessFile.seek(offset); } while ((len = inputStream.read(buf)) != -1) { accessFile.write(buf, 0, len); offset += len; } break; } catch (Exception e) { if (offset <= 0) { throw e; } log.warn("file dump to server EOF ERROR try to reconnect"); response.close(); response = HttpUtil.doGet(url, null, headers); assert response.body() != null; inputStream = response.body().byteStream(); log.warn("reconnect success, id:{} skip {}", recordId, offset); } } accessFile.close(); Map paramMap = Maps.newHashMap(); paramMap.put("key", "file_url"); paramMap.put("value", filePath); maps.add(paramMap); } } catch (Exception e) { log.error("exception message", e); } Map paramMap = Maps.newHashMap(); paramMap.put("key", "is_dump"); paramMap.put("value", 1); maps.add(paramMap); customMapper.updateById("object_rich_text", maps, id); }, 0, 0); futures.add(future); // 单线程 salesforceExecutor.waitForFutures(futures.toArray(new Future[]{})); } } catch (Throwable throwable) { log.error("dump file error", throwable); salesforceExecutor.remove(futures.toArray(new Future[]{})); } return null; } @Override public Object uploadImg(String token) { List> fieldList = customMapper.list("record_id,field_api","object_rich_text","is_upload = 0 and is_dump = 1 GROUP BY record_id,field_api"); if (fieldList.size() <= 0) { return "没有需要上传的图片"; } List> futures = Lists.newArrayList(); try { // 检测路径是否存在 File excel = new File(Const.SERVER_FILE_PATH + "/" + "richText"); if (!excel.exists()) { throw new RuntimeException("找不到文件路径"); } for (Map fieldMap : fieldList) { Future future = salesforceExecutor.execute(() -> { List> list = customMapper.list("Id,record_id,object_api,file_name,field_id,field_api,file_url", "object_rich_text", "is_upload = 0 and is_dump = 1 and record_id = '" + fieldMap.get("record_id") + "'and field_api = '" + fieldMap.get("field_api") + "'"); StringBuffer imageBase64 = new StringBuffer(); List ids = new ArrayList<>(); CloseableHttpResponse response = null; String recordId = ""; String objectApi = ""; String fieldApi = ""; for (Map map : list) { String id = map.get("Id").toString(); recordId = map.get("record_id").toString(); objectApi = map.get("object_api").toString(); fieldApi = map.get("field_api").toString(); String fileName = map.get("file_name").toString(); String fileUrl = map.get("file_url").toString(); Map objectMap = customMapper.getById("new_id", objectApi, recordId); recordId = objectMap.get("new_id").toString(); if (StringUtils.isNotBlank(fileUrl)) { String filePath = Const.SERVER_FILE_PATH + "/" + fileUrl; File file = new File(filePath); boolean exists = file.exists(); if (!exists) { log.info("文件不存在"); break; } log.info("开始组装参数"); String heard = "

\""

"; try { byte[] bytes = FileUtils.readFileToByteArray(file); // 得到文件 之后转成beye 然后使用base64转码 String encode = Base64.encodeBase64String(bytes);// 转码 StringBuffer richText = new StringBuffer(); richText.append(heard); richText.append(encode); richText.append(end); imageBase64 = imageBase64.append(richText); } catch (Exception e) { log.error("文件转换base64失败", e); EmailUtil.send("富文本上传异常", id, "文件转换base64失败"); throw new RuntimeException("文件转换base64失败"); } } ids.add(id); } String uploadUrl = null; List> poll = customMapper.list("code,value","org_config",null); for (Map map1 : poll) { if ("FILE_UPLOAD_URL".equals(map1.get("code"))) { uploadUrl = (String) map1.get("value"); } } if (StringUtils.isBlank(uploadUrl)) { EmailUtil.send("UploadFile ERROR", "文件上传失败!上传地址未配置"); return; } // 拼接url String url = uploadUrl + String.format(Const.SF_UPLOAD_RICH_TEXT_FILE_URL, objectApi, recordId); HttpPatch httpPatch = new HttpPatch(url); httpPatch.setHeader("Authorization", "Bearer " + token); httpPatch.setHeader("connection", "keep-alive"); httpPatch.setHeader("Content-Type", "application/json;charset=UTF-8"); JSONObject credentialsJsonParam = new JSONObject(); credentialsJsonParam.put(fieldApi, imageBase64); StringEntity entity = new StringEntity(credentialsJsonParam.toString(), "UTF-8"); httpPatch.setEntity(entity); CloseableHttpClient httpClient = HttpClients.createDefault(); try { response = httpClient.execute(httpPatch); log.info("上传图片返回状态码:{}", response.getStatusLine().getStatusCode()); if (response.getStatusLine().getStatusCode() != 204){ return; } } catch (Exception e) { log.error("获取文件失败", e); } finally { if (response != null) { try { response.close(); } catch (IOException e) { log.error("exception message", e); throw new RuntimeException("文件转换base64失败"); } } } for (String id : ids) { List> maps = Lists.newArrayList(); Map paramMap = Maps.newHashMap(); paramMap.put("key", "is_upload"); paramMap.put("value", 1); maps.add(paramMap); customMapper.updateById("object_rich_text", maps, id); } }, 0, 0); futures.add(future); } } catch (Exception e) { log.error("上传图片失败", e); EmailUtil.send("上传图片失败", e.getMessage()); salesforceExecutor.remove(futures.toArray(new Future[]{})); return "上传图片失败"; } return null; } // Object upload(String id, String img, String token) throws IOException { // String uploadUrl = ""; // String api = ""; // String url = uploadUrl + String.format(Const.SF_UPLOAD_FILE_URL, api); // String frontIDCard = ""+img; // JSONObject credentialsJsonParam = new JSONObject(); // credentialsJsonParam.put("FrontIDCard__c", frontIDCard); // // HttpPatch httpPatch = new HttpPatch(url); // httpPatch.setHeader("Authorization", "Bearer " + token); // httpPatch.setHeader("Content-type", "application/json"); // httpPatch.setHeader("connection", "keep-alive"); // // StringEntity entity = new StringEntity(credentialsJsonParam.toString(), "UTF-8"); // httpPatch.setEntity(entity); // CloseableHttpClient httpClient = HttpClients.createDefault(); // CloseableHttpResponse response = httpClient.execute(httpPatch); // Integer statusCode = response.getStatusLine().getStatusCode(); // httpClient.close(); // return statusCode; // } }