@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.
Files changed (39) hide show
  1. package/README.md +67 -0
  2. package/lib/index.js +46475 -0
  3. package/lib/static/imgs/approachPointIcon_f2eb69df51.png +0 -0
  4. package/lib/static/imgs/layers-2x_8f2c4d1147.png +0 -0
  5. package/lib/static/imgs/layers_416d91365b.png +0 -0
  6. package/lib/static/imgs/marker-icon_2b3e1faf89.png +0 -0
  7. package/package.json +59 -0
  8. package/src/common/schemaHandler.js +55 -0
  9. package/src/components/Cascader/index.jsx +75 -0
  10. package/src/components/Cascader/index.less +3 -0
  11. package/src/components/DatePicker/index.less +3 -0
  12. package/src/components/DatePicker/index.tsx +98 -0
  13. package/src/components/MapPicker/common/approachPointIcon.png +0 -0
  14. package/src/components/MapPicker/common/getCurrentPosition.js +27 -0
  15. package/src/components/MapPicker/common/gpsConvert.js +236 -0
  16. package/src/components/MapPicker/common/map-config.js +7 -0
  17. package/src/components/MapPicker/index.jsx +82 -0
  18. package/src/components/MapPicker/line-picker/car-route.json +426 -0
  19. package/src/components/MapPicker/line-picker/index.jsx +188 -0
  20. package/src/components/MapPicker/line-picker/index.less +41 -0
  21. package/src/components/MapPicker/line-picker/mockLonLat.js +1 -0
  22. package/src/components/MapPicker/location-picker/index.jsx +104 -0
  23. package/src/components/MapPicker/location-picker/index.less +36 -0
  24. package/src/components/NumberPicker/index.jsx +16 -0
  25. package/src/components/NumberPicker/index.less +3 -0
  26. package/src/components/Password/index.jsx +14 -0
  27. package/src/components/Select/index.less +3 -0
  28. package/src/components/Select/index.tsx +60 -0
  29. package/src/components/Text/index.tsx +23 -0
  30. package/src/components/Uploader/common/cordova-camera.js +188 -0
  31. package/src/components/Uploader/common/utils.js +87 -0
  32. package/src/components/Uploader/index.jsx +31 -0
  33. package/src/components/Uploader/uploader.jsx +246 -0
  34. package/src/components/Uploader/uploader.less +36 -0
  35. package/src/components/Uploader/video/index.jsx +37 -0
  36. package/src/components/Uploader/video/index.less +37 -0
  37. package/src/components/index.ts +10 -0
  38. package/src/index.tsx +101 -0
  39. package/src/type.d.ts +15 -0
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,3 @@
1
+ .formily-cascader {
2
+ height: 100%;
3
+ }
@@ -0,0 +1,3 @@
1
+ .formily-date-picker {
2
+ height: 100%;
3
+ }
@@ -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
+ );
@@ -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,7 @@
1
+ export const mapConfig = {
2
+ center: [30.25027961206251, 120.16514401757941], // 默认地图展示位置
3
+ minZoom: 3,
4
+ maxZoom: 16,
5
+ zoom: 14,
6
+ attributionControl: false,
7
+ };
@@ -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
+ &nbsp; 纬度:{_data.lat || data.lat}
54
+ &nbsp;
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
+ );