Vue3 前端补充:秒杀和商品 API 类型定义及首页更新

- 添加 flashsale/product API 接口模块
- 添加 flashsale/product TypeScript 类型定义
- 更新首页组件
This commit is contained in:
2026-03-05 20:31:29 +08:00
parent 989c2741a2
commit 9ca235907f
5 changed files with 150 additions and 5 deletions

View File

@@ -0,0 +1,34 @@
import request from './request'
import type { FlashSale, FlashSaleParams } from '@/types/flashsale'
export const flashSaleApi = {
// 获取秒杀活动列表
getList(params?: FlashSaleParams) {
return request.get<any, { list: FlashSale[], total: number }>('/api/flashsales', { params })
},
// 获取秒杀活动详情
getDetail(id: number) {
return request.get<any, FlashSale>(`/api/flashsales/${id}`)
},
// 参与秒杀
participate(flashSaleId: number, quantity: number = 1) {
return request.post('/api/flashsales/participate', {
flashSaleId,
quantity
})
},
// 获取正在进行的秒杀活动
getActive() {
return request.get<any, FlashSale[]>('/api/flashsales/active')
},
// 获取即将开始的秒杀活动
getUpcoming() {
return request.get<any, FlashSale[]>('/api/flashsales/upcoming')
}
}
export default flashSaleApi

View File

@@ -0,0 +1,44 @@
import request from './request'
import type { Product, ProductParams } from '@/types/product'
export const productApi = {
// 获取商品列表
getList(params?: ProductParams) {
return request.get<any, { list: Product[], total: number }>('/api/products', { params })
},
// 获取商品详情
getDetail(id: number) {
return request.get<any, Product>(`/api/products/${id}`)
},
// 获取热门商品
getHot(limit: number = 8) {
return request.get<any, Product[]>('/api/products/hot', {
params: { limit }
})
},
// 获取推荐商品
getRecommended(limit: number = 8) {
return request.get<any, Product[]>('/api/products/recommended', {
params: { limit }
})
},
// 搜索商品
search(keyword: string) {
return request.get<any, Product[]>('/api/products/search', {
params: { keyword }
})
},
// 按分类获取商品
getByCategory(categoryId: number) {
return request.get<any, Product[]>('/api/products/category', {
params: { categoryId }
})
}
}
export default productApi

View File

@@ -117,7 +117,7 @@
<p class="text-gray-600">五种数据类型应用毫秒级响应</p>
</div>
<div class="feature-card">
<el-icon :size="40" class="text-orange-500 mb-4"><Speedometer /></el-icon>
<el-icon :size="40" class="text-orange-500 mb-4"><Odometer /></el-icon>
<h3 class="text-lg font-semibold mb-2">接口限流</h3>
<p class="text-gray-600">多种限流策略防止恶意刷单</p>
</div>
@@ -133,11 +133,12 @@ import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import FlashSaleCard from '@/components/business/FlashSaleCard.vue'
import ProductCard from '@/components/business/ProductCard.vue'
import { flashsaleApi } from '@/api/modules/flashsale'
import { productApi } from '@/api/modules/product'
import flashsaleApi from '@/api/flashsale'
import productApi from '@/api/product'
import { useCartStore } from '@/stores/cart'
import { useUserStore } from '@/stores/user'
import type { FlashSale, Product } from '@/types/api'
import type { FlashSale } from '@/types/flashsale'
import type { Product } from '@/types/product'
const router = useRouter()
const cartStore = useCartStore()
@@ -170,7 +171,7 @@ const banners = [
buttonText: '查看商品',
link: '/products',
bgColor: 'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)',
icon: 'Speedometer'
icon: 'Odometer'
}
]

View File

@@ -0,0 +1,29 @@
export interface FlashSale {
id: number
productId: number
productName: string
productImage: string
originalPrice: number
flashPrice: number
flashStock: number
soldCount: number
startTime: string
endTime: string
status: number // 0-未开始 1-进行中 2-已结束
description?: string
createdAt: string
updatedAt: string
}
export interface FlashSaleParams {
status?: number
keyword?: string
sort?: string
page?: number
size?: number
}
export interface FlashSaleParticipation {
flashSaleId: number
quantity: number
}

View File

@@ -0,0 +1,37 @@
export interface Product {
id: number
name: string
description: string
price: number
stock: number
image: string
category: string
categoryId: number
brand?: string
specifications?: Record<string, any>
sales: number
rating: number
reviewCount: number
status: number // 0-下架 1-上架
createdAt: string
updatedAt: string
}
export interface ProductParams {
categoryId?: number
keyword?: string
minPrice?: number
maxPrice?: number
sort?: string
page?: number
size?: number
}
export interface Category {
id: number
name: string
parentId?: number
icon?: string
sort: number
children?: Category[]
}