203 lines
7.2 KiB
TypeScript
203 lines
7.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";
|
||
|
||
|
||
type DefaultValueParm = {
|
||
val: {name?: string, id?:string|number}
|
||
}
|
||
|
||
type Params = {
|
||
addressOnSelect?: (val:DefaultValueParm[]) => void,
|
||
addressOnClose?: () => void,
|
||
show?: true|false,
|
||
defaultValue?:any[]
|
||
}
|
||
|
||
type AddresParam = {
|
||
ad_code?: string,
|
||
id?: number,
|
||
level?: number,
|
||
level_name?: string,
|
||
name?: string,
|
||
parent_id?: number
|
||
}
|
||
|
||
|
||
export default memo(({
|
||
addressOnSelect,
|
||
addressOnClose,
|
||
show = false,
|
||
defaultValue = []
|
||
}: 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<any[]>([]) //选中的省市区
|
||
const [cityStatus, setCityStatus] = useState(false) //城市是否存在
|
||
const [areaStatus, setAreaStatus] = 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)
|
||
}
|
||
}, [defaultValue])
|
||
|
||
|
||
//获取地址
|
||
const {fetchData} = GetAddressListApi()
|
||
useEffect(() => {
|
||
getProvince()
|
||
}, [])
|
||
|
||
//选中内容
|
||
const selectItem = (item) => {
|
||
setSelectId(item.id)
|
||
if(selectIndex == 0) {
|
||
setSelectArr([{name:item.name, id:item.id}])
|
||
getCity(item.id)
|
||
setAreaStatus(false)
|
||
setCityStatus(false)
|
||
} else if(selectIndex == 1){
|
||
setSelectArr([selectArr[0], {name:item.name, id:item.id}])
|
||
area(item.id)
|
||
} else {
|
||
setSelectArr([selectArr[0], selectArr[1], {name:item.name, id:item.id}])
|
||
getDomDes('#address_tab_2')
|
||
}
|
||
}
|
||
|
||
//选中标题
|
||
const onSelectIndex = (index) => {
|
||
setSelectIndex(index)
|
||
const selectid = selectArr[index]?selectArr[index].id:0
|
||
setSelectId(selectid)
|
||
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')
|
||
} else {
|
||
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')
|
||
} else {
|
||
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={() => addressOnClose?.()}>
|
||
<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>
|
||
{(selectId == item.id)&&<View className={`iconfont icon-a-tick1 ${styles.address_iconfont}` }></View>}
|
||
</View>
|
||
)
|
||
})}
|
||
</View>
|
||
</ScrollView>
|
||
</View>
|
||
</View>
|
||
</Drawer>
|
||
</>
|
||
)
|
||
}) |