后端:公告√
注意数据库新建notice表
This commit is contained in:
82
backend/src/main/java/com/example/demo/notice/Notice.java
Normal file
82
backend/src/main/java/com/example/demo/notice/Notice.java
Normal file
@@ -0,0 +1,82 @@
|
||||
package com.example.demo.notice;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Entity
|
||||
@Table(name = "notices")
|
||||
public class Notice {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "shop_id", nullable = false)
|
||||
private Long shopId;
|
||||
|
||||
@Column(name = "user_id", nullable = false)
|
||||
private Long userId;
|
||||
|
||||
@Column(name = "title", nullable = false, length = 120)
|
||||
private String title;
|
||||
|
||||
@Column(name = "content", nullable = false, length = 500)
|
||||
private String content;
|
||||
|
||||
@Column(name = "tag", length = 32)
|
||||
private String tag;
|
||||
|
||||
@Column(name = "is_pinned", nullable = false)
|
||||
private Boolean pinned = false;
|
||||
|
||||
@Column(name = "starts_at")
|
||||
private LocalDateTime startsAt;
|
||||
|
||||
@Column(name = "ends_at")
|
||||
private LocalDateTime endsAt;
|
||||
|
||||
@Convert(converter = NoticeStatusConverter.class)
|
||||
@Column(name = "status", nullable = false, length = 16)
|
||||
private NoticeStatus status = NoticeStatus.PUBLISHED;
|
||||
|
||||
@Column(name = "created_at", nullable = false, updatable = false)
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@Column(name = "updated_at", nullable = false)
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
@PrePersist
|
||||
protected void onCreate() {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
this.createdAt = now;
|
||||
this.updatedAt = now;
|
||||
}
|
||||
|
||||
@PreUpdate
|
||||
protected void onUpdate() {
|
||||
this.updatedAt = LocalDateTime.now();
|
||||
}
|
||||
|
||||
public Long getId() { return id; }
|
||||
public Long getShopId() { return shopId; }
|
||||
public void setShopId(Long shopId) { this.shopId = shopId; }
|
||||
public Long getUserId() { return userId; }
|
||||
public void setUserId(Long userId) { this.userId = userId; }
|
||||
public String getTitle() { return title; }
|
||||
public void setTitle(String title) { this.title = title; }
|
||||
public String getContent() { return content; }
|
||||
public void setContent(String content) { this.content = content; }
|
||||
public String getTag() { return tag; }
|
||||
public void setTag(String tag) { this.tag = tag; }
|
||||
public Boolean getPinned() { return pinned; }
|
||||
public void setPinned(Boolean pinned) { this.pinned = pinned; }
|
||||
public LocalDateTime getStartsAt() { return startsAt; }
|
||||
public void setStartsAt(LocalDateTime startsAt) { this.startsAt = startsAt; }
|
||||
public LocalDateTime getEndsAt() { return endsAt; }
|
||||
public void setEndsAt(LocalDateTime endsAt) { this.endsAt = endsAt; }
|
||||
public NoticeStatus getStatus() { return status; }
|
||||
public void setStatus(NoticeStatus status) { this.status = status; }
|
||||
public LocalDateTime getCreatedAt() { return createdAt; }
|
||||
public LocalDateTime getUpdatedAt() { return updatedAt; }
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.example.demo.notice;
|
||||
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/notices")
|
||||
public class NoticeController {
|
||||
|
||||
private final NoticeService noticeService;
|
||||
|
||||
public NoticeController(NoticeService noticeService) {
|
||||
this.noticeService = noticeService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 简化:通过请求头 X-Shop-Id 传递当前店铺ID。
|
||||
*/
|
||||
@GetMapping
|
||||
public ResponseEntity<List<Notice>> list(@RequestHeader(name = "X-Shop-Id", required = false) Long shopId) {
|
||||
Long sid = (shopId == null ? 1L : shopId);
|
||||
return ResponseEntity.ok(noticeService.listActive(sid));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.example.demo.notice;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface NoticeRepository extends JpaRepository<Notice, Long> {
|
||||
|
||||
@Query("SELECT n FROM Notice n WHERE n.shopId = :shopId AND n.status = :status " +
|
||||
"AND (n.startsAt IS NULL OR n.startsAt <= CURRENT_TIMESTAMP) AND (n.endsAt IS NULL OR n.endsAt >= CURRENT_TIMESTAMP) " +
|
||||
"ORDER BY n.pinned DESC, n.createdAt DESC")
|
||||
List<Notice> findActiveNotices(@Param("shopId") Long shopId, @Param("status") NoticeStatus status);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.example.demo.notice;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class NoticeService {
|
||||
private final NoticeRepository noticeRepository;
|
||||
|
||||
public NoticeService(NoticeRepository noticeRepository) {
|
||||
this.noticeRepository = noticeRepository;
|
||||
}
|
||||
|
||||
public List<Notice> listActive(Long shopId) {
|
||||
return noticeRepository.findActiveNotices(shopId, NoticeStatus.PUBLISHED);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.example.demo.notice;
|
||||
|
||||
/**
|
||||
* 公告状态。
|
||||
*/
|
||||
public enum NoticeStatus {
|
||||
DRAFT,
|
||||
PUBLISHED,
|
||||
OFFLINE
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.example.demo.notice;
|
||||
|
||||
import jakarta.persistence.AttributeConverter;
|
||||
import jakarta.persistence.Converter;
|
||||
|
||||
@Converter(autoApply = false)
|
||||
public class NoticeStatusConverter implements AttributeConverter<NoticeStatus, String> {
|
||||
@Override
|
||||
public String convertToDatabaseColumn(NoticeStatus attribute) {
|
||||
if (attribute == null) return null;
|
||||
return switch (attribute) {
|
||||
case DRAFT -> "draft";
|
||||
case PUBLISHED -> "published";
|
||||
case OFFLINE -> "offline";
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public NoticeStatus convertToEntityAttribute(String dbData) {
|
||||
if (dbData == null) return null;
|
||||
return switch (dbData) {
|
||||
case "draft" -> NoticeStatus.DRAFT;
|
||||
case "published" -> NoticeStatus.PUBLISHED;
|
||||
case "offline" -> NoticeStatus.OFFLINE;
|
||||
default -> NoticeStatus.PUBLISHED;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user