mirror of
https://gitee.com/baidu/amis.git
synced 2024-11-29 18:39:05 +08:00
* fix(amis): 地理位置选择组件/只读模式,不展示地图控件,不支持位置选择操作 * feat(amis): Location地理选择组件增加autoSelectCurrentLoc和onlySelectCurrentLoc配置项 * docs(amis): 补充地理选择组件的新增配置说明 * feat(amis-editor): Location地理选择组件增加autoSelectCurrentLoc和onlySelectCurrentLoc可视化配置 * fix(amis-editor): 完善Location地理选择组件的placeholder配置 * docs(amis): 增加Location地理选择组件Schema属性说明
This commit is contained in:
parent
29cb3b4ea1
commit
ef48b59d13
@ -60,5 +60,7 @@ order: 30
|
||||
| vendor | 'baidu' | 'baidu' \| 'gaode' | 地图厂商,目前只实现了百度地图和高德地图 |
|
||||
| ak | `string` | 无 | 百度/高德地图的 ak |
|
||||
| clearable | `boolean` | false | 输入框是否可清空 |
|
||||
| placeholder | `string` | '请选择位置' | 默认提示 |
|
||||
| coordinatesType | `string` | 'bd09' | 默为百度/高德坐标,可设置为'gcj02', 高德地图不支持坐标转换 |
|
||||
| placeholder | `string` | '请选择位置' | 默认提示 |
|
||||
| autoSelectCurrentLoc | `boolean` | false | 是否自动选中当前地理位置 |
|
||||
| onlySelectCurrentLoc | `boolean` | false | 是否限制只能选中当前地理位置,设置为true后,可用于充当定位组件 |
|
||||
| coordinatesType | `string` | 'bd09' | 默为百度/高德坐标,可设置为'gcj02', 高德地图不支持坐标转换 |
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {EditorNodeType, getSchemaTpl} from 'amis-editor-core';
|
||||
import {EditorNodeType, getSchemaTpl, tipedLabel} from 'amis-editor-core';
|
||||
import {registerEditorPlugin} from 'amis-editor-core';
|
||||
import {BasePlugin, BaseEventContext} from 'amis-editor-core';
|
||||
import {ValidatorTag} from '../../validator';
|
||||
@ -82,11 +82,30 @@ export class LocationControlPlugin extends BasePlugin {
|
||||
{label: '国测局坐标', value: 'gcj02'}
|
||||
]
|
||||
},
|
||||
|
||||
getSchemaTpl('switch', {
|
||||
name: 'autoSelectCurrentLoc',
|
||||
label: tipedLabel(
|
||||
'自动选择',
|
||||
'开启后,自动选中用户当前的地理位置'
|
||||
)
|
||||
}),
|
||||
getSchemaTpl('switch', {
|
||||
name: 'onlySelectCurrentLoc',
|
||||
label: tipedLabel(
|
||||
'只读模式',
|
||||
'开启后,只能使用当前地理位置,不可选择其他地理位置'
|
||||
)
|
||||
}),
|
||||
getSchemaTpl('clearable'),
|
||||
getSchemaTpl('labelRemark'),
|
||||
getSchemaTpl('remark'),
|
||||
getSchemaTpl('placeholder'),
|
||||
getSchemaTpl('placeholder', {
|
||||
visibleOn: '!onlySelectCurrentLoc'
|
||||
}),
|
||||
getSchemaTpl('placeholder', {
|
||||
name: 'getLocationPlaceholder',
|
||||
visibleOn: 'onlySelectCurrentLoc'
|
||||
}),
|
||||
getSchemaTpl('description')
|
||||
]
|
||||
},
|
||||
|
@ -38,6 +38,8 @@ interface MapPickerProps {
|
||||
city?: string;
|
||||
};
|
||||
onChange?: (value: any) => void;
|
||||
autoSelectCurrentLoc?: boolean;
|
||||
onlySelectCurrentLoc?: boolean;
|
||||
}
|
||||
|
||||
interface LocationItem {
|
||||
@ -109,6 +111,7 @@ export class BaiduMapPicker extends React.Component<
|
||||
|
||||
@autobind
|
||||
async initMap() {
|
||||
const autoSelectCurrentLoc = this.props.autoSelectCurrentLoc ?? false;
|
||||
const map = new BMap.Map(this.mapRef.current, {
|
||||
enableMapClick: false
|
||||
});
|
||||
@ -137,11 +140,14 @@ export class BaiduMapPicker extends React.Component<
|
||||
|
||||
const geolocationControl = new BMap.GeolocationControl();
|
||||
geolocationControl.addEventListener('locationSuccess', (e: any) => {
|
||||
this.getLocations(e.point);
|
||||
this.getLocations(e.point, autoSelectCurrentLoc);
|
||||
});
|
||||
map.addControl(geolocationControl);
|
||||
|
||||
map.addEventListener('click', (e: any) => {
|
||||
if (this.props.onlySelectCurrentLoc) {
|
||||
return;
|
||||
}
|
||||
this.getLocations(e.point, true);
|
||||
});
|
||||
|
||||
@ -187,7 +193,8 @@ export class BaiduMapPicker extends React.Component<
|
||||
value ? this.getLocations(point) : geolocationControl.location();
|
||||
}
|
||||
|
||||
getLocations(point: any, select?: boolean) {
|
||||
@autobind
|
||||
getLocations(point: any, selectCurrentLoc?: boolean) {
|
||||
const map = this.map;
|
||||
|
||||
map.clearOverlays();
|
||||
@ -231,7 +238,7 @@ export class BaiduMapPicker extends React.Component<
|
||||
locs
|
||||
},
|
||||
() => {
|
||||
if (!select) {
|
||||
if (!selectCurrentLoc) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -318,7 +325,7 @@ export class BaiduMapPicker extends React.Component<
|
||||
});
|
||||
|
||||
var local = new BMap.LocalSearch(this.map, {
|
||||
//智能搜索
|
||||
// 智能搜索
|
||||
onSearchComplete: () => {
|
||||
const results = local.getResults();
|
||||
const poi = results.getPoi(0);
|
||||
@ -334,20 +341,23 @@ export class BaiduMapPicker extends React.Component<
|
||||
|
||||
render() {
|
||||
const {classnames: cx} = this.props;
|
||||
const onlySelectCurrentLoc = this.props.onlySelectCurrentLoc ?? false;
|
||||
const {locIndex, locs, inputValue, sugs} = this.state;
|
||||
const hasSug = Array.isArray(sugs) && sugs.length;
|
||||
|
||||
return (
|
||||
<div className={cx('MapPicker')}>
|
||||
<div className={cx('MapPicker-search TextControl-control')}>
|
||||
<div className={cx('TextControl-input')}>
|
||||
<input
|
||||
onChange={this.handleChange}
|
||||
value={inputValue}
|
||||
placeholder="搜索地点"
|
||||
/>
|
||||
{!onlySelectCurrentLoc && (
|
||||
<div className={cx('MapPicker-search TextControl-control')}>
|
||||
<div className={cx('TextControl-input')}>
|
||||
<input
|
||||
onChange={this.handleChange}
|
||||
value={inputValue}
|
||||
placeholder="搜索地点"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div
|
||||
ref={this.mapRef}
|
||||
@ -361,23 +371,36 @@ export class BaiduMapPicker extends React.Component<
|
||||
invisible: hasSug
|
||||
})}
|
||||
>
|
||||
{locs.map((item, index) => (
|
||||
{!onlySelectCurrentLoc &&
|
||||
locs.map((item, index) => (
|
||||
<div
|
||||
onClick={this.handleSelect}
|
||||
key={index}
|
||||
data-index={index}
|
||||
className={cx('MapPicker-item')}
|
||||
>
|
||||
<div className={cx('MapPicker-itemTitle')}>{item.title}</div>
|
||||
<div className={cx('MapPicker-itemDesc')}>{item.address}</div>
|
||||
{locIndex === index ? (
|
||||
<Icon icon="success" className="icon" />
|
||||
) : null}
|
||||
</div>
|
||||
))}
|
||||
{onlySelectCurrentLoc && locs.length > 0 && (
|
||||
<div
|
||||
onClick={this.handleSelect}
|
||||
key={index}
|
||||
data-index={index}
|
||||
key="locs-current"
|
||||
data-index={0}
|
||||
className={cx('MapPicker-item')}
|
||||
>
|
||||
<div className={cx('MapPicker-itemTitle')}>{item.title}</div>
|
||||
<div className={cx('MapPicker-itemDesc')}>{item.address}</div>
|
||||
{locIndex === index ? (
|
||||
<Icon icon="success" className="icon" />
|
||||
) : null}
|
||||
<div className={cx('MapPicker-itemTitle')}>{locs[0].title}</div>
|
||||
<div className={cx('MapPicker-itemDesc')}>{locs[0].address}</div>
|
||||
{locIndex === 0 ? <Icon icon="success" className="icon" /> : null}
|
||||
</div>
|
||||
))}
|
||||
)}
|
||||
</div>
|
||||
|
||||
{hasSug ? (
|
||||
{hasSug && !onlySelectCurrentLoc ? (
|
||||
<div className={cx('MapPicker-sug')}>
|
||||
{sugs.map(item => (
|
||||
<div
|
||||
|
@ -14,6 +14,7 @@ export interface LocationProps extends ThemeProps, LocaleProps {
|
||||
vendor: 'baidu' | 'gaode' | 'tenxun';
|
||||
coordinatesType: 'bd09' | 'gcj02';
|
||||
placeholder: string;
|
||||
getLocationPlaceholder: string;
|
||||
clearable: boolean;
|
||||
ak: string;
|
||||
value?: {
|
||||
@ -27,6 +28,8 @@ export interface LocationProps extends ThemeProps, LocaleProps {
|
||||
popoverClassName?: string;
|
||||
onChange: (value: any) => void;
|
||||
popOverContainer?: any;
|
||||
autoSelectCurrentLoc?: boolean;
|
||||
onlySelectCurrentLoc?: boolean;
|
||||
}
|
||||
|
||||
export interface LocationState {
|
||||
@ -40,6 +43,7 @@ export class LocationPicker extends React.Component<
|
||||
> {
|
||||
static defaultProps = {
|
||||
placeholder: 'LocationPicker.placeholder',
|
||||
getLocationPlaceholder: 'LocationPicker.getLocation',
|
||||
clearable: false
|
||||
};
|
||||
domRef: React.RefObject<HTMLDivElement> = React.createRef();
|
||||
@ -155,12 +159,15 @@ export class LocationPicker extends React.Component<
|
||||
popoverClassName,
|
||||
disabled,
|
||||
placeholder,
|
||||
getLocationPlaceholder,
|
||||
clearable,
|
||||
popOverContainer,
|
||||
vendor,
|
||||
coordinatesType,
|
||||
ak,
|
||||
mobileUI
|
||||
mobileUI,
|
||||
autoSelectCurrentLoc,
|
||||
onlySelectCurrentLoc
|
||||
} = this.props;
|
||||
const __ = this.props.translate;
|
||||
const {isFocused, isOpened} = this.state;
|
||||
@ -173,6 +180,8 @@ export class LocationPicker extends React.Component<
|
||||
ak={ak}
|
||||
value={value}
|
||||
coordinatesType={coordinatesType}
|
||||
autoSelectCurrentLoc={autoSelectCurrentLoc}
|
||||
onlySelectCurrentLoc={onlySelectCurrentLoc}
|
||||
onChange={this.handleChange}
|
||||
/>
|
||||
);
|
||||
@ -213,7 +222,7 @@ export class LocationPicker extends React.Component<
|
||||
<span className={cx('LocationPicker-value')}>{value.address}</span>
|
||||
) : (
|
||||
<span className={cx('LocationPicker-placeholder')}>
|
||||
{__(placeholder)}
|
||||
{__(onlySelectCurrentLoc ? getLocationPlaceholder : placeholder)}
|
||||
</span>
|
||||
)}
|
||||
|
||||
@ -242,6 +251,8 @@ export class LocationPicker extends React.Component<
|
||||
ak={ak}
|
||||
value={value}
|
||||
coordinatesType={coordinatesType}
|
||||
autoSelectCurrentLoc={autoSelectCurrentLoc}
|
||||
onlySelectCurrentLoc={onlySelectCurrentLoc}
|
||||
onChange={this.handleTempChange}
|
||||
/>
|
||||
) : (
|
||||
@ -268,6 +279,8 @@ export class LocationPicker extends React.Component<
|
||||
ak={ak}
|
||||
value={value}
|
||||
coordinatesType={coordinatesType}
|
||||
autoSelectCurrentLoc={autoSelectCurrentLoc}
|
||||
onlySelectCurrentLoc={onlySelectCurrentLoc}
|
||||
onChange={this.handleChange}
|
||||
/>
|
||||
) : (
|
||||
|
@ -188,6 +188,8 @@ register('de-DE', {
|
||||
'loading': 'Wird geladen...',
|
||||
'loadingFailed': 'Das Laden ist fehlgeschlagen',
|
||||
'LocationPicker.placeholder': 'Wählen Sie einen Ort',
|
||||
'LocationPicker.getLocation':
|
||||
'Klicken Sie hier, um Standortinformationen zu erhalten',
|
||||
'Month.placeholder': 'Wählen Sie einen Monat',
|
||||
'Nav.sourceError': 'Fehler beim Abrufen des Links',
|
||||
'networkError':
|
||||
|
@ -180,6 +180,7 @@ register('en-US', {
|
||||
'loading': 'Loading',
|
||||
'loadingFailed': 'Loading failed',
|
||||
'LocationPicker.placeholder': 'Pick location',
|
||||
'LocationPicker.getLocation': 'Click to obtain location information',
|
||||
'Month.placeholder': 'Select a month',
|
||||
'Nav.sourceError': 'Fetch link error',
|
||||
'networkError': 'Network error or missing CORS configuration',
|
||||
|
@ -185,6 +185,7 @@ register('zh-CN', {
|
||||
'loading': '加载中',
|
||||
'loadingFailed': '加载失败',
|
||||
'LocationPicker.placeholder': '请选择位置',
|
||||
'LocationPicker.getLocation': '点击获取位置信息',
|
||||
'Month.placeholder': '请选择月份',
|
||||
'Nav.sourceError': '获取链接错误',
|
||||
'networkError': '网络错误,可能是未配置跨域 CORS',
|
||||
|
@ -29,6 +29,23 @@ export interface LocationControlSchema extends FormBaseControlSchema {
|
||||
* 有的地图需要设置 ak 信息
|
||||
*/
|
||||
ak?: string;
|
||||
|
||||
/**
|
||||
* 是否自动选中当前地理位置
|
||||
*/
|
||||
autoSelectCurrentLoc?: boolean;
|
||||
|
||||
/**
|
||||
* 是否限制只能选中当前地理位置
|
||||
* 备注:可用于充当定位组件,只允许选择当前位置
|
||||
*/
|
||||
onlySelectCurrentLoc?: boolean;
|
||||
|
||||
/**
|
||||
* 开启只读模式后的占位提示,默认为“点击获取位置信息”
|
||||
* 备注:区分下现有的placeholder(“请选择位置”)
|
||||
*/
|
||||
getLocationPlaceholder?: string;
|
||||
}
|
||||
|
||||
export interface LocationControlProps
|
||||
@ -51,33 +68,6 @@ export class LocationControl extends React.Component<LocationControlProps> {
|
||||
coordinatesType: 'bd09'
|
||||
};
|
||||
domRef: React.RefObject<HTMLDivElement> = React.createRef();
|
||||
state = {
|
||||
isOpened: false
|
||||
};
|
||||
|
||||
@autobind
|
||||
close() {
|
||||
this.setState({
|
||||
isOpened: false
|
||||
});
|
||||
}
|
||||
|
||||
@autobind
|
||||
open() {
|
||||
this.setState({
|
||||
isOpened: true
|
||||
});
|
||||
}
|
||||
|
||||
@autobind
|
||||
handleClick() {
|
||||
this.state.isOpened ? this.close() : this.open();
|
||||
}
|
||||
|
||||
@autobind
|
||||
getParent() {
|
||||
return this.domRef.current?.parentElement;
|
||||
}
|
||||
|
||||
@autobind
|
||||
getTarget() {
|
||||
@ -85,14 +75,7 @@ export class LocationControl extends React.Component<LocationControlProps> {
|
||||
}
|
||||
|
||||
renderStatic(displayValue = '-') {
|
||||
const {
|
||||
classnames: cx,
|
||||
value,
|
||||
vendor,
|
||||
ak,
|
||||
coordinatesType,
|
||||
popOverContainer
|
||||
} = this.props;
|
||||
const {classnames: cx, value} = this.props;
|
||||
const __ = this.props.translate;
|
||||
|
||||
if (!value) {
|
||||
@ -107,35 +90,6 @@ export class LocationControl extends React.Component<LocationControlProps> {
|
||||
ref={this.domRef}
|
||||
>
|
||||
<span>{value.address}</span>
|
||||
<a
|
||||
className={cx('LocationPicker-toggler', 'ml-1')}
|
||||
onClick={this.handleClick}
|
||||
>
|
||||
<Icon icon="location" className="icon" />
|
||||
</a>
|
||||
<Overlay
|
||||
target={this.getTarget}
|
||||
container={popOverContainer || this.getParent}
|
||||
rootClose={false}
|
||||
show={this.state.isOpened}
|
||||
>
|
||||
<PopOver
|
||||
className={cx('LocationPicker-popover')}
|
||||
onHide={this.close}
|
||||
overlay
|
||||
style={{width: this.getTarget()?.offsetWidth}}
|
||||
>
|
||||
{vendor === 'baidu' ? (
|
||||
<BaiduMapPicker
|
||||
ak={ak}
|
||||
value={value}
|
||||
coordinatesType={coordinatesType}
|
||||
/>
|
||||
) : (
|
||||
<Alert2>{__('{{vendor}} 地图控件不支持', {vendor})}</Alert2>
|
||||
)}
|
||||
</PopOver>
|
||||
</Overlay>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user