220 lines
8.2 KiB
TypeScript
220 lines
8.2 KiB
TypeScript
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>
|
||
</>
|
||
)
|
||
}) |