import { Image, ScrollView, Text, View } from '@tarojs/components' import Taro from '@tarojs/taro' import classnames from 'classnames' import { Ref, useCallback, useEffect, useMemo, useRef, useState, useTransition } from 'react' import Counter from '../counter' import type { SalesManDialogRef } from '../bindSalesManDialog' import BindSalesManDialog from '../bindSalesManDialog' import LabAndImgShow from '../LabAndImgShow' import LabAndImg from '../LabAndImg' import OrganizationNameModal from '../organizationNameModal' import styles from './index.module.scss' import ProductItem from './components/productItem' import Popup from '@/components/popup' import MCheckbox from '@/components/checkbox' import LoadingCard from '@/components/loadingCard' import InfiniteScroll from '@/components/infiniteScroll' import { alert, goLink, retrieval } from '@/common/common' import { DelShoppingCartApi, GetShoppingCartApi, UpdateShoppingCartApi } from '@/api/shopCart' import { formatHashTag, formatImgUrl, formatPriceDiv } from '@/common/format' import { setParam } from '@/common/system' import { debounce, throttle } from '@/common/util' import { ApplyOrderAccessApi, GetAdminUserInfoApi, SubscriptionMessageApi } from '@/api/user' import useCommonData from '@/use/useCommonData' import type { saleModeType } from '@/common/enum' import { useSelector } from '@/reducers/hooks' import { companyDetailApi, companyUpdateApi } from '@/api/company' import useLogin from '@/use/useLogin' interface param { show?: true | false onClose?: () => void intoStatus?: 'again' | 'shop' default_sale_mode?: saleModeType // 面料类型(0:大货, 1:剪版,2:散剪 } interface modelClassType { value: saleModeType title: string unit: string step: number digits: number minNum: number maxNum: number defaultNum: number eunit: string } const ShopCart = ({ 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.3, maxNum: 100000, defaultNum: 0.3 }, { value: 2, title: '散剪', unit: '米', eunit: 'kg', step: 1, digits: 2, minNum: 3, maxNum: 100000, defaultNum: 3 }, ] const userInfo = useSelector(state => state.userInfo) const bindSalesManDialogRef = useRef(null) const [isPending, startTransition] = useTransition() // 切换面料类型 const [selectIndex, setSelectIndex] = useState(default_sale_mode || 0) const selectProduct = (index: 0 | 1 | 2) => { setSelectIndex(index) } useEffect(() => { if (!isPending) { setSelectIndex(() => default_sale_mode!) } }, [default_sale_mode]) // 获取购物车数据数量 const { getShopCount } = useCommonData() // 获取所有数据数据 const [list, setList] = useState>({}) const [loading, setLoading] = useState(false) const { fetchData: getShoppingFetchData } = GetShoppingCartApi() // 更新单条数据 const getShoppingCartInfo = async(item) => { const res = await getShoppingFetchData({ id: item.id }) if (res.success) { const info = res.data.color_list[0] const 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) => { const obj = {} color_list?.forEach((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 getShoppingCart = async() => { const { data } = await getShoppingFetchData() const color_list = data.color_list || [] initList(color_list) setLoading(false) } // 重置勾选数据 const resetList = () => { Object.values(list)?.forEach((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) bindSalesManDialogRef.current?.handleChange(false) } }, [show]) const [showPopup, setShowPopup] = useState(false) useEffect(() => { setShowPopup(show) }, [show]) // 全选反选 const [selectStatus, setSelectStatus] = useState(false) const selectAll = () => { Object.values(list)?.forEach((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)?.forEach((item) => { if (selectIndex == item.sale_mode) { list_count++ if (item.selected) { select_count++ } } }) setSelectStatus(select_count == list_count) }, [list]) // 计数组件-当后端修改完成才修改前端显示 const { fetchData: fetchDataUpdateShoppingCart } = UpdateShoppingCartApi() const getInputValue = debounce(async(item) => { const 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 onChangeCount = useCallback((item) => { getInputValue(item) }, []) // 修改选择 const onChangeSelect = useCallback((item) => { setList(e => ({ ...e, [item.id]: { ...item } })) }, []) // popup关闭 const closePopup = () => { onClose?.() setShowPopup(false) } // 获取面料选中的id const selectIds = useRef([]) const getSelectId = () => { selectIds.current = [] Object.values(list)?.forEach((item) => { if (selectIndex == item.sale_mode) { item.selected && selectIds.current.push(item.id) } }) } // 删除购物车内容 const { fetchData: delShopFetchData } = DelShoppingCartApi() const delSelect = () => { getSelectId() if (selectIds.current.length <= 0) { return alert.none('请选择要删除的面料!') } Taro.showModal({ content: '删除所选商品?', async success(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('用户点击取消') } }, }) } // 预估金额和总条数 const estimatePrice = useMemo(() => { let estimate_amount = 0 const product_list = new Set() // 面料 let color_count = 0 // 颜色数量 let all_count = 0 // 总数量 Object.values(list)?.forEach((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) } }) const 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 [showModal, setShowModal] = useState(false) const handleClose = () => { setShowModal(false) } const handleShowChange = (val: boolean) => { setShowModal(val) } // 去结算 const { fetchData: FetchData } = GetAdminUserInfoApi() const { fetchData: applyOrderAccessFetchData } = ApplyOrderAccessApi() const orderDetail = throttle(async() => { const res = await FetchData() if (res.data.order_access_status !== 3) { if (res.data.order_access_status == 1) { applyOrderAccessFetchData() } bindSalesManDialogRef.current?.handleChange(true) onClose?.() return } // 检测是否修改过组织昵称 if (userInfo.adminUserInfo.first_change_name) { setShowModal(true) return } getSelectId() if (selectIds.current.length == 0) { alert.error('请选择面料') } else { const 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 [showLabImage, setShowLabImage] = useState(false) const [labImageValue, setLabImageValue] = useState() const getLabAndImg = useCallback((val) => { setShowLabImage(() => true) setLabImageValue(val) }, []) const closeLabImgShow = useCallback(() => { setShowLabImage(() => false) }, []) const goShop = useCallback(() => { onClose?.() goLink('/pages/index/index', null, 'switchTab') }, []) useEffect(() => { startTransition(() => { resetList() setSelectStatus(true) }) }, [selectIndex]) // 弹出修改组织昵称弹窗 const handleBindSalesManSuccess = () => { // 检测是否修改过组织昵称 if (userInfo.adminUserInfo.first_change_name) { setShowModal(true) } } const { getAdminUserInfo } = useLogin() const { fetchData: saveFetch } = companyUpdateApi() const { fetchData: getCompanyFetch } = companyDetailApi() const handleOrganizationNameModalConfirm = async(text: string) => { const params = await getCompanyFetch() const result = await saveFetch({ ...params.data, company_name: text, }) if (result.success) { getAdminUserInfo() handleClose() alert.success('保存成功') } else { alert.none(result.msg) } } return ( closePopup()}> {!selectStatus ? '全选' : '反选'} 删除所选 {estimatePrice.countText} {selectList.map((item) => { return ( selectProduct(item.value)} className={classnames(styles.search_item, selectIndex == item.value && styles.search_item_select)} > {item.title} ) })} {(loading || isPending) && } {!loading && !isPending && listData?.length > 0 && ( {listData?.map((item) => { return })} )} {!loading && listData?.length == 0 && ( 暂未选择商品 去选购 )} {estimatePrice.price} 预估金额 orderDetail()}> 去结算({estimatePrice.color_count}) ) } export default ShopCart