|
|
@@ -8,18 +8,19 @@ import { Navbar } from '@/components/ui/navbar'
|
|
|
import { Button } from '@/components/ui/button'
|
|
|
import { Carousel } from '@/components/ui/carousel'
|
|
|
// 规格选择功能暂时移除,后端暂无规格API
|
|
|
-// import { GoodsSpecSelector } from '@/components/goods-spec-selector'
|
|
|
+import { GoodsSpecSelector } from '@/components/goods-spec-selector'
|
|
|
import { useCart } from '@/contexts/CartContext'
|
|
|
import './index.css'
|
|
|
|
|
|
// type GoodsResponse = InferResponseType<typeof goodsClient[':id']['$get'], 200>
|
|
|
|
|
|
// 规格选择功能暂时移除,后端暂无规格API
|
|
|
-// interface SelectedSpec {
|
|
|
-// name: string
|
|
|
-// price: number
|
|
|
-// stock: number
|
|
|
-// }
|
|
|
+interface SelectedSpec {
|
|
|
+ id: number
|
|
|
+ name: string
|
|
|
+ price: number
|
|
|
+ stock: number
|
|
|
+}
|
|
|
|
|
|
interface Review {
|
|
|
id: number
|
|
|
@@ -42,8 +43,8 @@ interface ReviewStats {
|
|
|
export default function GoodsDetailPage() {
|
|
|
const [quantity, setQuantity] = useState(1)
|
|
|
// 规格选择功能暂时移除,后端暂无规格API
|
|
|
- // const [selectedSpec, setSelectedSpec] = useState<SelectedSpec | null>(null)
|
|
|
- // const [showSpecModal, setShowSpecModal] = useState(false)
|
|
|
+ const [selectedSpec, setSelectedSpec] = useState<SelectedSpec | null>(null)
|
|
|
+ const [showSpecModal, setShowSpecModal] = useState(false)
|
|
|
const { addToCart } = useCart()
|
|
|
|
|
|
// 模拟评价数据
|
|
|
@@ -230,16 +231,34 @@ export default function GoodsDetailPage() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // 规格选择确认
|
|
|
+ const handleSpecConfirm = (spec: SelectedSpec | null, qty: number) => {
|
|
|
+ if (spec) {
|
|
|
+ setSelectedSpec(spec)
|
|
|
+ setQuantity(qty)
|
|
|
+ }
|
|
|
+ setShowSpecModal(false)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 打开规格选择弹窗
|
|
|
+ const handleOpenSpecModal = () => {
|
|
|
+ setShowSpecModal(true)
|
|
|
+ }
|
|
|
+
|
|
|
// 添加到购物车
|
|
|
const handleAddToCart = () => {
|
|
|
if (!goods) return
|
|
|
|
|
|
- const currentPrice = goods.price
|
|
|
- const currentStock = goods.stock
|
|
|
+ // 如果有选中的规格,使用规格信息;否则使用父商品信息
|
|
|
+ const targetGoodsId = selectedSpec ? selectedSpec.id : goods.id
|
|
|
+ const targetGoodsName = selectedSpec ? selectedSpec.name : goods.name
|
|
|
+ const targetPrice = selectedSpec ? selectedSpec.price : goods.price
|
|
|
+ const targetStock = selectedSpec ? selectedSpec.stock : goods.stock
|
|
|
+ const targetSpec = selectedSpec ? selectedSpec.name : ''
|
|
|
|
|
|
const finalQuantity = quantity === 0 ? 1 : quantity
|
|
|
|
|
|
- if (finalQuantity > currentStock) {
|
|
|
+ if (finalQuantity > targetStock) {
|
|
|
Taro.showToast({
|
|
|
title: '库存不足',
|
|
|
icon: 'none'
|
|
|
@@ -248,13 +267,13 @@ export default function GoodsDetailPage() {
|
|
|
}
|
|
|
|
|
|
addToCart({
|
|
|
- id: goods.id,
|
|
|
- name: goods.name,
|
|
|
- price: currentPrice,
|
|
|
+ id: targetGoodsId,
|
|
|
+ name: targetGoodsName,
|
|
|
+ price: targetPrice,
|
|
|
image: goods.imageFile?.fullUrl || '',
|
|
|
- stock: currentStock,
|
|
|
+ stock: targetStock,
|
|
|
quantity: finalQuantity,
|
|
|
- spec: ''
|
|
|
+ spec: targetSpec
|
|
|
})
|
|
|
|
|
|
Taro.showToast({
|
|
|
@@ -267,11 +286,15 @@ export default function GoodsDetailPage() {
|
|
|
const handleBuyNow = () => {
|
|
|
if (!goods) return
|
|
|
|
|
|
- const currentPrice = goods.price
|
|
|
- const currentStock = goods.stock
|
|
|
+ // 如果有选中的规格,使用规格信息;否则使用父商品信息
|
|
|
+ const targetGoodsId = selectedSpec ? selectedSpec.id : goods.id
|
|
|
+ const targetGoodsName = selectedSpec ? selectedSpec.name : goods.name
|
|
|
+ const targetPrice = selectedSpec ? selectedSpec.price : goods.price
|
|
|
+ const targetStock = selectedSpec ? selectedSpec.stock : goods.stock
|
|
|
+ const targetSpec = selectedSpec ? selectedSpec.name : ''
|
|
|
const finalQuantity = quantity === 0 ? 1 : quantity
|
|
|
|
|
|
- if (finalQuantity > currentStock) {
|
|
|
+ if (finalQuantity > targetStock) {
|
|
|
Taro.showToast({
|
|
|
title: '库存不足',
|
|
|
icon: 'none'
|
|
|
@@ -285,14 +308,14 @@ export default function GoodsDetailPage() {
|
|
|
// 将商品信息存入临时存储,跳转到订单确认页
|
|
|
Taro.setStorageSync('buyNow', {
|
|
|
goods: {
|
|
|
- id: goods.id,
|
|
|
- name: goods.name,
|
|
|
- price: currentPrice,
|
|
|
+ id: targetGoodsId,
|
|
|
+ name: targetGoodsName,
|
|
|
+ price: targetPrice,
|
|
|
image: goods.imageFile?.fullUrl || '',
|
|
|
quantity: finalQuantity,
|
|
|
- spec: ''
|
|
|
+ spec: targetSpec
|
|
|
},
|
|
|
- totalAmount: currentPrice * finalQuantity
|
|
|
+ totalAmount: targetPrice * finalQuantity
|
|
|
})
|
|
|
|
|
|
// const buyNowData = Taro.getStorageSync('buyNow')
|
|
|
@@ -375,7 +398,24 @@ export default function GoodsDetailPage() {
|
|
|
<Text className="goods-title">{goods.name}</Text>
|
|
|
<Text className="goods-description">{goods.instructions || '暂无商品描述'}</Text>
|
|
|
|
|
|
- {/* 规格选择区域 - 暂时移除,后端暂无规格API */}
|
|
|
+ {/* 规格选择区域 */}
|
|
|
+ <View className="spec-selection-section">
|
|
|
+ <Text className="spec-label">规格</Text>
|
|
|
+ <Button
|
|
|
+ size="sm"
|
|
|
+ variant="outline"
|
|
|
+ className="spec-select-btn"
|
|
|
+ onClick={handleOpenSpecModal}
|
|
|
+ >
|
|
|
+ {selectedSpec ? selectedSpec.name : '选择规格'}
|
|
|
+ </Button>
|
|
|
+ {selectedSpec && (
|
|
|
+ <View className="selected-spec-info">
|
|
|
+ <Text className="spec-price">¥{selectedSpec.price.toFixed(2)}</Text>
|
|
|
+ <Text className="spec-stock">库存: {selectedSpec.stock}</Text>
|
|
|
+ </View>
|
|
|
+ )}
|
|
|
+ </View>
|
|
|
</View>
|
|
|
|
|
|
{/* 商品评价区域 - 暂时移除,后端暂无评价API */}
|
|
|
@@ -452,7 +492,15 @@ export default function GoodsDetailPage() {
|
|
|
</View>
|
|
|
</View>
|
|
|
|
|
|
- {/* 规格选择弹窗 - 暂时移除,后端暂无规格API */}
|
|
|
+ {/* 规格选择弹窗 */}
|
|
|
+ <GoodsSpecSelector
|
|
|
+ visible={showSpecModal}
|
|
|
+ onClose={() => setShowSpecModal(false)}
|
|
|
+ onConfirm={handleSpecConfirm}
|
|
|
+ parentGoodsId={goods?.id || 0}
|
|
|
+ currentSpec={selectedSpec?.name}
|
|
|
+ currentQuantity={quantity}
|
|
|
+ />
|
|
|
</View>
|
|
|
)
|
|
|
}
|