536 lines
19 KiB
Java
536 lines
19 KiB
Java
package com.org.flashsalesystem.controller;
|
|
|
|
import com.org.flashsalesystem.dto.FlashSaleDTO;
|
|
import com.org.flashsalesystem.dto.UserDTO;
|
|
import com.org.flashsalesystem.service.FlashSaleService;
|
|
import com.org.flashsalesystem.service.UserService;
|
|
import io.swagger.v3.oas.annotations.Operation;
|
|
import io.swagger.v3.oas.annotations.Parameter;
|
|
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
|
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.http.ResponseEntity;
|
|
import org.springframework.validation.annotation.Validated;
|
|
import org.springframework.web.bind.annotation.*;
|
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
import javax.servlet.http.HttpSession;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
|
|
/**
|
|
* 秒杀控制器
|
|
* 处理秒杀相关的HTTP请求
|
|
*/
|
|
@Tag(name = "秒杀管理", description = "秒杀活动创建、参与、状态管理等接口")
|
|
@RestController
|
|
@RequestMapping("/api/flashsale")
|
|
@Slf4j
|
|
public class FlashSaleController {
|
|
|
|
@Autowired
|
|
private FlashSaleService flashSaleService;
|
|
|
|
@Autowired
|
|
private UserService userService;
|
|
|
|
/**
|
|
* 创建秒杀活动
|
|
*/
|
|
@Operation(summary = "创建秒杀活动", description = "创建新的秒杀活动")
|
|
@ApiResponses(value = {
|
|
@ApiResponse(responseCode = "200", description = "秒杀活动创建成功"),
|
|
@ApiResponse(responseCode = "400", description = "创建失败,参数验证错误")
|
|
})
|
|
@PostMapping("/create")
|
|
public ResponseEntity<Map<String, Object>> createFlashSale(@Validated @RequestBody FlashSaleDTO.CreateDTO createDTO) {
|
|
try {
|
|
FlashSaleDTO flashSale = flashSaleService.createFlashSale(createDTO);
|
|
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("success", true);
|
|
response.put("message", "秒杀活动创建成功");
|
|
response.put("data", flashSale);
|
|
|
|
return ResponseEntity.ok(response);
|
|
} catch (Exception e) {
|
|
log.error("创建秒杀活动失败", e);
|
|
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("success", false);
|
|
response.put("message", e.getMessage());
|
|
|
|
return ResponseEntity.badRequest().body(response);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 参与秒杀
|
|
*/
|
|
@PostMapping("/participate")
|
|
public ResponseEntity<Map<String, Object>> participateFlashSale(@Validated @RequestBody FlashSaleDTO.ParticipateDTO participateDTO,
|
|
HttpServletRequest request) {
|
|
try {
|
|
Long userId = getCurrentUserId(request);
|
|
if (userId == null) {
|
|
return createUnauthorizedResponse();
|
|
}
|
|
|
|
FlashSaleDTO.ResultDTO result = flashSaleService.participateFlashSale(userId, participateDTO);
|
|
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("success", result.getSuccess());
|
|
response.put("message", result.getMessage());
|
|
response.put("data", result);
|
|
|
|
if (result.getSuccess()) {
|
|
return ResponseEntity.ok(response);
|
|
} else {
|
|
return ResponseEntity.badRequest().body(response);
|
|
}
|
|
} catch (Exception e) {
|
|
log.error("参与秒杀失败", e);
|
|
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("success", false);
|
|
response.put("message", "系统异常,请稍后重试");
|
|
|
|
return ResponseEntity.badRequest().body(response);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 获取秒杀活动列表
|
|
*/
|
|
@PostMapping("/list")
|
|
public ResponseEntity<Map<String, Object>> getFlashSaleList(@RequestBody FlashSaleDTO.QueryDTO queryDTO) {
|
|
try {
|
|
Map<String, Object> result = flashSaleService.getFlashSaleList(queryDTO);
|
|
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("success", true);
|
|
response.put("data", result);
|
|
|
|
return ResponseEntity.ok(response);
|
|
} catch (Exception e) {
|
|
log.error("获取秒杀活动列表失败", e);
|
|
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("success", false);
|
|
response.put("message", e.getMessage());
|
|
|
|
return ResponseEntity.badRequest().body(response);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 获取正在进行的秒杀活动
|
|
*/
|
|
@GetMapping("/active")
|
|
public ResponseEntity<Map<String, Object>> getActiveFlashSales() {
|
|
try {
|
|
List<FlashSaleDTO> activeFlashSales = flashSaleService.getActiveFlashSales();
|
|
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("success", true);
|
|
response.put("data", activeFlashSales);
|
|
|
|
return ResponseEntity.ok(response);
|
|
} catch (Exception e) {
|
|
log.error("获取正在进行的秒杀活动失败", e);
|
|
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("success", false);
|
|
response.put("message", e.getMessage());
|
|
|
|
return ResponseEntity.badRequest().body(response);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 获取秒杀活动详情
|
|
*/
|
|
@Operation(summary = "获取秒杀活动详情", description = "根据ID获取秒杀活动的详细信息")
|
|
@GetMapping("/{id}")
|
|
public ResponseEntity<Map<String, Object>> getFlashSale(@Parameter(description = "秒杀活动ID", required = true) @PathVariable Long id) {
|
|
try {
|
|
FlashSaleDTO flashSale = flashSaleService.getFlashSaleDTOById(id);
|
|
|
|
if (flashSale == null) {
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("success", false);
|
|
response.put("message", "秒杀活动不存在");
|
|
return ResponseEntity.notFound().build();
|
|
}
|
|
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("success", true);
|
|
response.put("data", flashSale);
|
|
|
|
return ResponseEntity.ok(response);
|
|
} catch (Exception e) {
|
|
log.error("获取秒杀活动详情失败", e);
|
|
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("success", false);
|
|
response.put("message", e.getMessage());
|
|
|
|
return ResponseEntity.badRequest().body(response);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 预热所有秒杀活动库存(管理员功能)
|
|
*/
|
|
@PostMapping("/admin/preload-all")
|
|
public ResponseEntity<Map<String, Object>> preloadAllFlashSales() {
|
|
try {
|
|
flashSaleService.preloadAllActiveFlashSales();
|
|
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("success", true);
|
|
response.put("message", "所有秒杀活动库存预热完成");
|
|
|
|
return ResponseEntity.ok(response);
|
|
} catch (Exception e) {
|
|
log.error("预热所有秒杀活动库存失败", e);
|
|
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("success", false);
|
|
response.put("message", "预热失败: " + e.getMessage());
|
|
|
|
return ResponseEntity.badRequest().body(response);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 更新秒杀活动
|
|
*/
|
|
@Operation(summary = "更新秒杀活动", description = "更新秒杀活动信息")
|
|
@ApiResponses(value = {
|
|
@ApiResponse(responseCode = "200", description = "秒杀活动更新成功"),
|
|
@ApiResponse(responseCode = "400", description = "更新失败,参数验证错误"),
|
|
@ApiResponse(responseCode = "404", description = "秒杀活动不存在")
|
|
})
|
|
@PutMapping("/{id}")
|
|
public ResponseEntity<Map<String, Object>> updateFlashSale(@Parameter(description = "秒杀活动ID", required = true) @PathVariable Long id,
|
|
@Validated @RequestBody FlashSaleDTO.UpdateDTO updateDTO) {
|
|
try {
|
|
FlashSaleDTO flashSale = flashSaleService.updateFlashSale(id, updateDTO);
|
|
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("success", true);
|
|
response.put("message", "秒杀活动更新成功");
|
|
response.put("data", flashSale);
|
|
|
|
return ResponseEntity.ok(response);
|
|
} catch (Exception e) {
|
|
log.error("更新秒杀活动失败", e);
|
|
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("success", false);
|
|
response.put("message", e.getMessage());
|
|
|
|
return ResponseEntity.badRequest().body(response);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 删除秒杀活动
|
|
*/
|
|
@Operation(summary = "删除秒杀活动", description = "删除指定的秒杀活动")
|
|
@ApiResponses(value = {
|
|
@ApiResponse(responseCode = "200", description = "秒杀活动删除成功"),
|
|
@ApiResponse(responseCode = "400", description = "删除失败"),
|
|
@ApiResponse(responseCode = "404", description = "秒杀活动不存在")
|
|
})
|
|
@DeleteMapping("/{id}")
|
|
public ResponseEntity<Map<String, Object>> deleteFlashSale(@Parameter(description = "秒杀活动ID", required = true) @PathVariable Long id) {
|
|
try {
|
|
boolean success = flashSaleService.deleteFlashSale(id);
|
|
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("success", success);
|
|
response.put("message", success ? "秒杀活动删除成功" : "秒杀活动删除失败");
|
|
|
|
return ResponseEntity.ok(response);
|
|
} catch (Exception e) {
|
|
log.error("删除秒杀活动失败", e);
|
|
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("success", false);
|
|
response.put("message", e.getMessage());
|
|
|
|
return ResponseEntity.badRequest().body(response);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 获取秒杀活动剩余库存
|
|
*/
|
|
@GetMapping("/{id}/stock")
|
|
public ResponseEntity<Map<String, Object>> getFlashSaleStock(@PathVariable Long id) {
|
|
try {
|
|
Integer stock = flashSaleService.getFlashSaleStock(id);
|
|
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("success", true);
|
|
Map<String, Object> data = new HashMap<>();
|
|
data.put("flashSaleId", id);
|
|
data.put("remainingStock", stock);
|
|
response.put("data", data);
|
|
|
|
return ResponseEntity.ok(response);
|
|
} catch (Exception e) {
|
|
log.error("获取秒杀活动库存失败", e);
|
|
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("success", false);
|
|
response.put("message", e.getMessage());
|
|
|
|
return ResponseEntity.badRequest().body(response);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 预热秒杀活动
|
|
*/
|
|
@PostMapping("/{id}/preload")
|
|
public ResponseEntity<Map<String, Object>> preloadFlashSale(@PathVariable Long id) {
|
|
try {
|
|
flashSaleService.preloadFlashSale(id);
|
|
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("success", true);
|
|
response.put("message", "秒杀活动预热成功");
|
|
|
|
return ResponseEntity.ok(response);
|
|
} catch (Exception e) {
|
|
log.error("预热秒杀活动失败", e);
|
|
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("success", false);
|
|
response.put("message", e.getMessage());
|
|
|
|
return ResponseEntity.badRequest().body(response);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 更新秒杀活动状态(定时任务调用)
|
|
*/
|
|
@PostMapping("/update-status")
|
|
public ResponseEntity<Map<String, Object>> updateFlashSaleStatus() {
|
|
try {
|
|
flashSaleService.updateFlashSaleStatus();
|
|
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("success", true);
|
|
response.put("message", "秒杀活动状态更新成功");
|
|
|
|
return ResponseEntity.ok(response);
|
|
} catch (Exception e) {
|
|
log.error("更新秒杀活动状态失败", e);
|
|
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("success", false);
|
|
response.put("message", e.getMessage());
|
|
|
|
return ResponseEntity.badRequest().body(response);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 发布秒杀活动
|
|
*/
|
|
@Operation(summary = "发布秒杀活动", description = "将秒杀活动状态设置为可参与")
|
|
@PostMapping("/{id}/publish")
|
|
public ResponseEntity<Map<String, Object>> publishFlashSale(@Parameter(description = "秒杀活动ID", required = true) @PathVariable Long id) {
|
|
try {
|
|
FlashSaleDTO flashSale = flashSaleService.publishFlashSale(id);
|
|
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("success", true);
|
|
response.put("message", "秒杀活动发布成功");
|
|
response.put("data", flashSale);
|
|
|
|
return ResponseEntity.ok(response);
|
|
} catch (Exception e) {
|
|
log.error("发布秒杀活动失败", e);
|
|
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("success", false);
|
|
response.put("message", e.getMessage());
|
|
|
|
return ResponseEntity.badRequest().body(response);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 暂停秒杀活动
|
|
*/
|
|
@Operation(summary = "暂停秒杀活动", description = "暂停正在进行的秒杀活动")
|
|
@PostMapping("/{id}/pause")
|
|
public ResponseEntity<Map<String, Object>> pauseFlashSale(@Parameter(description = "秒杀活动ID", required = true) @PathVariable Long id) {
|
|
try {
|
|
FlashSaleDTO flashSale = flashSaleService.pauseFlashSale(id);
|
|
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("success", true);
|
|
response.put("message", "秒杀活动暂停成功");
|
|
response.put("data", flashSale);
|
|
|
|
return ResponseEntity.ok(response);
|
|
} catch (Exception e) {
|
|
log.error("暂停秒杀活动失败", e);
|
|
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("success", false);
|
|
response.put("message", e.getMessage());
|
|
|
|
return ResponseEntity.badRequest().body(response);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 恢复秒杀活动
|
|
*/
|
|
@Operation(summary = "恢复秒杀活动", description = "恢复已暂停的秒杀活动")
|
|
@PostMapping("/{id}/resume")
|
|
public ResponseEntity<Map<String, Object>> resumeFlashSale(@Parameter(description = "秒杀活动ID", required = true) @PathVariable Long id) {
|
|
try {
|
|
FlashSaleDTO flashSale = flashSaleService.resumeFlashSale(id);
|
|
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("success", true);
|
|
response.put("message", "秒杀活动恢复成功");
|
|
response.put("data", flashSale);
|
|
|
|
return ResponseEntity.ok(response);
|
|
} catch (Exception e) {
|
|
log.error("恢复秒杀活动失败", e);
|
|
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("success", false);
|
|
response.put("message", e.getMessage());
|
|
|
|
return ResponseEntity.badRequest().body(response);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 结束秒杀活动
|
|
*/
|
|
@Operation(summary = "结束秒杀活动", description = "提前结束秒杀活动")
|
|
@PostMapping("/{id}/end")
|
|
public ResponseEntity<Map<String, Object>> endFlashSale(@Parameter(description = "秒杀活动ID", required = true) @PathVariable Long id) {
|
|
try {
|
|
FlashSaleDTO flashSale = flashSaleService.endFlashSale(id);
|
|
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("success", true);
|
|
response.put("message", "秒杀活动结束成功");
|
|
response.put("data", flashSale);
|
|
|
|
return ResponseEntity.ok(response);
|
|
} catch (Exception e) {
|
|
log.error("结束秒杀活动失败", e);
|
|
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("success", false);
|
|
response.put("message", e.getMessage());
|
|
|
|
return ResponseEntity.badRequest().body(response);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 秒杀压力测试接口
|
|
*/
|
|
@PostMapping("/stress-test")
|
|
public ResponseEntity<Map<String, Object>> stressTest(@RequestParam Long flashSaleId,
|
|
@RequestParam(defaultValue = "100") int concurrency,
|
|
HttpServletRequest request) {
|
|
try {
|
|
Long userId = getCurrentUserId(request);
|
|
if (userId == null) {
|
|
return createUnauthorizedResponse();
|
|
}
|
|
|
|
// 这里可以实现压力测试逻辑
|
|
// 模拟多个用户同时参与秒杀
|
|
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("success", true);
|
|
response.put("message", "压力测试启动成功");
|
|
Map<String, Object> data = new HashMap<>();
|
|
data.put("flashSaleId", flashSaleId);
|
|
data.put("concurrency", concurrency);
|
|
response.put("data", data);
|
|
|
|
return ResponseEntity.ok(response);
|
|
} catch (Exception e) {
|
|
log.error("秒杀压力测试失败", e);
|
|
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("success", false);
|
|
response.put("message", e.getMessage());
|
|
|
|
return ResponseEntity.badRequest().body(response);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 修复秒杀活动库存
|
|
*/
|
|
@PostMapping("/{id}/repair-stock")
|
|
@Operation(summary = "修复秒杀库存", description = "修复指定秒杀活动的Redis库存数据")
|
|
public ResponseEntity<Map<String, Object>> repairFlashSaleStock(@PathVariable Long id) {
|
|
try {
|
|
flashSaleService.repairFlashSaleStock(id);
|
|
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("success", true);
|
|
response.put("message", "库存数据修复成功");
|
|
|
|
return ResponseEntity.ok(response);
|
|
} catch (Exception e) {
|
|
log.error("修复秒杀库存失败", e);
|
|
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("success", false);
|
|
response.put("message", e.getMessage());
|
|
|
|
return ResponseEntity.badRequest().body(response);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 获取当前用户ID
|
|
*/
|
|
private Long getCurrentUserId(HttpServletRequest request) {
|
|
HttpSession session = request.getSession(false);
|
|
if (session == null) {
|
|
return null;
|
|
}
|
|
|
|
String token = (String) session.getAttribute("token");
|
|
UserDTO user = userService.getUserByToken(token);
|
|
|
|
return user != null ? user.getId() : null;
|
|
}
|
|
|
|
/**
|
|
* 创建未授权响应
|
|
*/
|
|
private ResponseEntity<Map<String, Object>> createUnauthorizedResponse() {
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("success", false);
|
|
response.put("message", "用户未登录或登录已过期");
|
|
return ResponseEntity.status(401).body(response);
|
|
}
|
|
}
|