feat: add group buy secondhand and file storage

This commit is contained in:
王鹏
2026-07-07 16:04:02 +08:00
parent 9c579b3173
commit fa8f243486
26 changed files with 2159 additions and 0 deletions

View File

@@ -0,0 +1,48 @@
package com.linhelp.feedback;
import com.linhelp.common.api.ApiResponse;
import com.linhelp.common.security.AuthService;
import com.linhelp.common.security.CurrentUser;
import com.linhelp.common.security.RequireRole;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import java.util.List;
@RestController
public class FeedbackController {
private final FeedbackService feedbackService;
private final AuthService authService;
public FeedbackController(FeedbackService feedbackService, AuthService authService) {
this.feedbackService = feedbackService;
this.authService = authService;
}
@PostMapping("/api/mini/feedback")
public ApiResponse<FeedbackResponse> create(@Valid @RequestBody FeedbackRequest request) {
CurrentUser user = authService.currentUser();
request.setTenantId(user.getTenantId());
request.setCommunityId(user.getCommunityId());
return ApiResponse.ok(feedbackService.create(user.getUserId(), request));
}
@GetMapping("/api/admin/feedback")
@RequireRole({"PLATFORM_ADMIN", "COMMUNITY_ADMIN"})
public ApiResponse<List<FeedbackResponse>> listAdmin(@RequestParam(required = false) String status) {
CurrentUser user = authService.currentUser();
return ApiResponse.ok(feedbackService.listAdmin(user.getCommunityId(), status));
}
@PutMapping("/api/admin/feedback/{id}/process")
@RequireRole({"PLATFORM_ADMIN", "COMMUNITY_ADMIN"})
public ApiResponse<FeedbackResponse> process(@PathVariable Long id, @RequestBody FeedbackProcessRequest request) {
return ApiResponse.ok(feedbackService.process(id, request.getProcessNote()));
}
}

View File

@@ -0,0 +1,13 @@
package com.linhelp.feedback;
public class FeedbackProcessRequest {
private String processNote;
public String getProcessNote() {
return processNote;
}
public void setProcessNote(String processNote) {
this.processNote = processNote;
}
}

View File

@@ -0,0 +1,72 @@
package com.linhelp.feedback;
import javax.validation.constraints.NotBlank;
public class FeedbackRequest {
private Long tenantId;
private Long communityId;
private String category;
@NotBlank
private String content;
private String contactPhone;
private String bizType;
private Long bizOrderId;
public Long getTenantId() {
return tenantId;
}
public void setTenantId(Long tenantId) {
this.tenantId = tenantId;
}
public Long getCommunityId() {
return communityId;
}
public void setCommunityId(Long communityId) {
this.communityId = communityId;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getContactPhone() {
return contactPhone;
}
public void setContactPhone(String contactPhone) {
this.contactPhone = contactPhone;
}
public String getBizType() {
return bizType;
}
public void setBizType(String bizType) {
this.bizType = bizType;
}
public Long getBizOrderId() {
return bizOrderId;
}
public void setBizOrderId(Long bizOrderId) {
this.bizOrderId = bizOrderId;
}
}

View File

@@ -0,0 +1,123 @@
package com.linhelp.feedback;
import java.time.LocalDateTime;
public class FeedbackResponse {
private Long id;
private Long tenantId;
private Long communityId;
private Long userId;
private String category;
private String content;
private String contactPhone;
private String bizType;
private Long bizOrderId;
private String status;
private String processNote;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getTenantId() {
return tenantId;
}
public void setTenantId(Long tenantId) {
this.tenantId = tenantId;
}
public Long getCommunityId() {
return communityId;
}
public void setCommunityId(Long communityId) {
this.communityId = communityId;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getContactPhone() {
return contactPhone;
}
public void setContactPhone(String contactPhone) {
this.contactPhone = contactPhone;
}
public String getBizType() {
return bizType;
}
public void setBizType(String bizType) {
this.bizType = bizType;
}
public Long getBizOrderId() {
return bizOrderId;
}
public void setBizOrderId(Long bizOrderId) {
this.bizOrderId = bizOrderId;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getProcessNote() {
return processNote;
}
public void setProcessNote(String processNote) {
this.processNote = processNote;
}
public LocalDateTime getCreatedAt() {
return createdAt;
}
public void setCreatedAt(LocalDateTime createdAt) {
this.createdAt = createdAt;
}
public LocalDateTime getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(LocalDateTime updatedAt) {
this.updatedAt = updatedAt;
}
}

View File

@@ -0,0 +1,81 @@
package com.linhelp.feedback;
import com.linhelp.common.exception.BizException;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
@Service
public class FeedbackService {
public static final String STATUS_PENDING = "PENDING";
public static final String STATUS_PROCESSED = "PROCESSED";
private final AtomicLong ids = new AtomicLong(1L);
private final Map<Long, FeedbackResponse> feedbacks = new LinkedHashMap<Long, FeedbackResponse>();
public synchronized FeedbackResponse create(Long userId, FeedbackRequest request) {
FeedbackResponse feedback = new FeedbackResponse();
feedback.setId(ids.getAndIncrement());
feedback.setTenantId(request.getTenantId());
feedback.setCommunityId(request.getCommunityId());
feedback.setUserId(userId);
feedback.setCategory(request.getCategory());
feedback.setContent(request.getContent());
feedback.setContactPhone(request.getContactPhone());
feedback.setBizType(request.getBizType());
feedback.setBizOrderId(request.getBizOrderId());
feedback.setStatus(STATUS_PENDING);
feedback.setCreatedAt(LocalDateTime.now());
feedback.setUpdatedAt(feedback.getCreatedAt());
feedbacks.put(feedback.getId(), feedback);
return copy(feedback);
}
public synchronized List<FeedbackResponse> listAdmin(Long communityId, String status) {
List<FeedbackResponse> result = new ArrayList<FeedbackResponse>();
for (FeedbackResponse feedback : feedbacks.values()) {
if (!communityId.equals(feedback.getCommunityId())) {
continue;
}
if (status != null && !status.equals(feedback.getStatus())) {
continue;
}
result.add(copy(feedback));
}
return result;
}
public synchronized FeedbackResponse process(Long id, String processNote) {
FeedbackResponse feedback = feedbacks.get(id);
if (feedback == null) {
throw new BizException(404, "反馈不存在");
}
feedback.setStatus(STATUS_PROCESSED);
feedback.setProcessNote(processNote);
feedback.setUpdatedAt(LocalDateTime.now());
return copy(feedback);
}
private FeedbackResponse copy(FeedbackResponse source) {
FeedbackResponse target = new FeedbackResponse();
target.setId(source.getId());
target.setTenantId(source.getTenantId());
target.setCommunityId(source.getCommunityId());
target.setUserId(source.getUserId());
target.setCategory(source.getCategory());
target.setContent(source.getContent());
target.setContactPhone(source.getContactPhone());
target.setBizType(source.getBizType());
target.setBizOrderId(source.getBizOrderId());
target.setStatus(source.getStatus());
target.setProcessNote(source.getProcessNote());
target.setCreatedAt(source.getCreatedAt());
target.setUpdatedAt(source.getUpdatedAt());
return target;
}
}