@hzab/form-render-mobile 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +67 -0
- package/lib/index.js +46475 -0
- package/lib/static/imgs/approachPointIcon_f2eb69df51.png +0 -0
- package/lib/static/imgs/layers-2x_8f2c4d1147.png +0 -0
- package/lib/static/imgs/layers_416d91365b.png +0 -0
- package/lib/static/imgs/marker-icon_2b3e1faf89.png +0 -0
- package/package.json +59 -0
- package/src/common/schemaHandler.js +55 -0
- package/src/components/Cascader/index.jsx +75 -0
- package/src/components/Cascader/index.less +3 -0
- package/src/components/DatePicker/index.less +3 -0
- package/src/components/DatePicker/index.tsx +98 -0
- package/src/components/MapPicker/common/approachPointIcon.png +0 -0
- package/src/components/MapPicker/common/getCurrentPosition.js +27 -0
- package/src/components/MapPicker/common/gpsConvert.js +236 -0
- package/src/components/MapPicker/common/map-config.js +7 -0
- package/src/components/MapPicker/index.jsx +82 -0
- package/src/components/MapPicker/line-picker/car-route.json +426 -0
- package/src/components/MapPicker/line-picker/index.jsx +188 -0
- package/src/components/MapPicker/line-picker/index.less +41 -0
- package/src/components/MapPicker/line-picker/mockLonLat.js +1 -0
- package/src/components/MapPicker/location-picker/index.jsx +104 -0
- package/src/components/MapPicker/location-picker/index.less +36 -0
- package/src/components/NumberPicker/index.jsx +16 -0
- package/src/components/NumberPicker/index.less +3 -0
- package/src/components/Password/index.jsx +14 -0
- package/src/components/Select/index.less +3 -0
- package/src/components/Select/index.tsx +60 -0
- package/src/components/Text/index.tsx +23 -0
- package/src/components/Uploader/common/cordova-camera.js +188 -0
- package/src/components/Uploader/common/utils.js +87 -0
- package/src/components/Uploader/index.jsx +31 -0
- package/src/components/Uploader/uploader.jsx +246 -0
- package/src/components/Uploader/uploader.less +36 -0
- package/src/components/Uploader/video/index.jsx +37 -0
- package/src/components/Uploader/video/index.less +37 -0
- package/src/components/index.ts +10 -0
- package/src/index.tsx +101 -0
- package/src/type.d.ts +15 -0
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hzab/form-render-mobile",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "formily-form-render-mobile",
|
|
5
|
+
"main": "lib",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "npm run prepare && webpack serve -c ./config/webpack.config.js --env local",
|
|
8
|
+
"build": "webpack -c ./config/webpack.config.js --env production",
|
|
9
|
+
"publish-patch": "npm run build && git add . && git commit -m \"build: patch\" && npm version patch && npm publish --access public",
|
|
10
|
+
"publish-minor": "npm run build && git add . && git commit -m \"build: minor\" && npm version minor && npm publish --access public",
|
|
11
|
+
"publish-major": "npm run build && git add . && git commit -m \"build: major\" && npm version major && npm publish --access public",
|
|
12
|
+
"prepare": "husky install",
|
|
13
|
+
"mac-chmod": "chmod +x .husky && chmod +x .husky/pre-commit",
|
|
14
|
+
"docs": "typedoc"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"lib",
|
|
18
|
+
"src"
|
|
19
|
+
],
|
|
20
|
+
"keywords": [],
|
|
21
|
+
"author": "CaiYansong",
|
|
22
|
+
"license": "ISC",
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@hzab/permissions": "0.0.4",
|
|
25
|
+
"@hzab/webpack-config": "0.0.12",
|
|
26
|
+
"@types/react": "^17.0.62",
|
|
27
|
+
"@types/react-dom": "^17.0.20",
|
|
28
|
+
"axios": "^1.4.0",
|
|
29
|
+
"babel-plugin-import": "^1.13.8",
|
|
30
|
+
"eslint": "^8.30.0",
|
|
31
|
+
"less": "^4.1.3",
|
|
32
|
+
"mobx": "^6.7.0",
|
|
33
|
+
"mobx-react": "^7.6.0",
|
|
34
|
+
"react": "^17.0.2",
|
|
35
|
+
"react-dom": "^17.0.2",
|
|
36
|
+
"react-router-dom": "^6.14.1",
|
|
37
|
+
"typedoc": "^0.24.8",
|
|
38
|
+
"typescript": "^4.9.4"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@ant-design/icons": "^4.8.1",
|
|
42
|
+
"@formily/antd-mobile": "^1.0.0-beta.3",
|
|
43
|
+
"@formily/core": "^2.2.29",
|
|
44
|
+
"@formily/react": "^2.2.29",
|
|
45
|
+
"antd": "^4.24.13",
|
|
46
|
+
"antd-mobile": "^5.32.0",
|
|
47
|
+
"antd-mobile-icons": "^0.2.2",
|
|
48
|
+
"leaflet": "^1.9.4",
|
|
49
|
+
"react-leaflet": "^2.8.0"
|
|
50
|
+
},
|
|
51
|
+
"directories": {
|
|
52
|
+
"lib": "lib"
|
|
53
|
+
},
|
|
54
|
+
"lint-staged": {
|
|
55
|
+
"**.{js,jsx,ts,tsx,css,scss,less,json,html}": [
|
|
56
|
+
"prettier --write"
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import _ from "lodash";
|
|
2
|
+
|
|
3
|
+
export const formLayoutTPL = {
|
|
4
|
+
type: "object",
|
|
5
|
+
properties: {
|
|
6
|
+
formLayout_tfsvvph1s7i: {
|
|
7
|
+
type: "void",
|
|
8
|
+
"x-component": "FormLayout",
|
|
9
|
+
"x-component-props": {
|
|
10
|
+
layout: "vertical",
|
|
11
|
+
},
|
|
12
|
+
"x-designable-id": "formLayout_tfsvvph1s7i",
|
|
13
|
+
"x-index": 0,
|
|
14
|
+
properties: {},
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
"x-designable-id": "ndi5r4fw9jd",
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export function schemaHandler(_schema) {
|
|
21
|
+
let formSchema = _.cloneDeep(_schema);
|
|
22
|
+
let schema = formSchema.schema || formSchema;
|
|
23
|
+
const formConf = formSchema.form || {};
|
|
24
|
+
|
|
25
|
+
if (!formConf.layout) {
|
|
26
|
+
formConf.layout = "horizontal";
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (schema.properties && Object.keys(schema.properties).length > 0) {
|
|
30
|
+
const key = Object.keys(schema.properties)[0];
|
|
31
|
+
// 手动添加 FormLayout
|
|
32
|
+
if (schema.properties[key]["x-component"] !== "FormLayout") {
|
|
33
|
+
const _s = _.cloneDeep(formLayoutTPL);
|
|
34
|
+
if (formConf) {
|
|
35
|
+
if (!_s.properties.formLayout_tfsvvph1s7i["x-component-props"]) {
|
|
36
|
+
_s.properties.formLayout_tfsvvph1s7i["x-component-props"] = _.cloneDeep(formConf);
|
|
37
|
+
} else {
|
|
38
|
+
_s.properties.formLayout_tfsvvph1s7i["x-component-props"] = {
|
|
39
|
+
..._s.properties.formLayout_tfsvvph1s7i["x-component-props"],
|
|
40
|
+
...formConf,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
_s.properties.formLayout_tfsvvph1s7i.properties = schema.properties;
|
|
45
|
+
schema = _s;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
formSchema = {
|
|
50
|
+
form: formConf,
|
|
51
|
+
schema: schema,
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
return formSchema;
|
|
55
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { useState, useEffect } from "react";
|
|
2
|
+
import { connect, mapProps } from "@formily/react";
|
|
3
|
+
import { CascadePicker } from "antd-mobile";
|
|
4
|
+
|
|
5
|
+
import "./index.less";
|
|
6
|
+
|
|
7
|
+
function Select(props) {
|
|
8
|
+
const { disabled, readOnly, placeholder = "请选择", field = {}, onChange } = props;
|
|
9
|
+
|
|
10
|
+
const { dataSource } = field;
|
|
11
|
+
|
|
12
|
+
const [_options, setOptions] = useState(dataSource || []);
|
|
13
|
+
|
|
14
|
+
const [visible, setVisible] = useState(false);
|
|
15
|
+
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
if (dataSource) {
|
|
18
|
+
setOptions(dataSource);
|
|
19
|
+
}
|
|
20
|
+
}, [dataSource]);
|
|
21
|
+
|
|
22
|
+
function onClose() {
|
|
23
|
+
setVisible(false);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function onClick() {
|
|
27
|
+
if (readOnly || disabled) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
setVisible((val) => {
|
|
31
|
+
return !val;
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function onConfirm(value) {
|
|
36
|
+
onChange && onChange(value);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<div className="formily-cascader" onClick={onClick}>
|
|
41
|
+
<CascadePicker
|
|
42
|
+
{...props}
|
|
43
|
+
style={{ pointerEvents: readOnly || disabled ? "none" : undefined }}
|
|
44
|
+
options={_options}
|
|
45
|
+
visible={visible}
|
|
46
|
+
onClose={onClose}
|
|
47
|
+
onConfirm={onConfirm}
|
|
48
|
+
>
|
|
49
|
+
{(value) => {
|
|
50
|
+
if (!value || value.length <= 0) {
|
|
51
|
+
return placeholder;
|
|
52
|
+
}
|
|
53
|
+
return value?.reduce((pre, cur) => {
|
|
54
|
+
if (!cur) {
|
|
55
|
+
return pre;
|
|
56
|
+
}
|
|
57
|
+
if (pre) {
|
|
58
|
+
pre += " - ";
|
|
59
|
+
}
|
|
60
|
+
return (pre += cur?.label);
|
|
61
|
+
}, "");
|
|
62
|
+
}}
|
|
63
|
+
</CascadePicker>
|
|
64
|
+
</div>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export default connect(
|
|
69
|
+
Select,
|
|
70
|
+
mapProps((props, field) => {
|
|
71
|
+
console.log("props, field", props, field);
|
|
72
|
+
|
|
73
|
+
return { ...props, form: field.form, field };
|
|
74
|
+
}),
|
|
75
|
+
);
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { useState, useEffect, useMemo } from "react";
|
|
2
|
+
import { connect, mapProps } from "@formily/react";
|
|
3
|
+
import { DatePicker as ADataPicker } from "antd-mobile";
|
|
4
|
+
import dayjs from "dayjs";
|
|
5
|
+
|
|
6
|
+
import advancedFormat from "dayjs/plugin/advancedFormat";
|
|
7
|
+
import weekOfYear from "dayjs/plugin/weekOfYear";
|
|
8
|
+
|
|
9
|
+
dayjs.extend(advancedFormat);
|
|
10
|
+
dayjs.extend(weekOfYear);
|
|
11
|
+
|
|
12
|
+
import "./index.less";
|
|
13
|
+
|
|
14
|
+
const formatEnum = {
|
|
15
|
+
// 'year' | 'month' | 'day' | 'hour' | 'minute' | 'second' | 'week' | 'week-day'
|
|
16
|
+
year: "YYYY",
|
|
17
|
+
month: "YYYY-MM",
|
|
18
|
+
day: "YYYY-MM-DD",
|
|
19
|
+
hour: "YYYY-MM-DD HH",
|
|
20
|
+
minute: "YYYY-MM-DD HH:mm",
|
|
21
|
+
second: "YYYY-MM-DD HH:mm:ss",
|
|
22
|
+
week: "YYYY年 第ww周",
|
|
23
|
+
"week-day": "YYYY年 第ww周 ddd",
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
function DatePicker(props) {
|
|
27
|
+
const { disabled, readOnly, placeholder = "请选择", field = {}, onChange } = props;
|
|
28
|
+
|
|
29
|
+
const { dataSource } = field;
|
|
30
|
+
|
|
31
|
+
const [_options, setOptions] = useState(dataSource ? [dataSource] : []);
|
|
32
|
+
|
|
33
|
+
const [visible, setVisible] = useState(false);
|
|
34
|
+
|
|
35
|
+
console.log(props.showTime);
|
|
36
|
+
|
|
37
|
+
const precision = useMemo(() => {
|
|
38
|
+
if (props.precision) {
|
|
39
|
+
return props.precision;
|
|
40
|
+
}
|
|
41
|
+
const {
|
|
42
|
+
// time date month year
|
|
43
|
+
picker,
|
|
44
|
+
showTime,
|
|
45
|
+
} = props;
|
|
46
|
+
// 'year' | 'month' | 'day' | 'hour' | 'minute' | 'second' | 'week' | 'week-day'
|
|
47
|
+
let _precision = "day";
|
|
48
|
+
if ((!picker || picker === "date") && showTime) {
|
|
49
|
+
_precision = "second";
|
|
50
|
+
}
|
|
51
|
+
return _precision;
|
|
52
|
+
}, [props.precision, props.mode, props.showTime]);
|
|
53
|
+
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
if (dataSource) {
|
|
56
|
+
setOptions([dataSource]);
|
|
57
|
+
}
|
|
58
|
+
}, [dataSource]);
|
|
59
|
+
|
|
60
|
+
function onClose() {
|
|
61
|
+
setVisible(false);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function onClick() {
|
|
65
|
+
if (readOnly || disabled) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
setVisible((val) => {
|
|
69
|
+
return !val;
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function onConfirm(value) {
|
|
74
|
+
onChange && onChange(value);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return (
|
|
78
|
+
<div className="formily-date-picker" onClick={onClick}>
|
|
79
|
+
<ADataPicker
|
|
80
|
+
{...props}
|
|
81
|
+
style={{ pointerEvents: readOnly || disabled ? "none" : undefined }}
|
|
82
|
+
visible={visible}
|
|
83
|
+
onClose={onClose}
|
|
84
|
+
precision={precision}
|
|
85
|
+
onConfirm={onConfirm}
|
|
86
|
+
>
|
|
87
|
+
{(val) => (val ? dayjs(val).format(formatEnum[precision] || "YYYY-MM-DD") : placeholder)}
|
|
88
|
+
</ADataPicker>
|
|
89
|
+
</div>
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export default connect(
|
|
94
|
+
DatePicker,
|
|
95
|
+
mapProps((props, field) => {
|
|
96
|
+
return { ...props, form: field.form, field };
|
|
97
|
+
}),
|
|
98
|
+
);
|
|
Binary file
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
function getCurrentPosition(config) {
|
|
2
|
+
return new Promise((resolve, reject) => {
|
|
3
|
+
// if (window._isMock) {
|
|
4
|
+
// // TODO: 去除 mock 数据
|
|
5
|
+
// resolve({
|
|
6
|
+
// coords: {
|
|
7
|
+
// longitude: 120.19832490988816,
|
|
8
|
+
// latitude: 30.229457352287543,
|
|
9
|
+
// },
|
|
10
|
+
// });
|
|
11
|
+
// return;
|
|
12
|
+
// }
|
|
13
|
+
navigator.geolocation.getCurrentPosition(
|
|
14
|
+
(position) => {
|
|
15
|
+
resolve(position);
|
|
16
|
+
},
|
|
17
|
+
reject,
|
|
18
|
+
{
|
|
19
|
+
enableHighAccuracy: true,
|
|
20
|
+
timeout: 5000,
|
|
21
|
+
...config,
|
|
22
|
+
},
|
|
23
|
+
);
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export default getCurrentPosition;
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
/* eslint-disable*/
|
|
2
|
+
/*
|
|
3
|
+
* BD-09:百度坐标系(百度地图)
|
|
4
|
+
* GCJ-02:火星坐标系(谷歌中国地图、高德地图)
|
|
5
|
+
* WGS84:地球坐标系(国际通用坐标系,谷歌地图)
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const x_PI = (3.14159265358979324 * 3000.0) / 180.0;
|
|
9
|
+
const PI = 3.1415926535897932384626;
|
|
10
|
+
const a = 6378245.0;
|
|
11
|
+
const ee = 0.00669342162296594323;
|
|
12
|
+
|
|
13
|
+
// 百度坐标系转火星坐标系
|
|
14
|
+
function bd09togcj02(bd_lon, bd_lat) {
|
|
15
|
+
const x = bd_lon - 0.0065;
|
|
16
|
+
const y = bd_lat - 0.006;
|
|
17
|
+
const z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_PI);
|
|
18
|
+
const theta = Math.Atan2(y, x) - 0.000003 * Math.cos(x * x_PI);
|
|
19
|
+
|
|
20
|
+
const gcj_lon = z * Math.cos(theta);
|
|
21
|
+
const gcj_lat = z * Math.sin(theta);
|
|
22
|
+
const gcj = [gcj_lon, gcj_lat]; // 火星坐标系值
|
|
23
|
+
|
|
24
|
+
// 火星坐标系转wgs84
|
|
25
|
+
const wgs = [gcj02towgs84(gcj[0], gcj[1])];
|
|
26
|
+
return wgs;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// 火星坐标系转wgs84
|
|
30
|
+
export function gcj02towgs84(gcj_lon, gcj_lat) {
|
|
31
|
+
gcj_lon = Number(gcj_lon);
|
|
32
|
+
gcj_lat = Number(gcj_lat);
|
|
33
|
+
if (out_of_china(gcj_lon, gcj_lat)) {
|
|
34
|
+
// 不在国内,不进行纠偏
|
|
35
|
+
const back = [gcj_lat, gcj_lon];
|
|
36
|
+
return back;
|
|
37
|
+
} else {
|
|
38
|
+
let dlon = transformlon(gcj_lon - 105.0, gcj_lat - 35.0);
|
|
39
|
+
let dlat = transformlat(gcj_lon - 105.0, gcj_lat - 35.0);
|
|
40
|
+
const radlat = (gcj_lat / 180.0) * PI;
|
|
41
|
+
let magic = Math.sin(radlat);
|
|
42
|
+
magic = 1 - ee * magic * magic;
|
|
43
|
+
const sqrtmagic = Math.sqrt(magic);
|
|
44
|
+
dlon = (dlon * 180.0) / ((a / sqrtmagic) * Math.cos(radlat) * PI);
|
|
45
|
+
dlat = (dlat * 180.0) / (((a * (1 - ee)) / (magic * sqrtmagic)) * PI);
|
|
46
|
+
const mglon = gcj_lon + dlon;
|
|
47
|
+
const mglat = gcj_lat + dlat;
|
|
48
|
+
const wgs_lon = gcj_lon * 2 - mglon;
|
|
49
|
+
const wgs_lat = gcj_lat * 2 - mglat;
|
|
50
|
+
const wgs = [wgs_lat, wgs_lon]; // wgs84坐标系值
|
|
51
|
+
return wgs;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// 火星坐标系转百度坐标系
|
|
56
|
+
function gcj02tobd09(gcj_lon, gcj_lat) {
|
|
57
|
+
const z = Math.sqrt(gcj_lon * gcj_lon + gcj_lat * gcj_lat) + 0.00002 * Math.sin(gcj_lat * x_PI);
|
|
58
|
+
const theta = Math.atan2(gcj_lat, gcj_lon) + 0.000003 * Math.cos(gcj_lon * x_PI);
|
|
59
|
+
const bd_lon = z * Math.cos(theta) + 0.0065;
|
|
60
|
+
const bd_lat = z * Math.sin(theta) + 0.006;
|
|
61
|
+
const bd = [bd_lon, bd_lat];
|
|
62
|
+
return bd;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// wgs84转火星坐标系
|
|
66
|
+
export function wgs84togcj02(wgs_lon, wgs_lat, isWgs84 = false) {
|
|
67
|
+
wgs_lon = Number(wgs_lon);
|
|
68
|
+
wgs_lat = Number(wgs_lat);
|
|
69
|
+
if (out_of_china(wgs_lon, wgs_lat)) {
|
|
70
|
+
// 不在国内
|
|
71
|
+
const back = [wgs_lon, wgs_lat];
|
|
72
|
+
return back;
|
|
73
|
+
} else {
|
|
74
|
+
if (isWgs84) {
|
|
75
|
+
return [wgs_lat, wgs_lon];
|
|
76
|
+
} else {
|
|
77
|
+
let dwgs_lon = transformlon(wgs_lon - 105.0, wgs_lat - 35.0);
|
|
78
|
+
let dwgs_lat = transformlat(wgs_lon - 105.0, wgs_lat - 35.0);
|
|
79
|
+
const radwgs_lat = (wgs_lat / 180.0) * PI;
|
|
80
|
+
let magic = Math.sin(radwgs_lat);
|
|
81
|
+
magic = 1 - ee * magic * magic;
|
|
82
|
+
const sqrtmagic = Math.sqrt(magic);
|
|
83
|
+
dwgs_lon = (dwgs_lon * 180.0) / ((a / sqrtmagic) * Math.cos(radwgs_lat) * PI);
|
|
84
|
+
dwgs_lat = (dwgs_lat * 180.0) / (((a * (1 - ee)) / (magic * sqrtmagic)) * PI);
|
|
85
|
+
const gcj_lon = wgs_lon + dwgs_lon;
|
|
86
|
+
const gcj_lat = wgs_lat + dwgs_lat;
|
|
87
|
+
const gcj = [gcj_lat, gcj_lon];
|
|
88
|
+
return gcj;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function transformlon(lon, lat) {
|
|
94
|
+
let ret = 300.0 + lon + 2.0 * lat + 0.1 * lon * lon + 0.1 * lon * lat + 0.1 * Math.sqrt(Math.abs(lon));
|
|
95
|
+
ret += ((20.0 * Math.sin(6.0 * lon * PI) + 20.0 * Math.sin(2.0 * lon * PI)) * 2.0) / 3.0;
|
|
96
|
+
ret += ((20.0 * Math.sin(lon * PI) + 40.0 * Math.sin((lon / 3.0) * PI)) * 2.0) / 3.0;
|
|
97
|
+
ret += ((150.0 * Math.sin((lon / 12.0) * PI) + 300.0 * Math.sin((lon / 30.0) * PI)) * 2.0) / 3.0;
|
|
98
|
+
return ret;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function transformlat(lon, lat) {
|
|
102
|
+
let ret = -100.0 + 2.0 * lon + 3.0 * lat + 0.2 * lat * lat + 0.1 * lon * lat + 0.2 * Math.sqrt(Math.abs(lon));
|
|
103
|
+
ret += ((20.0 * Math.sin(6.0 * lon * PI) + 20.0 * Math.sin(2.0 * lon * PI)) * 2.0) / 3.0;
|
|
104
|
+
ret += ((20.0 * Math.sin(lat * PI) + 40.0 * Math.sin((lat / 3.0) * PI)) * 2.0) / 3.0;
|
|
105
|
+
ret += ((160.0 * Math.sin((lat / 12.0) * PI) + 320 * Math.sin((lat * PI) / 30.0)) * 2.0) / 3.0;
|
|
106
|
+
return ret;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// 判断是否在国内,不在国内则不做偏移
|
|
110
|
+
function out_of_china(lon, lat) {
|
|
111
|
+
return lon < 72.004 || lon > 137.8347 || lat < 0.8293 || lat > 55.8271 || false;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// 1.加密解密方法使用:
|
|
115
|
+
|
|
116
|
+
// 1.加密
|
|
117
|
+
// var str = '124中文内容';
|
|
118
|
+
// var base = new Base64();
|
|
119
|
+
// var result = base.encode(str);
|
|
120
|
+
// document.write(result);
|
|
121
|
+
|
|
122
|
+
// 2.解密
|
|
123
|
+
// var result2 = base.decode(result);
|
|
124
|
+
// document.write(result2);
|
|
125
|
+
// 2.加密、解密算法封装:
|
|
126
|
+
|
|
127
|
+
function Base64() {
|
|
128
|
+
// private property
|
|
129
|
+
_keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
|
130
|
+
|
|
131
|
+
// public method for encoding
|
|
132
|
+
this.encode = function (input) {
|
|
133
|
+
let output = "";
|
|
134
|
+
let chr1;
|
|
135
|
+
let chr2;
|
|
136
|
+
let chr3;
|
|
137
|
+
let enc1;
|
|
138
|
+
let enc2;
|
|
139
|
+
let enc3;
|
|
140
|
+
let enc4;
|
|
141
|
+
let i = 0;
|
|
142
|
+
input = _utf8_encode(input);
|
|
143
|
+
while (i < input.length) {
|
|
144
|
+
chr1 = input.charCodeAt(i++);
|
|
145
|
+
chr2 = input.charCodeAt(i++);
|
|
146
|
+
chr3 = input.charCodeAt(i++);
|
|
147
|
+
enc1 = chr1 >> 2;
|
|
148
|
+
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
|
|
149
|
+
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
|
|
150
|
+
enc4 = chr3 & 63;
|
|
151
|
+
if (isNaN(chr2)) {
|
|
152
|
+
enc3 = enc4 = 64;
|
|
153
|
+
} else if (isNaN(chr3)) {
|
|
154
|
+
enc4 = 64;
|
|
155
|
+
}
|
|
156
|
+
output = output + _keyStr.charAt(enc1) + _keyStr.charAt(enc2) + _keyStr.charAt(enc3) + _keyStr.charAt(enc4);
|
|
157
|
+
}
|
|
158
|
+
return output;
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
// public method for decoding
|
|
162
|
+
this.decode = function (input) {
|
|
163
|
+
let output = "";
|
|
164
|
+
let chr1;
|
|
165
|
+
let chr2;
|
|
166
|
+
let chr3;
|
|
167
|
+
let enc1;
|
|
168
|
+
let enc2;
|
|
169
|
+
let enc3;
|
|
170
|
+
let enc4;
|
|
171
|
+
let i = 0;
|
|
172
|
+
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
|
|
173
|
+
while (i < input.length) {
|
|
174
|
+
enc1 = _keyStr.indexOf(input.charAt(i++));
|
|
175
|
+
enc2 = _keyStr.indexOf(input.charAt(i++));
|
|
176
|
+
enc3 = _keyStr.indexOf(input.charAt(i++));
|
|
177
|
+
enc4 = _keyStr.indexOf(input.charAt(i++));
|
|
178
|
+
chr1 = (enc1 << 2) | (enc2 >> 4);
|
|
179
|
+
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
|
|
180
|
+
chr3 = ((enc3 & 3) << 6) | enc4;
|
|
181
|
+
output += String.fromCharCode(chr1);
|
|
182
|
+
if (enc3 != 64) {
|
|
183
|
+
output += String.fromCharCode(chr2);
|
|
184
|
+
}
|
|
185
|
+
if (enc4 != 64) {
|
|
186
|
+
output += String.fromCharCode(chr3);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
output = _utf8_decode(output);
|
|
190
|
+
return output;
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
// private method for UTF-8 encoding
|
|
194
|
+
_utf8_encode = function (string) {
|
|
195
|
+
string = string.replace(/\r\n/g, "\n");
|
|
196
|
+
let utftext = "";
|
|
197
|
+
for (let n = 0; n < string.length; n++) {
|
|
198
|
+
const c = string.charCodeAt(n);
|
|
199
|
+
if (c < 128) {
|
|
200
|
+
utftext += String.fromCharCode(c);
|
|
201
|
+
} else if (c > 127 && c < 2048) {
|
|
202
|
+
utftext += String.fromCharCode((c >> 6) | 192);
|
|
203
|
+
utftext += String.fromCharCode((c & 63) | 128);
|
|
204
|
+
} else {
|
|
205
|
+
utftext += String.fromCharCode((c >> 12) | 224);
|
|
206
|
+
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
|
|
207
|
+
utftext += String.fromCharCode((c & 63) | 128);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return utftext;
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
// private method for UTF-8 decoding
|
|
214
|
+
_utf8_decode = function (utftext) {
|
|
215
|
+
let string = "";
|
|
216
|
+
let i = 0;
|
|
217
|
+
let c = (c1 = c2 = 0);
|
|
218
|
+
while (i < utftext.length) {
|
|
219
|
+
c = utftext.charCodeAt(i);
|
|
220
|
+
if (c < 128) {
|
|
221
|
+
string += String.fromCharCode(c);
|
|
222
|
+
i++;
|
|
223
|
+
} else if (c > 191 && c < 224) {
|
|
224
|
+
c2 = utftext.charCodeAt(i + 1);
|
|
225
|
+
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
|
|
226
|
+
i += 2;
|
|
227
|
+
} else {
|
|
228
|
+
c2 = utftext.charCodeAt(i + 1);
|
|
229
|
+
c3 = utftext.charCodeAt(i + 2);
|
|
230
|
+
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
|
|
231
|
+
i += 3;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return string;
|
|
235
|
+
};
|
|
236
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
import { connect, mapProps } from "@formily/react";
|
|
3
|
+
import { Form, Button, Popup } from "antd-mobile";
|
|
4
|
+
|
|
5
|
+
import LocationPicker from "./location-picker";
|
|
6
|
+
import LinePicker from "./line-picker";
|
|
7
|
+
|
|
8
|
+
function LocationPickerCom(props) {
|
|
9
|
+
const { name, formInstance, onChange, data = {}, disabled, readOnly, fieldConf, mode } = props;
|
|
10
|
+
|
|
11
|
+
const [visible, setVisible] = useState(false);
|
|
12
|
+
const [_data, setData] = useState({});
|
|
13
|
+
|
|
14
|
+
function onLocationChange(res) {
|
|
15
|
+
formInstance?.setFieldValue(name, res);
|
|
16
|
+
|
|
17
|
+
setData(res);
|
|
18
|
+
onChange && onChange(res);
|
|
19
|
+
onCancel();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function onCancel() {
|
|
23
|
+
setVisible(false);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
let _mode = mode;
|
|
27
|
+
if (fieldConf && fieldConf.mode && !_mode) {
|
|
28
|
+
_mode = fieldConf.mode;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<>
|
|
33
|
+
{_mode === "line" ? (
|
|
34
|
+
// TODO: 展示逻辑优化
|
|
35
|
+
<div>
|
|
36
|
+
<div>
|
|
37
|
+
起点:{_data?.start?.lng || data?.start?.lng}, {_data?.start?.lat || data?.start?.lat}
|
|
38
|
+
</div>
|
|
39
|
+
<div>
|
|
40
|
+
终点:{_data?.end?.lng || data?.end?.lng}, {_data?.end?.lat || data?.end?.lat}
|
|
41
|
+
</div>
|
|
42
|
+
{/* <div>
|
|
43
|
+
起点:{_data.start && _data.start.lng},{" "}
|
|
44
|
+
{_data.start && _data.start.lat}
|
|
45
|
+
</div>
|
|
46
|
+
<div>
|
|
47
|
+
终点:{_data.end && _data.end.lng}, {_data.end && _data.end.lat}
|
|
48
|
+
</div> */}
|
|
49
|
+
</div>
|
|
50
|
+
) : (
|
|
51
|
+
<span>
|
|
52
|
+
经度:{_data.lng || data.lng}
|
|
53
|
+
纬度:{_data.lat || data.lat}
|
|
54
|
+
|
|
55
|
+
</span>
|
|
56
|
+
)}
|
|
57
|
+
{disabled || readOnly ? null : (
|
|
58
|
+
<Button
|
|
59
|
+
onClick={() => {
|
|
60
|
+
setVisible(true);
|
|
61
|
+
}}
|
|
62
|
+
>
|
|
63
|
+
地图选点
|
|
64
|
+
</Button>
|
|
65
|
+
)}
|
|
66
|
+
<Popup visible={visible} onMaskClick={onCancel} bodyStyle={{ height: "80vh" }}>
|
|
67
|
+
{_mode === "line" ? (
|
|
68
|
+
<LinePicker data={props.data} onConfirm={onLocationChange} onCancel={onCancel} />
|
|
69
|
+
) : (
|
|
70
|
+
<LocationPicker data={props.data} onConfirm={onLocationChange} onCancel={onCancel} />
|
|
71
|
+
)}
|
|
72
|
+
</Popup>
|
|
73
|
+
</>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export default connect(
|
|
78
|
+
LocationPickerCom,
|
|
79
|
+
mapProps((props, field) => {
|
|
80
|
+
return { ...props, form: field.form, field };
|
|
81
|
+
}),
|
|
82
|
+
);
|