diff --git a/im-center-server/pom.xml b/im-center-server/pom.xml index 1861b19..b58ae0b 100644 --- a/im-center-server/pom.xml +++ b/im-center-server/pom.xml @@ -21,6 +21,10 @@ + + joda-time + joda-time + com.xuxueli xxl-job-core diff --git a/im-center-server/src/main/java/cn/axzo/im/dao/mapper/MessageTaskMapper.java b/im-center-server/src/main/java/cn/axzo/im/dao/mapper/MessageTaskMapper.java index 2afaedc..a3e5874 100644 --- a/im-center-server/src/main/java/cn/axzo/im/dao/mapper/MessageTaskMapper.java +++ b/im-center-server/src/main/java/cn/axzo/im/dao/mapper/MessageTaskMapper.java @@ -2,8 +2,16 @@ package cn.axzo.im.dao.mapper; import cn.axzo.im.entity.MessageTask; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Delete; +import org.apache.ibatis.annotations.Param; import org.springframework.stereotype.Repository; +import java.util.Date; + @Repository public interface MessageTaskMapper extends BaseMapper { -} + + @Delete("DELETE FROM im_message_task WHERE create_at <= #{until} and status = 'SUCCEED'" ) + int expunge(@Param("until") Date until); + +} \ No newline at end of file diff --git a/im-center-server/src/main/java/cn/axzo/im/job/ExpungeImTaskJob.java b/im-center-server/src/main/java/cn/axzo/im/job/ExpungeImTaskJob.java new file mode 100644 index 0000000..9a7bfed --- /dev/null +++ b/im-center-server/src/main/java/cn/axzo/im/job/ExpungeImTaskJob.java @@ -0,0 +1,52 @@ +package cn.axzo.im.job; + +import cn.axzo.im.dao.mapper.MessageTaskMapper; +import cn.axzo.im.utils.JSONObjectUtil; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.handler.IJobHandler; +import com.xxl.job.core.handler.annotation.XxlJob; +import lombok.Data; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.joda.time.DateTime; +import org.springframework.stereotype.Component; + +import java.util.Date; + +/** + * @author yanglin + */ +@Slf4j +@Component +@RequiredArgsConstructor +public class ExpungeImTaskJob extends IJobHandler { + + private final MessageTaskMapper messageTaskMapper; + + @Override + @XxlJob("expungeImTaskJob") + public ReturnT execute(String paramStr) { + log.info("start - run job with param={}", paramStr); + try { + Param param = JSONObjectUtil.parseObject(paramStr, Param.class); + executeImpl(param); + log.info("end - run job with param={}", param); + return ReturnT.SUCCESS; + } catch (Exception e) { + log.warn("job failed. param={}", paramStr, e); + return ReturnT.FAIL; + } + } + + private void executeImpl(Param param) { + Date until = DateTime.now().minusDays(param.daysAgo).toDate(); + int count = messageTaskMapper.expunge(until); + log.info("deleted count={}", count); + } + + @Data + public static class Param { + private int daysAgo = 7; + } + +} \ No newline at end of file diff --git a/im-center-server/src/main/java/cn/axzo/im/utils/DateFormatUtil.java b/im-center-server/src/main/java/cn/axzo/im/utils/DateFormatUtil.java new file mode 100644 index 0000000..c47b101 --- /dev/null +++ b/im-center-server/src/main/java/cn/axzo/im/utils/DateFormatUtil.java @@ -0,0 +1,51 @@ +package cn.axzo.im.utils; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.util.Date; +import java.util.Objects; +import java.util.Optional; + +/** + * @description + * 日期格式转换工具类 + * + * @author cold_blade + * @date 2023/9/28 + * @version 1.0 + */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class DateFormatUtil { + + public static String toReadableString(Date date) { + if (date == null) + return null; + return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date); + } + + public static LocalDateTime toLocalDateTime(Date date) { + if (Objects.isNull(date)) { + return null; + } + ZoneId zoneId = ZoneId.systemDefault(); + return date.toInstant().atZone(zoneId).toLocalDateTime(); + } + + public static Long toTimestamp(LocalDateTime dateTime) { + return Optional.ofNullable(dateTime) + .map(v -> v.atZone(ZoneOffset.systemDefault()).toInstant().toEpochMilli()) + .orElse(null); + } + + public static Date toDate(LocalDateTime dateTime) { + return Optional.ofNullable(dateTime) + .map(v -> toTimestamp(dateTime)) + .map(Date::new) + .orElse(null); + } +} diff --git a/im-center-server/src/main/java/cn/axzo/im/utils/JSONObjectUtil.java b/im-center-server/src/main/java/cn/axzo/im/utils/JSONObjectUtil.java new file mode 100644 index 0000000..29bcab8 --- /dev/null +++ b/im-center-server/src/main/java/cn/axzo/im/utils/JSONObjectUtil.java @@ -0,0 +1,87 @@ +package cn.axzo.im.utils; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +/** + * @author cold_blade + * @date 2023/10/13 + * @version 1.0 + */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class JSONObjectUtil { + private static final String EMPTY_JSON_OBJ_STR = "{}"; + private static final String EMPTY_JSON_ARR_STR = "[]"; + + /** + * 解析JSON字符串,若字符串格式不正确,抛异常 + * + * @param str 待解析的字符串 + * @return JSONObject + */ + public static JSONObject parseObject(String str) { + if (StringUtils.isBlank(str)) { + return new JSONObject(); + } + return JSON.parseObject(str); + } + + /** + * 解析JSON字符串,若字符串格式不正确,抛异常 + * + * @param str 待解析的字符串 + * @return JSONObject + */ + public static T parseObject(String str, Class type) { + if (StringUtils.isBlank(str)) { + return ReflectionUtils.newInstance(type); + } + return JSON.parseObject(str, type); + } + + /** + * 解析JSON字符串,若字符串格式不正确,抛异常 + * + * @param str 待解析的字符串 + * @return List + */ + public static List parseArray(String str, Class clazz) { + if (StringUtils.isBlank(str)) { + return Collections.emptyList(); + } + return JSON.parseArray(str, clazz); + } + + public static String toJSONString(Object obj) { + if (Objects.isNull(obj)) { + return EMPTY_JSON_OBJ_STR; + } + return JSON.toJSONString(obj); + } + + public static String toJSONString(Collection objCollection) { + if (CollectionUtils.isEmpty(objCollection)) { + return EMPTY_JSON_ARR_STR; + } + return JSON.toJSONString(objCollection); + } + + /** + * 校验字符串是否为有效的JSON字符串,若字符串格式不正确,抛异常 + * + * @param str 待校验的字符串 + * @return 原字符串OR空的JSONObject + */ + public static String checkAndReturn(String str) { + return parseObject(str).toJSONString(); + } +} diff --git a/im-center-server/src/main/java/cn/axzo/im/utils/ReflectionUtils.java b/im-center-server/src/main/java/cn/axzo/im/utils/ReflectionUtils.java new file mode 100644 index 0000000..3135b73 --- /dev/null +++ b/im-center-server/src/main/java/cn/axzo/im/utils/ReflectionUtils.java @@ -0,0 +1,19 @@ +package cn.axzo.im.utils; + +import cn.axzo.basics.common.exception.ServiceException; + +/** + * @author: wangli + * @date: 2022/3/26 14:29 + */ +public final class ReflectionUtils { + + public static T newInstance(Class type) { + try { + return type.newInstance(); + } catch (Exception e) { + throw new ServiceException(String.format("初始化失败. type=%s", type.getName()), e); + } + } + +} diff --git a/im-center-server/src/test/java/cn/axzo/im/job/ExpungeImTaskJobTest.java b/im-center-server/src/test/java/cn/axzo/im/job/ExpungeImTaskJobTest.java new file mode 100644 index 0000000..2d67b38 --- /dev/null +++ b/im-center-server/src/test/java/cn/axzo/im/job/ExpungeImTaskJobTest.java @@ -0,0 +1,23 @@ +package cn.axzo.im.job; + +import cn.axzo.im.Application; +import lombok.RequiredArgsConstructor; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +/** + * @author yanglin + */ +@SpringBootTest(classes = Application.class) +@RequiredArgsConstructor(onConstructor_ = @Autowired) +class ExpungeImTaskJobTest { + + private final ExpungeImTaskJob expungeImTaskJob; + + @Test + void foo() { + expungeImTaskJob.execute(null); + } + +} \ No newline at end of file