清除数据

This commit is contained in:
2026-05-06 23:30:54 +08:00
parent 17a5734d67
commit d16fc36264
149 changed files with 6691 additions and 5575 deletions

View File

@@ -6,10 +6,10 @@ import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling
public class FlashSaleSystemApplication {
public class CommunityFreshGroupBuySystemApplication {
public static void main(String[] args) {
SpringApplication.run(FlashSaleSystemApplication.class, args);
SpringApplication.run(CommunityFreshGroupBuySystemApplication.class, args);
}
}

View File

@@ -46,16 +46,16 @@ public class GlobalExceptionHandler {
}
/**
* 秒杀相关异常处理
* 限时活动相关异常处理
*/
@ExceptionHandler(FlashSaleException.class)
public ResponseEntity<ErrorResponse> handleFlashSaleException(FlashSaleException e, HttpServletRequest request) {
log.warn("秒杀异常: {} - {}", e.getErrorCode(), e.getMessage(), e);
log.warn("限时活动异常: {} - {}", e.getErrorCode(), e.getMessage(), e);
ErrorResponse errorResponse = ErrorResponse.builder()
.timestamp(LocalDateTime.now())
.status(HttpStatus.BAD_REQUEST.value())
.error("Flash Sale Error")
.error("Group Buy Error")
.message(e.getMessage())
.errorCode(e.getErrorCode())
.path(request.getRequestURI())
@@ -379,7 +379,7 @@ public class GlobalExceptionHandler {
}
/**
* 秒杀异常类
* 限时活动异常类
*/
public static class FlashSaleException extends RuntimeException {
private final String errorCode;

View File

@@ -32,7 +32,7 @@ public class RedisInitializer implements ApplicationRunner {
// 1. 测试Redis连接
testRedisConnection();
// 2. 预热活跃的秒杀活动库存
// 2. 预热活跃的限时活动库存
preloadActiveFlashSales();
// 3. 清理过期数据(可选)
@@ -81,18 +81,18 @@ public class RedisInitializer implements ApplicationRunner {
}
/**
* 预热活跃的秒杀活动库存
* 预热活跃的限时活动库存
*/
private void preloadActiveFlashSales() {
try {
log.info("正在预热活跃秒杀活动库存...");
log.info("正在预热活跃限时活动库存...");
// 调用FlashSaleService的预热方法
flashSaleService.preloadAllActiveFlashSales();
log.info("活跃秒杀活动库存预热完成");
log.info("活跃限时活动库存预热完成");
} catch (Exception e) {
log.error("预热秒杀活动库存失败", e);
log.error("预热限时活动库存失败", e);
// 不抛出异常,允许应用继续启动
}
}

View File

@@ -234,14 +234,14 @@ public class RedissonConfig {
}
/**
* 秒杀Lua脚本
* 限时活动Lua脚本
*/
@Bean
public DefaultRedisScript<Long> flashSaleScript() {
DefaultRedisScript<Long> script = new DefaultRedisScript<>();
script.setScriptSource(new ResourceScriptSource(new ClassPathResource("lua/flashsale.lua")));
script.setResultType(Long.class);
log.info("加载秒杀Lua脚本");
log.info("加载限时活动Lua脚本");
return script;
}

View File

@@ -27,8 +27,8 @@ public class SwaggerConfig {
.version("1.0.0")
.contact(new Contact()
.name("开发团队")
.email("dev@flashsale.com")
.url("https://github.com/flashsale"))
.email("dev@community-fresh-groupbuy.example")
.url("https://github.com/community-fresh-group-buy"))
.license(new License()
.name("MIT License")
.url("https://opensource.org/licenses/MIT")));
@@ -57,12 +57,12 @@ public class SwaggerConfig {
}
/**
* 秒杀管理API分组
* 限时活动管理API分组
*/
@Bean
public GroupedOpenApi flashSaleApi() {
return GroupedOpenApi.builder()
.group("秒杀管理")
.group("限时活动管理")
.pathsToMatch("/api/flashsale/**")
.build();
}
@@ -110,4 +110,4 @@ public class SwaggerConfig {
.pathsToMatch("/**")
.build();
}
}
}

View File

@@ -137,9 +137,9 @@ public class AdminController {
}
/**
* 获取秒杀统计数据
* 获取限时活动统计数据
*/
@Operation(summary = "获取秒杀统计数据")
@Operation(summary = "获取限时活动统计数据")
@GetMapping("/flashsales/stats")
public ResponseEntity<Map<String, Object>> getFlashSaleStats() {
try {
@@ -147,16 +147,16 @@ public class AdminController {
Map<String, Object> response = new HashMap<>();
response.put("success", true);
response.put("message", "获取秒杀统计数据成功");
response.put("message", "获取限时活动统计数据成功");
response.put("data", stats);
return ResponseEntity.ok(response);
} catch (Exception e) {
log.error("获取秒杀统计数据失败", e);
log.error("获取限时活动统计数据失败", e);
Map<String, Object> response = new HashMap<>();
response.put("success", false);
response.put("message", "获取秒杀统计数据失败");
response.put("message", "获取限时活动统计数据失败");
return ResponseEntity.badRequest().body(response);
}

View File

@@ -75,10 +75,10 @@ public class ApiController {
}
/**
* 获取活跃的秒杀活动
* 获取活跃的限时活动
*/
@GetMapping("/flashsales/active")
@Operation(summary = "获取活跃的秒杀活动")
@Operation(summary = "获取活跃的限时活动")
public ResponseEntity<Map<String, Object>> getActiveFlashSales() {
Map<String, Object> response = new HashMap<>();
@@ -107,19 +107,19 @@ public class ApiController {
response.put("data", result);
} catch (Exception e) {
log.error("获取活跃秒杀活动失败", e);
log.error("获取活跃限时活动失败", e);
response.put("success", false);
response.put("message", "获取活跃秒杀活动失败");
response.put("message", "获取活跃限时活动失败");
}
return ResponseEntity.ok(response);
}
/**
* 参与秒杀
* 参与限时活动
*/
@PostMapping("/flashsales/participate")
@Operation(summary = "参与秒杀")
@Operation(summary = "参与限时活动")
public ResponseEntity<Map<String, Object>> participate(
@RequestBody Map<String, Object> request,
HttpServletRequest httpRequest) {
@@ -143,8 +143,8 @@ public class ApiController {
FlashSaleDTO.ParticipateDTO participateDTO = new FlashSaleDTO.ParticipateDTO();
participateDTO.setFlashSaleId(flashSaleId);
participateDTO.setQuantity(quantity);
// 调用秒杀服务
// 调用限时活动服务
FlashSaleDTO.ResultDTO result = flashSaleService.participateFlashSale(userId, participateDTO);
response.put("success", result.getSuccess());
@@ -154,7 +154,7 @@ public class ApiController {
}
} catch (Exception e) {
log.error("参与秒杀失败", e);
log.error("参与限时活动失败", e);
response.put("success", false);
response.put("message", e.getMessage());
}
@@ -204,10 +204,10 @@ public class ApiController {
}
/**
* 获取秒杀活动列表
* 获取限时活动列表
*/
@GetMapping("/flashsales")
@Operation(summary = "获取秒杀活动列表")
@Operation(summary = "获取限时活动列表")
public ResponseEntity<Map<String, Object>> getFlashSales() {
Map<String, Object> response = new HashMap<>();
@@ -220,9 +220,9 @@ public class ApiController {
response.put("total", flashSales.size());
} catch (Exception e) {
log.error("获取秒杀活动列表失败", e);
log.error("获取限时活动列表失败", e);
response.put("success", false);
response.put("message", "获取秒杀活动列表失败");
response.put("message", "获取限时活动列表失败");
}
return ResponseEntity.ok(response);

View File

@@ -22,10 +22,10 @@ import java.util.List;
import java.util.Map;
/**
* 秒杀控制器
* 处理秒杀相关的HTTP请求
* 限时活动控制器
* 处理限时活动相关的HTTP请求
*/
@Tag(name = "秒杀管理", description = "秒杀活动创建、参与、状态管理等接口")
@Tag(name = "限时活动管理", description = "限时活动创建、参与、状态管理等接口")
@RestController
@RequestMapping("/api/flashsale")
@Slf4j
@@ -38,11 +38,11 @@ public class FlashSaleController {
private UserService userService;
/**
* 创建秒杀活动
* 创建限时活动
*/
@Operation(summary = "创建秒杀活动", description = "创建新的秒杀活动")
@Operation(summary = "创建限时活动", description = "创建新的限时活动")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "秒杀活动创建成功"),
@ApiResponse(responseCode = "200", description = "限时活动创建成功"),
@ApiResponse(responseCode = "400", description = "创建失败,参数验证错误")
})
@PostMapping("/create")
@@ -52,12 +52,12 @@ public class FlashSaleController {
Map<String, Object> response = new HashMap<>();
response.put("success", true);
response.put("message", "秒杀活动创建成功");
response.put("message", "限时活动创建成功");
response.put("data", flashSale);
return ResponseEntity.ok(response);
} catch (Exception e) {
log.error("创建秒杀活动失败", e);
log.error("创建限时活动失败", e);
Map<String, Object> response = new HashMap<>();
response.put("success", false);
@@ -68,7 +68,7 @@ public class FlashSaleController {
}
/**
* 参与秒杀
* 参与限时活动
*/
@PostMapping("/participate")
public ResponseEntity<Map<String, Object>> participateFlashSale(@Validated @RequestBody FlashSaleDTO.ParticipateDTO participateDTO,
@@ -92,7 +92,7 @@ public class FlashSaleController {
return ResponseEntity.badRequest().body(response);
}
} catch (Exception e) {
log.error("参与秒杀失败", e);
log.error("参与限时活动失败", e);
Map<String, Object> response = new HashMap<>();
response.put("success", false);
@@ -103,7 +103,7 @@ public class FlashSaleController {
}
/**
* 获取秒杀活动列表
* 获取限时活动列表
*/
@PostMapping("/list")
public ResponseEntity<Map<String, Object>> getFlashSaleList(@RequestBody FlashSaleDTO.QueryDTO queryDTO) {
@@ -116,7 +116,7 @@ public class FlashSaleController {
return ResponseEntity.ok(response);
} catch (Exception e) {
log.error("获取秒杀活动列表失败", e);
log.error("获取限时活动列表失败", e);
Map<String, Object> response = new HashMap<>();
response.put("success", false);
@@ -127,7 +127,7 @@ public class FlashSaleController {
}
/**
* 获取正在进行的秒杀活动
* 获取正在进行的限时活动
*/
@GetMapping("/active")
public ResponseEntity<Map<String, Object>> getActiveFlashSales() {
@@ -140,7 +140,7 @@ public class FlashSaleController {
return ResponseEntity.ok(response);
} catch (Exception e) {
log.error("获取正在进行的秒杀活动失败", e);
log.error("获取正在进行的限时活动失败", e);
Map<String, Object> response = new HashMap<>();
response.put("success", false);
@@ -151,7 +151,7 @@ public class FlashSaleController {
}
/**
* 获取秒杀活动统计信息
* 获取限时活动统计信息
*/
@GetMapping("/statistics")
public ResponseEntity<Map<String, Object>> getFlashSaleStatistics(HttpServletRequest request) {
@@ -165,7 +165,7 @@ public class FlashSaleController {
return ResponseEntity.ok(response);
} catch (Exception e) {
log.error("获取秒杀统计失败", e);
log.error("获取限时活动统计失败", e);
Map<String, Object> response = new HashMap<>();
response.put("success", false);
@@ -176,18 +176,18 @@ public class FlashSaleController {
}
/**
* 获取秒杀活动详情
* 获取限时活动详情
*/
@Operation(summary = "获取秒杀活动详情", description = "根据ID获取秒杀活动的详细信息")
@Operation(summary = "获取限时活动详情", description = "根据ID获取限时活动的详细信息")
@GetMapping("/{id}")
public ResponseEntity<Map<String, Object>> getFlashSale(@Parameter(description = "秒杀活动ID", required = true) @PathVariable Long 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", "秒杀活动不存在");
response.put("message", "限时活动不存在");
return ResponseEntity.notFound().build();
}
@@ -197,7 +197,7 @@ public class FlashSaleController {
return ResponseEntity.ok(response);
} catch (Exception e) {
log.error("获取秒杀活动详情失败", e);
log.error("获取限时活动详情失败", e);
Map<String, Object> response = new HashMap<>();
response.put("success", false);
@@ -208,7 +208,7 @@ public class FlashSaleController {
}
/**
* 预热所有秒杀活动库存(管理员功能)
* 预热所有限时活动库存(管理员功能)
*/
@PostMapping("/admin/preload-all")
public ResponseEntity<Map<String, Object>> preloadAllFlashSales() {
@@ -217,11 +217,11 @@ public class FlashSaleController {
Map<String, Object> response = new HashMap<>();
response.put("success", true);
response.put("message", "所有秒杀活动库存预热完成");
response.put("message", "所有限时活动库存预热完成");
return ResponseEntity.ok(response);
} catch (Exception e) {
log.error("预热所有秒杀活动库存失败", e);
log.error("预热所有限时活动库存失败", e);
Map<String, Object> response = new HashMap<>();
response.put("success", false);
@@ -232,28 +232,28 @@ public class FlashSaleController {
}
/**
* 更新秒杀活动
* 更新限时活动
*/
@Operation(summary = "更新秒杀活动", description = "更新秒杀活动信息")
@Operation(summary = "更新限时活动", description = "更新限时活动信息")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "秒杀活动更新成功"),
@ApiResponse(responseCode = "200", description = "限时活动更新成功"),
@ApiResponse(responseCode = "400", description = "更新失败,参数验证错误"),
@ApiResponse(responseCode = "404", description = "秒杀活动不存在")
@ApiResponse(responseCode = "404", description = "限时活动不存在")
})
@PutMapping("/{id}")
public ResponseEntity<Map<String, Object>> updateFlashSale(@Parameter(description = "秒杀活动ID", required = true) @PathVariable Long 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("message", "限时活动更新成功");
response.put("data", flashSale);
return ResponseEntity.ok(response);
} catch (Exception e) {
log.error("更新秒杀活动失败", e);
log.error("更新限时活动失败", e);
Map<String, Object> response = new HashMap<>();
response.put("success", false);
@@ -264,26 +264,26 @@ public class FlashSaleController {
}
/**
* 删除秒杀活动
* 删除限时活动
*/
@Operation(summary = "删除秒杀活动", description = "删除指定的秒杀活动")
@Operation(summary = "删除限时活动", description = "删除指定的限时活动")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "秒杀活动删除成功"),
@ApiResponse(responseCode = "200", description = "限时活动删除成功"),
@ApiResponse(responseCode = "400", description = "删除失败"),
@ApiResponse(responseCode = "404", description = "秒杀活动不存在")
@ApiResponse(responseCode = "404", description = "限时活动不存在")
})
@DeleteMapping("/{id}")
public ResponseEntity<Map<String, Object>> deleteFlashSale(@Parameter(description = "秒杀活动ID", required = true) @PathVariable Long 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 ? "秒杀活动删除成功" : "秒杀活动删除失败");
response.put("message", success ? "限时活动删除成功" : "限时活动删除失败");
return ResponseEntity.ok(response);
} catch (Exception e) {
log.error("删除秒杀活动失败", e);
log.error("删除限时活动失败", e);
Map<String, Object> response = new HashMap<>();
response.put("success", false);
@@ -294,7 +294,7 @@ public class FlashSaleController {
}
/**
* 获取秒杀活动剩余库存
* 获取限时活动剩余库存
*/
@GetMapping("/{id}/stock")
public ResponseEntity<Map<String, Object>> getFlashSaleStock(@PathVariable Long id) {
@@ -310,7 +310,7 @@ public class FlashSaleController {
return ResponseEntity.ok(response);
} catch (Exception e) {
log.error("获取秒杀活动库存失败", e);
log.error("获取限时活动库存失败", e);
Map<String, Object> response = new HashMap<>();
response.put("success", false);
@@ -321,7 +321,7 @@ public class FlashSaleController {
}
/**
* 预热秒杀活动
* 预热限时活动
*/
@PostMapping("/{id}/preload")
public ResponseEntity<Map<String, Object>> preloadFlashSale(@PathVariable Long id) {
@@ -330,11 +330,11 @@ public class FlashSaleController {
Map<String, Object> response = new HashMap<>();
response.put("success", true);
response.put("message", "秒杀活动预热成功");
response.put("message", "限时活动预热成功");
return ResponseEntity.ok(response);
} catch (Exception e) {
log.error("预热秒杀活动失败", e);
log.error("预热限时活动失败", e);
Map<String, Object> response = new HashMap<>();
response.put("success", false);
@@ -345,7 +345,7 @@ public class FlashSaleController {
}
/**
* 更新秒杀活动状态(定时任务调用)
* 更新限时活动状态(定时任务调用)
*/
@PostMapping("/update-status")
public ResponseEntity<Map<String, Object>> updateFlashSaleStatus() {
@@ -354,11 +354,11 @@ public class FlashSaleController {
Map<String, Object> response = new HashMap<>();
response.put("success", true);
response.put("message", "秒杀活动状态更新成功");
response.put("message", "限时活动状态更新成功");
return ResponseEntity.ok(response);
} catch (Exception e) {
log.error("更新秒杀活动状态失败", e);
log.error("更新限时活动状态失败", e);
Map<String, Object> response = new HashMap<>();
response.put("success", false);
@@ -369,22 +369,22 @@ public class FlashSaleController {
}
/**
* 发布秒杀活动
* 发布限时活动
*/
@Operation(summary = "发布秒杀活动", description = "秒杀活动状态设置为可参与")
@Operation(summary = "发布限时活动", description = "限时活动状态设置为可参与")
@PostMapping("/{id}/publish")
public ResponseEntity<Map<String, Object>> publishFlashSale(@Parameter(description = "秒杀活动ID", required = true) @PathVariable Long id) {
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("message", "限时活动发布成功");
response.put("data", flashSale);
return ResponseEntity.ok(response);
} catch (Exception e) {
log.error("发布秒杀活动失败", e);
log.error("发布限时活动失败", e);
Map<String, Object> response = new HashMap<>();
response.put("success", false);
@@ -395,22 +395,22 @@ public class FlashSaleController {
}
/**
* 暂停秒杀活动
* 暂停限时活动
*/
@Operation(summary = "暂停秒杀活动", description = "暂停正在进行的秒杀活动")
@Operation(summary = "暂停限时活动", description = "暂停正在进行的限时活动")
@PostMapping("/{id}/pause")
public ResponseEntity<Map<String, Object>> pauseFlashSale(@Parameter(description = "秒杀活动ID", required = true) @PathVariable Long id) {
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("message", "限时活动暂停成功");
response.put("data", flashSale);
return ResponseEntity.ok(response);
} catch (Exception e) {
log.error("暂停秒杀活动失败", e);
log.error("暂停限时活动失败", e);
Map<String, Object> response = new HashMap<>();
response.put("success", false);
@@ -421,22 +421,22 @@ public class FlashSaleController {
}
/**
* 恢复秒杀活动
* 恢复限时活动
*/
@Operation(summary = "恢复秒杀活动", description = "恢复已暂停的秒杀活动")
@Operation(summary = "恢复限时活动", description = "恢复已暂停的限时活动")
@PostMapping("/{id}/resume")
public ResponseEntity<Map<String, Object>> resumeFlashSale(@Parameter(description = "秒杀活动ID", required = true) @PathVariable Long id) {
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("message", "限时活动恢复成功");
response.put("data", flashSale);
return ResponseEntity.ok(response);
} catch (Exception e) {
log.error("恢复秒杀活动失败", e);
log.error("恢复限时活动失败", e);
Map<String, Object> response = new HashMap<>();
response.put("success", false);
@@ -447,22 +447,22 @@ public class FlashSaleController {
}
/**
* 结束秒杀活动
* 结束限时活动
*/
@Operation(summary = "结束秒杀活动", description = "提前结束秒杀活动")
@Operation(summary = "结束限时活动", description = "提前结束限时活动")
@PostMapping("/{id}/end")
public ResponseEntity<Map<String, Object>> endFlashSale(@Parameter(description = "秒杀活动ID", required = true) @PathVariable Long id) {
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("message", "限时活动结束成功");
response.put("data", flashSale);
return ResponseEntity.ok(response);
} catch (Exception e) {
log.error("结束秒杀活动失败", e);
log.error("结束限时活动失败", e);
Map<String, Object> response = new HashMap<>();
response.put("success", false);
@@ -473,7 +473,7 @@ public class FlashSaleController {
}
/**
* 秒杀压力测试接口
* 限时活动压力测试接口
*/
@PostMapping("/stress-test")
public ResponseEntity<Map<String, Object>> stressTest(@RequestParam Long flashSaleId,
@@ -486,7 +486,7 @@ public class FlashSaleController {
}
// 这里可以实现压力测试逻辑
// 模拟多个用户同时参与秒杀
// 模拟多个用户同时参与限时活动
Map<String, Object> response = new HashMap<>();
response.put("success", true);
@@ -498,7 +498,7 @@ public class FlashSaleController {
return ResponseEntity.ok(response);
} catch (Exception e) {
log.error("秒杀压力测试失败", e);
log.error("限时活动压力测试失败", e);
Map<String, Object> response = new HashMap<>();
response.put("success", false);
@@ -509,10 +509,10 @@ public class FlashSaleController {
}
/**
* 修复秒杀活动库存
* 修复限时活动库存
*/
@PostMapping("/{id}/repair-stock")
@Operation(summary = "修复秒杀库存", description = "修复指定秒杀活动的Redis库存数据")
@Operation(summary = "修复活动库存", description = "修复指定限时活动的Redis库存数据")
public ResponseEntity<Map<String, Object>> repairFlashSaleStock(@PathVariable Long id) {
try {
flashSaleService.repairFlashSaleStock(id);
@@ -523,7 +523,7 @@ public class FlashSaleController {
return ResponseEntity.ok(response);
} catch (Exception e) {
log.error("修复秒杀库存失败", e);
log.error("修复活动库存失败", e);
Map<String, Object> response = new HashMap<>();
response.put("success", false);

View File

@@ -81,20 +81,20 @@ public class PageController {
}
/**
* 秒杀活动列表页面
* 限时活动列表页面
*/
@GetMapping("/flashsales")
public String flashSales(Model model) {
model.addAttribute("pageTitle", "秒杀活动");
model.addAttribute("pageTitle", "限时活动");
return "flashsales";
}
/**
* 秒杀活动详情页面
* 限时活动详情页面
*/
@GetMapping("/flashsale/{id}")
public String flashSaleDetail(@PathVariable Long id, Model model) {
model.addAttribute("pageTitle", "秒杀详情");
model.addAttribute("pageTitle", "限时活动详情");
model.addAttribute("flashSaleId", id);
return "flashsale-detail";
}
@@ -179,7 +179,7 @@ public class PageController {
}
/**
* 秒杀活动管理页面
* 限时活动管理页面
*/
@GetMapping("/admin/flashsales")
public String adminFlashSales(Model model, HttpServletRequest request) {
@@ -187,7 +187,7 @@ public class PageController {
return "redirect:/login?returnUrl=/admin/flashsales";
}
model.addAttribute("pageTitle", "秒杀管理");
model.addAttribute("pageTitle", "限时活动管理");
return "admin/flashsales";
}

View File

@@ -13,7 +13,7 @@ import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* 秒杀活动数据传输对象
* 限时活动数据传输对象
*/
@Data
@NoArgsConstructor
@@ -42,7 +42,7 @@ public class FlashSaleDTO {
// 活动状态描述
private String statusDescription;
// 是否可以参与秒杀
// 是否可以参与限时活动
private Boolean canParticipate;
// 距离开始时间(毫秒)
private Long timeToStart;
@@ -50,7 +50,7 @@ public class FlashSaleDTO {
private Long timeToEnd;
/**
* 创建秒杀活动DTO
* 创建限时活动DTO
*/
@Data
@NoArgsConstructor
@@ -59,11 +59,11 @@ public class FlashSaleDTO {
@NotNull(message = "商品ID不能为空")
private Long productId;
@NotNull(message = "秒杀价格不能为空")
@DecimalMin(value = "0.01", message = "秒杀价格必须大于0")
@NotNull(message = "活动价格不能为空")
@DecimalMin(value = "0.01", message = "活动价格必须大于0")
private BigDecimal flashPrice;
@Min(value = 1, message = "秒杀库存必须大于0")
@Min(value = 1, message = "活动库存必须大于0")
private Integer flashStock;
@NotNull(message = "开始时间不能为空")
@@ -76,16 +76,16 @@ public class FlashSaleDTO {
}
/**
* 更新秒杀活动DTO
* 更新限时活动DTO
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class UpdateDTO {
@DecimalMin(value = "0.01", message = "秒杀价格必须大于0")
@DecimalMin(value = "0.01", message = "活动价格必须大于0")
private BigDecimal flashPrice;
@Min(value = 1, message = "秒杀库存必须大于0")
@Min(value = 1, message = "活动库存必须大于0")
private Integer flashStock;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@@ -100,13 +100,13 @@ public class FlashSaleDTO {
}
/**
* 秒杀参与DTO
* 限时活动参与DTO
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class ParticipateDTO {
@NotNull(message = "秒杀活动ID不能为空")
@NotNull(message = "限时活动ID不能为空")
private Long flashSaleId;
@Min(value = 1, message = "购买数量必须大于0")
@@ -118,7 +118,7 @@ public class FlashSaleDTO {
}
/**
* 秒杀查询DTO
* 限时活动查询DTO
*/
@Data
@NoArgsConstructor
@@ -139,7 +139,7 @@ public class FlashSaleDTO {
}
/**
* 秒杀结果DTO
* 限时活动结果DTO
*/
@Data
@NoArgsConstructor

View File

@@ -12,7 +12,7 @@ import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* 秒杀活动实体类
* 限时活动实体类
* 对应数据库flash_sales表
*/
@Entity
@@ -30,12 +30,12 @@ public class FlashSale {
@Column(name = "product_id", nullable = false)
private Long productId;
@NotNull(message = "秒杀价格不能为空")
@DecimalMin(value = "0.01", message = "秒杀价格必须大于0")
@NotNull(message = "活动价格不能为空")
@DecimalMin(value = "0.01", message = "活动价格必须大于0")
@Column(name = "flash_price", nullable = false, precision = 10, scale = 2)
private BigDecimal flashPrice;
@Min(value = 1, message = "秒杀库存必须大于0")
@Min(value = 1, message = "活动库存必须大于0")
@Column(name = "flash_stock", nullable = false)
private Integer flashStock;

View File

@@ -62,7 +62,7 @@ public class Order {
private Integer status = 1;
/**
* 订单类型1-普通订单2-秒杀订单
* 订单类型1-普通订单2-限时订单
*/
@Column(name = "order_type", nullable = false)
private Integer orderType = 1;
@@ -153,7 +153,7 @@ public class Order {
*/
public enum OrderType {
NORMAL(1, "普通订单"),
FLASH_SALE(2, "秒杀订单"),
FLASH_SALE(2, "限时订单"),
GROUP_BUYING(3, "拼团订单");
private final int code;

View File

@@ -13,71 +13,71 @@ import java.time.LocalDateTime;
import java.util.List;
/**
* 秒杀活动数据访问层
* 限时活动数据访问层
*/
@Repository
public interface FlashSaleRepository extends JpaRepository<FlashSale, Long> {
/**
* 分页查找指定商品的秒杀活动
* 分页查找指定商品的限时活动
*/
Page<FlashSale> findByProductId(Long productId, Pageable pageable);
/**
* 查找指定时间点覆盖的商品秒杀活动
* 查找指定时间点覆盖的商品限时活动
*/
@Query("SELECT f FROM FlashSale f WHERE f.productId = :productId AND f.startTime <= :targetTime AND f.endTime >= :targetTime")
List<FlashSale> findByProductIdAndCoveringTime(@Param("productId") Long productId,
@Param("targetTime") LocalDateTime targetTime);
/**
* 根据商品ID和状态查找秒杀活动
* 根据商品ID和状态查找限时活动
*/
Page<FlashSale> findByProductIdAndStatus(Long productId, Integer status, Pageable pageable);
/**
* 查找正在进行的秒杀活动
* 查找正在进行的限时活动
*/
@Query("SELECT f FROM FlashSale f WHERE f.startTime <= :now AND f.endTime > :now AND f.status = 2")
List<FlashSale> findActiveFlashSales(@Param("now") LocalDateTime now);
/**
* 分页查找正在进行的秒杀活动
* 分页查找正在进行的限时活动
*/
@Query("SELECT f FROM FlashSale f WHERE f.startTime <= :now AND f.endTime > :now AND f.status = 2")
Page<FlashSale> findActiveFlashSales(@Param("now") LocalDateTime now, Pageable pageable);
/**
* 查找即将开始的秒杀活动
* 查找即将开始的限时活动
*/
@Query("SELECT f FROM FlashSale f WHERE f.startTime > :now AND f.status = 1")
List<FlashSale> findUpcomingFlashSales(@Param("now") LocalDateTime now);
/**
* 分页查找即将开始的秒杀活动
* 分页查找即将开始的限时活动
*/
@Query("SELECT f FROM FlashSale f WHERE f.startTime > :now AND f.status = 1")
Page<FlashSale> findUpcomingFlashSales(@Param("now") LocalDateTime now, Pageable pageable);
/**
* 查找已结束的秒杀活动
* 查找已结束的限时活动
*/
@Query("SELECT f FROM FlashSale f WHERE f.endTime <= :now OR f.status = 3")
List<FlashSale> findEndedFlashSales(@Param("now") LocalDateTime now);
/**
* 分页查找已结束的秒杀活动
* 分页查找已结束的限时活动
*/
@Query("SELECT f FROM FlashSale f WHERE f.endTime <= :now OR f.status = 3")
Page<FlashSale> findEndedFlashSales(@Param("now") LocalDateTime now, Pageable pageable);
/**
* 按状态分页查找秒杀活动
* 按状态分页查找限时活动
*/
Page<FlashSale> findByStatus(Integer status, Pageable pageable);
/**
* 更新秒杀库存
* 更新活动库存
*/
@Modifying
@Query("UPDATE FlashSale f SET f.flashStock = f.flashStock - :quantity WHERE f.id = :flashSaleId AND f.flashStock" +
@@ -85,50 +85,50 @@ public interface FlashSaleRepository extends JpaRepository<FlashSale, Long> {
int updateFlashStock(@Param("flashSaleId") Long flashSaleId, @Param("quantity") Integer quantity);
/**
* 恢复秒杀库存(订单取消时使用)
* 恢复活动库存(订单取消时使用)
*/
@Modifying
@Query("UPDATE FlashSale f SET f.flashStock = f.flashStock + :quantity WHERE f.id = :flashSaleId")
int increaseFlashStock(@Param("flashSaleId") Long flashSaleId, @Param("quantity") Integer quantity);
/**
* 更新秒杀活动状态
* 更新限时活动状态
*/
@Modifying
@Query("UPDATE FlashSale f SET f.status = :status WHERE f.id = :flashSaleId")
int updateStatus(@Param("flashSaleId") Long flashSaleId, @Param("status") Integer status);
/**
* 查找指定时间范围内的秒杀活动
* 查找指定时间范围内的限时活动
*/
@Query("SELECT f FROM FlashSale f WHERE f.startTime >= :startTime AND f.endTime <= :endTime")
List<FlashSale> findByTimeRange(@Param("startTime") LocalDateTime startTime,
@Param("endTime") LocalDateTime endTime);
/**
* 查找有库存的正在进行的秒杀活动
* 查找有库存的正在进行的限时活动
*/
@Query("SELECT f FROM FlashSale f WHERE f.startTime <= :now AND f.endTime > :now AND f.status = 2 AND f" +
".flashStock > 0")
List<FlashSale> findActiveFlashSalesWithStock(@Param("now") LocalDateTime now);
/**
* 根据商品ID查找所有秒杀活动
* 根据商品ID查找所有限时活动
*/
List<FlashSale> findByProductId(Long productId);
/**
* 统计指定时间范围内正在进行的秒杀活动数量
* 统计指定时间范围内正在进行的限时活动数量
*/
long countByStartTimeLessThanEqualAndEndTimeGreaterThanEqual(LocalDateTime startTime, LocalDateTime endTime);
/**
* 统计指定时间范围内的秒杀活动数量
* 统计指定时间范围内的限时活动数量
*/
long countByStartTimeBetween(LocalDateTime startTime, LocalDateTime endTime);
/**
* 统计已结束的秒杀活动数量
* 统计已结束的限时活动数量
*/
long countByEndTimeLessThan(LocalDateTime endTime);
}

View File

@@ -68,7 +68,7 @@ public interface OrderRepository extends JpaRepository<Order, Long> {
Long countByUserIdAndOrderTypeAndStatusNot5(@Param("userId") Long userId, @Param("orderType") Integer orderType);
/**
* 查找秒杀订单
* 查找限时订单
*/
@Query("SELECT o FROM Order o WHERE o.orderType = 2")
List<Order> findFlashSaleOrders();
@@ -128,18 +128,18 @@ public interface OrderRepository extends JpaRepository<Order, Long> {
List<Order> findByUserIdAndProductId(@Param("userId") Long userId, @Param("productId") Long productId);
/**
* 查找用户的秒杀订单
* 查找用户的限时订单
*/
@Query("SELECT o FROM Order o WHERE o.userId = :userId AND o.orderType = 2")
List<Order> findFlashSaleOrdersByUserId(@Param("userId") Long userId);
/**
* 检查用户是否已经参与过指定秒杀活动
* 检查用户是否已经参与过指定限时活动
*/
boolean existsByUserIdAndFlashSaleIdAndOrderType(Long userId, Long flashSaleId, Integer orderType);
/**
* 检查指定秒杀活动是否已有订单
* 检查指定限时活动是否已有订单
*/
boolean existsByFlashSaleIdAndOrderType(Long flashSaleId, Integer orderType);

View File

@@ -96,7 +96,7 @@ public class AdminService {
long totalProducts = productRepository.count();
stats.put("totalProducts", totalProducts);
// 活跃秒杀
// 活跃限时活动
LocalDateTime now = LocalDateTime.now();
long activeFlashSales = flashSaleRepository.countByStartTimeLessThanEqualAndEndTimeGreaterThanEqual(now,
now);
@@ -272,7 +272,7 @@ public class AdminService {
}
/**
* 获取秒杀统计数据
* 获取限时活动统计数据
*/
public Map<String, Object> getFlashSaleStats() {
Map<String, Object> stats = new HashMap<>();
@@ -280,26 +280,26 @@ public class AdminService {
try {
LocalDateTime now = LocalDateTime.now();
// 总秒杀活动数
// 总限时活动数
long totalFlashSales = flashSaleRepository.count();
stats.put("totalFlashSales", totalFlashSales);
// 活跃秒杀
// 活跃限时活动
long activeFlashSales = flashSaleRepository.countByStartTimeLessThanEqualAndEndTimeGreaterThanEqual(now,
now);
stats.put("activeFlashSales", activeFlashSales);
// 即将开始的秒杀
// 即将开始的限时活动
LocalDateTime oneHourLater = now.plusHours(1);
long upcomingFlashSales = flashSaleRepository.countByStartTimeBetween(now, oneHourLater);
stats.put("upcomingFlashSales", upcomingFlashSales);
// 已结束的秒杀
// 已结束的限时活动
long endedFlashSales = flashSaleRepository.countByEndTimeLessThan(now);
stats.put("endedFlashSales", endedFlashSales);
} catch (Exception e) {
log.error("获取秒杀统计数据失败", e);
log.error("获取限时活动统计数据失败", e);
stats.put("totalFlashSales", 0L);
stats.put("activeFlashSales", 0L);
stats.put("upcomingFlashSales", 0L);
@@ -327,7 +327,7 @@ public class AdminService {
orderMap.put("status", order.getStatus());
orderMap.put("createdAt", order.getCreatedAt());
orderMap.put("orderType", order.getOrderType());
orderMap.put("isFlashSale", order.getOrderType() == 2); // 2表示秒杀订单
orderMap.put("isFlashSale", order.getOrderType() == 2); // 2表示限时订单
return orderMap;
}).collect(Collectors.toList());
@@ -502,7 +502,7 @@ public class AdminService {
orderMap.put("status", order.getStatus());
orderMap.put("createdAt", order.getCreatedAt());
orderMap.put("orderType", order.getOrderType());
orderMap.put("isFlashSale", order.getOrderType() == 2); // 2表示秒杀订单
orderMap.put("isFlashSale", order.getOrderType() == 2); // 2表示限时订单
return orderMap;
}).collect(Collectors.toList());
@@ -753,7 +753,7 @@ public class AdminService {
fileUploadService.deleteProductImage(oldImageUrl);
}
// 清除引用该商品的秒杀活动缓存,确保图片/名称/价格更新及时生效
// 清除引用该商品的限时活动缓存,确保图片/名称/价格更新及时生效
invalidateFlashSaleCacheByProductId(id);
} else {
throw new RuntimeException("商品不存在");
@@ -765,7 +765,7 @@ public class AdminService {
}
/**
* 清除引用指定商品的所有秒杀活动缓存
* 清除引用指定商品的所有限时活动缓存
*/
private void invalidateFlashSaleCacheByProductId(Long productId) {
try {
@@ -774,10 +774,10 @@ public class AdminService {
for (com.org.flashsalesystem.entity.FlashSale fs : flashSales) {
String cacheKey = "flashsale:" + fs.getId();
redisService.delete(cacheKey);
log.debug("清除秒杀活动缓存: {}", cacheKey);
log.debug("清除限时活动缓存: {}", cacheKey);
}
} catch (Exception e) {
log.warn("清除秒杀活动缓存失败: {}", e.getMessage());
log.warn("清除限时活动缓存失败: {}", e.getMessage());
}
}
@@ -793,7 +793,7 @@ public class AdminService {
fileUploadService.deleteProductImage(product.getImageUrl());
productService.invalidateProductCaches(id);
productService.removeProductStockCache(id);
// 清除关联的秒杀活动缓存
// 清除关联的限时活动缓存
invalidateFlashSaleCacheByProductId(id);
productRepository.deleteById(id);
} else {

View File

@@ -30,8 +30,8 @@ import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
* 秒杀服务类
* 实现秒杀活动管理、库存控制、分布式锁等核心功能
* 限时活动服务类
* 实现限时活动管理、库存控制、分布式锁等核心功能
*/
@Service
@Slf4j
@@ -64,11 +64,11 @@ public class FlashSaleService {
private int maxQuantityPerUser;
/**
* 创建秒杀活动
* 创建限时活动
*/
@Transactional
public FlashSaleDTO createFlashSale(FlashSaleDTO.CreateDTO createDTO) {
log.info("创建秒杀活动: 商品ID={}, 秒杀价格={}, 库存={}",
log.info("创建限时活动: 商品ID={}, 活动价格={}, 库存={}",
createDTO.getProductId(), createDTO.getFlashPrice(), createDTO.getFlashStock());
// 验证商品是否存在
@@ -87,14 +87,14 @@ public class FlashSaleService {
throw new RuntimeException("结束时间必须晚于开始时间");
}
// 创建秒杀活动
// 创建限时活动
FlashSale flashSale = new FlashSale();
BeanUtils.copyProperties(createDTO, flashSale);
flashSale.setStatus(1); // 未开始
flashSale = flashSaleRepository.save(flashSale);
// 缓存秒杀活动信息
// 缓存限时活动信息
cacheFlashSaleInfo(flashSale, product);
// 预热库存到Redis - 确保存储为数字类型
@@ -104,7 +104,7 @@ public class FlashSaleService {
// 验证库存设置是否成功
String verifyStock = redisService.getString(stockKey);
log.info("秒杀活动库存初始化验证: flashSaleId={}, stockKey={}, setStock={}, actualStock={}",
log.info("限时活动库存初始化验证: flashSaleId={}, stockKey={}, setStock={}, actualStock={}",
flashSale.getId(), stockKey, flashSale.getFlashStock(), verifyStock);
if (!flashSale.getFlashStock().toString().equals(verifyStock)) {
@@ -112,17 +112,17 @@ public class FlashSaleService {
flashSale.getId(), flashSale.getFlashStock(), verifyStock);
}
log.info("秒杀活动创建成功: ID={}", flashSale.getId());
log.info("限时活动创建成功: ID={}", flashSale.getId());
return buildFlashSaleDTO(flashSale, product);
}
/**
* 参与秒杀
* 参与限时活动
*/
@Transactional
public FlashSaleDTO.ResultDTO participateFlashSale(Long userId, FlashSaleDTO.ParticipateDTO participateDTO) {
log.info("用户参与秒杀: 用户ID={}, 秒杀ID={}, 数量={}",
log.info("用户参与限时活动: 用户ID={}, 限时活动ID={}, 数量={}",
userId, participateDTO.getFlashSaleId(), participateDTO.getQuantity());
// 限流检查
@@ -130,26 +130,26 @@ public class FlashSaleService {
return createFailResult("请求过于频繁,请稍后再试");
}
// 获取秒杀活动信息
// 获取限时活动信息
FlashSale flashSale = getFlashSaleById(participateDTO.getFlashSaleId());
if (flashSale == null) {
return createFailResult("秒杀活动不存在");
return createFailResult("限时活动不存在");
}
// 检查活动状态
if (!flashSale.isActive()) {
return createFailResult("秒杀活动未开始或已结束");
return createFailResult("限时活动未开始或已结束");
}
// 检查用户是否已经参与过
String successUsersKey = FLASH_SALE_SUCCESS_USERS_PREFIX + flashSale.getId();
if (redisService.sIsMember(successUsersKey, userId)) {
return createFailResult("您已经参与过该秒杀活动");
return createFailResult("您已经参与过该限时活动");
}
// 检查数据库中是否已有订单
if (orderRepository.existsByUserIdAndFlashSaleIdAndOrderType(userId, flashSale.getId(), 2)) {
return createFailResult("您已经参与过该秒杀活动");
return createFailResult("您已经参与过该限时活动");
}
// 检查购买数量限制
@@ -167,16 +167,16 @@ public class FlashSaleService {
try {
// 二次校验:锁内重新检查用户是否已参与(防止并发竞态)
if (redisService.sIsMember(successUsersKey, userId)) {
return createFailResult("您已经参与过该秒杀活动");
return createFailResult("您已经参与过该限时活动");
}
if (orderRepository.existsByUserIdAndFlashSaleIdAndOrderType(userId, flashSale.getId(), 2)) {
return createFailResult("您已经参与过该秒杀活动");
return createFailResult("您已经参与过该限时活动");
}
// 检查并修复库存数据
String stockKey = FLASH_SALE_STOCK_PREFIX + flashSale.getId();
String currentStock = redisService.getString(stockKey);
log.info("秒杀前库存检查: flashSaleId={}, stockKey={}, currentStock={}",
log.info("限时活动前库存检查: flashSaleId={}, stockKey={}, currentStock={}",
flashSale.getId(), stockKey, currentStock);
if (currentStock == null || currentStock.trim().isEmpty()) {
@@ -203,18 +203,18 @@ public class FlashSaleService {
currentStock = redisService.getString(stockKey);
if (currentStock == null || currentStock.trim().isEmpty()) {
log.error("库存数据最终验证失败: flashSaleId={}, stockKey={}", flashSale.getId(), stockKey);
return createFailResult("秒杀活动库存初始化失败,请稍后重试");
return createFailResult("限时活动库存初始化失败,请稍后重试");
}
// 使用Lua脚本原子性扣减库存
log.info("准备执行秒杀脚本: stockKey={}, quantity={}, userId={}, currentStock={}",
log.info("准备执行活动脚本: stockKey={}, quantity={}, userId={}, currentStock={}",
stockKey, participateDTO.getQuantity(), userId, currentStock);
Long remainingStock = redisService.executeFlashSaleScript(stockKey, participateDTO.getQuantity());
log.info("秒杀脚本执行完成: stockKey={}, remainingStock={}", stockKey, remainingStock);
log.info("活动脚本执行完成: stockKey={}, remainingStock={}", stockKey, remainingStock);
if (remainingStock < 0) {
if (remainingStock == -1) {
log.warn("秒杀库存key不存在或数据异常: flashSaleId={}, stockKey={}", flashSale.getId(), stockKey);
log.warn("活动库存key不存在或数据异常: flashSaleId={}, stockKey={}", flashSale.getId(), stockKey);
// 自动修复数据并重试一次
log.info("开始自动修复库存数据: flashSaleId={}", flashSale.getId());
@@ -224,10 +224,10 @@ public class FlashSaleService {
// 修复后重新验证库存
String repairedStock = redisService.getString(stockKey);
if (repairedStock != null && !repairedStock.trim().isEmpty()) {
log.info("库存修复成功,重新执行秒杀脚本: flashSaleId={}, stock={}",
log.info("库存修复成功,重新执行活动脚本: flashSaleId={}, stock={}",
flashSale.getId(), repairedStock);
// 重新执行秒杀脚本
// 重新执行活动脚本
Long retryResult = redisService.executeFlashSaleScript(stockKey,
participateDTO.getQuantity());
log.info("修复后重试结果: flashSaleId={}, result={}", flashSale.getId(), retryResult);
@@ -252,14 +252,14 @@ public class FlashSaleService {
return createFailResult("系统繁忙,请稍后重试");
}
} else if (remainingStock == -2) {
log.info("秒杀库存不足: flashSaleId={}, 剩余库存不足", flashSale.getId());
log.info("活动库存不足: flashSaleId={}, 剩余库存不足", flashSale.getId());
return createFailResult("商品已售罄");
} else if (remainingStock == -3) {
log.error("秒杀参数异常: flashSaleId={}, quantity={}", flashSale.getId(),
log.error("限时活动参数异常: flashSaleId={}, quantity={}", flashSale.getId(),
participateDTO.getQuantity());
return createFailResult("参数异常,请检查购买数量");
} else {
log.error("秒杀脚本执行异常: flashSaleId={}, returnValue={}", flashSale.getId(), remainingStock);
log.error("活动脚本执行异常: flashSaleId={}, returnValue={}", flashSale.getId(), remainingStock);
return createFailResult("系统异常,请稍后重试");
}
}
@@ -274,26 +274,26 @@ public class FlashSaleService {
// 更新数据库库存
flashSaleRepository.updateFlashStock(flashSale.getId(), participateDTO.getQuantity());
// 发布秒杀成功消息
// 发布限时活动成功消息
publishFlashSaleResult(userId, flashSale, order, true);
// 更新商品销量排行榜
productService.increaseSalesRank(flashSale.getProductId(), participateDTO.getQuantity());
log.info("秒杀成功: 用户ID={}, 订单ID={}, 剩余库存={}", userId, order.getId(), remainingStock);
log.info("限时活动成功: 用户ID={}, 订单ID={}, 剩余库存={}", userId, order.getId(), remainingStock);
return createSuccessResult(order, flashSale);
} catch (Exception e) {
log.error("秒杀处理异常: 用户ID={}, 秒杀ID={}", userId, participateDTO.getFlashSaleId(), e);
return createFailResult("秒杀失败,请重试");
log.error("限时活动处理异常: 用户ID={}, 限时活动ID={}", userId, participateDTO.getFlashSaleId(), e);
return createFailResult("限时活动失败,请重试");
} finally {
redissonLockService.unlock(lockKey);
}
}
/**
* 获取秒杀活动列表
* 获取限时活动列表
*/
public Map<String, Object> getFlashSaleList(FlashSaleDTO.QueryDTO queryDTO) {
// 验证排序字段
@@ -360,7 +360,7 @@ public class FlashSaleService {
}
/**
* 获取正在进行的秒杀活动
* 获取正在进行的限时活动
*/
public List<FlashSaleDTO> getActiveFlashSales() {
// 尝试从缓存获取
@@ -394,7 +394,7 @@ public class FlashSaleService {
}
/**
* 根据ID获取秒杀活动
* 根据ID获取限时活动
*/
public FlashSaleDTO getFlashSaleDTOById(Long flashSaleId) {
FlashSale flashSale = getFlashSaleById(flashSaleId);
@@ -407,21 +407,21 @@ public class FlashSaleService {
}
/**
* 预热秒杀活动
* 预热限时活动
*/
public void preloadFlashSale(Long flashSaleId) {
log.info("预热秒杀活动: {}", flashSaleId);
log.info("预热限时活动: {}", flashSaleId);
Optional<FlashSale> flashSaleOpt = flashSaleRepository.findById(flashSaleId);
if (!flashSaleOpt.isPresent()) {
log.warn("秒杀活动不存在: {}", flashSaleId);
log.warn("限时活动不存在: {}", flashSaleId);
return;
}
FlashSale flashSale = flashSaleOpt.get();
Product product = productRepository.findById(flashSale.getProductId()).orElse(null);
// 缓存秒杀活动信息
// 缓存限时活动信息
cacheFlashSaleInfo(flashSale, product);
// 预热库存 - 确保存储为数字类型
@@ -431,14 +431,14 @@ public class FlashSaleService {
// 验证预热是否成功
String verifyStock = redisService.getString(stockKey);
log.info("秒杀活动预热验证: flashSaleId={}, stockKey={}, setStock={}, actualStock={}",
log.info("限时活动预热验证: flashSaleId={}, stockKey={}, setStock={}, actualStock={}",
flashSaleId, stockKey, flashSale.getFlashStock(), verifyStock);
if (!flashSale.getFlashStock().toString().equals(verifyStock)) {
log.error("秒杀活动预热失败: flashSaleId={}, expected={}, actual={}",
log.error("限时活动预热失败: flashSaleId={}, expected={}, actual={}",
flashSaleId, flashSale.getFlashStock(), verifyStock);
} else {
log.info("秒杀活动预热完成: flashSaleId={}, stock={}", flashSaleId, verifyStock);
log.info("限时活动预热完成: flashSaleId={}, stock={}", flashSaleId, verifyStock);
}
}
@@ -446,11 +446,11 @@ public class FlashSaleService {
* 修复Redis中的库存数据
*/
public void repairFlashSaleStock(Long flashSaleId) {
log.info("修复秒杀活动库存数据: {}", flashSaleId);
log.info("修复限时活动库存数据: {}", flashSaleId);
Optional<FlashSale> flashSaleOpt = flashSaleRepository.findById(flashSaleId);
if (!flashSaleOpt.isPresent()) {
log.warn("秒杀活动不存在: {}", flashSaleId);
log.warn("限时活动不存在: {}", flashSaleId);
return;
}
@@ -501,18 +501,18 @@ public class FlashSaleService {
}
/**
* 重新预热所有活跃的秒杀活动库存
* 重新预热所有活跃的限时活动库存
*/
public void preloadAllActiveFlashSales() {
log.info("开始预热所有活跃秒杀活动库存");
log.info("开始预热所有活跃限时活动库存");
try {
// 获取所有秒杀活动(包括未开始、进行中的)
// 获取所有限时活动(包括未开始、进行中的)
LocalDateTime now = LocalDateTime.now();
List<FlashSale> activeFlashSales = flashSaleRepository.findAll();
if (activeFlashSales.isEmpty()) {
log.info("没有找到任何秒杀活动,跳过预热");
log.info("没有找到任何限时活动,跳过预热");
return;
}
@@ -525,13 +525,13 @@ public class FlashSaleService {
// 检查活动状态,只预热有效的活动
if (flashSale.getStatus() == 3) { // 已结束的活动跳过
log.debug("跳过已结束的秒杀活动: flashSaleId={}", flashSale.getId());
log.debug("跳过已结束的限时活动: flashSaleId={}", flashSale.getId());
continue;
}
// 验证库存数据有效性
if (flashSale.getFlashStock() == null || flashSale.getFlashStock() < 0) {
log.warn("秒杀活动库存数据无效,跳过: flashSaleId={}, stock={}",
log.warn("限时活动库存数据无效,跳过: flashSaleId={}, stock={}",
flashSale.getId(), flashSale.getFlashStock());
failCount++;
continue;
@@ -567,27 +567,27 @@ public class FlashSaleService {
// 验证设置是否成功
String verifyStock = redisService.getString(stockKey);
if (flashSale.getFlashStock().toString().equals(verifyStock)) {
log.info("预热秒杀活动库存成功: flashSaleId={}, stock={}, status={}",
log.info("预热限时活动库存成功: flashSaleId={}, stock={}, status={}",
flashSale.getId(), flashSale.getFlashStock(), getStatusText(flashSale.getStatus()));
successCount++;
} else {
log.error("预热秒杀活动库存验证失败: flashSaleId={}, expected={}, actual={}",
log.error("预热限时活动库存验证失败: flashSaleId={}, expected={}, actual={}",
flashSale.getId(), flashSale.getFlashStock(), verifyStock);
failCount++;
}
} catch (Exception e) {
log.error("预热秒杀活动库存失败: flashSaleId={}", flashSale.getId(), e);
log.error("预热限时活动库存失败: flashSaleId={}", flashSale.getId(), e);
failCount++;
}
}
log.info("所有秒杀活动库存预热完成: 总数={}, 成功={}, 失败={}",
log.info("所有限时活动库存预热完成: 总数={}, 成功={}, 失败={}",
activeFlashSales.size(), successCount, failCount);
} catch (Exception e) {
log.error("预热所有秒杀活动库存时发生异常", e);
throw new RuntimeException("预热秒杀活动库存失败: " + e.getMessage(), e);
log.error("预热所有限时活动库存时发生异常", e);
throw new RuntimeException("预热限时活动库存失败: " + e.getMessage(), e);
}
}
@@ -611,13 +611,13 @@ public class FlashSaleService {
}
/**
* 恢复秒杀库存(订单取消时调用)
* 恢复活动库存(订单取消时调用)
* 恢复Redis库存、DB库存并移除成功用户集合记录
*/
@Transactional
public void restoreFlashSaleStock(Long flashSaleId, Long productId, LocalDateTime orderCreatedAt, Long userId,
Integer quantity) {
log.info("恢复秒杀库存: flashSaleId={}, productId={}, orderCreatedAt={}, userId={}, quantity={}",
log.info("恢复活动库存: flashSaleId={}, productId={}, orderCreatedAt={}, userId={}, quantity={}",
flashSaleId, productId, orderCreatedAt, userId, quantity);
Optional<FlashSale> flashSaleOpt = Optional.empty();
@@ -626,10 +626,10 @@ public class FlashSaleService {
orderCreatedAt);
if (matchedFlashSales.size() == 1) {
flashSaleOpt = Optional.of(matchedFlashSales.get(0));
log.info("根据商品和下单时间回填秒杀活动: flashSaleId={}, productId={}",
log.info("根据商品和下单时间回填限时活动: flashSaleId={}, productId={}",
flashSaleOpt.get().getId(), productId);
} else {
log.warn("订单未记录秒杀活动ID且无法唯一匹配历史活动跳过秒杀库存恢复: productId={}, matches={}",
log.warn("订单未记录限时活动ID且无法唯一匹配历史活动跳过活动库存恢复: productId={}, matches={}",
productId, matchedFlashSales.size());
return;
}
@@ -638,7 +638,7 @@ public class FlashSaleService {
}
if (!flashSaleOpt.isPresent()) {
log.warn("未找到对应的秒杀活动,跳过秒杀库存恢复: flashSaleId={}", flashSaleId);
log.warn("未找到对应的限时活动,跳过活动库存恢复: flashSaleId={}", flashSaleId);
return;
}
@@ -655,12 +655,12 @@ public class FlashSaleService {
String successUsersKey = FLASH_SALE_SUCCESS_USERS_PREFIX + flashSale.getId();
redisService.sRem(successUsersKey, userId);
log.info("秒杀库存恢复成功: flashSaleId={}, userId={}, quantity={}",
log.info("活动库存恢复成功: flashSaleId={}, userId={}, quantity={}",
flashSale.getId(), userId, quantity);
}
/**
* 获取秒杀活动剩余库存
* 获取限时活动剩余库存
*/
public Integer getFlashSaleStock(Long flashSaleId) {
String stockKey = FLASH_SALE_STOCK_PREFIX + flashSaleId;
@@ -669,16 +669,16 @@ public class FlashSaleService {
}
/**
* 更新秒杀活动
* 更新限时活动
*/
@Transactional
public FlashSaleDTO updateFlashSale(Long flashSaleId, FlashSaleDTO.UpdateDTO updateDTO) {
log.info("更新秒杀活动: ID={}", flashSaleId);
log.info("更新限时活动: ID={}", flashSaleId);
// 获取现有秒杀活动
// 获取现有限时活动
Optional<FlashSale> flashSaleOpt = flashSaleRepository.findById(flashSaleId);
if (!flashSaleOpt.isPresent()) {
throw new RuntimeException("秒杀活动不存在");
throw new RuntimeException("限时活动不存在");
}
FlashSale flashSale = flashSaleOpt.get();
@@ -711,40 +711,40 @@ public class FlashSaleService {
String stockKey = FLASH_SALE_STOCK_PREFIX + flashSale.getId();
redisService.set(stockKey, flashSale.getFlashStock());
log.info("秒杀活动更新成功: ID={}", flashSale.getId());
log.info("限时活动更新成功: ID={}", flashSale.getId());
return buildFlashSaleDTO(flashSale, product);
}
/**
* 删除秒杀活动
* 删除限时活动
*/
@Transactional
public boolean deleteFlashSale(Long flashSaleId) {
log.info("删除秒杀活动: ID={}", flashSaleId);
log.info("删除限时活动: ID={}", flashSaleId);
// 删除秒杀活动
// 删除限时活动
flashSaleRepository.deleteById(flashSaleId);
// 清除相关缓存
clearFlashSaleCache(flashSaleId);
log.info("秒杀活动删除成功: ID={}", flashSaleId);
log.info("限时活动删除成功: ID={}", flashSaleId);
return true;
}
/**
* 发布秒杀活动
* 发布限时活动
*/
@Transactional
public FlashSaleDTO publishFlashSale(Long flashSaleId) {
log.info("发布秒杀活动: ID={}", flashSaleId);
log.info("发布限时活动: ID={}", flashSaleId);
// 获取现有秒杀活动
// 获取现有限时活动
Optional<FlashSale> flashSaleOpt = flashSaleRepository.findById(flashSaleId);
if (!flashSaleOpt.isPresent()) {
throw new RuntimeException("秒杀活动不存在");
throw new RuntimeException("限时活动不存在");
}
FlashSale flashSale = flashSaleOpt.get();
@@ -760,22 +760,22 @@ public class FlashSaleService {
Product product = productRepository.findById(flashSale.getProductId()).orElse(null);
cacheFlashSaleInfo(flashSale, product);
log.info("秒杀活动发布成功: ID={}", flashSaleId);
log.info("限时活动发布成功: ID={}", flashSaleId);
return buildFlashSaleDTO(flashSale, product);
}
/**
* 暂停秒杀活动
* 暂停限时活动
*/
@Transactional
public FlashSaleDTO pauseFlashSale(Long flashSaleId) {
log.info("暂停秒杀活动: ID={}", flashSaleId);
log.info("暂停限时活动: ID={}", flashSaleId);
// 获取现有秒杀活动
// 获取现有限时活动
Optional<FlashSale> flashSaleOpt = flashSaleRepository.findById(flashSaleId);
if (!flashSaleOpt.isPresent()) {
throw new RuntimeException("秒杀活动不存在");
throw new RuntimeException("限时活动不存在");
}
FlashSale flashSale = flashSaleOpt.get();
@@ -788,22 +788,22 @@ public class FlashSaleService {
Product product = productRepository.findById(flashSale.getProductId()).orElse(null);
cacheFlashSaleInfo(flashSale, product);
log.info("秒杀活动暂停成功: ID={}", flashSaleId);
log.info("限时活动暂停成功: ID={}", flashSaleId);
return buildFlashSaleDTO(flashSale, product);
}
/**
* 恢复秒杀活动
* 恢复限时活动
*/
@Transactional
public FlashSaleDTO resumeFlashSale(Long flashSaleId) {
log.info("恢复秒杀活动: ID={}", flashSaleId);
log.info("恢复限时活动: ID={}", flashSaleId);
// 获取现有秒杀活动
// 获取现有限时活动
Optional<FlashSale> flashSaleOpt = flashSaleRepository.findById(flashSaleId);
if (!flashSaleOpt.isPresent()) {
throw new RuntimeException("秒杀活动不存在");
throw new RuntimeException("限时活动不存在");
}
FlashSale flashSale = flashSaleOpt.get();
@@ -816,22 +816,22 @@ public class FlashSaleService {
Product product = productRepository.findById(flashSale.getProductId()).orElse(null);
cacheFlashSaleInfo(flashSale, product);
log.info("秒杀活动恢复成功: ID={}", flashSaleId);
log.info("限时活动恢复成功: ID={}", flashSaleId);
return buildFlashSaleDTO(flashSale, product);
}
/**
* 结束秒杀活动
* 结束限时活动
*/
@Transactional
public FlashSaleDTO endFlashSale(Long flashSaleId) {
log.info("结束秒杀活动: ID={}", flashSaleId);
log.info("结束限时活动: ID={}", flashSaleId);
// 获取现有秒杀活动
// 获取现有限时活动
Optional<FlashSale> flashSaleOpt = flashSaleRepository.findById(flashSaleId);
if (!flashSaleOpt.isPresent()) {
throw new RuntimeException("秒杀活动不存在");
throw new RuntimeException("限时活动不存在");
}
FlashSale flashSale = flashSaleOpt.get();
@@ -847,13 +847,13 @@ public class FlashSaleService {
Product product = productRepository.findById(flashSale.getProductId()).orElse(null);
cacheFlashSaleInfo(flashSale, product);
log.info("秒杀活动结束成功: ID={}", flashSaleId);
log.info("限时活动结束成功: ID={}", flashSaleId);
return buildFlashSaleDTO(flashSale, product);
}
/**
* 获取秒杀活动统计信息(即将开始、正在进行的全局数量 + 用户参与/成功数量)
* 获取限时活动统计信息(即将开始、正在进行的全局数量 + 用户参与/成功数量)
*/
public Map<String, Object> getFlashSaleStatistics(Long userId) {
LocalDateTime now = LocalDateTime.now();
@@ -877,11 +877,11 @@ public class FlashSaleService {
}
/**
* 定时预热即将开始的秒杀活动库存每5分钟执行一次
* 定时预热即将开始的限时活动库存每5分钟执行一次
*/
@Scheduled(fixedRate = 300000)
public void scheduledPreloadFlashSales() {
log.info("定时任务:检查即将开始的秒杀活动并预热库存");
log.info("定时任务:检查即将开始的限时活动并预热库存");
try {
LocalDateTime now = LocalDateTime.now();
LocalDateTime threshold = now.plusMinutes(30);
@@ -896,18 +896,18 @@ public class FlashSaleService {
}
if (preloadCount > 0) {
log.info("定时预热完成:预热了{}个即将开始的秒杀活动", preloadCount);
log.info("定时预热完成:预热了{}个即将开始的限时活动", preloadCount);
}
// 同时更新秒杀活动状态
// 同时更新限时活动状态
updateFlashSaleStatus();
} catch (Exception e) {
log.error("定时预热秒杀活动失败", e);
log.error("定时预热限时活动失败", e);
}
}
/**
* 更新秒杀活动状态
* 更新限时活动状态
*/
@Transactional
public void updateFlashSaleStatus() {
@@ -918,7 +918,7 @@ public class FlashSaleService {
for (FlashSale flashSale : upcomingFlashSales) {
if (flashSale.isStarted() && !flashSale.isEnded()) {
flashSaleRepository.updateStatus(flashSale.getId(), 2);
log.info("秒杀活动开始: {}", flashSale.getId());
log.info("限时活动开始: {}", flashSale.getId());
}
}
@@ -927,7 +927,7 @@ public class FlashSaleService {
for (FlashSale flashSale : activeFlashSales) {
if (flashSale.isEnded()) {
flashSaleRepository.updateStatus(flashSale.getId(), 3);
log.info("秒杀活动结束: {}", flashSale.getId());
log.info("限时活动结束: {}", flashSale.getId());
// 清除相关缓存
clearFlashSaleCache(flashSale.getId());
@@ -936,7 +936,7 @@ public class FlashSaleService {
}
/**
* 根据ID获取秒杀活动实体
* 根据ID获取限时活动实体
*/
private FlashSale getFlashSaleById(Long flashSaleId) {
// 先从缓存获取
@@ -968,7 +968,7 @@ public class FlashSaleService {
}
/**
* 缓存秒杀活动信息
* 缓存限时活动信息
*/
private void cacheFlashSaleInfo(FlashSale flashSale, Product product) {
String cacheKey = FLASH_SALE_CACHE_PREFIX + flashSale.getId();
@@ -991,7 +991,7 @@ public class FlashSaleService {
}
/**
* 构建秒杀活动DTO
* 构建限时活动DTO
*/
private FlashSaleDTO buildFlashSaleDTO(FlashSale flashSale, Product product) {
FlashSaleDTO dto = new FlashSaleDTO();
@@ -1064,7 +1064,7 @@ public class FlashSaleService {
}
/**
* 创建秒杀订单
* 创建限时订单
*/
private Order createFlashSaleOrder(Long userId, FlashSale flashSale, FlashSaleDTO.ParticipateDTO participateDTO) {
Order order = new Order();
@@ -1075,16 +1075,16 @@ public class FlashSaleService {
order.setQuantity(participateDTO.getQuantity());
order.setTotalPrice(flashSale.getFlashPrice().multiply(BigDecimal.valueOf(participateDTO.getQuantity())));
order.setStatus(1); // 待支付
order.setOrderType(2); // 秒杀订单
order.setOrderType(2); // 限时订单
order.setReceiverPhone(participateDTO.getPhone());
order.setReceiverAddress(participateDTO.getAddress());
order.setRemark("秒杀订单");
order.setRemark("限时订单");
return orderRepository.save(order);
}
/**
* 发布秒杀结果消息
* 发布限时活动结果消息
*/
private void publishFlashSaleResult(Long userId, FlashSale flashSale, Order order, boolean success) {
Map<String, Object> message = new HashMap<>();
@@ -1104,7 +1104,7 @@ public class FlashSaleService {
private FlashSaleDTO.ResultDTO createSuccessResult(Order order, FlashSale flashSale) {
FlashSaleDTO.ResultDTO result = new FlashSaleDTO.ResultDTO();
result.setSuccess(true);
result.setMessage("秒杀成功");
result.setMessage("限时活动成功");
result.setOrderId(order.getId());
result.setFlashSaleId(flashSale.getId());
result.setProductId(flashSale.getProductId());
@@ -1126,7 +1126,7 @@ public class FlashSaleService {
}
/**
* 清除秒杀活动缓存
* 清除限时活动缓存
*/
private void clearFlashSaleCache(Long flashSaleId) {
String cacheKey = FLASH_SALE_CACHE_PREFIX + flashSaleId;

View File

@@ -48,7 +48,7 @@ public class MessageListenerService {
new ChannelTopic("stock:change")
);
// 秒杀结果监听
// 限时活动结果监听
redisMessageListenerContainer.addMessageListener(
new FlashSaleResultListener(),
new ChannelTopic("flashsale:result")
@@ -138,26 +138,26 @@ public class MessageListenerService {
}
/**
* 处理秒杀结果
* 处理限时活动结果
*/
private void handleFlashSaleResult(Long userId, Long flashSaleId, Boolean success, Map<String, Object> data) {
if (userId == null) {
log.warn("秒杀结果缺少用户ID: flashSaleId={}", flashSaleId);
log.warn("限时活动结果缺少用户ID: flashSaleId={}", flashSaleId);
return;
}
String link = "/flashsale/" + flashSaleId;
if (success) {
String title = "秒杀成功";
String message = "恭喜您成功抢购秒杀商品,请尽快完成支付!";
String title = "限时活动成功";
String message = "恭喜您成功抢购限时活动商品,请尽快完成支付!";
notificationService.createNotification(userId, "flashsale", title, message, link);
log.info("秒杀成功通知已创建: 用户ID={}, 秒杀ID={}", userId, flashSaleId);
log.info("限时活动成功通知已创建: 用户ID={}, 限时活动ID={}", userId, flashSaleId);
} else {
String title = "秒杀未中";
String message = "很遗憾,本次秒杀未能抢购成功,下次再来吧!";
String title = "活动未中";
String message = "很遗憾,本次限时活动未能抢购成功,下次再来吧!";
notificationService.createNotification(userId, "flashsale", title, message, link);
log.info("秒杀失败通知已创建: 用户ID={}, 秒杀ID={}", userId, flashSaleId);
log.info("限时活动失败通知已创建: 用户ID={}, 限时活动ID={}", userId, flashSaleId);
}
}
@@ -390,14 +390,14 @@ public class MessageListenerService {
}
/**
* 秒杀结果监听器
* 限时活动结果监听器
*/
private class FlashSaleResultListener implements MessageListener {
@Override
public void onMessage(Message message, byte[] pattern) {
try {
String messageBody = new String(message.getBody());
log.debug("接收到秒杀结果消息: {}", messageBody);
log.debug("接收到限时活动结果消息: {}", messageBody);
Map<String, Object> data = parseRedissonMessage(messageBody);
@@ -405,13 +405,13 @@ public class MessageListenerService {
Long flashSaleId = extractLongValue(data.get("flashSaleId"));
Boolean success = Boolean.valueOf(data.get("success").toString());
log.info("秒杀结果: 用户ID={}, 秒杀ID={}, 成功={}", userId, flashSaleId, success);
log.info("限时活动结果: 用户ID={}, 限时活动ID={}, 成功={}", userId, flashSaleId, success);
// 这里可以添加具体的业务处理逻辑
handleFlashSaleResult(userId, flashSaleId, success, data);
} catch (Exception e) {
log.error("处理秒杀结果消息失败", e);
log.error("处理限时活动结果消息失败", e);
}
}
}

View File

@@ -443,7 +443,7 @@ public class OrderService {
// 恢复库存
productService.updateStock(order.getProductId(), order.getQuantity(), "increase");
// 秒杀订单额外恢复秒杀库存
// 限时订单额外恢复活动库存
if (order.getOrderType() != null && order.getOrderType() == 2) {
flashSaleService.restoreFlashSaleStock(order.getFlashSaleId(), order.getProductId(), order.getCreatedAt(),
order.getUserId(), order.getQuantity());
@@ -925,7 +925,7 @@ public class OrderService {
case 1:
return "普通订单";
case 2:
return "秒杀订单";
return "限时订单";
case 3:
return "拼团订单";
default:

View File

@@ -57,7 +57,7 @@ public class RateLimitService {
}
/**
* 检查用户秒杀接口限流
* 检查用户限时活动接口限流
*
* @param userId 用户ID
*

View File

@@ -369,19 +369,19 @@ public class RedisService {
// ========== Lua脚本操作 ==========
/**
* 执行秒杀脚本
* 执行活动脚本
*/
public Long executeFlashSaleScript(String stockKey, int quantity) {
log.info("执行秒杀脚本: stockKey={}, quantity={}", stockKey, quantity);
log.info("执行活动脚本: stockKey={}, quantity={}", stockKey, quantity);
try {
Long result = stringRedisTemplate.execute(flashSaleScript, Collections.singletonList(stockKey),
String.valueOf(quantity));
log.info("秒杀脚本执行结果: result={}", result);
log.info("活动脚本执行结果: result={}", result);
return result;
} catch (Exception e) {
log.error("执行秒杀脚本异常: stockKey={}, quantity={}", stockKey, quantity, e);
log.error("执行活动脚本异常: stockKey={}, quantity={}", stockKey, quantity, e);
throw e;
}
}

View File

@@ -168,7 +168,7 @@ public class JSPFunctions {
}
/**
* 格式化秒杀状态
* 格式化限时活动状态
*
* @param status 状态码
*