import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; import { Form, Input, Button, message } from "antd"; import style from 'styled-components'; import PLoading from './PLoading' import PCascader from './PCascader' import bcx_utils from '../../common/bcx_utils' const FormItem = Form.Item; export const formItemLayout2 = { labelCol: { xs: { span: 24 }, sm: { span: 3 } }, wrapperCol: { xs: { span: 24 }, sm: { span: 21 }, md: { span: 21 } } }; /* //this.props.init 事例 const init = { points: [116.396636, 39.869063], address: "北京市市辖区东城区-东城区中医药特色健康管理社区", area: [110000, 110100, 110101], }; */ export default class PMap extends PureComponent { state = { loading: true, area: [],//所在区域 省市区 address: "",//详细地址 points: [0, 0],//坐标 ifSearch: false,//是否初始化过地址(根据父组件 init 信息) taskCityName: this.props.taskCityName || '', }; static defaultProps = { ifProvince: true, } static propTypes = { areaChange: PropTypes.func, taskCityName: PropTypes.string, init: PropTypes.shape({ points: PropTypes.array, address: PropTypes.string, area: PropTypes.array }), ifProvince: PropTypes.bool,//是否显示 省市区 ,并根据省市区 搜索地址。 } /******************************生命周期******************************/ componentWillMount = () => { this.loadMapScript(); } componentDidMount = () => { } componentWillReceiveProps = (nextProps, newState) => { if ((this.props.init) && !this.state.ifSearch) { this.loading(); } } //加载地图依赖 loadMapScript = () => { // 高德地图 const script = document.createElement("script"); script.src = "http://webapi.amap.com/maps?v=1.4.4&key=9066916e054aa3083a6f081a2a9f9d7a"; document.body.appendChild(script); const script2 = document.createElement("script"); script2.src = "http://cache.amap.com/lbs/static/addToolbar.js"; document.body.appendChild(script2); this.loading(); }; loading = () => { let _this = this; function nextStep() { return new Promise((resolve) => { setTimeout(() => { resolve("AMap" in window); }, 500); }); } async function ajaxMap() { let ifComplete = false; for (var i = 0; i < 10; i++) { if (!ifComplete) { ifComplete = await nextStep(); } else { if (ifComplete) { console.log("地图初始化中。。。"); _this.initializeMap(); } else { message.error("网络超时") } } } } ajaxMap(); } //初始化生成地图 initializeMap = (lng, lat) => { let config = { resizeEnable: true, zoom: 14, }; if (lng && lat) { config = { ...config, ...{ center: [lng, lat] } } } this.map = new AMap.Map("gaodeMapContainer", config); if ("showInitialMarker" in this) { this.showInitialMarker = false; } //是否显示初始化的标注 let showInitialMarker = this.showInitialMarker; if (showInitialMarker) { let marker = new AMap.Marker({ icon: "http://webapi.amap.com/theme/v1.3/markers/n/mark_r.png", position: [lng, lat] }); marker.setMap(map); } this.setState({ loading: false }); //根据 父组件 props 查找地点 if ((this.props.init) && !this.state.ifSearch) { const { init: { points: [lng, lat], address, area = [] } } = this.props; //判读是否包含省份信息 if (address.includes("-")) { const [province, detail] = address.split("-"); this.setState({ points: [lng, lat], address: detail, area: province, ifSearch: true }, () => { this.search(); }); } else { this.setState({ points: [lng, lat], address, area: [], ifSearch: true }, () => { this.search(); }); } } } pCascaderChange = (value, selectedOptions) => { this.setState({ area: selectedOptions, address: "" }); } //详细地址栏 change 事件 addressChange = (para) => { let value = ""; const { ifProvince } = this.props; let area; if (ifProvince) { area = this.changeAdress(this.state.area); } else { area = this.props.taskCityName; } if (Object.prototype.toString.call(para).slice(8, -1) === "String") { value = para; } else { value = para.target.value; //强制不可删除 省市区前缀 if (value.length < area.length) { return; } // if (!value.includes(area)) { // return; // } value = value.replace(area, ''); } this.setState({ address: value }); return value; } //地区级联框地址转换 changeAdress = (arr) => { if (!this.props.ifProvince) { return ""; } if (typeof arr === "string") { return arr; } return [...arr].reduce((acc, item) => acc += item.label, ''); } //搜索地址 search = () => { const { area, address } = this.state; //判断选择省市区 if (area.length === 0 && this.props.ifProvince) { bcx_utils.preventRepeatAsync((callback) => callback((resolve) => { message.warning('请选择省市区', 1.5, () => { window.setTimeout(() => { resolve(); }, 500); }); })) return; } //判断选择省市区 if (area.length === 0 && address === "") { bcx_utils.preventRepeatAsync((callback) => callback((resolve) => { message.warning('请填写地址', 1.5, () => { window.setTimeout(() => { resolve(); }, 500); }); })) return; } const { ifProvince } = this.props; let addressDetail; if (ifProvince) { addressDetail = this.changeAdress(area) + address; } else { addressDetail = this.props.taskCityName + address; } this.showInitialMarker = false; this.mapSearch(addressDetail); } //地图搜索地址 mapSearch = (addressDetail) => { const { AMap } = window; //搜索该地址,并生成标记点 AMap.service('AMap.PlaceSearch', () => { //实例化PlaceSearch let placeSearch = new AMap.PlaceSearch(); //TODO: 使用placeSearch对象调用关键字搜索的功能 placeSearch.search(addressDetail, (status, result) => { const messageTip = () => { bcx_utils.preventRepeatAsync((callback) => callback((resolve) => { message.warning(`当前搜索地址:${addressDetail} 暂无记录`, 1.5, () => { window.setTimeout(() => { resolve(); }, 500); }); })) } //判断是否有结果 if (Object.keys(result).length === 0) { messageTip(); return; } if (result.poiList.pois.length === 0) { messageTip(); return; } const { poiList: { pois: [{ location: { lng = 0, lat = 0 }, name }, ...other] } } = result; this.saveResult(lng, lat, name);//保存结果 this.initializeMap(lng, lat);//重新构建地图 //生成标记点 // result.poiList.pois.map(({location: {lng, lat}, name}) => { // this.addMarker(lng, lat, name); // }); this.addMarker(...result.poiList.pois); }); }) } //生成标记点(气泡) addMarker = (...para) => { for (let { location: { lng, lat }, name } of para) { let marker = new AMap.Marker({ icon: "http://webapi.amap.com/theme/v1.3/markers/n/mark_b.png", position: [lng, lat] }); marker.setMap(this.map); marker.on('click', () => { this.saveResult(lng, lat, name);//保存结果 }); } } //保存结果,并调用 回调函数 saveResult = (lng, lat, name) => { this.setState({ points: [lng, lat], }); //将第一个结果放在输入地址中 const addressDetail = this.addressChange(name); if ("areaChange" in this.props) { const area = [...this.state.area]; const { ifProvince } = this.props; let province; if (ifProvince) { province = this.changeAdress(area); } else { province = this.props.taskCityName; } if (!this.props.ifProvince) { this.props.areaChange([lng, lat], addressDetail); return; } //增加省市区前缀 const cascader = area.reduce((acc, item) => acc.concat([item.value]), []); this.props.areaChange([lng, lat], addressDetail, province + "-" + cascader); } } render() { const { loading, area, address, taskCityName } = this.state; const { ifProvince } = this.props; let areaStr; if (ifProvince) { areaStr = this.changeAdress(area); } else { areaStr = taskCityName } return (