forked from gxwebsoft/mp-10550
feat(config): 新增网站配置字段和自定义Hook
- 在cmsWebsiteField模型中新增deliveryText、guaranteeText和openComments三个字段 - 创建useConfig自定义Hook用于获取和管理网站配置数据 - 更新Banner组件中的默认轮播图高度从200px调整为300px- 修改Banner组件中热门商品列表项的右边距样式 - 在ArticleList组件中为map函数添加类型注解 - 移除IsDealer组件中旧的配置获取逻辑,改用新的useConfig Hook - 删除src/pages/user_bak目录下的所有旧版用户相关组件文件 - 删除src/pages/user_bak目录下的配置文件和样式文件
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import {useEffect, useState} from "react";
|
||||
import {Image, Divider, Badge} from "@nutui/nutui-react-taro";
|
||||
import {ArrowLeft, Headphones, Share, Cart} from "@nutui/icons-react-taro";
|
||||
import {Image, Badge, Popup, CellGroup, Cell} from "@nutui/nutui-react-taro";
|
||||
import {ArrowLeft, Headphones, Share, Cart, ArrowRight} from "@nutui/icons-react-taro";
|
||||
import Taro, {useShareAppMessage} from "@tarojs/taro";
|
||||
import {RichText, View} from '@tarojs/components'
|
||||
import {RichText, View, Text} from '@tarojs/components'
|
||||
import {ShopGoods} from "@/api/shop/shopGoods/model";
|
||||
import {getShopGoods} from "@/api/shop/shopGoods";
|
||||
import {listShopGoodsSpec} from "@/api/shop/shopGoodsSpec";
|
||||
@@ -14,21 +14,30 @@ import navTo, {wxParse} from "@/utils/common";
|
||||
import SpecSelector from "@/components/SpecSelector";
|
||||
import "./index.scss";
|
||||
import {useCart} from "@/hooks/useCart";
|
||||
import {useConfig} from "@/hooks/useConfig";
|
||||
|
||||
const GoodsDetail = () => {
|
||||
const [statusBarHeight, setStatusBarHeight] = useState<number>(44);
|
||||
const [windowWidth, setWindowWidth] = useState<number>(390)
|
||||
const [goods, setGoods] = useState<ShopGoods | null>(null);
|
||||
const [files, setFiles] = useState<any[]>([]);
|
||||
const [specs, setSpecs] = useState<ShopGoodsSpec[]>([]);
|
||||
const [skus, setSkus] = useState<ShopGoodsSku[]>([]);
|
||||
const [showSpecSelector, setShowSpecSelector] = useState(false);
|
||||
const [specAction, setSpecAction] = useState<'cart' | 'buy'>('cart');
|
||||
const [showBottom, setShowBottom] = useState(false)
|
||||
const [bottomItem, setBottomItem] = useState<any>({
|
||||
title: '',
|
||||
content: ''
|
||||
})
|
||||
// const [selectedSku, setSelectedSku] = useState<ShopGoodsSku | null>(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const router = Taro.getCurrentInstance().router;
|
||||
const goodsId = router?.params?.id;
|
||||
|
||||
// 使用购物车Hook
|
||||
const {cartCount, addToCart} = useCart();
|
||||
const {cartCount, addToCart} = useCart()
|
||||
const {config} = useConfig()
|
||||
|
||||
// 处理加入购物车
|
||||
const handleAddToCart = () => {
|
||||
@@ -117,7 +126,21 @@ const GoodsDetail = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const openBottom = (title: string, content: string) => {
|
||||
setBottomItem({
|
||||
title,
|
||||
content
|
||||
})
|
||||
setShowBottom(true)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
Taro.getSystemInfo({
|
||||
success: (res) => {
|
||||
setWindowWidth(res.windowWidth)
|
||||
setStatusBarHeight(Number(res.statusBarHeight) + 5)
|
||||
},
|
||||
});
|
||||
if (goodsId) {
|
||||
setLoading(true);
|
||||
|
||||
@@ -187,12 +210,12 @@ const GoodsDetail = () => {
|
||||
});
|
||||
|
||||
if (!goods || loading) {
|
||||
return <div>加载中...</div>;
|
||||
return <View>加载中...</View>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={"py-0"}>
|
||||
<div
|
||||
<View className={"py-0"}>
|
||||
<View
|
||||
className={
|
||||
"fixed z-10 bg-white flex justify-center items-center font-bold shadow-sm opacity-70"
|
||||
}
|
||||
@@ -200,36 +223,36 @@ const GoodsDetail = () => {
|
||||
borderRadius: "100%",
|
||||
width: "32px",
|
||||
height: "32px",
|
||||
top: "50px",
|
||||
top: statusBarHeight + 'px',
|
||||
left: "10px",
|
||||
}}
|
||||
onClick={() => Taro.navigateBack()}
|
||||
>
|
||||
<ArrowLeft size={14}/>
|
||||
</div>
|
||||
<div className={
|
||||
</View>
|
||||
<View className={
|
||||
"fixed z-10 bg-white flex justify-center items-center font-bold shadow-sm opacity-90"
|
||||
}
|
||||
style={{
|
||||
borderRadius: "100%",
|
||||
width: "32px",
|
||||
height: "32px",
|
||||
top: "50px",
|
||||
right: "110px",
|
||||
}}
|
||||
onClick={() => Taro.switchTab({url: `/pages/cart/cart`})}>
|
||||
style={{
|
||||
borderRadius: "100%",
|
||||
width: "32px",
|
||||
height: "32px",
|
||||
top: statusBarHeight + 'px',
|
||||
right: "110px",
|
||||
}}
|
||||
onClick={() => Taro.switchTab({url: `/pages/cart/cart`})}>
|
||||
<Badge value={cartCount} top="-2" right="2">
|
||||
<div style={{display: 'flex', alignItems: 'center'}}>
|
||||
<View style={{display: 'flex', alignItems: 'center'}}>
|
||||
<Cart size={16}/>
|
||||
</div>
|
||||
</View>
|
||||
</Badge>
|
||||
</div>
|
||||
</View>
|
||||
{
|
||||
files.length > 0 && (
|
||||
<Swiper defaultValue={0} indicator height={'350px'}>
|
||||
<Swiper defaultValue={0} indicator height={windowWidth}>
|
||||
{files.map((item) => (
|
||||
<Swiper.Item key={item}>
|
||||
<Image width="100%" height={'100%'} src={item.url} mode={'scaleToFill'} lazyLoad={false}/>
|
||||
<Image width={windowWidth} height={windowWidth} src={item.url} mode={'scaleToFill'} lazyLoad={false}/>
|
||||
</Swiper.Item>
|
||||
))}
|
||||
</Swiper>
|
||||
@@ -245,69 +268,116 @@ const GoodsDetail = () => {
|
||||
/>
|
||||
)
|
||||
}
|
||||
<div
|
||||
className={"flex flex-col justify-between items-center rounded-lg px-2"}
|
||||
<View
|
||||
className={"flex flex-col justify-between items-center"}
|
||||
>
|
||||
<div
|
||||
<View
|
||||
className={
|
||||
"flex flex-col rounded-lg bg-white shadow-sm w-full mt-2"
|
||||
"flex flex-col bg-white w-full"
|
||||
}
|
||||
>
|
||||
<div className={"flex flex-col p-2 rounded-lg"}>
|
||||
<View className={"flex flex-col p-3 rounded-lg"}>
|
||||
<>
|
||||
<div className={'flex justify-between'}>
|
||||
<div className={'flex text-red-500 text-xl items-baseline'}>
|
||||
<View className={'flex justify-between'}>
|
||||
<View className={'flex text-red-500 text-xl items-baseline'}>
|
||||
<span className={'text-xs'}>¥</span>
|
||||
<span className={'font-bold text-2xl'}>{goods.price}</span>
|
||||
</div>
|
||||
</View>
|
||||
<span className={"text-gray-400 text-xs"}>已售 {goods.sales}</span>
|
||||
</div>
|
||||
<div className={'flex justify-between items-center'}>
|
||||
<div className={'goods-info'}>
|
||||
<div className={"car-no text-lg"}>
|
||||
</View>
|
||||
<View className={'flex justify-between items-center'}>
|
||||
<View className={'goods-info'}>
|
||||
<View className={"car-no text-lg"}>
|
||||
{goods.name}
|
||||
</div>
|
||||
<div className={"flex justify-between text-xs py-1"}>
|
||||
</View>
|
||||
<View className={"flex justify-between text-xs py-1"}>
|
||||
<span className={"text-orange-500"}>
|
||||
{goods.comments}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</View>
|
||||
</View>
|
||||
<View>
|
||||
<button
|
||||
className={'flex flex-col justify-center items-center text-gray-500 px-1 gap-1 text-nowrap whitespace-nowrap'}
|
||||
open-type="share"><Share
|
||||
size={20}/>
|
||||
className={'flex flex-col justify-center items-center bg-white text-gray-500 px-1 gap-1 text-nowrap whitespace-nowrap'}
|
||||
open-type="share">
|
||||
<Share size={20}/>
|
||||
<span className={'text-xs'}>分享</span>
|
||||
</button>
|
||||
</View>
|
||||
</div>
|
||||
</View>
|
||||
</>
|
||||
</div>
|
||||
</div>
|
||||
<div className={"mt-2 py-2"}>
|
||||
<Divider>商品详情</Divider>
|
||||
</View>
|
||||
</View>
|
||||
<View className={'w-full'}>
|
||||
{
|
||||
config?.deliveryText && (
|
||||
<CellGroup>
|
||||
<Cell title={'配送'} extra={
|
||||
<View className="flex items-center">
|
||||
<Text className={'truncate max-w-56 inline-block'}>{config?.deliveryText || '14:30下单,明天配送'}</Text>
|
||||
<ArrowRight color="#cccccc" size={15}/>
|
||||
</View>
|
||||
} onClick={() => openBottom('配送', `${config?.deliveryText}`)}/>
|
||||
<Cell title={'保障'} extra={
|
||||
<View className="flex items-center">
|
||||
<Text className={'truncate max-w-56 inline-block'}>{config?.guaranteeText || '支持7天无理由退货'}</Text>
|
||||
<ArrowRight color="#cccccc" size={15}/>
|
||||
</View>
|
||||
} onClick={() => openBottom('保障', `${config?.guaranteeText}`)}/>
|
||||
</CellGroup>
|
||||
)
|
||||
}
|
||||
{config?.openComments == '1' && (
|
||||
<CellGroup>
|
||||
<Cell title={'用户评价 (0)'} extra={
|
||||
<>
|
||||
<Text>查看全部</Text>
|
||||
<ArrowRight color="#cccccc" size={15}/>
|
||||
</>
|
||||
} onClick={() => navTo(`/shop/comments/index`)}/>
|
||||
<Cell className={'flex h-32 bg-white p-4'}>
|
||||
暂无评价
|
||||
</Cell>
|
||||
</CellGroup>
|
||||
)}
|
||||
</View>
|
||||
<View className={'w-full'}>
|
||||
<RichText nodes={goods.content || '内容详情'}/>
|
||||
</div>
|
||||
</div>
|
||||
<View className={'h-24'}></View>
|
||||
</View>
|
||||
</View>
|
||||
{/*底部弹窗*/}
|
||||
<Popup
|
||||
visible={showBottom}
|
||||
position="bottom"
|
||||
onClose={() => {
|
||||
setShowBottom(false)
|
||||
}}
|
||||
lockScroll
|
||||
>
|
||||
<View className={'flex flex-col p-4'}>
|
||||
<Text className={'font-bold text-sm'}>{bottomItem.title}</Text>
|
||||
<Text className={'text-gray-500 my-2'}>{bottomItem.content}</Text>
|
||||
</View>
|
||||
</Popup>
|
||||
{/*底部购买按钮*/}
|
||||
<div className={'fixed bg-white w-full bottom-0 left-0 pt-4 pb-10'}>
|
||||
<View className={'fixed bg-white w-full bottom-0 left-0 pt-4 pb-8'}>
|
||||
<View className={'btn-bar flex justify-between items-center'}>
|
||||
<div className={'flex justify-center items-center mx-4'}>
|
||||
<View className={'flex justify-center items-center mx-4'}>
|
||||
<button open-type="contact" className={'flex items-center'}>
|
||||
<Headphones size={18} style={{marginRight: '4px'}}/>咨询
|
||||
</button>
|
||||
</div>
|
||||
<div className={'buy-btn mx-4'}>
|
||||
<div className={'cart-add px-4 text-sm'}
|
||||
onClick={() => handleAddToCart()}>加入购物车
|
||||
</div>
|
||||
<div className={'cart-buy pl-4 pr-5 text-sm'}
|
||||
onClick={() => handleBuyNow()}>立即购买
|
||||
</div>
|
||||
</div>
|
||||
</View>
|
||||
<View className={'buy-btn mx-4'}>
|
||||
<View className={'cart-add px-4 text-sm'}
|
||||
onClick={() => handleAddToCart()}>加入购物车
|
||||
</View>
|
||||
<View className={'cart-buy pl-4 pr-5 text-sm'}
|
||||
onClick={() => handleBuyNow()}>立即购买
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</div>
|
||||
</View>
|
||||
|
||||
{/* 规格选择器 */}
|
||||
{showSpecSelector && (
|
||||
@@ -320,7 +390,7 @@ const GoodsDetail = () => {
|
||||
onClose={() => setShowSpecSelector(false)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user