增加公告图片编辑, 增加取消归档

This commit is contained in:
yml
2026-06-15 20:37:13 +08:00
parent 85f2d9b3b3
commit 9271f47553
16 changed files with 765 additions and 26 deletions
@@ -173,6 +173,22 @@ func (h *Handler) Archive(c *gin.Context) {
response.OK(c, gin.H{"message": "归档成功"})
}
// Unarchive 取消归档公告
func (h *Handler) Unarchive(c *gin.Context) {
id, err := parseID(c)
if err != nil {
response.BadRequest(c, "公告ID不正确")
return
}
if err := h.service.Unarchive(c.Request.Context(), id); err != nil {
response.InternalServerError(c, "取消归档公告失败")
return
}
response.OK(c, gin.H{"message": "取消归档成功"})
}
// Delete 删除公告
func (h *Handler) Delete(c *gin.Context) {
id, err := parseID(c)
@@ -179,6 +179,17 @@ func (r *Repository) Archive(ctx context.Context, id uint64) error {
Update("status", "archived").Error
}
// Unarchive 取消归档公告,恢复为已发布状态
func (r *Repository) Unarchive(ctx context.Context, id uint64) error {
now := time.Now()
return r.db.WithContext(ctx).Model(&model.Announcement{}).
Where("id = ?", id).
Updates(map[string]interface{}{
"status": "published",
"published_at": gorm.Expr("COALESCE(published_at, ?)", now),
}).Error
}
// Delete 删除公告
func (r *Repository) Delete(ctx context.Context, id uint64) error {
return r.db.WithContext(ctx).Where("id = ?", id).Delete(&model.Announcement{}).Error
@@ -95,6 +95,11 @@ func (s *Service) Archive(ctx context.Context, id uint64) error {
return s.repo.Archive(ctx, id)
}
// Unarchive 取消归档公告
func (s *Service) Unarchive(ctx context.Context, id uint64) error {
return s.repo.Unarchive(ctx, id)
}
// Delete 删除公告
func (s *Service) Delete(ctx context.Context, id uint64) error {
return s.repo.Delete(ctx, id)
+1 -1
View File
@@ -65,7 +65,7 @@ func (h *Handler) writeObject(c *gin.Context, publicOnly bool) {
response.BadRequest(c, "文件 key 不正确")
return
}
if publicOnly && !strings.HasPrefix(key, "home-banner/") && !strings.HasPrefix(key, "avatar/") && !strings.HasPrefix(key, "payment-cert/") {
if publicOnly && !strings.HasPrefix(key, "home-banner/") && !strings.HasPrefix(key, "avatar/") && !strings.HasPrefix(key, "payment-cert/") && !strings.HasPrefix(key, "announcement/") {
response.Error(c, http.StatusNotFound, "not_found", "文件不存在或暂不可访问")
return
}
+2 -2
View File
@@ -106,7 +106,7 @@ func normalizeContentType(contentType string, data []byte) string {
func fileURLForScene(scene string, key string) string {
fileURL := "/api/files/object?key=" + url.QueryEscape(key)
if scene == "home-banner" || scene == "avatar" || scene == "payment-cert" {
if scene == "home-banner" || scene == "avatar" || scene == "payment-cert" || scene == "announcement" {
fileURL = "/api/public/files/object?key=" + url.QueryEscape(key)
}
return fileURL
@@ -115,7 +115,7 @@ func fileURLForScene(scene string, key string) string {
func normalizeScene(scene string) string {
scene = strings.TrimSpace(strings.ToLower(scene))
switch scene {
case "listing", "handoff", "dispute", "realname", "avatar", "home-banner", "chat", "payment-cert":
case "listing", "handoff", "dispute", "realname", "avatar", "home-banner", "chat", "payment-cert", "announcement":
return scene
default:
return "misc"
+19 -1
View File
@@ -1,6 +1,9 @@
package file
import "testing"
import (
"strings"
"testing"
)
func TestSanitizeObjectMetadataEscapesNonASCII(t *testing.T) {
got := sanitizeObjectMetadata(map[string]string{
@@ -11,3 +14,18 @@ func TestSanitizeObjectMetadataEscapesNonASCII(t *testing.T) {
t.Fatalf("metadata filename = %q", got["original-filename"])
}
}
func TestAnnouncementSceneUsesPublicFileURL(t *testing.T) {
key := "announcement/2026/06/15/example.webp"
got := fileURLForScene("announcement", key)
if !strings.HasPrefix(got, "/api/public/files/object?") {
t.Fatalf("announcement file url = %q, want public file endpoint", got)
}
}
func TestNormalizeSceneAllowsAnnouncement(t *testing.T) {
if got := normalizeScene("announcement"); got != "announcement" {
t.Fatalf("normalize announcement scene = %q", got)
}
}