zoukankan      html  css  js  c++  java
  • taro3.x: 查询条件

    tsx:

    import React, { useEffect, useState } from 'react'
    import { View, Text, ScrollView, Image } from '@tarojs/components'
    import classnames from 'classnames'
    import { find, remove } from 'lodash'
    
    import api from '@services/api'
    import app from '@services/request'
    import NavBar from '@components/navbar/index'
    import useNavData from '@hooks/useNavData'
    import { PRICE_TYPE, SALE_STATUS } from '@constants/house'
    import '@styles/common/house-list.scss'
    import '@styles/common/search-tab.scss'
    import './index.scss'
    
    interface IFilter {
        id: string
        name: string
        value?: string
    }
    
    interface IConditionState {
        region?: IFilter
        unit_price?: IFilter
        total_price?: IFilter
        house_type?: IFilter
        house_property?: IFilter
        sale_status?: IFilter
        renovation?: IFilter
        feature?: IFilter
    
    }
    
    const initial_value = { id: '', name: '', value: '' }
    
    const INIT_CONDITION = {
        region: { id: 'all000', name: '不限', value: '' },
        unit_price: { id: 'all000', name: '不限', value: '' },
        total_price: initial_value,
        house_type: { id: 'all000', name: '不限', value: '' },
        house_property: initial_value,
        sale_status: initial_value,
        renovation: initial_value,
        feature: initial_value
    }
    
    const NewHouse = () => {
        const { appHeaderHeight, contentHeight } = useNavData()
        const footerBtnHeight = 60
        const scrollHeight = contentHeight * 0.5 - footerBtnHeight
        const scrollMoreHeight = contentHeight * 0.6 - footerBtnHeight
        const [tab, setTab] = useState<string>('')
        const [priceType, setPriceType] = useState<string>('unit_price')
        const [selected, setSelected] = useState<IConditionState>(INIT_CONDITION)
        const [condition, setCondition] = useState<any>()
        const [houseList, setHouseList] = useState<any>([])
        const tabs = [
            {
                type: 'region',
                name: '区域',
                keys: ['region']
            },
            {
                type: 'price',
                name: '价格',
                keys: ['unit_price', 'total_price']
            },
            {
                type: 'house_type',
                name: '户型',
                keys: ['house_type']
            },
            {
                type: 'more',
                name: '更多',
                keys: ['house_property', 'sale_status', 'renovation', 'feature']
            }]
        const priceTabs = [
            {
                id: 'id_01',
                name: '按单价',
                value: "unit_price"
            },
            {
                id: 'id_02',
                name: '按总价',
                value: "total_price"
            }
        ]
    
        useEffect(() => {
            fetchCondition()
            fetchHouseList()
        }, [])
    
        const fetchCondition = () => {
            app.request({
                url: api.getHouseCondition,
                data: { type: 'newHouse' }
            }, {
                isMock: true,
                loading: false
            }).then((result: any) => {
                setCondition(result || {})
            })
        }
    
        const fetchHouseList = () => {
            app.request({
                url: api.getHouseNew,
                data: {}
            }, {
                isMock: true,
                loading: false
            }).then((result: any) => {
                setHouseList(result || [])
            })
        }
    
        const switchCondition = (item) => {
            if (tab === item.type) {
                setTab('')
                return
            }
            setTab(item.type)
        }
    
        const handleSingleClick = (key: string, item: any) => {
            setTab('')
            if (key === 'unit_price') {
                setSelected({
                    ...selected,
                    total_price: initial_value,
                    [key]: item
                })
            } else if (key === 'total_price') {
                setSelected({
                    ...selected,
                    unit_price: initial_value,
                    [key]: item
                })
            } else {
                setSelected({
                    ...selected,
                    [key]: item
                })
            }
        }
        const handleMultiClick = (key: string, item: any) => {
            let selectedValue = selected[key]
            if (selectedValue instanceof Object) {
                if (selectedValue.id === item.id) {
                    setSelected({
                        ...selected,
                        [key]: initial_value
                    })
                } else {
                    setSelected({
                        ...selected,
                        [key]: item
                    })
                }
            }
    
            if (selectedValue instanceof Array) {
                let target = find(selectedValue, { id: item.id })
                if (target) {
                    remove(selectedValue, { id: item.id })
                    setSelected({
                        ...selected,
                        [key]: selectedValue
                    })
                } else {
                    setSelected({
                        ...selected,
                        [key]: [...selectedValue, item]
                    })
                }
            }
        }
    
        const handleReset = () => {
            setSelected({
                ...selected,
                house_property: initial_value,
                renovation: initial_value,
                sale_status: initial_value,
                feature: initial_value
            })
        }
    
        const handleConfirm = () => {
            setTab('')
        }
    
        const renderSplitItem = (key: string) => {
            return (
                <ScrollView className="split-list flex-item" scrollY style={{ height: scrollHeight }}>
                    {
                        condition && condition[key].map((item: any, index: number) => (
                            <View
                                key={index}
                                className={classnames("split-item", selected[key].id === item.id && 'actived')}
                                onClick={() => handleSingleClick(key, item)}
                            >{item.name}
                            </View>
                        ))
                    }
                </ScrollView>
            )
        }
    
        const renderMultiItem = (key: string, title: string = '') => {
            return (
                <View className="search-multi-item">
                    {title && <View className="title">{title}</View>}
                    <View className="options">
                        {
                            condition && condition[key].map((item: any, index: number) => (
                                <View
                                    key={index}
                                    className={classnames("options-item", selected[key].id === item.id && 'actived')}
                                    onClick={() => handleMultiClick(key, item)}
                                >
                                    {item.name}
                                </View>
                            ))
                        }
                    </View>
                </View>
            )
        }
    
        const renderShowName = (item: any) => {
            let showList: string[] = []
            for (const key of item.keys) {
                if (selected[key] instanceof Object) {
                    let showName: string = selected[key].name
                    if (!showName || ['不限', '全部'].includes(showName)) {
                        continue
                    }
                    showList.push(showName)
                }
            }
    
            if (showList.length > 1) {
                showList = ['多选']
            }
    
            return showList.join(',')
        }
        return (
            <View className="newhouse">
                <NavBar title="新房" back={true} />
                <View className="fixed-top" style={{ top: appHeaderHeight }}>
                    <View className="newhouse-header view-content">
                        <View className="newhouse-search">
                            <Text className="iconfont iconsearch"></Text>
                            <Text className="newhouse-search-text placeholder">请输入楼盘名称或地址</Text>
                        </View>
                        <View className="newhouse-nav-right">
                            <Text className="iconfont iconmap"></Text>
                            <Text className="text">地图找房</Text>
                        </View>
                    </View>
                    <View className="search-tab">
                        {
    
                            tabs.map((item: any, index: number) => {
                                let showName = renderShowName(item)
                                return (
                                    <View
                                        key={index}
                                        className={classnames('search-tab-item', showName && 'actived')}
                                        onClick={() => switchCondition(item)}
                                    >
                                        <Text className="text">{showName ? showName : item.name}</Text>
                                        <Text className="iconfont iconarrow-down-bold"></Text>
                                    </View>
                                )
                            })
                        }
                    </View>
                    <View className={classnames('search-container', tab === 'region' && 'actived')}>
                        <View className="search-content">
                            <View className="search-split">
                                <View className="split-type flex-item">
                                    <View className="split-item actived">区域</View>
                                </View>
                                {renderSplitItem('region')}
                            </View>
                        </View>
                    </View>
                    <View className={classnames('search-container', tab === 'price' && 'actived')}>
                        <View className="search-content">
                            <View className="search-split">
                                <View className="split-type flex-item">
                                    {
                                        priceTabs.map((item: any) => (
                                            <View
                                                key={item.id}
                                                className={classnames("split-item", item.value === priceType && 'actived')}
                                                onClick={() => setPriceType(item.value)}>
                                                {item.name}
                                            </View>
                                        ))
                                    }
                                </View>
                                {renderSplitItem(priceType)}
                            </View>
                        </View>
                        {/* <View className="search-footer">
                            <Input className="search-input" placeholder="最低价" />-
                            <Input className="search-input" placeholder="最高价" />
                            <View className="btn confirm-btn single-btn">确定</View>
                        </View> */}
                    </View>
                    <View className={classnames('search-container', tab === 'house_type' && 'actived')}>
                        <View className="search-content">
                            <View className="search-split">
                                {renderSplitItem('house_type')}
                            </View>
                        </View>
                    </View>
                    <View className={classnames('search-container', 'search-multi-container', tab === 'more' && 'actived')}>
                        <ScrollView className="search-content search-content-scroll" scrollY style={{ maxHeight: scrollMoreHeight }}>
                            {renderMultiItem('house_property', '类型')}
                            {renderMultiItem('renovation', '装修')}
                            {renderMultiItem('sale_status', '状态')}
                            {renderMultiItem('feature', '特色')}
                        </ScrollView>
                        <View className="search-footer">
                            <View className="btn reset-btn" onClick={handleReset}>重置</View>
                            <View className="btn confirm-btn" onClick={handleConfirm}>确定</View>
                        </View>
                    </View>
                </View>
                <View className={classnames('mask', tab && 'show')} onClick={() => setTab('')}></View>
    
                <View className="newhouse-content">
                    <ScrollView className="house-list view-content" scrollY style={{ height: contentHeight - 85 }}>
                        <View className="house-list-ul">
                            {
                                houseList.length > 0 && houseList.map((item: any) => (
                                    <View className="house-list-li" key={item.id}>
                                        <View className="li-image">
                                            <Image src={item.image_path}></Image>
                                        </View>
                                        <View className="li-text">
                                            <View className="title mb10">
                                                <Text>{item.house_name}</Text>
                                            </View>
                                            <View className="small-desc mb10">
                                                <Text>{item.area && item.area.name}</Text>
                                                <Text className="line-split"></Text>
                                                <Text>建面{item.building_area}平米</Text>
                                            </View>
                                            <View className="mb10">
                                                <Text className="price">{item.price}</Text>
                                                <Text className="price-unit">{PRICE_TYPE[item.price_type]}</Text>
                                            </View>
                                            <View className="tags">
                                                <Text className={classnames('tags-item', `sale-status-${item.sale_status}`)}>{SALE_STATUS[item.sale_status]}</Text>
                                            </View>
                                        </View>
                                    </View>
                                ))
                            }
                        </View>
                    </ScrollView>
                </View>
            </View>
        )
    }
    export default NewHouse

    图例:

    scss:

    .search-tab {
        display: flex;
        justify-content: center;
        align-items: center;
        height: 80px;
        line-height: 80px;
        font-size: $font-basic;
        border-bottom: $border;
        background-color: $white;
        z-index: 99;
        &-item {
            flex: 1;
            text-align: center;
    
            &.actived {
                color: $primary-color;
    
                .iconfont {
                    color: $primary-color;
                }
            }
    
            .text {
                display: inline-block;
                max-width: 70%;
                white-space: nowrap;
                overflow: hidden;
                text-overflow: ellipsis;
                vertical-align: middle;
            }
    
            .iconfont {
                color: $desc-color;
                margin-left: 10px;
                vertical-align: middle;
            }
        }
    }
    
    .search-container {
        position: absolute;
        width: 100%;
        max-height: 50vh;
        z-index: -10;
        background-color: $white;
        font-size: $font-basic;
        transform: translateY(-100%);
        transition: 0.2s;
        &.actived {
            transform: translateY(0);
        }
        .search-content-scroll {
            margin-bottom: 120px;
        }
        .search-content {
            .search-split {
                display: flex;
    
                .flex-item {
                    flex: 1;
                    border-right: $border;
                }
                .flex-item:last-child {
                    border-right: 0;
                }
                .split-item {
                    height: 80px;
                    line-height: 80px;
                    padding-left: 30px;
                    border-bottom: $border;
                    &.actived {
                        color: $primary-color;
                        background-color: $bg-color;
                    }
                }
            }
    
            .search-multi-item {
                padding: 16px 24px;
                .title {
                    font-size: 30px;
                    color: $title-color;
                    padding: 10px;
                }
    
                .options {
                    display: flex;
                    flex-wrap: wrap;
    
                    &-item {
                        width: 19.5%;
                        margin: 8px;
                        text-align: center;
                        font-size: 24px;
                        padding: 14px 10px;
                        border: 0.5px solid $bg2-color;
                        border-radius: 6px;
                        background-color: $bg2-color;
                        color: $text-color;
    
                        &.actived {
                            color: $primary-color;
                            border-color: $primary-color;
                            background-color: $white;
                        }
                    }
                }
            }
        }
    
        .search-footer {
            position: absolute;
            bottom: 0;
            display: flex;
            width: 100%;
            justify-content: space-around;
            align-items: center;
            padding: 20px 0;
            background-color: #fff;
            .btn {
                width: 40%;
                line-height: 80px;
                text-align: center;
                border-radius: 6px;
    
                &.reset-btn {
                    color: $text-color;
                    background-color: $bg-color;
                }
    
                &.confirm-btn {
                    color: $white;
                    background-color: $primary-color;
                }
    
                &.single-btn {
                    width: 25%;
                }
            }
            .search-input {
                width: 25%;
                height: 80px;
                line-height: 80px;
                text-align: center;
                background-color: $bg-color;
            }
        }
    }
    
    .search-multi-container {
        max-height: 60vh;
    }
  • 相关阅读:
    小量程称重传感器
    一个苹果证书怎么多次使用——导出p12文件
    ios申请真机调试( xcode 5)详细解析
    iOS Developer:真机测试
    mac使用技巧
    How to Create a Provisioning Profile for iPhone
    ios申请真机调试( xcode 5)详细解析
    ui develop
    google ip address
    remove xcode recent projects from dock menu 移除xcode dock菜单显示的项目列表
  • 原文地址:https://www.cnblogs.com/Nyan-Workflow-FC/p/13667629.html
Copyright © 2011-2022 走看看