2022-10-19 17:37:24 +08:00

220 lines
8.2 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 { ScrollView, Text, View } from "@tarojs/components";
import { memo, ReactHTMLElement, useEffect, useRef, useState } from "react";
import Drawer from "@/components/popup";
import styles from "./index.module.scss"
import classnames from "classnames";
import Taro from "@tarojs/taro";
import { GetAddressListApi } from "@/api/addressList";
import { alert } from "@/common/common";
import IconFont from "../iconfont/iconfont";
type DefaultValueParm = { name: string, id: string | number, level?: number | string }
type Params = {
addressOnSelect?: (val: DefaultValueParm[]) => void,
addressOnChange?: (val: DefaultValueParm[]) => void,
addressOnClose?: () => void,
show?: true | false,
defaultValue?: DefaultValueParm[]
selectStatus?: false | true, //false不需要选择完整地址true需要选择完整地址
}
type AddresParam = {
ad_code?: string,
id?: number,
level?: number,
level_name?: string,
name?: string,
parent_id?: number,
}
export default memo(({
addressOnSelect,
addressOnChange,
addressOnClose,
show = false,
defaultValue = [],
selectStatus = true
}: Params) => {
//省
const provinceList = useRef<AddresParam[]>([])
//市
const cityList = useRef<AddresParam[]>([])
//区
const areaList = useRef<AddresParam[]>([])
const [list, setList] = useState<AddresParam[]>([])
const [selectIndex, setSelectIndex] = useState(0) //0 省, 1 市2 区
const [selectId, setSelectId] = useState(1) //选中的id
const [selectArr, setSelectArr] = useState<DefaultValueParm[]>([]) //选中的省市区
const [cityStatus, setCityStatus] = useState(false) //城市是否存在
const [areaStatus, setAreaStatus] = useState(false) //区镇是否存在
const [confirmBtnStatus, setConfirmBtnStatus] = useState(false) //确认按钮是否可用
const [bottomStyle, setBottomStyle] = useState({ width: '100rpx', left: '0rpx' }) //底部滚动条样式
useEffect(() => {
if (selectArr.length == 0) {
setSelectArr(defaultValue)
if (defaultValue.length > 1) setCityStatus(true)
if (defaultValue.length > 2) setAreaStatus(true)
if (defaultValue.length > 0) setConfirmBtnStatus(true)
}
}, [defaultValue])
//获取地址
const { fetchData } = GetAddressListApi()
useEffect(() => {
getProvince()
}, [])
//选中内容
const selectItem = (item) => {
setSelectId(item.id)
if (selectIndex == 0) {
setSelectArr([{ name: item.name, id: item.id, level: item.level }])
getCity(item.id)
setAreaStatus(false)
setCityStatus(false)
} else if (selectIndex == 1) {
setSelectArr([selectArr[0], { name: item.name, id: item.id, level: item.level }])
area(item.id)
} else {
setSelectArr([selectArr[0], selectArr[1], { name: item.name, id: item.id, level: item.level }])
getDomDes('#address_tab_2')
}
}
//地址数据
useEffect(() => {
if (selectArr && selectArr.length > 0)
addressOnChange?.(selectArr)
}, [selectArr])
//选中标题
const onSelectIndex = (index) => {
setSelectIndex(index)
const selectid = selectArr[index] ? selectArr[index].id : 0
setSelectId(selectid as number)
if (index == 0) {
getProvince()
} else if (index == 1) {
const id = selectArr[0]?.id
getCity(id)
} else {
const id = selectArr[1]?.id
area(id)
}
}
//获取省
const getProvince = async () => {
let res = await fetchData({ parent_id: 1 })
provinceList.current = res.data.list || []
if (provinceList.current.length > 0) {
setSelectIndex(0)
setList(() => provinceList.current)
getDomDes('#address_tab_0')
}
}
//获取市
const getCity = async (id) => {
let res = await fetchData({ parent_id: id })
cityList.current = res.data.list || []
if (cityList.current.length > 0) {
setSelectIndex(1)
setList(() => cityList.current)
setCityStatus(true)
getDomDes('#address_tab_1')
setConfirmBtnStatus(false)
} else {
setConfirmBtnStatus(true)
setCityStatus(false)
}
}
//获取区
const area = async (id) => {
let res = await fetchData({ parent_id: id })
areaList.current = res.data.list || []
if (areaList.current.length > 0) {
setSelectIndex(2)
setList(() => areaList.current)
setAreaStatus(true)
getDomDes('#address_tab_2')
setConfirmBtnStatus(false)
} else {
setConfirmBtnStatus(true)
setAreaStatus(false)
}
}
//确定按钮
const submitSelect = () => {
addressOnClose?.()
addressOnSelect?.(selectArr)
}
//获取省市区宽度
const getDomDes = (id) => {
setTimeout(() => {
let query = Taro.createSelectorQuery();
query.select(id).boundingClientRect(rect => {
let left = rect.left;
let clientWidth = rect.width;
console.log(clientWidth)
setBottomStyle({
width: clientWidth + 'px',
left: left + 'px'
})
}).exec();
}, 100)
}
//点击标题栏
const selectTab = (index) => {
onSelectIndex(index)
getDomDes('#address_tab_' + index)
}
return (
<>
<Drawer showTitle={false} show={show} onClose={submitSelect}>
<View className={styles.address_main}>
<View className={styles.address_title}>
<View onClick={() => addressOnClose?.()}></View>
<View onClick={() => submitSelect()}></View>
</View>
<View className={styles.address_select}>
<View id="address_tab_0" onClick={() => selectTab(0)} className={classnames(styles.address_item, { [styles.addresst_select]: (selectIndex == 0) })}>{selectArr[0] ? selectArr[0].name : '请选择'}</View>
{cityStatus && <View id="address_tab_1" onClick={() => selectTab(1)} className={classnames(styles.address_item, { [styles.addresst_select]: (selectIndex == 1) })}>{selectArr[1] ? selectArr[1].name : '请选择'}</View>}
{areaStatus && <View id="address_tab_2" onClick={() => selectTab(2)} className={classnames(styles.address_item, { [styles.addresst_select]: (selectIndex == 2) })}>{selectArr[2] ? selectArr[2].name : '请选择'}</View>}
<View style={bottomStyle} className={styles.bottom_index}></View>
</View>
<View className={styles.address_list}>
<ScrollView scrollY className={styles.address_scroll}>
<View className={styles.address_scroll_list}>
{list.map(item => {
return (
<View onClick={() => selectItem(item)} className={classnames(styles.address_list_item, { [styles.addresst_select]: (selectId == item.id) })}>
<View className={styles.address_list_item_name}>{item.name}</View>
{(selectArr[selectIndex]?.id == item.id) &&
<IconFont name={'icon-lujing'} color={'#327fff'} size={30}></IconFont>
}
</View>
)
})}
</View>
</ScrollView>
</View>
</View>
</Drawer>
</>
)
})