diff --git a/src/main/java/com/celnet/datadump/entity/DataField.java b/src/main/java/com/celnet/datadump/entity/DataField.java
index 03bb633..d5ca2a6 100644
--- a/src/main/java/com/celnet/datadump/entity/DataField.java
+++ b/src/main/java/com/celnet/datadump/entity/DataField.java
@@ -104,6 +104,13 @@ public class DataField implements Serializable {
@ApiModelProperty(value = "是否更新")
private Boolean isUpdateable;
+ /**
+ * 是否富文本字段
+ */
+ @TableField("isHtmlFormatted")
+ @ApiModelProperty(value = "是否富文本字段")
+ private Boolean isHtmlFormatted;
+
/**
* 是否为空(目标库)
*/
diff --git a/src/main/java/com/celnet/datadump/entity/RichTextLog.java b/src/main/java/com/celnet/datadump/entity/RichTextLog.java
new file mode 100644
index 0000000..b32346a
--- /dev/null
+++ b/src/main/java/com/celnet/datadump/entity/RichTextLog.java
@@ -0,0 +1,68 @@
+package com.celnet.datadump.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ *
+ * 富文本替换记录表
+ *
+ *
+ * @author Lingma
+ * @since 2025-10-10
+ */
+@Getter
+@Setter
+@TableName("richText_log")
+@ApiModel(value = "RichTextLog对象", description = "富文本替换记录表")
+public class RichTextLog implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty("主键ID")
+ @TableId(value = "ID", type = IdType.AUTO)
+ private Long id;
+
+ @ApiModelProperty("对象API名称")
+ @TableField("api")
+ private String api;
+
+ @ApiModelProperty("字段API名称")
+ @TableField("field")
+ private String field;
+
+ @ApiModelProperty("记录ID")
+ @TableField("record_id")
+ private String recordId;
+
+ @ApiModelProperty("记录OwnerID")
+ @TableField("record_owner_id")
+ private String recordOwnerId;
+
+ @ApiModelProperty("原始富文本内容")
+ @TableField("original_rich_text")
+ private String originalRichText;
+
+ @ApiModelProperty("原图片链接")
+ @TableField("original_image_url")
+ private String originalImageUrl;
+
+ @ApiModelProperty("新图片链接")
+ @TableField("new_image_url")
+ private String newImageUrl;
+
+ @ApiModelProperty("新文件ID(ContentDocumentId)")
+ @TableField("new_file_id")
+ private String newFileId;
+
+ @ApiModelProperty("创建时间")
+ @TableField(value = "created_time", fill = FieldFill.INSERT)
+ private Date createdTime;
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/celnet/datadump/mapper/RichTextLogMapper.java b/src/main/java/com/celnet/datadump/mapper/RichTextLogMapper.java
new file mode 100644
index 0000000..5010e01
--- /dev/null
+++ b/src/main/java/com/celnet/datadump/mapper/RichTextLogMapper.java
@@ -0,0 +1,18 @@
+package com.celnet.datadump.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.celnet.datadump.entity.RichTextLog;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ *
+ * 富文本替换记录表 Mapper 接口
+ *
+ *
+ * @author Lingma
+ * @since 2025-10-10
+ */
+@Mapper
+public interface RichTextLogMapper extends BaseMapper {
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/celnet/datadump/service/RichTextLogService.java b/src/main/java/com/celnet/datadump/service/RichTextLogService.java
new file mode 100644
index 0000000..0beadca
--- /dev/null
+++ b/src/main/java/com/celnet/datadump/service/RichTextLogService.java
@@ -0,0 +1,31 @@
+package com.celnet.datadump.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.celnet.datadump.entity.RichTextLog;
+
+/**
+ *
+ * 富文本替换记录表 服务类
+ *
+ *
+ * @author Lingma
+ * @since 2025-10-10
+ */
+public interface RichTextLogService extends IService {
+
+ /**
+ * 记录富文本图片替换日志
+ * @param api 对象API名称
+ * @param field 字段API名称
+ * @param recordId 记录ID
+ * @param recordOwnerId 记录OwnerID
+ * @param originalRichText 原始富文本内容
+ * @param originalImageUrl 原图片链接
+ * @param newImageUrl 新图片链接
+ * @param newFileId 新文件ID(ContentDocumentId)
+ */
+ void logRichTextImageReplace(String api, String field, String recordId, String recordOwnerId,
+ String originalRichText, String originalImageUrl,
+ String newImageUrl, String newFileId);
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/celnet/datadump/service/impl/CommonServiceImpl.java b/src/main/java/com/celnet/datadump/service/impl/CommonServiceImpl.java
index bd427ea..5b47add 100644
--- a/src/main/java/com/celnet/datadump/service/impl/CommonServiceImpl.java
+++ b/src/main/java/com/celnet/datadump/service/impl/CommonServiceImpl.java
@@ -979,10 +979,7 @@ public class CommonServiceImpl implements CommonService {
String blobField = null;
List dataPicklists = Lists.newArrayList();
for (Field field : dsr.getFields()) {
- if ("textarea".equalsIgnoreCase(field.getType().toString()) && field.isHtmlFormatted()) {
- log.info("检测到富文本字段: {},API: {}", field.getName(), apiName);
- }
// 过滤字段
if (Const.TABLE_FILTERS.contains(field.getName())) {
continue;
@@ -1016,6 +1013,15 @@ public class CommonServiceImpl implements CommonService {
} else {
log.info("referenceTo too long set null, api:{}, field:{}, reference to:{}", apiName, field.getName(), StringUtils.join(field.getReferenceTo(), ","));
}
+ if ("textarea".equalsIgnoreCase(field.getType().toString()) && field.isHtmlFormatted()) {
+ log.info("检测到富文本字段: {},API: {}", field.getName(), apiName);
+ dataField.setIsHtmlFormatted(true);
+ Map htmlMap = Maps.newHashMap();
+ htmlMap.put("type", "text");
+ htmlMap.put("comment", field.getLabel()+ "备份字段");
+ htmlMap.put("name", field.getName()+ "_back");
+ list.add(htmlMap);
+ }
if (field.getReferenceTo().length > 1){
if (field.getName().contains("Id") && !"OwnerId".equals(field.getName()) && !"UserOrGroupId".equals(field.getName())){
LinkConfig linkConfig = new LinkConfig();
@@ -1337,6 +1343,7 @@ public class CommonServiceImpl implements CommonService {
String blobField = null;
List dataPicklists = Lists.newArrayList();
for (Field field : dsr.getFields()) {
+
// 过滤字段
if (Const.TABLE_FILTERS.contains(field.getName())) {
continue;
@@ -1356,48 +1363,47 @@ public class CommonServiceImpl implements CommonService {
list.add(map);
DataField dataField = new DataField();
dataField.setApi(apiName);
- dataField.setSfType(sfType);
dataField.setField(field.getName());
dataField.setName(field.getLabel());
- dataField.setIsCreateable(field.getCreateable());
- dataField.setIsUpdateable(field.getUpdateable());
- dataField.setIsNillable(field.getNillable());
- dataField.setIsDefaultedOnCreate(field.getDefaultedOnCreate());
- String join = null;
- // 会有非常多映射关系的字段在 这里置空不管
- if (field.getReferenceTo().length <= 3) {
- join = StringUtils.join(field.getReferenceTo(), ",");
- } else {
- log.info("referenceTo too long set null, api:{}, field:{}, reference to:{}", apiName, field.getName(), StringUtils.join(field.getReferenceTo(), ","));
- }
- if (field.getReferenceTo().length > 1){
- if (field.getName().contains("Id") && !"OwnerId".equals(field.getName()) && !"UserOrGroupId".equals(field.getName())){
- LinkConfig linkConfig = new LinkConfig();
- linkConfig.setApi(apiName);
- linkConfig.setLabel(label);
- linkConfig.setField(field.getName());
- linkConfig.setLinkField(StringUtils.replace(field.getName(), "Id", "_Type"));
- linkConfigService.save(linkConfig);
- }
- }
- // picklist保存到picklist表
- if ("picklist".equalsIgnoreCase(sfType)) {
- join = "data_picklist";
- PicklistEntry[] picklistValues = field.getPicklistValues();
- if (ArrayUtils.isNotEmpty(picklistValues)) {
- for (PicklistEntry picklistValue : picklistValues) {
- DataPicklist dataPicklist = new DataPicklist();
- dataPicklist.setApi(apiName);
- dataPicklist.setField(field.getName());
- dataPicklist.setLabel(picklistValue.getLabel());
- dataPicklist.setValue(picklistValue.getValue());
- dataPicklists.add(dataPicklist);
- }
- }
- }
- dataField.setReferenceTo(join);
+ dataField.setReferenceTo(field.getReferenceTo() != null && field.getReferenceTo().length > 0 ? field.getReferenceTo()[0] : null);
+ dataField.setLeftIndex(field.getLeftSideReferenceTo() != null && field.getLeftSideReferenceTo().length > 0 ? field.getLeftSideReferenceTo()[0] : null);
+ dataField.setRightIndex(field.getRightSideReferenceTo() != null && field.getRightSideReferenceTo().length > 0 ? field.getRightSideReferenceTo()[0] : null);
+ dataField.setOnList(field.isListVisible());
+ dataField.setSfType(sfType);
+ dataField.setCreateable(field.isCreateable());
+ dataField.setUpdateable(field.isUpdateable());
+ dataField.setHtmlFormatted(field.isHtmlFormatted());
+ dataField.setNillable(field.isNillable());
+ dataField.setDefaultedOnCreate(field.isDefaultedOnCreate());
fieldList.add(dataField);
fields.add(field.getName());
+
+ // 如果是富文本字段,添加备份字段
+ if (field.isHtmlFormatted()) {
+ String backupFieldName = field.getName() + "_back";
+ Map backupMap = Maps.newHashMap();
+ backupMap.put("type", DataUtil.fieldTypeToMysql(field));
+ backupMap.put("comment", field.getLabel() + " 备份");
+ backupMap.put("name", backupFieldName);
+ list.add(backupMap);
+
+ DataField backupDataField = new DataField();
+ backupDataField.setApi(apiName);
+ backupDataField.setField(backupFieldName);
+ backupDataField.setName(field.getLabel() + " 备份");
+ backupDataField.setReferenceTo(field.getReferenceTo() != null && field.getReferenceTo().length > 0 ? field.getReferenceTo()[0] : null);
+ backupDataField.setLeftIndex(field.getLeftSideReferenceTo() != null && field.getLeftSideReferenceTo().length > 0 ? field.getLeftSideReferenceTo()[0] : null);
+ backupDataField.setRightIndex(field.getRightSideReferenceTo() != null && field.getRightSideReferenceTo().length > 0 ? field.getRightSideReferenceTo()[0] : null);
+ backupDataField.setOnList(field.isListVisible());
+ backupDataField.setSfType(sfType);
+ backupDataField.setCreateable(field.isCreateable());
+ backupDataField.setUpdateable(field.isUpdateable());
+ backupDataField.setHtmlFormatted(field.isHtmlFormatted());
+ backupDataField.setNillable(field.isNillable());
+ backupDataField.setDefaultedOnCreate(field.isDefaultedOnCreate());
+ fieldList.add(backupDataField);
+ fields.add(backupFieldName);
+ }
}
// 存在ownerId字段
String extraField = "";
diff --git a/src/main/java/com/celnet/datadump/service/impl/DataImportNewServiceImpl.java b/src/main/java/com/celnet/datadump/service/impl/DataImportNewServiceImpl.java
index 33f8c7e..7c973e6 100644
--- a/src/main/java/com/celnet/datadump/service/impl/DataImportNewServiceImpl.java
+++ b/src/main/java/com/celnet/datadump/service/impl/DataImportNewServiceImpl.java
@@ -93,6 +93,9 @@ public class DataImportNewServiceImpl implements DataImportNewService {
@Autowired
private DataLogService dataLogService;
+ @Autowired
+ private RichTextLogService richTextLogService;
+
private static final String TEMP_FILE_PATH = "verify/";
static {
@@ -2637,85 +2640,99 @@ public class DataImportNewServiceImpl implements DataImportNewService {
@Override
public ReturnT richTextImageReplace(SalesforceParam param) throws Exception {
log.info("richTextImageReplace execute start ..................");
+ String beginDateStr = null;
+ String endDateStr = null;
+ if (param.getType() != 1){
+ Date beginDate = param.getBeginCreateDate();
+ Date endDate = param.getEndCreateDate();
+ if (param.getBeginCreateDate() != null && param.getEndCreateDate() != null){
+ beginDateStr = DateUtil.format(beginDate, "yyyy-MM-dd HH:mm:ss");
+ endDateStr = DateUtil.format(endDate, "yyyy-MM-dd HH:mm:ss");
+ }
+ }
// 获取连接
PartnerConnection sourceConnection = salesforceConnect.createConnect();
PartnerConnection targetConnection = salesforceTargetConnect.createConnect();
- String api = param.getApi();
- String field = null;
-
- if (StringUtils.isBlank(api)) {
- return new ReturnT<>(500, "api不能为空!");
+ QueryWrapper qw = new QueryWrapper<>();
+ if (StringUtils.isNotBlank(param.getApi())) {
+ List apis = DataUtil.toIdList(param.getApi());
+ qw.in("name", apis);
}
+ qw.eq("data_work", true);
+ List objectList = dataObjectService.list(qw);
- if (StringUtils.isBlank(field)) {
- return new ReturnT<>(500, "field不能为空!");
- }
+ for (DataObject dataObject : objectList) {
+ String api = dataObject.getName();
+ QueryWrapper qw1 = new QueryWrapper<>();
+ qw1.eq("api", api);
+ qw1.eq("isHtmlFormatted", true);
+ List fields = dataFieldService.list(qw1);
+
+ for (DataField dataField : fields) {
+ String field = dataField.getField();
+ String sqlCondition = "new_id is not null and " + field + " like '%
= '" + beginDateStr + "' and CreatedDate < '" + endDateStr + "'";
+ }
- String sqlCondition = "new_id is not null and " + field + " like '%
= '" + beginDateStr + "' and CreatedDate < '" + endDateStr + "'";
- }
+ // 获取记录总数
+ Integer count = customMapper.countBySQL(api, "where " + sqlCondition);
+ log.info("对象 {} 字段 {} 需要处理的富文本记录总数: {}", api, field, count);
- // 获取记录总数
- Integer count = customMapper.countBySQL(api, "where " + sqlCondition);
- log.info("需要处理的富文本记录总数: {}", count);
+ if (count == 0) {
+ log.info("对象 {} 字段 {} 没有需要处理的富文本记录", api, field);
+ continue;
+ }
- if (count == 0) {
- log.info("没有需要处理的富文本记录");
- return ReturnT.SUCCESS;
- }
+ // 分批处理,每批200条记录
+ int pageSize = 200;
+ int totalPages = (count + pageSize - 1) / pageSize;
- // 分批处理,每批200条记录
- int pageSize = 200;
- int totalPages = (count + pageSize - 1) / pageSize;
+ for (int page = 0; page < totalPages; page++) {
+ List