447 lines
18 KiB
TypeScript
447 lines
18 KiB
TypeScript
import { Button, Icon, RichText, Text, View } from '@tarojs/components'
|
||
import Taro, { useDidShow, usePullDownRefresh, useRouter } from '@tarojs/taro'
|
||
import classnames from 'classnames'
|
||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||
import DesSwiper from './components/swiper'
|
||
import OrderCount from './components/orderCount'
|
||
import styles from './index.module.scss'
|
||
import FeaturePopup from './components/feature'
|
||
import Recommend from './components/recommend'
|
||
import ShopCart from '@/components/shopCart'
|
||
import { formatDateTime, formatHashTag, formatImgUrl, formatPriceDiv, formatRemoveHashTag } from '@/common/fotmat'
|
||
import { GetProductDetailApi } from '@/api/material'
|
||
import useLogin from '@/use/useLogin'
|
||
import { AnalysisShortCodeApi, GetShortCodeApi } from '@/api/share'
|
||
import { SHARE_SCENE } from '@/common/enum'
|
||
import useUserInfo from '@/use/useUserInfo'
|
||
import LabAndImg from '@/components/LabAndImg'
|
||
import { alert, goLink } from '@/common/common'
|
||
import AddCollection from '@/components/addCollection'
|
||
import { AddFavoriteApi, DelFavoriteProductApi } from '@/api/favorite'
|
||
import useCommonData from '@/use/useCommonData'
|
||
import MoveBtn from '@/components/moveBtn'
|
||
import Dialog from '@/components/Dialog'
|
||
import NormalButton from '@/components/normalButton'
|
||
import IconFont from '@/components/iconfont/iconfont'
|
||
import LabAndImgShow from '@/components/LabAndImgShow'
|
||
import PopupSelectColor from '@/components/popupSelectColor'
|
||
import { GetColorCardOrderByProductApi } from '@/api/colorCard'
|
||
|
||
interface item { title: string; img: string; url: string; id: number }
|
||
|
||
interface Params {
|
||
list?: item[]
|
||
swiperOnClick?: (val: item) => void
|
||
style?: Object
|
||
}
|
||
interface CurrentDialogDetail {
|
||
lab: { l: number; a: number; b: number }
|
||
rgb: { r: number; g: number; b: number }
|
||
texture_url: string
|
||
code: string
|
||
name: string
|
||
bulk_price: number
|
||
update_price_time: string | Date
|
||
length_cut_price: number
|
||
}
|
||
const Details = (props: Params) => {
|
||
const { getPhoneNumber, userInfo } = useLogin()
|
||
|
||
// 获取参数(有两种参数:1.商品id, 2.页面分享)
|
||
const router = useRouter()
|
||
const [params, setParams] = useState({ id: '', share: null })
|
||
|
||
const [productId, setProductId] = useState(0)
|
||
const [recommendStatus, setRecommendStatus] = useState(false)
|
||
|
||
// 解析短码参数
|
||
const { fetchData: fetchDataAnalysisShortCode } = AnalysisShortCodeApi()
|
||
const analysisShortCode = async() => {
|
||
const res = await fetchDataAnalysisShortCode({ md5_key: router.params.share })
|
||
setParams({ id: res.data.product_id, share: res.data })
|
||
}
|
||
// 判断是否是分享过来的参数
|
||
const judgeParam = async() => {
|
||
if (router.params.id) {
|
||
setParams({ ...params, id: router.params.id })
|
||
}
|
||
else if (router.params.share) {
|
||
analysisShortCode()
|
||
}
|
||
}
|
||
// 获取购物车数据数量
|
||
const { getShopCount, commonData } = useCommonData()
|
||
|
||
// 获取数据
|
||
const [productInfo, setProductInfo] = useState<any>({})
|
||
const { fetchData } = GetProductDetailApi()
|
||
const getProductDetail = async() => {
|
||
const { data } = await fetchData({ id: params.id })
|
||
setProductId(data.id)
|
||
setProductInfo(data)
|
||
Taro.stopPullDownRefresh()
|
||
}
|
||
|
||
// 面料名称
|
||
const productName = useMemo(() => {
|
||
return formatHashTag(productInfo.code, productInfo.name)
|
||
}, [productInfo])
|
||
const recommendName = useMemo(() => {
|
||
return formatHashTag(productInfo.product_screw_code, productInfo.product_screw_name)
|
||
}, [productInfo])
|
||
|
||
const [showCart, setShowCart] = useState(false)
|
||
const [showOrderCount, setShowOrderCount] = useState(false)
|
||
// const html = `
|
||
// <img style="width:100%" src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic24.nipic.com%2F20121021%2F10910884_100200815001_2.jpg&refer=http%3A%2F%2Fpic24.nipic.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1652257920&t=9353dda34f18ae2fe6803f3da35954bb">
|
||
// `
|
||
const html = ''
|
||
|
||
const shareImg = useMemo(() => {
|
||
const data = productInfo.texture_url ? productInfo.texture_url.toString().split(',') : []
|
||
const str = data.length > 0 ? data[0] : '/mall/share_img_01.png'
|
||
return formatImgUrl(str, '!w400')
|
||
}, [productInfo])
|
||
|
||
const { setSortCode, userInfo: userObj } = useUserInfo()
|
||
// 详情页获取分享短码
|
||
const { ShareDetail } = SHARE_SCENE
|
||
const { fetchData: fetchDataShortCode } = GetShortCodeApi()
|
||
const getShortCode = async() => {
|
||
const { data: resDetail } = await fetchDataShortCode({
|
||
share_user_id: userObj.adminUserInfo.user_id,
|
||
type: ShareDetail.value,
|
||
product_id: parseInt(params.id),
|
||
})
|
||
setSortCode({ ...userObj.sort_code, shareShortDetail: { title: productName as string, code: resDetail.md5_key, img: shareImg } })
|
||
}
|
||
useDidShow(() => {
|
||
judgeParam()
|
||
setShowCart(false)
|
||
getShopCount()
|
||
})
|
||
|
||
useEffect(() => {
|
||
if (params.id) {
|
||
getProductDetail()
|
||
}
|
||
}, [params])
|
||
|
||
// 授权手机号和下单
|
||
const placeOrder = async(status = 'to_phone', e: any = {}) => {
|
||
if (!productInfo.id) { return false }
|
||
if (status == 'to_phone') {
|
||
if (!e.detail.code) { return alert.error('请授权手机号') }
|
||
try {
|
||
await getPhoneNumber(e.detail.code)
|
||
}
|
||
catch (msg) {
|
||
Taro.showToast({
|
||
icon: 'none',
|
||
title: msg,
|
||
})
|
||
return false
|
||
}
|
||
}
|
||
setProductId(productInfo.id)
|
||
setRecommendStatus(false)
|
||
setShowOrderCount(true)
|
||
}
|
||
|
||
// 收藏功能
|
||
const [collectStatus, setCollectStatus] = useState(false)
|
||
const [collectionShow, setCollectionShow] = useState(false)
|
||
const { fetchData: addFavoritefetchData } = AddFavoriteApi()
|
||
|
||
const onAdd = useCallback(
|
||
async(val) => {
|
||
const res = await addFavoritefetchData({ favorite_id: val.id, product_id: Number(params.id) })
|
||
if (res.success) {
|
||
alert.none('收藏成功')
|
||
setCollectStatus(true)
|
||
getProductDetail()
|
||
}
|
||
else {
|
||
alert.none(res.msg)
|
||
}
|
||
|
||
setCollectionShow(false)
|
||
},
|
||
[params],
|
||
)
|
||
|
||
useEffect(() => {
|
||
if (productInfo.code) {
|
||
getShortCode()
|
||
setCollectStatus(() => productInfo.is_favorite)
|
||
}
|
||
}, [productInfo])
|
||
const closeCollection = useCallback(() => {
|
||
setCollectionShow(false)
|
||
}, [])
|
||
// 取消收藏
|
||
const { fetchData: delFavoriteProductFetchData } = DelFavoriteProductApi()
|
||
const delFavoriteProduct = async() => {
|
||
const res = await delFavoriteProductFetchData({ favorite_id: productInfo.favorite_id, product_id: [productInfo.id] })
|
||
if (res.success) {
|
||
setCollectStatus(false)
|
||
getProductDetail()
|
||
alert.none('已取消收藏')
|
||
}
|
||
}
|
||
const openCollection = () => {
|
||
if (productInfo.is_favorite) {
|
||
delFavoriteProduct()
|
||
}
|
||
else {
|
||
setCollectionShow(true)
|
||
}
|
||
}
|
||
// 页面下拉刷新
|
||
usePullDownRefresh(() => {
|
||
getProductDetail()
|
||
})
|
||
|
||
const [showPopup, setshowPopup] = useState(false)
|
||
const currentDialogDetail = useRef<CurrentDialogDetail>({} as CurrentDialogDetail)
|
||
const [showDialog, setShowDialog] = useState(false)
|
||
const handleCloseDialog = () => {
|
||
setShowDialog(false)
|
||
}
|
||
const handleChangeDialog = (isShow) => {
|
||
setShowDialog(isShow)
|
||
}
|
||
// 选择颜色
|
||
const handleClickProductColor = (current) => {
|
||
console.log('current', current)
|
||
currentDialogDetail.current = current
|
||
setShowDialog(true)
|
||
}
|
||
|
||
const recommendData = useMemo(() => {
|
||
return {
|
||
product_screw_id: productInfo?.product_screw_id,
|
||
product_screw_name: productInfo?.product_screw_name,
|
||
product_screw_code: productInfo?.product_screw_code,
|
||
screw_rgb: productInfo?.screw_rgb,
|
||
screw_lab: productInfo?.screw_lab,
|
||
screw_texture_url: productInfo?.screw_texture_url,
|
||
}
|
||
}, [productInfo])
|
||
|
||
const openProduct = useCallback((id) => {
|
||
setProductId(id)
|
||
setShowOrderCount(true)
|
||
setRecommendStatus(true)
|
||
}, [])
|
||
|
||
const { fetchData: colorCardFetchData } = GetColorCardOrderByProductApi()
|
||
const getColorCardData = async() => {
|
||
const res = await colorCardFetchData({ product_id: productInfo.id })
|
||
if (res.data) {
|
||
res.data.count = 1
|
||
Taro.setStorageSync('colorCard', JSON.stringify([res.data]))
|
||
Taro.navigateTo({
|
||
url: '/pages/colorCardOrder/index',
|
||
})
|
||
}
|
||
}
|
||
|
||
const [showColorSelect, setShowColorSelect] = useState(false)
|
||
const openColorSelect = () => {
|
||
setShowColorSelect(true)
|
||
}
|
||
|
||
const onCutSampleList = (val) => {
|
||
const data = { ...productInfo }
|
||
val.map((item) => {
|
||
item.count = 1
|
||
})
|
||
data.colors = val
|
||
Taro.setStorageSync('cutSample', JSON.stringify([data]))
|
||
Taro.redirectTo({
|
||
url: '/pages/cutSampleListOrder/index',
|
||
})
|
||
}
|
||
|
||
return (
|
||
<MoveBtn showList={['order']}>
|
||
<View className={styles.main}>
|
||
<DesSwiper list={productInfo.texture_url ? productInfo.texture_url.toString().split(',') : []} />
|
||
<View className={styles.product_header}>
|
||
<View className={styles.title}>
|
||
{productInfo.code && <View className={styles.name}>{productName}</View>}
|
||
<View className={styles.des}>{productInfo.describe}</View>
|
||
</View>
|
||
<View className={styles.collect} onClick={openCollection}>
|
||
<View
|
||
className={classnames(
|
||
`iconfont ${collectStatus ? 'icon-shoucangchenggong' : 'icon-dianjishoucang'}`,
|
||
styles.miconfont,
|
||
collectStatus && styles.collected,
|
||
)}
|
||
></View>
|
||
<View className={styles.text}>收藏</View>
|
||
</View>
|
||
<View className={styles.share}>
|
||
<View className={classnames('iconfont icon-fenxiangshangpin', styles.miconfont)}></View>
|
||
<View className={styles.text}>分享</View>
|
||
<Button open-type="share" className={styles.shareBtn}></Button>
|
||
</View>
|
||
</View>
|
||
<View className={styles.des_data}>
|
||
<View className={styles.flexBox}>
|
||
<View className={styles.title}>商品参数</View>
|
||
{
|
||
productInfo.is_instruct && <View className={styles.flexRight} onClick={() => setshowPopup(true)}>{'特色百科 >'}</View>
|
||
}
|
||
</View>
|
||
<View className={styles.con}>
|
||
{/* <View className={styles.des_text}>
|
||
编号:<Text>{productInfo.code}</Text>
|
||
</View> */}
|
||
<View className={styles.des_text}>
|
||
幅宽:<Text>{productInfo.width}</Text>
|
||
</View>
|
||
<View className={styles.des_text}>
|
||
工艺:<Text>{productInfo.craft}</Text>
|
||
</View>
|
||
<View className={styles.des_text}>
|
||
空差:<Text>{productInfo.weight_error_discount / 1000}KG</Text>
|
||
</View>
|
||
<View className={styles.des_text}>
|
||
克重:<Text>{productInfo.weight_density}</Text>
|
||
</View>
|
||
<View className={styles.des_text}>
|
||
成分:<Text>{productInfo.component}</Text>
|
||
</View>
|
||
<View className={styles.des_text}>
|
||
纸筒:<Text>{productInfo.tube / 1000}KG</Text>
|
||
</View>
|
||
<View className={styles.des_text}>
|
||
出米数:<Text>{productInfo.length_to_weight_rate / 100}</Text>
|
||
</View>
|
||
<View className={styles.des_text}>
|
||
开单减空差:<Text>{productInfo.weight_error / 1000}KG</Text>
|
||
</View>
|
||
</View>
|
||
</View>
|
||
{!!productInfo?.product_screw_id && <Recommend onClick={openProduct} data={recommendData} />}
|
||
<View className={styles.product_color}>
|
||
<View className={styles.title}>色号信息 ({productInfo?.product_color_list?.length})</View>
|
||
<View className={styles.list}>
|
||
{productInfo?.product_color_list?.map((item) => {
|
||
return (
|
||
<View key={item.id} className={styles.item} onClick={() => handleClickProductColor(item)}>
|
||
<View className={styles.item_color}>
|
||
<LabAndImg
|
||
value={{ lab: item.lab, rgb: item.rgb, texture_url: item.texture_url, title: item.code }}
|
||
round
|
||
name={formatRemoveHashTag(item.code)}
|
||
/>
|
||
</View>
|
||
<View className={styles.item_name}>{item.name}</View>
|
||
<View className={styles.bulk_price}>{formatPriceDiv(item.bulk_price)}/Kg{
|
||
item.length_cut_price ? (item.bulk_price > item.length_cut_price) ? <Text style={{ color: 'red', marginLeft: '10rpx' }}>↑</Text> : <Text style={{ color: 'green', marginLeft: '10rpx' }}>↓</Text> : null
|
||
}</View>
|
||
</View>
|
||
)
|
||
})}
|
||
</View>
|
||
</View>
|
||
<View className={styles.product_detail}>
|
||
<RichText nodes={html}></RichText>
|
||
</View>
|
||
<View className={styles.product_buy}>
|
||
<View className={styles.icon_btn}>
|
||
{/* <View className={styles.customer_service}>
|
||
<View className={classnames('iconfont icon-kefu', styles.miconfont)}></View>
|
||
<View className={styles.text}>
|
||
询货/咨询
|
||
<Button
|
||
className={styles.wxBtn}
|
||
openType="contact"
|
||
sendMessageImg={shareImg}
|
||
sendMessageTitle={productName}
|
||
showMessageCard
|
||
sendMessagePath={`/pages/details/index?id=${productInfo.id}`}
|
||
></Button>
|
||
</View>
|
||
</View> */}
|
||
<View className={styles.buy_cart} onClick={() => goLink('/pages/shopCar/index', {}, 'switchTab')}>
|
||
<View className={classnames('iconfont icon-gouwuche', styles.miconfont)}></View>
|
||
<View className={styles.text}>购物车</View>
|
||
{commonData.shopCount > 0 && <View className={styles.product_num}>{commonData.shopCount > 99 ? '99+' : commonData.shopCount}</View>}
|
||
</View>
|
||
<View className={styles.buy_cart} onClick={getColorCardData}>
|
||
<IconFont name="icon-lingseka" size={50} />
|
||
<View className={styles.text}>领取色卡</View>
|
||
</View>
|
||
<View className={styles.buy_cart} onClick={openColorSelect}>
|
||
<IconFont name="icon-lingjianyang" size={50} />
|
||
<View className={styles.text}>领取剪样</View>
|
||
</View>
|
||
|
||
</View>
|
||
|
||
{(!userInfo.adminUserInfo?.is_authorize_phone && (
|
||
<View className={styles.buy_btn}>
|
||
<Button className={styles.wxBtn} open-type="getPhoneNumber" onGetPhoneNumber={e => placeOrder('to_phone', e)}></Button>
|
||
选购商品
|
||
</View>
|
||
)) || (
|
||
<View className={styles.buy_btn} onClick={() => placeOrder('to_order')}>
|
||
选购商品
|
||
</View>
|
||
)}
|
||
</View>
|
||
<OrderCount show={showOrderCount} recommendStatus={recommendStatus} is_first_login={productInfo.is_first_login} onClose={() => setShowOrderCount(false)} recom_title={recommendName} title={productName} productId={productId} />
|
||
<ShopCart show={showCart} onClose={() => setShowCart(false)} />
|
||
<AddCollection show={collectionShow} onAdd={onAdd} onClose={closeCollection} />
|
||
<FeaturePopup showPopup={showPopup} closePopup={() => setshowPopup(false)} productName={productName} productIds={Number(params?.id)}></FeaturePopup>
|
||
<Dialog show={showDialog} onClose={handleCloseDialog} onChange={handleChangeDialog} >
|
||
<View className={styles.productColorDialog}>
|
||
<View className={styles.productColorDialog_content}>
|
||
<View className={styles.productColorDialog_img}>
|
||
<LabAndImg
|
||
customImageStyle={{ borderRadius: '0' }}
|
||
suffix="!w1000"
|
||
value={{ lab: currentDialogDetail.current!.lab, rgb: currentDialogDetail.current!.rgb, texture_url: currentDialogDetail.current!.texture_url, title: currentDialogDetail.current!.code }}
|
||
/>
|
||
</View>
|
||
<View className={styles.productColorDialog_info}>
|
||
<View className={styles.productColorDialog_title}>
|
||
<Text className={styles.productColorDialog_name}>{formatHashTag(currentDialogDetail.current!.code, currentDialogDetail.current!.name)}</Text>
|
||
<View className={styles.productColorDialog_price}>
|
||
<Text>¥{formatPriceDiv(currentDialogDetail.current!.bulk_price)}/KG</Text>
|
||
{
|
||
currentDialogDetail.current!.length_cut_price ? (currentDialogDetail.current!.bulk_price > currentDialogDetail.current!.length_cut_price) ? <Text style={{ color: 'red', marginLeft: '10rpx' }}>↑</Text> : <Text style={{ color: 'green', marginLeft: '10rpx' }}>↓</Text> : null
|
||
}
|
||
</View>
|
||
</View>
|
||
<View className={styles.productColorDialog_bottomBar}>
|
||
{
|
||
currentDialogDetail.current!.length_cut_price
|
||
? <>
|
||
<Text className={styles.productColorDialog_history}>更新于:{formatDateTime(currentDialogDetail.current!.update_price_time, 'YYYY-MM-DD') }</Text>
|
||
<Text className={styles.productColorDialog_oldPrice}>¥{formatPriceDiv(currentDialogDetail.current!.length_cut_price)}/KG</Text>
|
||
</>
|
||
: <Text className={styles.productColorDialog_history}>暂无历史报价</Text>
|
||
}
|
||
</View>
|
||
</View>
|
||
</View>
|
||
<View className={styles.productColorDialog_button}>
|
||
<NormalButton circle type="primary" size="normal" onClick={handleCloseDialog}>知道了</NormalButton>
|
||
</View>
|
||
</View>
|
||
</Dialog>
|
||
<PopupSelectColor onSelected={onCutSampleList} show={showColorSelect} product_id={productInfo.id} onClose={() => setShowColorSelect(false)} />
|
||
<View className="common_safe_area_y"></View>
|
||
</View>
|
||
</MoveBtn>
|
||
)
|
||
}
|
||
|
||
export default Details
|