Files
FlashSaleSystem/flash-sale-frontend/src/api/modules/flashsale.ts
YoVinchen 0f67f6cc49 fix: 修复秒杀活动发布后状态未更新的问题
根因:publishFlashSale() 只做了缓存预热,从未调用 updateStatus()
将状态从1(未开始)更新为2(进行中),导致发布后UI无变化,
且活动无法被"进行中"查询找到。

修复内容:
- publishFlashSale() 添加 updateStatus(id, 2) 和缓存更新
- 简化 getFlashSaleList 状态查询,直接按 status 字段过滤
- 新增 findByStatus 仓库方法
- 前后端全面支持 PAUSED(status=4) 状态
- 修复管理后台"恢复"按钮错误显示在"已结束"状态上

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 17:46:43 +08:00

165 lines
5.1 KiB
TypeScript

import { request } from '../request'
import type { ApiResponse, FlashSale, PageParams, PageResponse } from '@/types/api'
import { mapOrderStatus, normalizeFlashSale, normalizePage } from '@/utils/normalizers'
const flashSaleStatusToCode = (status?: string) => {
if (status === 'UPCOMING') return 1
if (status === 'ACTIVE') return 2
if (status === 'ENDED') return 3
if (status === 'PAUSED') return 4
return undefined
}
const flashSaleSortField = (sort?: string) => {
if (sort === 'flashPrice') return 'flashPrice'
if (sort === 'endTime') return 'endTime'
return 'startTime'
}
export const flashsaleApi = {
// 获取秒杀活动统计信息(即将开始/正在进行/我的参与/抢购成功)
getStatistics(): Promise<ApiResponse<{ upcoming: number; active: number; participated: number; success: number }>> {
return request.get('/api/flashsale/statistics')
},
// 获取秒杀活动列表
getList(params?: PageParams & { status?: string }): Promise<ApiResponse<PageResponse<FlashSale>>> {
return request.post<ApiResponse<Record<string, any>>>('/api/flashsale/list', {
status: flashSaleStatusToCode(params?.status),
page: params?.page ?? 0,
size: params?.size ?? 10,
sortBy: flashSaleSortField(params?.sort),
sortDirection: params?.order || 'asc',
}).then((res) => ({
...res,
data: normalizePage(res.data, normalizeFlashSale),
}))
},
// 获取正在进行的秒杀活动
getActive(limit?: number): Promise<ApiResponse<FlashSale[]>> {
return request.get<ApiResponse<any[]>>('/api/flashsale/active').then((res) => ({
...res,
data: (Array.isArray(res.data) ? res.data : [])
.map((item) => normalizeFlashSale(item))
.slice(0, limit ?? Number.MAX_SAFE_INTEGER),
}))
},
// 获取秒杀活动详情
getDetail(id: number): Promise<ApiResponse<FlashSale>> {
return request.get<ApiResponse<any>>(`/api/flashsale/${id}`).then((res) => ({
...res,
data: normalizeFlashSale(res.data),
}))
},
// 参与秒杀
participate(data: {
flashSaleId: number;
quantity: number;
timestamp?: number;
}): Promise<ApiResponse<{ orderId: number }>> {
return request.post<ApiResponse<any>>('/api/flashsale/participate', data).then((res) => ({
...res,
data: {
orderId: Number(res.data?.orderId || res.data?.id || 0),
},
}))
},
// 获取用户参与记录
getUserRecords(): Promise<ApiResponse<any[]>> {
return request.post<ApiResponse<Record<string, any>>>('/api/order/my-orders', {
orderType: 2,
page: 0,
size: 100,
sortBy: 'createdAt',
sortDirection: 'desc',
}).then((res) => {
const content = Array.isArray(res.data?.content) ? res.data.content : []
return {
...res,
data: content.map((item: Record<string, any>) => ({
id: item.id,
success: mapOrderStatus(item.status) !== 'CANCELLED',
status: item.status,
})),
}
})
},
// 检查用户是否可以参与
checkEligibility(flashSaleId: number): Promise<ApiResponse<{
eligible: boolean;
reason?: string;
remainingQuota?: number;
}>> {
return this.getDetail(flashSaleId).then((res) => {
const eligible = res.data.status === 'ACTIVE' && res.data.remainingStock > 0
return {
code: 0,
success: true,
message: '检查成功',
data: {
eligible,
reason: eligible ? '' : '活动未开始、已结束或库存不足',
remainingQuota: res.data.limitPerUser,
},
}
})
},
create(data: {
productId: number
flashPrice: number
flashStock: number
startTime: string
endTime: string
}): Promise<ApiResponse<FlashSale>> {
return request.post<ApiResponse<any>>('/api/flashsale/create', data).then((res) => ({
...res,
data: normalizeFlashSale(res.data),
}))
},
update(id: number, data: Record<string, unknown>): Promise<ApiResponse<FlashSale>> {
return request.put<ApiResponse<any>>(`/api/flashsale/${id}`, data).then((res) => ({
...res,
data: normalizeFlashSale(res.data),
}))
},
delete(id: number): Promise<ApiResponse> {
return request.delete(`/api/flashsale/${id}`)
},
publish(id: number): Promise<ApiResponse<FlashSale>> {
return request.post<ApiResponse<any>>(`/api/flashsale/${id}/publish`).then((res) => ({
...res,
data: normalizeFlashSale(res.data),
}))
},
pause(id: number): Promise<ApiResponse<FlashSale>> {
return request.post<ApiResponse<any>>(`/api/flashsale/${id}/pause`).then((res) => ({
...res,
data: normalizeFlashSale(res.data),
}))
},
resume(id: number): Promise<ApiResponse<FlashSale>> {
return request.post<ApiResponse<any>>(`/api/flashsale/${id}/resume`).then((res) => ({
...res,
data: normalizeFlashSale(res.data),
}))
},
end(id: number): Promise<ApiResponse<FlashSale>> {
return request.post<ApiResponse<any>>(`/api/flashsale/${id}/end`).then((res) => ({
...res,
data: normalizeFlashSale(res.data),
}))
},
}