2025-03-28 17:38:34 +08:00
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 < FileManageVo > 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 < Map < String , Object > > list = customMapper . list ( " Id,CreatedDate,LastModifiedDate,Title,is_upload,is_dump,new_id,url " , " ContentVersion " , " IsLatest = 1 " + sql ) ;
List < FileManageVo > fileManageVos = new ArrayList < > ( ) ;
for ( Map < String , Object > 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 < FileManageVo > fileManageVoPage = new Page < > ( ) ;
fileManageVoPage . setRecords ( fileManageVos ) ;
fileManageVoPage . setTotal ( fileManageVos . size ( ) ) ;
fileManageVoPage . setCurrent ( page ) ;
fileManageVoPage . setSize ( pageSize ) ;
return fileManageVoPage ;
}
@Override
public Page < FileManageVo > 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 < Map < String , Object > > list = customMapper . list ( " Id,CreatedDate,LastModifiedDate,`Name`,is_upload,is_dump,new_id,url " , " Attachment " , sql ) ;
List < FileManageVo > fileManageVos = new ArrayList < > ( ) ;
for ( Map < String , Object > 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 < FileManageVo > 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 < Map < String , Object > > 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 < Future < ? > > futures = Lists . newArrayList ( ) ;
try {
for ( Map < String , Object > map : list ) {
Future < ? > future = salesforceExecutor . execute ( ( ) - > {
List < Map < String , Object > > 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 < String , Object > 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 < String , String > headers = Maps . newHashMap ( ) ;
headers . put ( " Authorization " , " Bearer " + token ) ;
headers . put ( " connection " , " keep-alive " ) ;
2025-06-17 15:41:28 +08:00
String downloadUrl = null ;
List < Map < String , Object > > poll = customMapper . list ( " code,value " , " org_config " , null ) ;
for ( Map < String , Object > map1 : poll ) {
if ( " FILE_DOWNLOAD_URL " . equals ( map1 . get ( " code " ) ) ) {
downloadUrl = ( String ) map1 . get ( " value " ) ;
}
}
2025-06-24 18:57:34 +08:00
if ( StringUtils . isBlank ( downloadUrl ) ) {
2025-06-24 10:52:55 +08:00
EmailUtil . send ( " DumpFile ERROR " , " 文件下载失败!下载地址未配置 " ) ;
return ;
}
2025-03-28 17:38:34 +08:00
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 < String , Object > paramMap = Maps . newHashMap ( ) ;
paramMap . put ( " key " , " file_url " ) ;
paramMap . put ( " value " , filePath ) ;
maps . add ( paramMap ) ;
}
} catch ( Exception e ) {
2025-06-06 10:29:08 +08:00
log . error ( " exception message " , e ) ;
2025-03-28 17:38:34 +08:00
}
Map < String , Object > 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 < Map < String , Object > > 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 < Future < ? > > futures = Lists . newArrayList ( ) ;
try {
// 检测路径是否存在
File excel = new File ( Const . SERVER_FILE_PATH + " / " + " richText " ) ;
if ( ! excel . exists ( ) ) {
throw new RuntimeException ( " 找不到文件路径 " ) ;
}
for ( Map < String , Object > fieldMap : fieldList ) {
Future < ? > future = salesforceExecutor . execute ( ( ) - > {
List < Map < String , Object > > 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 < String > ids = new ArrayList < > ( ) ;
CloseableHttpResponse response = null ;
String recordId = " " ;
String objectApi = " " ;
String fieldApi = " " ;
for ( Map < String , Object > 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 < String , Object > 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 = " <p><img src= \" data:image/png;base64, " ;
String end = " \" alt= \" " + fileName + " \" ></img></p> " ;
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 ) ;
}
2025-06-17 15:41:28 +08:00
String uploadUrl = null ;
List < Map < String , Object > > poll = customMapper . list ( " code,value " , " org_config " , null ) ;
for ( Map < String , Object > map1 : poll ) {
if ( " FILE_UPLOAD_URL " . equals ( map1 . get ( " code " ) ) ) {
uploadUrl = ( String ) map1 . get ( " value " ) ;
}
}
2025-06-24 10:52:55 +08:00
if ( StringUtils . isBlank ( uploadUrl ) ) {
EmailUtil . send ( " UploadFile ERROR " , " 文件上传失败!上传地址未配置 " ) ;
return ;
}
2025-06-17 15:41:28 +08:00
2025-03-28 17:38:34 +08:00
// 拼接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 ) {
2025-06-06 10:29:08 +08:00
log . error ( " exception message " , e ) ;
2025-03-28 17:38:34 +08:00
throw new RuntimeException ( " 文件转换base64失败 " ) ;
}
}
}
for ( String id : ids ) {
List < Map < String , Object > > maps = Lists . newArrayList ( ) ;
Map < String , Object > 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;
// }
}