2022-11-30 17:14:28 +08:00

378 lines
13 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Image, ScrollView, View } from '@tarojs/components'
import Popup from '@/components/popup'
import classnames from 'classnames'
import MCheckbox from '@/components/checkbox'
import LoadingCard from '@/components/loadingCard'
import InfiniteScroll from '@/components/infiniteScroll'
import styles from './index.module.scss'
import { useCallback, useEffect, useMemo, useRef, useState, useTransition } from 'react'
import Taro from '@tarojs/taro'
import { alert, goLink } from '@/common/common'
import { GetShoppingCartApi, DelShoppingCartApi, UpdateShoppingCartApi } from '@/api/shopCart'
import { formatHashTag, formatImgUrl, formatPriceDiv } from '@/common/fotmat'
import { setParam } from '@/common/system'
import { debounce, throttle } from '@/common/util'
import Counter from '../counter'
import { ApplyOrderAccessApi, GetAdminUserInfoApi, SubscriptionMessageApi } from '@/api/user'
import useCommonData from '@/use/useCommonData'
import BindSalesmanPopup from '../bindSalesmanPopup'
import LabAndImgShow from '../LabAndImgShow'
import LabAndImg from '../LabAndImg'
import ProductItem from './components/productItem'
import { saleModeType } from '@/common/enum'
type param = {
show?: true | false
onClose?: () => void
intoStatus?: 'again' | 'shop'
default_sale_mode?: saleModeType //面料类型0大货 1剪版2散剪
}
type modelClassType = {
value: saleModeType
title: string
unit: string
step: number
digits: number
minNum: number
maxNum: number
defaultNum: number
eunit: string
}
export default ({ show = false, onClose, intoStatus = 'shop', default_sale_mode }: param) => {
const selectList: modelClassType[] = [
{ value: 0, title: '大货', unit: '条', eunit: 'kg', step: 1, digits: 0, minNum: 1, maxNum: 100000, defaultNum: 1 },
{ value: 1, title: '剪板', unit: '米', eunit: 'm', step: 1, digits: 2, minNum: 0.5, maxNum: 9.99, defaultNum: 1 },
{ value: 2, title: '散剪', unit: '米', eunit: 'kg', step: 1, digits: 2, minNum: 3, maxNum: 100000, defaultNum: 3 },
]
const [isPending, startTransition] = useTransition()
//切换面料类型
const [selectIndex, setSelectIndex] = useState<saleModeType>(default_sale_mode || 0)
const selectProduct = (index: 0 | 1 | 2) => {
setSelectIndex(index)
}
useEffect(() => {
if (!isPending) {
setSelectIndex(() => default_sale_mode!)
}
}, [default_sale_mode])
useEffect(() => {
startTransition(() => {
resetList()
setSelectStatus(true)
})
}, [selectIndex])
//获取购物车数据数量
const { getShopCount } = useCommonData()
//获取所有数据数据
const [list, setList] = useState<{ [id: number]: any }>({})
const [loading, setLoading] = useState(false)
const { fetchData: getShoppingFetchData } = GetShoppingCartApi()
const getShoppingCart = async () => {
const { data } = await getShoppingFetchData()
let color_list = data.color_list || []
initList(color_list)
setLoading(false)
}
//更新单条数据
const getShoppingCartInfo = async (item) => {
const res = await getShoppingFetchData({ id: item.id })
if (res.success) {
let info = res.data.color_list[0]
let newInfo = {
...item,
estimate_amount: info.estimate_amount,
estimate_weight: info.estimate_weight,
lab: info.lab,
roll: info.roll,
length: info.length,
sale_offset: info.sale_offset,
sale_price: info.sale_price,
standard_price: info.standard_price,
}
setList((e) => ({ ...e, [item['id']]: newInfo }))
}
}
const listData = useMemo(() => {
return Object.values(list)
}, [list])
//初始化全部数据默认勾选
const initList = (color_list) => {
let obj = {}
color_list?.map((item) => {
item.selected = selectIndex == item.sale_mode
const { unit, eunit, step, digits, minNum, maxNum } = selectList[item.sale_mode]
item = { ...item, unit, eunit, step, digits, minNum, maxNum }
obj[item.id] = item
})
setList(() => ({ ...obj }))
}
//重置勾选数据
const resetList = () => {
Object.values(list)?.map((item) => {
if (selectIndex == item.sale_mode) {
item.selected = true
} else {
item.selected = false
}
list[item['id']] = { ...item }
})
setList(() => ({ ...list }))
}
//显示时展示数据
useEffect(() => {
if (!show) {
setList({})
setSelectIndex(default_sale_mode || 0)
} else {
setLoading(true)
getShoppingCart()
setShowBindSalesman(() => false)
}
}, [show])
const [showPopup, setShowPopup] = useState(false)
useEffect(() => {
setShowPopup(show)
}, [show])
//全选反选
const [selectStatus, setSelectStatus] = useState(false)
const selectAll = () => {
Object.values(list)?.map((item) => {
if (selectIndex == item.sale_mode) {
item.selected = !selectStatus
list[item['id']] = { ...item }
}
})
setList(() => ({ ...list }))
setSelectStatus(!selectStatus)
}
//checkbox选中判断是否全部选中全部选中后是全选否则反选
useEffect(() => {
let list_count = 0
let select_count = 0
Object.values(list)?.map((item) => {
if (selectIndex == item.sale_mode) {
list_count++
if (item.selected) select_count++
}
})
setSelectStatus(select_count == list_count)
}, [list])
//修改数量
const onChangeCount = useCallback((item) => {
getInputValue(item)
}, [])
//修改选择
const onChangeSelect = useCallback((item) => {
setList((e) => ({ ...e, [item.id]: { ...item } }))
}, [])
//popup关闭
const closePopup = () => {
onClose?.()
setShowPopup(false)
}
//删除购物车内容
const { fetchData: delShopFetchData } = DelShoppingCartApi()
const delSelect = () => {
getSelectId()
if (selectIds.current.length <= 0) return alert.none('请选择要删除的面料!')
Taro.showModal({
content: '删除所选商品?',
success: async function (res) {
if (res.confirm) {
const res = await delShopFetchData({ id: selectIds.current })
if (res.success) {
getShoppingCart()
getShopCount()
Taro.showToast({
title: '成功',
icon: 'success',
})
} else {
Taro.showToast({
title: res.msg,
icon: 'none',
})
}
} else if (res.cancel) {
console.log('用户点击取消')
}
},
})
}
//获取面料选中的id
const selectIds = useRef<number[]>([])
const getSelectId = () => {
selectIds.current = []
Object.values(list)?.map((item) => {
if (selectIndex == item.sale_mode) {
item.selected && selectIds.current.push(item.id)
}
})
}
//预估金额和总条数
const estimatePrice = useMemo(() => {
let estimate_amount = 0
let product_list = new Set() //面料
let color_count = 0 //颜色数量
let all_count = 0 //总数量
Object.values(list)?.map((item) => {
if (item.selected) {
estimate_amount += item.estimate_amount
product_list.add(item.product_id)
color_count++
all_count += item.sale_mode == 0 ? parseFloat(item.roll) : parseFloat(item.length)
}
})
let all_count_text = selectIndex == 0 ? all_count + ' 条' : all_count / 100 + ' 米'
console.log('text::', list)
return {
price: Number(formatPriceDiv(estimate_amount)).toFixed(2),
countText: `已选 ${product_list.size} 种面料,${color_count} 个颜色,共 ${all_count_text}`,
color_count,
}
}, [list])
//去结算
const { fetchData: useFetchData } = GetAdminUserInfoApi()
const { fetchData: applyOrderAccessFetchData } = ApplyOrderAccessApi()
const orderDetail = throttle(async () => {
let res = await useFetchData()
if (res.data.order_access_status !== 3) {
if (res.data.order_access_status == 1) applyOrderAccessFetchData()
setShowBindSalesman(() => true)
onClose?.()
return false
}
getSelectId()
if (selectIds.current.length == 0) {
alert.error('请选择面料')
} else {
let ids = selectIds.current.join('-')
setParam({ ids, sale_mode: selectIndex }) //临时存储
closePopup()
if (intoStatus == 'again') {
goLink('/pages/order/comfirm', null, 'redirectTo')
} else {
goLink('/pages/order/comfirm')
}
}
}, 500)
//计数组件-当后端修改完成才修改前端显示
const { fetchData: fetchDataUpdateShoppingCart } = UpdateShoppingCartApi()
const getInputValue = debounce(async (item) => {
let res = await fetchDataUpdateShoppingCart({ id: item.id, roll: item.roll, length: item.length })
if (res.success) {
console.log('item修改', item)
getShoppingCartInfo(item)
} else {
setList((e) => ({ ...e }))
}
}, 300)
//绑定业务员和电话号码
const [showBindSalesman, setShowBindSalesman] = useState(false)
//显示图片弹窗
const [showLabImage, setShowLabImage] = useState(false)
const [labImageValue, setLabImageValue] = useState()
const getLabAndImg = useCallback((val) => {
setShowLabImage(() => true)
setLabImageValue(val)
}, [])
const closeLabImgShow = useCallback(() => {
setShowLabImage(() => false)
}, [])
return (
<View className={styles.shop_cart_main}>
<Popup showTitle={false} show={showPopup} onClose={() => closePopup()}>
<View className={styles.popup_con}>
<View className={styles.header}>
<View onClick={selectAll}>{!selectStatus ? '全选' : '反选'}</View>
<View onClick={delSelect}>
<text className={classnames('iconfont', 'icon-shanchu', styles.miconfont)}></text>
</View>
</View>
<View className={styles.count_all}>{estimatePrice.countText}</View>
<View className={styles.search}>
{selectList.map((item) => {
return (
<View
key={item.value}
onClick={() => selectProduct(item.value)}
className={classnames(styles.search_item, selectIndex == item.value && styles.search_item_select)}>
{item.title}
</View>
)
})}
</View>
<View className={styles.con}>
{(loading || isPending) && <LoadingCard />}
{!loading && !isPending && listData?.length > 0 && (
<InfiniteScroll moreStatus={false}>
<View className={styles.product_list}>
{listData?.map((item) => {
return <ProductItem sale_model={selectIndex} onChangeCount={onChangeCount} onChangeSelect={onChangeSelect} item={item} />
})}
</View>
</InfiniteScroll>
)}
{!loading && listData?.length == 0 && (
<View className={styles.empty}>
<View className={styles.title}></View>
<View className={styles.btn} onClick={() => goLink('/pages/index/index', null, 'switchTab')}>
</View>
</View>
)}
</View>
<View className={styles.buy_btn}>
<View className={styles.buy_con}>
<View className={styles.icon}>
<View className={classnames('iconfont', 'icon-gouwuche', styles.miconfont)}></View>
</View>
<View className={styles.price_con}>
<View className={styles.price_real}>
<text></text>
{estimatePrice.price}
</View>
<View className={styles.price_forecast}></View>
</View>
<View className={styles.goPay} onClick={() => orderDetail()}>
({estimatePrice.color_count})
</View>
</View>
</View>
</View>
</Popup>
<View>
<BindSalesmanPopup show={showBindSalesman} onClose={() => setShowBindSalesman(false)} />
</View>
<View>
<LabAndImgShow value={labImageValue} show={showLabImage} onClose={closeLabImgShow} />
</View>
</View>
)
}