import React, { useEffect, useRef, useImperativeHandle } from 'react' import { useSelector, useDispatch } from 'react-redux' import Taro, { getCurrentInstance } from '@tarojs/taro' import { View, ScrollView, Text } from '@tarojs/components' import { AtInput } from 'taro-ui' import { useImmer } from 'use-immer' import { AddressChoose, SpCell, SpFloatLayout, SpForm, SpFormItem } from '@/components' import { updateChooseAddress } from '@/store/slices/user' import { enumdays } from '@/consts' import { classNames, VERSION_STANDARD } from '@/utils' import dayjs from 'dayjs' import api from '@/api' import { deliveryList } from '../const' import './comp-deliver.scss' const initialState = { distributorInfo: null, receiptType: '', showTimePicker: false, form: { pickerTime: '', pickerName: '', pickerPhone: '' }, rules: { pickerTime: [{ required: true, message: '提货时间不能为空' }], pickerName: [{ required: true, message: '提货人姓名不能为空' }], pickerPhone: [{ required: true, message: '提货人手机号不能为空' }] }, weekdays: [], timeSlots: [], pickerIndex: 0, activeTimeId: '' } function CompDeliver (props, ref) { const { address = {}, distributor_id, onChangReceiptType = () => { }, onChange = () => { }, onEidtZiti = () => { } } = props const dispatch = useDispatch() const { location = {}, address: storeAddress } = useSelector((state) => state.user) const { rgb, openStore } = useSelector((state) => state.sys) const { zitiAddress } = useSelector((state) => state.cart) const { zitiShop } = useSelector((state) => state.shop) const [state, setState] = useImmer(initialState) const { distributorInfo, receiptType, showTimePicker, form, rules, weekdays, timeSlots, pickerIndex, activeTimeId } = state const formRef = useRef() const $instance = getCurrentInstance() const { cart_type } = $instance.router?.params || {} // useEffect(() => { // fetch() // }, []) useEffect(() => { getShopInfo() }, []) useEffect(() => { if (distributorInfo) { fetchAddress() } }, [distributorInfo, receiptType]) useEffect(() => { if (zitiAddress) { calcZitiPickerData() } }, [zitiAddress]) useEffect(() => { if (weekdays.length > 0) { onChangeWeekDays(0) } }, [weekdays]) const getShopInfo = async () => { let _distributorInfo if (distributor_id == 0) { _distributorInfo = await api.shop.getHeadquarters({ distributor_id }) } else { _distributorInfo = await api.shop.getShop({ distributor_id }) } const _receiptType = deliveryList.find(item => !!_distributorInfo[item.key]) setState((draft) => { draft.distributorInfo = _distributorInfo draft.receiptType = _receiptType?.type || 'logistics' }) } const fetchAddress = async () => { if (receiptType == 'ziti') { onChange({ receipt_type: receiptType, distributor_info: distributorInfo, address_info: null }) return } let query = { receipt_type: receiptType } if (receiptType == 'dada') { query['city'] = distributorInfo.city } // 非自提情况下,把地址存起来,否则清空地址 const { list } = await api.member.addressList(query) const defaultAddress = list.find((item) => item.is_def) || list[0] || null const selectAddress = list.find(item => item.address_id == storeAddress?.address_id) onChange({ receipt_type: receiptType, distributor_info: distributorInfo, address_info: selectAddress || defaultAddress }) } const calcZitiPickerData = () => { const { wait_pickup_days, hours } = zitiAddress const _weekdays = [] for (let i = 0; i <= parseInt(wait_pickup_days); i++) { const _day = dayjs().add(i, 'day') _weekdays.push({ title: enumdays[i] || _day.format('YYYY-MM-DD'), value: _day }) } setState(draft => { draft.weekdays = _weekdays // draft.timeSlots = hours }) } const onChangeWeekDays = (index) => { const activeWeekday = weekdays[index].value const { hours, latest_pickup_time, workdays } = zitiAddress const week = dayjs(activeWeekday).day() const _timeSlots = [] for (let i = 0; i < hours.length; i++) { let enable = workdays.includes(week.toString()) // 下单时间在latest_pickup_time之前,可预约当天自提 // index == 0 即为当日 if (latest_pickup_time && index == 0) { const lasterDateTime = `${dayjs().format('YYYY-MM-DD')} ${latest_pickup_time}:00` enable = enable && dayjs().isBefore(lasterDateTime) } // 当前时间大于提货时间段结算时间,时间段有效 if (index == 0) { const timeSlotEnd = `${dayjs().format('YYYY-MM-DD')} ${hours[i][1]}:00` enable = enable && dayjs().isBefore(timeSlotEnd) } _timeSlots.push({ id: `${week}_${i}`, value: hours[i], date: dayjs(activeWeekday).format('YYYY-MM-DD'), disabled: !enable }) } setState(draft => { draft.pickerIndex = index draft.timeSlots = _timeSlots }) } const onChangeTimeSlot = ({ id, date, value, disabled }) => { if (disabled) { return } setState((draft) => { draft.form['pickerTime'] = { date, time: value } draft.showTimePicker = false draft.activeTimeId = id }) } const getPickerTime = () => { const { pickerTime } = form if (!pickerTime) { return '请选择提货时间' } else { const { date, time } = pickerTime return `${date} ${time.join('-')}` } } const handleSwitchExpress = async (receipt_type) => { // 切换配送方式 if (receiptType === receipt_type) return setState((draft) => { draft.receiptType = receipt_type }) } const handleMapClick = () => { // 点击地图icon const { lat, lng } = location || {} Taro.openLocation({ latitude: Number(lat), longitude: Number(lng), scale: 18 }) } // 切换自提店铺 const handleEditZitiClick = (id = 0) => { onEidtZiti(id) } const handleChooseAddress = (choose) => { // 自定义选择店铺跳转事件 let city = distributorInfo.city Taro.navigateTo({ url: `/marketing/pages/member/address?isPicker=${choose}&city=${city}&receipt_type=dada` }) } const zitiInfo = zitiShop && receiptType === 'ziti' ? zitiShop : distributorInfo const onInputChange = (key, value) => { setState((draft) => { draft.form[key] = value }) } useImperativeHandle(ref, () => ({ // reset 就是暴露给父组件的方法 getZitiInfo: () => { return form }, validateZitiInfo: async () => { await formRef.current.onSubmitAsync() } })) if (!distributorInfo) { return null } return ( {/* 0 && 'switch-tab')}> {deliveryList.map((item) => { if (distributorInfo[item.key]) { return ( {item.name} ) } })} */} {/** 普通快递 */} {receiptType === 'logistics' && } {/** 同城配 */} {receiptType === 'dada' && ( 配送门店: {distributorInfo.name} )} {/** 自提 */} {receiptType === 'ziti' && ( { Taro.navigateTo({ url: `/subpages/store/ziti-picker?distributor_id=${distributor_id}&cart_type=${cart_type}` }) }}>{zitiAddress?.name || '选择自提地址'} {zitiAddress && 提货地址:{`${zitiAddress?.province}${zitiAddress?.city}${zitiAddress?.area}${zitiAddress?.address}`} 联系电话:{zitiAddress?.contract_phone} } {zitiAddress && { setState(draft => { draft.showTimePicker = true }) }}> {getPickerTime()} } {/* {zitiInfo.name} {zitiInfo.store_address} {!openStore && VERSION_STANDARD ? ( handleEditZitiClick(zitiInfo.distributor_id)} > ) : ( handleMapClick()}> )} 门店营业时间:{zitiInfo.hour} 联系电话: {zitiInfo.phone} */} ) } {/* 自提时间选择 */} { setState(draft => { draft.showTimePicker = false }) }}> { weekdays.map((item, index) => ({item.title})) } { timeSlots.map((item, index) => ({`${item.value[0]} ~ ${item.value[1]}`})) } ) } CompDeliver.options = { addGlobalClass: true } export default React.forwardRef(CompDeliver)