feat: 删除JSP视图层,完善评价和通知系统,新增拼团模块

- 删除所有 JSP 页面(20个文件),前端完全迁移至 Vue 3 SPA
- 完善评价系统:ReviewDialog 组件、用户评价历史页、评价状态检查API
- 新增通知系统:Notification 实体/仓库/服务/控制器,NotificationCenter 接入真实API
- 新增拼团模块:GroupBuying 全套后端和前端页面
- 修复 review check API 参数双重包装导致请求格式错误
- 修复通知 API 路径缺少 /api 前缀和响应格式处理
- MessageListenerService 集成 NotificationService 创建持久化通知

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-14 16:40:26 +08:00
parent b684ea38d4
commit c4582655d9
115 changed files with 5968 additions and 12623 deletions

View File

@@ -0,0 +1,98 @@
package com.org.flashsalesystem.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Entity
@Table(name = "group_buying")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class GroupBuying {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "product_id", nullable = false)
private Long productId;
@Column(name = "group_price", nullable = false, precision = 10, scale = 2)
private BigDecimal groupPrice;
@Column(name = "required_members", nullable = false)
private Integer requiredMembers = 2;
@Column(name = "duration_minutes", nullable = false)
private Integer durationMinutes = 1440;
@Column(name = "total_stock", nullable = false)
private Integer totalStock;
@Column(name = "remaining_stock", nullable = false)
private Integer remainingStock;
@Column(name = "max_per_user", nullable = false)
private Integer maxPerUser = 1;
/**
* 状态0-草稿 1-未开始 2-进行中 3-已结束
*/
@Column(nullable = false)
private Integer status = 0;
@Column(name = "start_time", nullable = false)
private LocalDateTime startTime;
@Column(name = "end_time", nullable = false)
private LocalDateTime endTime;
@Column(name = "created_at", nullable = false, updatable = false)
private LocalDateTime createdAt;
@Column(name = "updated_at")
private LocalDateTime updatedAt;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "product_id", insertable = false, updatable = false)
private Product product;
@PrePersist
protected void onCreate() {
createdAt = LocalDateTime.now();
updatedAt = LocalDateTime.now();
}
@PreUpdate
protected void onUpdate() {
updatedAt = LocalDateTime.now();
}
public boolean isActive() {
LocalDateTime now = LocalDateTime.now();
return now.isAfter(startTime) && now.isBefore(endTime) && status == 2;
}
public enum GroupBuyingStatus {
DRAFT(0, "草稿"),
PENDING(1, "未开始"),
ACTIVE(2, "进行中"),
ENDED(3, "已结束");
private final int code;
private final String description;
GroupBuyingStatus(int code, String description) {
this.code = code;
this.description = description;
}
public int getCode() { return code; }
public String getDescription() { return description; }
}
}