|
|
@@ -19,12 +19,68 @@ interface SelectedSpec {
|
|
|
stock: number
|
|
|
}
|
|
|
|
|
|
+interface Review {
|
|
|
+ id: number
|
|
|
+ userName: string
|
|
|
+ rating: number
|
|
|
+ content: string
|
|
|
+ createTime: string
|
|
|
+ images?: string[]
|
|
|
+}
|
|
|
+
|
|
|
+interface ReviewStats {
|
|
|
+ averageRating: number
|
|
|
+ totalCount: number
|
|
|
+ goodRate: number
|
|
|
+ ratingDistribution: {
|
|
|
+ [key: number]: number
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
export default function GoodsDetailPage() {
|
|
|
const [quantity, setQuantity] = useState(1)
|
|
|
const [selectedSpec, setSelectedSpec] = useState<SelectedSpec | null>(null)
|
|
|
const [showSpecModal, setShowSpecModal] = useState(false)
|
|
|
const { addToCart } = useCart()
|
|
|
|
|
|
+ // 模拟评价数据
|
|
|
+ const [reviewStats] = useState<ReviewStats>({
|
|
|
+ averageRating: 4.8,
|
|
|
+ totalCount: 156,
|
|
|
+ goodRate: 0.95,
|
|
|
+ ratingDistribution: {
|
|
|
+ 5: 120,
|
|
|
+ 4: 25,
|
|
|
+ 3: 8,
|
|
|
+ 2: 2,
|
|
|
+ 1: 1
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ const [reviews] = useState<Review[]>([
|
|
|
+ {
|
|
|
+ id: 1,
|
|
|
+ userName: '用户****1234',
|
|
|
+ rating: 5,
|
|
|
+ content: '商品质量很好,物流很快,非常满意!包装也很精美,下次还会再来购买。',
|
|
|
+ createTime: '2025-11-20'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 2,
|
|
|
+ userName: '用户****5678',
|
|
|
+ rating: 4,
|
|
|
+ content: '商品不错,性价比很高,就是物流稍微慢了一点,总体还是很满意的。',
|
|
|
+ createTime: '2025-11-19'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 3,
|
|
|
+ userName: '用户****9012',
|
|
|
+ rating: 5,
|
|
|
+ content: '非常喜欢这个商品,质量超出预期,客服态度也很好,五星好评!',
|
|
|
+ createTime: '2025-11-18'
|
|
|
+ }
|
|
|
+ ])
|
|
|
+
|
|
|
// 获取商品ID
|
|
|
const params = Taro.getCurrentInstance().router?.params
|
|
|
const goodsId = params?.id ? parseInt(params.id) : 0
|
|
|
@@ -212,24 +268,33 @@ export default function GoodsDetailPage() {
|
|
|
|
|
|
<View className="review-stats">
|
|
|
<View className="rating-overview">
|
|
|
- <Text className="rating-score">4.8</Text>
|
|
|
+ <Text className="rating-score">{reviewStats.averageRating.toFixed(1)}</Text>
|
|
|
<Text className="rating-text">分</Text>
|
|
|
</View>
|
|
|
<View className="rating-details">
|
|
|
- <Text className="rating-count">999+ 条评价</Text>
|
|
|
- <Text className="rating-percent">99% 好评</Text>
|
|
|
+ <Text className="rating-count">{reviewStats.totalCount} 条评价</Text>
|
|
|
+ <Text className="rating-percent">{Math.round(reviewStats.goodRate * 100)}% 好评</Text>
|
|
|
</View>
|
|
|
</View>
|
|
|
|
|
|
- {/* 评价列表(模拟数据) */}
|
|
|
+ {/* 评价列表 */}
|
|
|
<View className="review-list">
|
|
|
- <View className="review-item">
|
|
|
- <View className="review-user">
|
|
|
- <Text className="user-name">用户****</Text>
|
|
|
- <Text className="review-time">2025-11-21</Text>
|
|
|
+ {reviews.map(review => (
|
|
|
+ <View key={review.id} className="review-item">
|
|
|
+ <View className="review-user">
|
|
|
+ <Text className="user-name">{review.userName}</Text>
|
|
|
+ <View className="review-rating">
|
|
|
+ {Array.from({ length: 5 }, (_, i) => (
|
|
|
+ <Text key={i} className={`star ${i < review.rating ? 'active' : ''}`}>
|
|
|
+ ★
|
|
|
+ </Text>
|
|
|
+ ))}
|
|
|
+ </View>
|
|
|
+ <Text className="review-time">{review.createTime}</Text>
|
|
|
+ </View>
|
|
|
+ <Text className="review-content">{review.content}</Text>
|
|
|
</View>
|
|
|
- <Text className="review-content">商品质量很好,物流很快,非常满意!</Text>
|
|
|
- </View>
|
|
|
+ ))}
|
|
|
</View>
|
|
|
</View>
|
|
|
|
|
|
@@ -240,8 +305,11 @@ export default function GoodsDetailPage() {
|
|
|
<RichText
|
|
|
className="detail-content"
|
|
|
nodes={goods.detail
|
|
|
- .replace(/<img/g, '<img style="max-width:100%;height:auto"')
|
|
|
- .replace(/<p>/g, '<p style="margin:10px 0">')
|
|
|
+ .replace(/<img/g, '<img style="max-width:100%;height:auto;display:block;margin:0 auto"')
|
|
|
+ .replace(/<p>/g, '<p style="margin:10px 0;line-height:1.6"')
|
|
|
+ .replace(/<h1>/g, '<h1 style="font-size:32rpx;font-weight:bold;margin:20rpx 0"')
|
|
|
+ .replace(/<h2>/g, '<h2 style="font-size:30rpx;font-weight:bold;margin:18rpx 0"')
|
|
|
+ .replace(/<h3>/g, '<h3 style="font-size:28rpx;font-weight:bold;margin:16rpx 0"')
|
|
|
}
|
|
|
/>
|
|
|
) : (
|