data-dump/src/main/java/com/celnet/datadump/util/DataUtil.java

501 lines
17 KiB
Java
Raw Normal View History

2025-03-28 17:38:34 +08:00
package com.celnet.datadump.util;
2025-07-15 11:21:08 +08:00
import cn.hutool.core.lang.UUID;
2025-03-28 17:38:34 +08:00
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.celnet.datadump.entity.DataField;
import com.celnet.datadump.entity.SystemConfig;
import com.celnet.datadump.global.Const;
import com.celnet.datadump.mapper.CustomMapper;
import com.celnet.datadump.param.SalesforceParam;
import com.celnet.datadump.global.SystemConfigCode;
import com.celnet.datadump.service.SystemConfigService;
import com.google.common.collect.Lists;
import com.sforce.soap.partner.Field;
import com.sforce.soap.partner.sobject.SObject;
import com.sforce.ws.bind.XmlObject;
import com.sforce.ws.types.Time;
import lombok.extern.slf4j.Slf4j;
2025-03-28 17:38:34 +08:00
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.map.CaseInsensitiveMap;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.commons.lang3.time.FastDateFormat;
import org.apache.commons.lang3.time.FastTimeZone;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* @author Red
* @description 数据处理工具
* @date 2022/11/16
*/
@Slf4j
2025-03-28 17:38:34 +08:00
@Component
public class DataUtil {
@Autowired
private SystemConfigService systemConfigService;
private static final FastDateFormat SF_DATE_FORMAT = FastDateFormat.getInstance(Const.SF_DATE_FORMAT, FastTimeZone.getGmtTimeZone());
private static final FastDateFormat SF_TIME_FORMAT = FastDateFormat.getInstance(Const.SF_TIME_FORMAT, FastTimeZone.getGmtTimeZone());
/**
* sf field to mysql field
*
* @param field sf filed type
* @return mysql filed type
*/
public static String fieldTypeToMysql(Field field) {
String type = field.getType().toString();
int length = field.getLength();
String result = type;
switch (type) {
case "id":
case "reference":
result = "varchar(" + length + ")";
break;
case "string":
// Name字段用varchar方便加索引
if ("Name".equalsIgnoreCase(field.getName())) {
result = "varchar(" + length + ")";
} else {
result = "text(" + length + ")";
}
break;
case "url":
case "email":
case "phone":
case "picklist":
case "textarea":
case "multipicklist":
case "address":
case "combobox":
case "location":
case "encryptedstring":
case "anyType":
result = "text(" + length + ")";
break;
case "date":
case "datetime":
case "boolean":
result = type;
break;
case "time":
result = "time(3)";
break;
2025-03-28 17:38:34 +08:00
case "long":
case "int":
result = "int(" + length + ")";
break;
case "double":
case "currency":
case "percent":
int scale = field.getScale();
result = "double(" + 18 + "," + scale + ")";
break;
case "base64":
result = "longblob";
break;
default:
result = "text(" + length + ")";
break;
}
return result;
}
/**
* 分割英文逗号字符串 并去除所有空格
*
* @param ids id串
* @return list
*/
public static List<String> toIdList(String ids) {
if (StringUtils.isBlank(ids)) {
return Lists.newArrayList();
}
return Arrays.asList(ids.replaceAll(StringUtils.SPACE, StringUtils.EMPTY).split(","));
}
private static final int MINUTE = 60;
private static final int HOUR = 24;
/**
* 计算两个时间差
*
* @param date1 日期1
* @param date2 日期2
* @return 返回日期格式 xxdxxhxxmin
*/
public static String calTime(Date date1, Date date2) {
if (date1 == null || date2 == null) {
return null;
}
long min = Math.abs(date2.getTime() - date1.getTime()) / 1000 / 60;
StringBuilder stringBuilder = new StringBuilder();
if (min >= MINUTE) {
long h = min / MINUTE;
long realMin = min % MINUTE;
if (h >= HOUR) {
stringBuilder.append(h / HOUR).append("d");
long realH = h % HOUR;
if (realH > 0) {
stringBuilder.append(realH).append("h");
}
} else {
stringBuilder.append(h).append("h");
}
if (realMin > 0) {
stringBuilder.append(realMin).append("min");
}
} else {
stringBuilder.append(min).append("min");
}
return stringBuilder.toString();
}
public static Date DEFAULT_BEGIN_DATE = null;
@PostConstruct
public void init() throws ParseException {
SystemConfig systemConfig = systemConfigService.getById(SystemConfigCode.DEFAULT_START_DATE);
if (systemConfig != null) {
DEFAULT_BEGIN_DATE = DateUtils.parseDate(systemConfig.getValue(), "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss");
}
}
/**
* 分割任务
*
* @param param 参数
* @return list
*/
public static List<SalesforceParam> splitTask(SalesforceParam param) {
if (CollectionUtils.isNotEmpty(param.getIds())) {
return Lists.newArrayList(param);
}
Date now = new Date();
DateUtils.truncate(now, Calendar.DATE);
Date beginCreateDate = param.getBeginCreateDate() != null ? param.getBeginCreateDate() : DEFAULT_BEGIN_DATE;
// 如果为空 取当天零点 作为最大时间
Date endCreateDate = null;
try {
endCreateDate = param.getEndCreateDate() != null ? param.getEndCreateDate() : DateUtils.parseDate(DateFormatUtils.format(now, "yyyy-MM-dd"), "yyyy-MM-dd");
} catch (Throwable ignored) {
}
Date startDate = beginCreateDate;
Date lastDay = null;
List<SalesforceParam> list = Lists.newArrayList();
int batch = 1;
do {
lastDay = getYearLastDay(endCreateDate, startDate);
SalesforceParam clone = param.clone();
clone.setBeginCreateDate(startDate);
clone.setEndCreateDate(lastDay);
clone.setBatch(batch);
batch++;
list.add(clone);
startDate = lastDay;
} while (lastDay.compareTo(endCreateDate) < 0);
return list;
}
/**
* 返回本周最后一天 如果大于结束日期 返回结束日期
*
* @param endDate 结束日期
* @param startDate 开始日期
* @return 本周最后一天
*/
public static Date getWeekLastDay(Date endDate, Date startDate) {
Date weekLastDay;
Calendar cal = DateUtils.toCalendar(startDate);
cal.set(Calendar.DAY_OF_WEEK, cal.getActualMaximum(Calendar.DAY_OF_WEEK));
cal.add(Calendar.DAY_OF_WEEK, 1);
weekLastDay = cal.getTime();
if (weekLastDay.compareTo(endDate) > 0) {
weekLastDay = endDate;
}
return weekLastDay;
}
/**
* 返回本月最后一天 如果大于结束日期 返回结束日期
*
* @param endDate 结束日期
* @param startDate 开始日期
* @return 本月最后一天
*/
public static Date getMonthLastDay(Date endDate, Date startDate) {
Date monthLastDay;
Calendar cal = DateUtils.toCalendar(startDate);
cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
cal.add(Calendar.DAY_OF_MONTH, 1);
monthLastDay = cal.getTime();
if (monthLastDay.compareTo(endDate) > 0) {
monthLastDay = endDate;
}
return monthLastDay;
}
/**
* 返回本周最后一天 如果大于结束日期 返回结束日期
*
* @param endDate 结束日期
* @param startDate 开始日期
* @return 本周最后一天
*/
public static Date getYearLastDay(Date endDate, Date startDate) {
Date yearLastDay;
startDate = DateUtils.addYears(startDate, 1);
Calendar cal = DateUtils.toCalendar(startDate);
cal.set(Calendar.YEAR, cal.get(Calendar.YEAR));
yearLastDay = cal.getTime();
if (yearLastDay.compareTo(endDate) > 0) {
yearLastDay = endDate;
}
return yearLastDay;
}
/**
* sObject 数组转 JSONObject
*
* @param sObject sObject
* @param fields 字段
* @return JSONObject
*/
public static JSONObject toJsonObject(SObject sObject, Field[] fields) throws ParseException {
Iterator<XmlObject> children = sObject.getChildren();
JSONObject jsonObject = new JSONObject();
CaseInsensitiveMap map = new CaseInsensitiveMap();
for (Field field : fields) {
map.put(field.getName(), field.getType().toString());
}
while (children.hasNext()) {
XmlObject next = children.next();
String name = next.getName().getLocalPart();
Object value = next.getValue();
// 全部当string处理
if (next instanceof SObject) {
SObject sObjectChild = (SObject) next;
Iterator<XmlObject> children1 = sObjectChild.getChildren();
while (children1.hasNext()) {
XmlObject childNext = children1.next();
String childName = childNext.getName().getLocalPart();
Object childValue = childNext.getValue();
// partner会多一个type 值为对象名称 这里过滤掉
if (Const.TYPE_FILTER.equals(childName)) {
continue;
}
if (childValue == null) {
continue;
}
jsonObject.put(name+"_"+childName, childValue);
}
}
// partner会多一个type 值为对象名称 这里过滤掉
if (Const.TYPE_FILTER.equals(name)) {
continue;
}
if (value == null) {
continue;
}
String type = (String) map.get(name);
if (type == null) {
continue;
}
switch (type) {
case "date":
jsonObject.put(name, DateUtils.parseDate((String) value, "yyyy-MM-dd"));
break;
case "datetime":
jsonObject.put(name, SF_DATE_FORMAT.parse((String) value));
break;
case "time":
jsonObject.put(name, SF_TIME_FORMAT.parse((String) value));
break;
case "boolean":
jsonObject.put(name, BooleanUtils.toBoolean((String) value));
break;
case "long":
case "int":
jsonObject.put(name, Integer.parseInt((String) value));
break;
case "double":
case "currency":
case "percent":
jsonObject.put(name, Double.parseDouble((String) value));
break;
case "base64":
// 文件不处理 统一存oss或者server
break;
default:
if (value instanceof GregorianCalendar) {
jsonObject.put(name, DateFormatUtils.format(((GregorianCalendar) value), "yyyy-MM-dd HH:mm:ss"));
} else if (value instanceof Time){
jsonObject.put(name, DateFormatUtils.format((((Time) value).getTimeInMillis()), "HH:mm:ss"));
}else {
jsonObject.put(name, String.valueOf(value));
}
break;
}
}
return jsonObject;
}
/**
* sObject 数组转 JSONArray
*
* @param records sObject 数组
* @return JSONArray
*/
public static JSONArray toJsonArray(SObject[] records, Field[] fields) throws ParseException {
JSONArray jsonArray = new JSONArray();
for (SObject sObject : records) {
jsonArray.add(toJsonObject(sObject, fields));
}
return jsonArray;
}
public static Object fieldTypeToSf(DataField dataField) throws ParseException {
String fieldType = dataField.getSfType();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date = sdf.parse("2023-03-23");
switch (fieldType) {
case "int":
return 1;
case "double":
case "currency":
case "percent":
return new BigDecimal("1");
case "boolean":
return true;
case "email":
return "jax.li@celnet.com.cn";
case "date":
//字符串转日期
return date;
case "datetime":
return date;
default:
2025-07-15 11:21:08 +08:00
return "初始"+ UUID.randomUUID();
2025-03-28 17:38:34 +08:00
}
}
public static Object localBulkDataToSfData(String fieldType, String data) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
Date date;
//date转Calendar类型
Calendar calendar = Calendar.getInstance();
switch (fieldType) {
case "int":
return Integer.parseInt(data);
case "double":
case "currency":
case "percent":
return new BigDecimal(data);
case "boolean":
return Boolean.valueOf(data);
case "date":
return data+"T08:00:00Z";
case "datetime":
try {
date = sd.parse(data);
}catch (ParseException e){
//解决当时间秒为0时转换秒精度丢失问题
date = sd.parse(data+":00");
}
calendar.setTime(date);
return calendar;
case "time":
return adjustHour(data);
default:
return data;
}
}
2025-03-28 17:38:34 +08:00
public static Object localDataToSfData(String fieldType, String data) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
Date date;
//date转Calendar类型
Calendar calendar = Calendar.getInstance();
switch (fieldType) {
case "int":
return Integer.parseInt(data);
case "double":
case "currency":
case "percent":
return new BigDecimal(data);
case "boolean":
return Boolean.valueOf(data);
case "date":
try {
return sdf.parse(data+"T08:00:00Z");
} catch (ParseException e) {
log.error("exception message", e);
2025-03-28 17:38:34 +08:00
}
case "datetime":
try {
date = sd.parse(data);
}catch (ParseException e){
//解决当时间秒为0时转换秒精度丢失问题
date = sd.parse(data+":00");
}
calendar.setTime(date);
return calendar;
case "time":
return adjustHour(data);
2025-03-28 17:38:34 +08:00
default:
return data;
}
}
public static String adjustHour(String timeStr) {
// 提取小时部分并转换为整数
int hour = Integer.parseInt(timeStr.substring(0, 2));
// 减去8小时并处理跨天逻辑
int adjustedHour = hour - 8;
if (adjustedHour < 0) {
adjustedHour += 24; // 处理负数情况(跨天)
}
// 格式化为两位字符串(自动补零)
String newHour = String.format("%02d", adjustedHour);
// 拼接原始字符串的剩余部分(分钟+秒+毫秒)
return newHour + timeStr.substring(2);
}
2025-03-28 17:38:34 +08:00
public static boolean isUpdate(String field){
switch (field) {
case "LastModifiedDate":
case "IsDeleted":
case "SystemModstamp":
case "CreatedById":
case "CreatedDate":
case "LastModifiedById":
case "LastViewedDate":
case "LastReferencedDate":
case "IsConverted":
return false;
default:
return true;
}
}
}