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>
This commit is contained in:
@@ -6,6 +6,7 @@ const flashSaleStatusToCode = (status?: string) => {
|
|||||||
if (status === 'UPCOMING') return 1
|
if (status === 'UPCOMING') return 1
|
||||||
if (status === 'ACTIVE') return 2
|
if (status === 'ACTIVE') return 2
|
||||||
if (status === 'ENDED') return 3
|
if (status === 'ENDED') return 3
|
||||||
|
if (status === 'PAUSED') return 4
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ const statusType = computed(() => {
|
|||||||
case 'UPCOMING': return 'warning'
|
case 'UPCOMING': return 'warning'
|
||||||
case 'ACTIVE': return 'danger'
|
case 'ACTIVE': return 'danger'
|
||||||
case 'ENDED': return 'info'
|
case 'ENDED': return 'info'
|
||||||
|
case 'PAUSED': return 'warning'
|
||||||
default: return 'info'
|
default: return 'info'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -70,6 +71,7 @@ const statusText = computed(() => {
|
|||||||
case 'UPCOMING': return '即将开始'
|
case 'UPCOMING': return '即将开始'
|
||||||
case 'ACTIVE': return '秒杀中'
|
case 'ACTIVE': return '秒杀中'
|
||||||
case 'ENDED': return '已结束'
|
case 'ENDED': return '已结束'
|
||||||
|
case 'PAUSED': return '已暂停'
|
||||||
default: return '未知'
|
default: return '未知'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -43,6 +43,7 @@
|
|||||||
<el-select v-model="query.status" clearable placeholder="全部状态" @change="handleSearch">
|
<el-select v-model="query.status" clearable placeholder="全部状态" @change="handleSearch">
|
||||||
<el-option label="即将开始" value="UPCOMING" />
|
<el-option label="即将开始" value="UPCOMING" />
|
||||||
<el-option label="进行中" value="ACTIVE" />
|
<el-option label="进行中" value="ACTIVE" />
|
||||||
|
<el-option label="已暂停" value="PAUSED" />
|
||||||
<el-option label="已结束" value="ENDED" />
|
<el-option label="已结束" value="ENDED" />
|
||||||
</el-select>
|
</el-select>
|
||||||
<el-button type="primary" @click="handleSearch">搜索</el-button>
|
<el-button type="primary" @click="handleSearch">搜索</el-button>
|
||||||
@@ -88,8 +89,8 @@
|
|||||||
<el-button text type="primary" @click="openEditDialog(row)">编辑</el-button>
|
<el-button text type="primary" @click="openEditDialog(row)">编辑</el-button>
|
||||||
<el-button v-if="row.status === 'UPCOMING'" text type="success" @click="changeStatus('publish', row)">发布</el-button>
|
<el-button v-if="row.status === 'UPCOMING'" text type="success" @click="changeStatus('publish', row)">发布</el-button>
|
||||||
<el-button v-if="row.status === 'ACTIVE'" text type="warning" @click="changeStatus('pause', row)">暂停</el-button>
|
<el-button v-if="row.status === 'ACTIVE'" text type="warning" @click="changeStatus('pause', row)">暂停</el-button>
|
||||||
<el-button v-if="row.status === 'ENDED'" text type="success" @click="changeStatus('resume', row)">恢复</el-button>
|
<el-button v-if="row.status === 'PAUSED'" text type="success" @click="changeStatus('resume', row)">恢复</el-button>
|
||||||
<el-button v-if="row.status !== 'ENDED'" text type="danger" @click="changeStatus('end', row)">结束</el-button>
|
<el-button v-if="row.status === 'ACTIVE' || row.status === 'PAUSED'" text type="danger" @click="changeStatus('end', row)">结束</el-button>
|
||||||
<el-button text type="danger" @click="removeFlashSale(row)">删除</el-button>
|
<el-button text type="danger" @click="removeFlashSale(row)">删除</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@@ -253,6 +254,7 @@ const getStatusText = (status: string) => {
|
|||||||
const map: Record<string, string> = {
|
const map: Record<string, string> = {
|
||||||
UPCOMING: '即将开始',
|
UPCOMING: '即将开始',
|
||||||
ACTIVE: '进行中',
|
ACTIVE: '进行中',
|
||||||
|
PAUSED: '已暂停',
|
||||||
ENDED: '已结束',
|
ENDED: '已结束',
|
||||||
}
|
}
|
||||||
return map[status] || status
|
return map[status] || status
|
||||||
@@ -262,6 +264,7 @@ const getStatusType = (status: string) => {
|
|||||||
const map: Record<string, string> = {
|
const map: Record<string, string> = {
|
||||||
UPCOMING: 'warning',
|
UPCOMING: 'warning',
|
||||||
ACTIVE: 'danger',
|
ACTIVE: 'danger',
|
||||||
|
PAUSED: 'warning',
|
||||||
ENDED: 'info',
|
ENDED: 'info',
|
||||||
}
|
}
|
||||||
return map[status] || 'info'
|
return map[status] || 'info'
|
||||||
|
|||||||
2
flash-sale-frontend/src/types/api.d.ts
vendored
2
flash-sale-frontend/src/types/api.d.ts
vendored
@@ -83,7 +83,7 @@ export interface FlashSale {
|
|||||||
remainingStock: number
|
remainingStock: number
|
||||||
startTime: string
|
startTime: string
|
||||||
endTime: string
|
endTime: string
|
||||||
status: 'UPCOMING' | 'ACTIVE' | 'ENDED'
|
status: 'UPCOMING' | 'ACTIVE' | 'ENDED' | 'PAUSED'
|
||||||
limitPerUser: number
|
limitPerUser: number
|
||||||
description?: string
|
description?: string
|
||||||
createdAt: string
|
createdAt: string
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ export const mapFlashSaleStatus = (status: number | string): FlashSale['status']
|
|||||||
if (value === 'UPCOMING' || value === 1) return 'UPCOMING'
|
if (value === 'UPCOMING' || value === 1) return 'UPCOMING'
|
||||||
if (value === 'ACTIVE' || value === 2) return 'ACTIVE'
|
if (value === 'ACTIVE' || value === 2) return 'ACTIVE'
|
||||||
if (value === 'ENDED' || value === 3) return 'ENDED'
|
if (value === 'ENDED' || value === 3) return 'ENDED'
|
||||||
|
if (value === 'PAUSED' || value === 4) return 'PAUSED'
|
||||||
return 'UPCOMING'
|
return 'UPCOMING'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -71,6 +71,11 @@ public interface FlashSaleRepository extends JpaRepository<FlashSale, Long> {
|
|||||||
@Query("SELECT f FROM FlashSale f WHERE f.endTime <= :now OR f.status = 3")
|
@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> findEndedFlashSales(@Param("now") LocalDateTime now, Pageable pageable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按状态分页查找秒杀活动
|
||||||
|
*/
|
||||||
|
Page<FlashSale> findByStatus(Integer status, Pageable pageable);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新秒杀库存
|
* 更新秒杀库存
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -326,19 +326,7 @@ public class FlashSaleService {
|
|||||||
} else {
|
} else {
|
||||||
// 根据状态查询
|
// 根据状态查询
|
||||||
if (queryDTO.getStatus() != null) {
|
if (queryDTO.getStatus() != null) {
|
||||||
switch (queryDTO.getStatus()) {
|
flashSalePage = flashSaleRepository.findByStatus(queryDTO.getStatus(), pageable);
|
||||||
case 1: // 未开始
|
|
||||||
flashSalePage = flashSaleRepository.findUpcomingFlashSales(now, pageable);
|
|
||||||
break;
|
|
||||||
case 2: // 进行中
|
|
||||||
flashSalePage = flashSaleRepository.findActiveFlashSales(now, pageable);
|
|
||||||
break;
|
|
||||||
case 3: // 已结束
|
|
||||||
flashSalePage = flashSaleRepository.findEndedFlashSales(now, pageable);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
flashSalePage = flashSaleRepository.findAll(pageable);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
flashSalePage = flashSaleRepository.findAll(pageable);
|
flashSalePage = flashSaleRepository.findAll(pageable);
|
||||||
}
|
}
|
||||||
@@ -753,10 +741,16 @@ public class FlashSaleService {
|
|||||||
|
|
||||||
FlashSale flashSale = flashSaleOpt.get();
|
FlashSale flashSale = flashSaleOpt.get();
|
||||||
|
|
||||||
|
// 更新状态为进行中 (status = 2)
|
||||||
|
flashSaleRepository.updateStatus(flashSaleId, 2);
|
||||||
|
flashSale.setStatus(2);
|
||||||
|
|
||||||
// 预热缓存
|
// 预热缓存
|
||||||
preloadFlashSale(flashSaleId);
|
preloadFlashSale(flashSaleId);
|
||||||
|
|
||||||
|
// 更新缓存
|
||||||
Product product = productRepository.findById(flashSale.getProductId()).orElse(null);
|
Product product = productRepository.findById(flashSale.getProductId()).orElse(null);
|
||||||
|
cacheFlashSaleInfo(flashSale, product);
|
||||||
|
|
||||||
log.info("秒杀活动发布成功: ID={}", flashSaleId);
|
log.info("秒杀活动发布成功: ID={}", flashSaleId);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user