轻松聘AI开发
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

65 lines
2.8 KiB

package com.mydreamjob.messaging;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Lock;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import jakarta.persistence.LockModeType;
import java.time.LocalDateTime;
import java.util.List;
@Repository
public interface MessageRepository extends JpaRepository<Message, Long>, MessageUnreadQueries {
List<Message> findBySenderUserIdAndMessageType(Long senderUserId, String messageType);
@Query("select coalesce(sum(m.resumeSize),0) from Message m where m.senderUserId = :userId "
+ "and m.messageType = 'RESUME' and m.status = 'SENT' and m.resumeRevoked = false")
long activeResumeBytes(@Param("userId") Long userId);
@Lock(LockModeType.PESSIMISTIC_WRITE)
java.util.Optional<Message> findByConversationIdAndSenderUserIdAndClientMessageId(
Long conversationId, Long senderUserId, String clientMessageId);
Page<Message> findByConversationIdOrderByCreatedAtDesc(Long conversationId, Pageable pageable);
List<Message> findByConversationIdInOrderByConversationIdAscCreatedAtDesc(List<Long> conversationIds);
interface ConversationUnreadCount {
Long getConversationId();
Long getUnreadCount();
}
/**
* 条件更新未命中后的当前读,用于区分并发请求已完成撤回与真实冲突。
* PESSIMISTIC_WRITE 强制读取提交后的最新行,避免 MySQL REPEATABLE READ 使用旧快照。
*/
@Lock(LockModeType.PESSIMISTIC_WRITE)
@Query("select m from Message m where m.id = :messageId")
java.util.Optional<Message> findCurrentByIdForRecall(@Param("messageId") Long messageId);
@Modifying(clearAutomatically = true, flushAutomatically = true)
@Query("""
update Message m
set m.status = 'RECALLED',
m.content = :placeholder,
m.recalledAt = :recalledAt,
m.version = m.version + 1
where m.id = :messageId
and m.conversationId = :conversationId
and m.senderUserId = :senderUserId
and m.status = 'SENT'
and m.version = :expectedVersion
""")
int recallIfCurrent(@Param("messageId") Long messageId,
@Param("conversationId") Long conversationId,
@Param("senderUserId") Long senderUserId,
@Param("expectedVersion") Long expectedVersion,
@Param("placeholder") String placeholder,
@Param("recalledAt") LocalDateTime recalledAt);
}