diff --git a/application/src/main/java/run/halo/app/core/attachment/AttachmentChangedEvent.java b/application/src/main/java/run/halo/app/core/attachment/AttachmentChangedEvent.java
new file mode 100644
index 000000000..6eee3fa15
--- /dev/null
+++ b/application/src/main/java/run/halo/app/core/attachment/AttachmentChangedEvent.java
@@ -0,0 +1,22 @@
+package run.halo.app.core.attachment;
+
+import lombok.Getter;
+import org.springframework.context.ApplicationEvent;
+import run.halo.app.core.extension.attachment.Attachment;
+
+/**
+ * Event triggered when an attachment is created, updated, or deleted.
+ *
+ * @author johnniang
+ */
+public class AttachmentChangedEvent extends ApplicationEvent {
+
+ @Getter
+ private final Attachment attachment;
+
+ public AttachmentChangedEvent(Object source, Attachment attachment) {
+ super(source);
+ this.attachment = attachment;
+ }
+
+}
diff --git a/application/src/main/java/run/halo/app/core/attachment/ThumbnailService.java b/application/src/main/java/run/halo/app/core/attachment/ThumbnailService.java
index e6e5d8500..5870f5b9f 100644
--- a/application/src/main/java/run/halo/app/core/attachment/ThumbnailService.java
+++ b/application/src/main/java/run/halo/app/core/attachment/ThumbnailService.java
@@ -1,33 +1,32 @@
package run.halo.app.core.attachment;
import java.net.URI;
+import java.util.Map;
import reactor.core.publisher.Mono;
-import run.halo.app.infra.ExternalLinkProcessor;
+/**
+ * Service for managing thumbnails.
+ *
+ * @author johnniang
+ * @since 2.22.0
+ */
public interface ThumbnailService {
/**
- * Generate thumbnail by the given image uri and size.
- *
if the imageUri is not absolute, it will be processed by {@link ExternalLinkProcessor}
- * .
- * if externalUrl is not configured, it will return empty.
+ * Get the thumbnail link for the given image URI and size.
*
- * @param imageUri image uri to generate thumbnail
- * @param size thumbnail size to generate
- * @return generated thumbnail uri if success, otherwise empty.
+ * @param permalink the permalink of the image
+ * @param size the size of the thumbnail
+ * @return the thumbnail link
*/
- Mono generate(URI imageUri, ThumbnailSize size);
+ Mono get(URI permalink, ThumbnailSize size);
/**
- * Get thumbnail by the given image uri and size.
- * It depends on the {@link #generate(URI, ThumbnailSize)} method, currently the thumbnail
- * generation is limited to the attachment service, that is, the thumbnail is strongly
- * associated with the attachment.
+ * Get all thumbnail links for the given image URI.
*
- * @return if thumbnail exists, return the thumbnail uri, otherwise return the original image
- * uri
+ * @param permalink the permalink of the image
+ * @return the map of thumbnail size to thumbnail link
*/
- Mono get(URI imageUri, ThumbnailSize size);
+ Mono