client-search
Version:
客户端搜索
135 lines (118 loc) • 3.78 kB
text/typescript
import * as qs from 'qs';
import moment from 'moment';
import { API, AMapQuery } from './api';
import { adapterAddressComponent, adapterDistrict, adapterTips } from './adapter';
interface IWindow {
fetch<T>(input: RequestInfo, init?: RequestInit): Promise<IApiResponse<T>>;
}
export default class Service {
constructor(private fetch: IWindow['fetch']) {}
/**
* 获取房源列表
*
* @param {HouseListParams} [body={}]
* @returns {Promise<IApiListResponse<IHouseDetail>>}
* @memberof Service
*/
public fetchHouseList(body: HouseListParams = {}): Promise<IApiListResponse<IHouseDetail>> {
const defaultResponse: IApiListResponse<IHouseDetail> = {
current: 0,
hasNextPage: false,
list: [],
pages: 0,
size: 0,
total: 0,
};
const queryData = { ...body };
if (body.beginDate) {
queryData.beginDate = moment(body.beginDate).format('YYYY-MM-DD');
}
if (body.endDate) {
queryData.endDate = moment(body.endDate).format('YYYY-MM-DD');
}
if (!body.limitImage) {
queryData.limitImage = 5;
}
if (!body.pageSize) {
queryData.pageSize = 10;
}
// 如果没有排序并且不是按位置搜索, 默认推荐排序
const sortKeys = ['rankingSort', 'starsSort', 'priceSort'];
if (!sortKeys.some(key => Reflect.has(queryData, key)) && !queryData.latitude) {
queryData.rankingSort = 0;
}
return this.fetch(API.SearchHouse + '?' + qs.stringify(queryData))
.then(response => {
if (!response || !response.data) {
return defaultResponse;
}
return response.data as IApiListResponse<IHouseDetail>;
})
.catch(() => defaultResponse);
}
/**
* 批量查找位置
*
* @param {string} keyword
* @returns {Promise<IAmapTips[]>}
* @memberof Service
*/
// tslint:disable-next-line:prefer-array-literal
public async batchSearchAddress(keywords: string): Promise<(IAmapTips | null)[]> {
function ops(poiType: AMapQuery) {
const querystring = qs.stringify({ datatype: 'poi', keywords, type: poiType });
return {
url: API.AmapOpsURL + querystring,
};
}
try {
const response = (await this.fetch(API.BathSearch, {
body: JSON.stringify({ ops: [ops(AMapQuery.normalType), ops(AMapQuery.allType)] }),
method: 'post',
})) as any;
const result = adapterTips(response as IAmapBatchResponse[]);
const returnResult: (IAmapTips | null)[] = [];
if (result[0]) {
returnResult.push.apply(returnResult, result[0]
.filter(v => !!v)
.map(v => ({ ...v, istrative: true })) as IAmapTips[]);
}
returnResult.push.apply(returnResult, result[1]);
return returnResult;
} catch (error) {
return [];
}
}
/**
* 地址逆装换
*
* @protected
* @param {ILocationBaseParams} location
* @returns {(Promise<IAddressComponent | null>)}
* @memberof Service
*/
public async georegeo(location: ILocationBaseParams): Promise<IAddressComponent | null> {
try {
const result = await this.fetch(`${API.regeo}&location=${location.longitude},${location.latitude}`);
return adapterAddressComponent(result as IGeoregeoResponse);
} catch (error) {
return null;
}
}
/**
* 区域转坐标
*
* @param {*} keyword
* @memberof Service
*/
public async districtToCoordinates(keyword?: string): Promise<ILocationBaseParams | null> {
if (!keyword) return null;
try {
const result = await this.fetch(`${API.AmapDistrict}&keywords=${keyword}`);
const [coord] = adapterDistrict(result as IDistrictResponse);
return coord;
} catch (error) {
return null;
}
}
}