sug列表

image.png

// 取消搜索的ck
 onCancelTextClick = () => {
        Taro.navigateBack();
 };
// 点击回车搜索的ck
 searchQuery = query => {
        Taro.redirectTo({
            url: `${pagePath.searchResult}?query=${query}&type=${this.state.type}`
        });
    };
// 点击历史记录的ck
onClickQuery = query => {
        this.searchQuery(query);
    };

2、Sug列表

sug要求:
根据用户输入关键字,生成不同的sug列表。
分为2类,项目词和机构词。在获取到用户地理位置的情况下,额外显示用户与机构之间的距离。

获取地理信息

class NewSearchPage extends Component {
    constructor(args) {
        super(args);
        const query = this.$router.params.query && decodeURI(this.$router.params.query) || '';
        const type = this.$router.params.type || ResultListType.zonghe;
        const placeholder = this.$router.params.placeholder && decodeURI(this.$router.params.placeholder) || '';
        this.state = {
            query: query === 'undefined' ? '' : query,
            type,
            searchContent: '',
            placeholder : placeholder === 'undefined' ? '' : placeholder,
            latitude: null,
            longitude: null
        };
    };
  componentDidMount() {
      this.getLocationInfo();
      this.getSugList(this.state.query);
  }
 getLocationInfo = () => {
        return new Promise(resolve => {
            getLocation2().then(({latitude, longitude}) => {
                this.setState({
                    latitude,
                    longitude
                });
                resolve();
            });
        });
    }

 getSugList(query) {
        // getCity接口,后端根据IP返回userCity
        query === '' ? this.onInputClear() : getCity().then(city => {
            const paramObj = {
                query,
                userCityName: city,
                latitude: JSON.stringify(this.state.latitude),
                longitude: JSON.stringify(this.state.longitude)
            };
            searchApi.getSugList(paramObj).then(res => {
                if (res.code === 0 && res.data) {
                    this.setState({
                        sugList: res.data.sugList,
                        query: query.trim()
                    });
                } else {
                    this.setState({
                        sugList: []
                    });
                }
            });
        });
    }

image.png

 onQuerySearch = query => {
        this.setState({
            searchContent: query
        },() => {
            this.searchQuery(query);
        });
    };
// 输入事件监听
 onQueryChange = debounce(query => {
        this.getSugList(query);
    }, 200, false);

<NewSearchInputBar
//  keyboardShow={keyboardShow} 
//  onQuerySearch={this.onQuerySearch}
    onQueryChange={this.onQueryChange}
    cancelTextShow={cancelTextShow} // 取消搜索的ck
    onCancelTextClick={this.onCancelTextClick}
    onInputClear={this.onInputClear} // 清空输入框的ck
    placeholder={this.state.placeholder}
    focus={focus}
    value={this.state.query}
    clear
/>
this.state.query === '' || (this.state.sugList && this.state.sugList.length <= 0)
    ? <NewSearchHistoryLayer
        hotSearchWords={this.state.hotSearchWords}
        searchContent={this.state.searchContent}
        onClickQuery={this.onClickQuery}
    />
    : (this.state.sugList && this.state.sugList.length > 0) && <SugList
        list={this.state.sugList}
        query={this.state.query}
        isHasParams={this.state.latitude ? true : false}
    ></SugList>

sug列表组件

import HospitalSugCard from './hospitalSugCard';
import ProjectSugCard from './projectSugCard';
import {ResultListType} from '@src/packageSearch/pages/result/model';
import {pagePath} from "@src/common/constant/constant";

enum SugType {
    project = 'project',
    hospital = 'hospital'
};

const HREF_TYPE = {
    [SugType.hospital]: ResultListType.hospital,
    [SugType.project]: ResultListType.zonghe
};

export interface ProjectSug {
    sug: string;
    contentType: string;
    count: number;
    query: string;
};

export interface HospitalSug {
    sug: string;
    contentType: string;
    hospitalId: number;
    province: string;
    city: string;
    address: string;
    doctorCount: number;
    goodsCount: number;
    distance: string;
    query: string;
    isHasParams: Boolean;
}

type SugItem = HospitalSug | ProjectSug;

export interface SugListProps {
    list: SugItem[];
    query: string,
    isHasParams: Boolean
};

const SugList = (props: SugListProps) => {
    const {list, query, isHasParams} = props;
    const onClickQuery = (sugType, obj, index) => {
        const url = sugType === SugType.hospital
                    ? `${pagePath.hospitalDetail}?id=${obj.hospialId}&name=${obj.sug}`
                    : `${pagePath.searchResult}?query=${obj.sug}&type=${HREF_TYPE[sugType]}`;
        Taro.redirectTo({
            url
        });
    };

    const listEl = list.map((item, index) => {
        const type = item.contentType;
        const showProjectSugCard = type === SugType.project ||
            (type !== SugType.project && type !== SugType.hospital);
        const showHospitalSugCard = type === SugType.hospital;
        return (
            <View className='sug-list-item' onClick={() => onClickQuery(type, item, index)}>
                {showProjectSugCard && <ProjectSugCard {...(item as ProjectSug)} query={query}></ProjectSugCard>}
                {showHospitalSugCard && <HospitalSugCard {...(item as HospitalSug)} query={query} isHasParams={isHasParams}></HospitalSugCard>}
            </View>
        );
    });
    return (
        <View className='sug-list'>
            {listEl}
        </View>
    );
};

export default SugList;

hospitalSugCard

const HospitalSugCard = (props: HospitalSug) => {
    const distance = (Number(props.distance) / 1000).toFixed(1);
    const {sug, query, isHasParams, goodsCount, doctorCount} = props;
    const isShowDistance = (!!props.distance) && isHasParams;
    return (
        <View className='sug-hospital'>
            <View className='sug-common'>
                <View className='sug-hospital-name sug-common-left'>
                    <Image className='sug-item-img' src={bosImgs.searchHospital} />
                    <View className='sug-item-title single-line'>
                        <HighLight content={sug} highlightWords={query} />
                    </View>
                    <Image className='sug-hospital-sign'
                        src='https://lemon.cdn.bcebos.com/lemon-taro-c/anesthesiologist_attestation.png'
                    />
                </View>
                {isShowDistance && (!distance ? '' : <View className='sug-hospital-distance sug-common-right'>
                    {`${Number(distance) > 50 ? '>50' : distance}km`}
                </View>)}
            </View>
            <View className='sug-hospital-bottom'>
                <Text className='sug-goodsCount'>商品数:{goodsCount}</Text>
                <Text className='sug-doctorCount'>医生数:{doctorCount}</Text>
            </View>
        </View>
    );
};
export default HospitalSugCard;

3、飘黄highLight组件

/*
 * @file: 搜索结果页搜索词飘黄显示
 */

import {View, Text, Block} from "@tarojs/components";
import handlePosition from './handlePosition';
import './highlight.scss';

/**
 * @param content  需要飘黄处理的字段
 * @param highlightPos  飘黄位置
 * @param highlightWords  飘黄文字
 * @param children  文本前可选添加内容
 * @param type  卡片类型
 * @param doHighLight 是否要飘黄,例如机构相关推荐部分,无需飘黄传false
 */
interface HighlightParams {
    content: string;
    highlightPos?: string [];
    highlightWords?: string;
    children?: JSX.Element;
    type?: string;
    doHighLight?: boolean;
};

4、拓展:

函数防抖:

function debounce(fn, delay = 500, immediate = true) {
    let timer = null;
    return function () {
        const context = this;
        const args = arguments;
        return new Promise((resolve, reject) => {
            timer && clearTimeout(timer);
            if (immediate) {
                const doNow = !timer;
                timer = setTimeout(() => {
                    timer = null;
                }, delay);
                doNow && resolve(fn.apply(context, args));
            } else {
                timer = setTimeout(() => {
                    resolve(fn.apply(context, args));
                }, delay);
            }
        });
    };
}

地理位置

// 获取地理位置 + 超时判断
export const getLocation2 = (time = 1500) => {
    return new Promise((resolve, reject) => {
        getLocation().then(resolve)
            .catch(() => {
                reject();
            });
    });
};

Taro中获取经纬度


export const getLocation = (timeout = 5000) => {
    return new Promise(function (resolve, reject) {
        const latitude = Taro.getStorageSync(v.latitude);
        const setTime = Taro.getStorageSync(v.setPosTime);
        const currentTime = new Date().getTime();
        if (latitude && currentTime - Number(setTime) < 8640000) {
            resolve({
                longitude: Taro.getStorageSync(v.longitude),
                latitude: Taro.getStorageSync(v.latitude)
            });
        } else {
            // H5中,taro最后实际调用的是window.navigator.geolocation.getCurrentPosition
            // 这个方法在某些特殊case下不会有回调,设置一个超时时间,强制失败
            const timer = setTimeout(() => {
                reject();
            }, timeout);
            Taro.getLocation().then(({latitude, longitude}) => {
                Taro.setStorage({key: v.latitude, data: latitude});
                Taro.setStorage({key: v.longitude, data: longitude});
                Taro.setStorage({key: v.setPosTime, data: `${currentTime}`});
                clearTimeout(timer);
                resolve({
                    latitude,
                    longitude
                });
            })
                .catch(() => {
                    clearTimeout(timer);
                    reject();
                });
        }
    });
};

toFixed() 方法使用定点表示法来格式化一个数值。

function financial(x) {
  return Number.parseFloat(x).toFixed(2);
}

console.log(financial(123.456));
// expected output: "123.46"

console.log(financial(0.004));
// expected output: "0.00"

digits
小数点后数字的个数;介于 0 到 20 (包括)之间,实现环境可能支持更大范围。如果忽略该参数,则默认为 0。
返回值
使用定点表示法表示给定数字的字符串。

猜你喜欢

转载自www.cnblogs.com/coderwang/p/12468609.html