@nocobase/plugin-map 0.8.1-alpha.3

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 (104) hide show
  1. package/LICENSE +201 -0
  2. package/client.d.ts +4 -0
  3. package/client.js +30 -0
  4. package/lib/client/components/AMap.d.ts +13 -0
  5. package/lib/client/components/AMap.js +502 -0
  6. package/lib/client/components/Configuration.d.ts +2 -0
  7. package/lib/client/components/Configuration.js +167 -0
  8. package/lib/client/components/Designer.d.ts +2 -0
  9. package/lib/client/components/Designer.js +308 -0
  10. package/lib/client/components/Map.d.ts +6 -0
  11. package/lib/client/components/Map.js +65 -0
  12. package/lib/client/components/ReadPretty.d.ts +2 -0
  13. package/lib/client/components/ReadPretty.js +81 -0
  14. package/lib/client/components/Search.d.ts +6 -0
  15. package/lib/client/components/Search.js +155 -0
  16. package/lib/client/constants.d.ts +4 -0
  17. package/lib/client/constants.js +17 -0
  18. package/lib/client/fields/circle.d.ts +2 -0
  19. package/lib/client/fields/circle.js +37 -0
  20. package/lib/client/fields/index.d.ts +2 -0
  21. package/lib/client/fields/index.js +22 -0
  22. package/lib/client/fields/lineString.d.ts +2 -0
  23. package/lib/client/fields/lineString.js +37 -0
  24. package/lib/client/fields/point.d.ts +2 -0
  25. package/lib/client/fields/point.js +37 -0
  26. package/lib/client/fields/polygon.d.ts +2 -0
  27. package/lib/client/fields/polygon.js +37 -0
  28. package/lib/client/fields/schema.d.ts +99 -0
  29. package/lib/client/fields/schema.js +79 -0
  30. package/lib/client/hooks/index.d.ts +1 -0
  31. package/lib/client/hooks/index.js +18 -0
  32. package/lib/client/hooks/useMapConfiguration.d.ts +2 -0
  33. package/lib/client/hooks/useMapConfiguration.js +33 -0
  34. package/lib/client/index.d.ts +3 -0
  35. package/lib/client/index.js +80 -0
  36. package/lib/client/initialize.d.ts +4 -0
  37. package/lib/client/initialize.js +67 -0
  38. package/lib/client/locales/en-US.d.ts +2 -0
  39. package/lib/client/locales/en-US.js +9 -0
  40. package/lib/client/locales/index.d.ts +4 -0
  41. package/lib/client/locales/index.js +56 -0
  42. package/lib/client/locales/zh-CN.d.ts +43 -0
  43. package/lib/client/locales/zh-CN.js +51 -0
  44. package/lib/index.d.ts +1 -0
  45. package/lib/index.js +15 -0
  46. package/lib/server/actions/index.d.ts +3 -0
  47. package/lib/server/actions/index.js +66 -0
  48. package/lib/server/collections/mapConfiguration.d.ts +3 -0
  49. package/lib/server/collections/mapConfiguration.js +30 -0
  50. package/lib/server/constants.d.ts +1 -0
  51. package/lib/server/constants.js +8 -0
  52. package/lib/server/fields/circle.d.ts +13 -0
  53. package/lib/server/fields/circle.js +84 -0
  54. package/lib/server/fields/index.d.ts +4 -0
  55. package/lib/server/fields/index.js +57 -0
  56. package/lib/server/fields/lineString.d.ts +13 -0
  57. package/lib/server/fields/lineString.js +91 -0
  58. package/lib/server/fields/point.d.ts +13 -0
  59. package/lib/server/fields/point.js +95 -0
  60. package/lib/server/fields/polygon.d.ts +13 -0
  61. package/lib/server/fields/polygon.js +89 -0
  62. package/lib/server/helpers/index.d.ts +6 -0
  63. package/lib/server/helpers/index.js +44 -0
  64. package/lib/server/index.d.ts +1 -0
  65. package/lib/server/index.js +15 -0
  66. package/lib/server/plugin.d.ts +11 -0
  67. package/lib/server/plugin.js +88 -0
  68. package/package.json +19 -0
  69. package/server.d.ts +4 -0
  70. package/server.js +30 -0
  71. package/src/client/components/AMap.tsx +369 -0
  72. package/src/client/components/Configuration.tsx +91 -0
  73. package/src/client/components/Designer.tsx +260 -0
  74. package/src/client/components/Map.tsx +29 -0
  75. package/src/client/components/ReadPretty.tsx +34 -0
  76. package/src/client/components/Search.tsx +93 -0
  77. package/src/client/constants.ts +6 -0
  78. package/src/client/fields/circle.ts +23 -0
  79. package/src/client/fields/index.ts +16 -0
  80. package/src/client/fields/lineString.ts +23 -0
  81. package/src/client/fields/point.ts +24 -0
  82. package/src/client/fields/polygon.ts +23 -0
  83. package/src/client/fields/schema.ts +57 -0
  84. package/src/client/hooks/index.ts +1 -0
  85. package/src/client/hooks/useMapConfiguration.ts +15 -0
  86. package/src/client/index.tsx +43 -0
  87. package/src/client/initialize.tsx +33 -0
  88. package/src/client/locales/en-US.ts +5 -0
  89. package/src/client/locales/index.ts +22 -0
  90. package/src/client/locales/zh-CN.ts +45 -0
  91. package/src/index.ts +1 -0
  92. package/src/server/__tests__/fields.test.ts +168 -0
  93. package/src/server/actions/index.ts +46 -0
  94. package/src/server/collections/mapConfiguration.ts +27 -0
  95. package/src/server/constants.ts +1 -0
  96. package/src/server/fields/.gitkeep +0 -0
  97. package/src/server/fields/circle.ts +50 -0
  98. package/src/server/fields/index.ts +4 -0
  99. package/src/server/fields/lineString.ts +56 -0
  100. package/src/server/fields/point.ts +59 -0
  101. package/src/server/fields/polygon.ts +56 -0
  102. package/src/server/helpers/index.ts +25 -0
  103. package/src/server/index.ts +1 -0
  104. package/src/server/plugin.ts +46 -0
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.PolygonField = void 0;
7
+
8
+ function _database() {
9
+ const data = require("@nocobase/database");
10
+
11
+ _database = function _database() {
12
+ return data;
13
+ };
14
+
15
+ return data;
16
+ }
17
+
18
+ function _sequelize() {
19
+ const data = require("sequelize");
20
+
21
+ _sequelize = function _sequelize() {
22
+ return data;
23
+ };
24
+
25
+ return data;
26
+ }
27
+
28
+ var _helpers = require("../helpers");
29
+
30
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
31
+
32
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
33
+
34
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
35
+
36
+ class Polygon extends _sequelize().DataTypes.ABSTRACT {
37
+ constructor(...args) {
38
+ super(...args);
39
+ this.key = 'Polygon';
40
+ }
41
+
42
+ }
43
+
44
+ class PolygonField extends _database().Field {
45
+ constructor(options, context) {
46
+ const name = options.name;
47
+ super(_objectSpread({
48
+ get() {
49
+ const value = this.getDataValue(name);
50
+
51
+ if ((0, _helpers.isPg)(context)) {
52
+ return (0, _helpers.toValue)(value);
53
+ } else if ((0, _helpers.isMysql)(context)) {
54
+ return (value === null || value === void 0 ? void 0 : value.coordinates[0].slice(0, -1)) || null;
55
+ } else {
56
+ return value;
57
+ }
58
+ },
59
+
60
+ set(value) {
61
+ var _value;
62
+
63
+ if (!((_value = value) === null || _value === void 0 ? void 0 : _value.length)) value = null;else if ((0, _helpers.isPg)(context)) {
64
+ value = (0, _helpers.joinComma)(value.map(item => (0, _helpers.joinComma)(item)));
65
+ } else if ((0, _helpers.isMysql)(context)) {
66
+ value = {
67
+ type: 'Polygon',
68
+ coordinates: [value.concat([value[0]])]
69
+ };
70
+ }
71
+ this.setDataValue(name, value);
72
+ }
73
+
74
+ }, options), context);
75
+ }
76
+
77
+ get dataType() {
78
+ if ((0, _helpers.isPg)(this.context)) {
79
+ return Polygon;
80
+ } else if ((0, _helpers.isMysql)(this.context)) {
81
+ return _sequelize().DataTypes.GEOMETRY('POLYGON');
82
+ } else {
83
+ return _sequelize().DataTypes.JSON;
84
+ }
85
+ }
86
+
87
+ }
88
+
89
+ exports.PolygonField = PolygonField;
@@ -0,0 +1,6 @@
1
+ export declare const joinComma: (value: any[]) => string;
2
+ export declare const toValue: (value?: string) => any;
3
+ export declare const getDialect: (ctx: any) => any;
4
+ export declare const isPg: (ctx: any) => boolean;
5
+ export declare const isSqlite: (ctx: any) => boolean;
6
+ export declare const isMysql: (ctx: any) => boolean;
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.toValue = exports.joinComma = exports.isSqlite = exports.isPg = exports.isMysql = exports.getDialect = void 0;
7
+
8
+ const joinComma = value => {
9
+ if (!value) return null;
10
+ return `(${value.join(',')})`;
11
+ };
12
+
13
+ exports.joinComma = joinComma;
14
+
15
+ const toValue = value => {
16
+ if (!value) return null;
17
+ return JSON.parse(value.replace(/\(/g, '[').replace(/\)/g, ']'));
18
+ };
19
+
20
+ exports.toValue = toValue;
21
+
22
+ const getDialect = ctx => {
23
+ return (ctx.db || ctx.database).sequelize.getDialect();
24
+ };
25
+
26
+ exports.getDialect = getDialect;
27
+
28
+ const isPg = ctx => {
29
+ return getDialect(ctx) === 'postgres';
30
+ };
31
+
32
+ exports.isPg = isPg;
33
+
34
+ const isSqlite = ctx => {
35
+ return getDialect(ctx) === 'sqlite';
36
+ };
37
+
38
+ exports.isSqlite = isSqlite;
39
+
40
+ const isMysql = ctx => {
41
+ return getDialect(ctx) === 'mysql';
42
+ };
43
+
44
+ exports.isMysql = isMysql;
@@ -0,0 +1 @@
1
+ export { default } from './plugin';
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "default", {
7
+ enumerable: true,
8
+ get: function get() {
9
+ return _plugin.default;
10
+ }
11
+ });
12
+
13
+ var _plugin = _interopRequireDefault(require("./plugin"));
14
+
15
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -0,0 +1,11 @@
1
+ import { InstallOptions, Plugin } from '@nocobase/server';
2
+ export declare class MapPlugin extends Plugin {
3
+ afterAdd(): void;
4
+ beforeLoad(): void;
5
+ load(): Promise<void>;
6
+ install(options?: InstallOptions): Promise<void>;
7
+ afterEnable(): Promise<void>;
8
+ afterDisable(): Promise<void>;
9
+ remove(): Promise<void>;
10
+ }
11
+ export default MapPlugin;
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.MapPlugin = void 0;
7
+
8
+ function _server() {
9
+ const data = require("@nocobase/server");
10
+
11
+ _server = function _server() {
12
+ return data;
13
+ };
14
+
15
+ return data;
16
+ }
17
+
18
+ var _fields = require("./fields");
19
+
20
+ function _path() {
21
+ const data = require("path");
22
+
23
+ _path = function _path() {
24
+ return data;
25
+ };
26
+
27
+ return data;
28
+ }
29
+
30
+ var _actions = require("./actions");
31
+
32
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
33
+
34
+ function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
35
+
36
+ class MapPlugin extends _server().Plugin {
37
+ afterAdd() {}
38
+
39
+ beforeLoad() {
40
+ const fields = {
41
+ point: _fields.PointField,
42
+ polygon: _fields.PolygonField,
43
+ lineString: _fields.LineStringField,
44
+ circle: _fields.CircleField
45
+ };
46
+ this.db.registerFieldTypes(fields);
47
+ }
48
+
49
+ load() {
50
+ var _this = this;
51
+
52
+ return _asyncToGenerator(function* () {
53
+ yield _this.db.import({
54
+ directory: (0, _path().resolve)(__dirname, 'collections')
55
+ });
56
+
57
+ _this.app.resource({
58
+ name: 'map-configuration',
59
+ actions: {
60
+ get: _actions.getConfiguration,
61
+ set: _actions.setConfiguration
62
+ },
63
+ only: ['get', 'set']
64
+ });
65
+ })();
66
+ }
67
+
68
+ install(options) {
69
+ return _asyncToGenerator(function* () {})();
70
+ }
71
+
72
+ afterEnable() {
73
+ return _asyncToGenerator(function* () {})();
74
+ }
75
+
76
+ afterDisable() {
77
+ return _asyncToGenerator(function* () {})();
78
+ }
79
+
80
+ remove() {
81
+ return _asyncToGenerator(function* () {})();
82
+ }
83
+
84
+ }
85
+
86
+ exports.MapPlugin = MapPlugin;
87
+ var _default = MapPlugin;
88
+ exports.default = _default;
package/package.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "@nocobase/plugin-map",
3
+ "version": "0.8.1-alpha.3",
4
+ "main": "lib/server/index.js",
5
+ "devDependencies": {
6
+ "@nocobase/server": "0.8.1-alpha.3",
7
+ "@nocobase/test": "0.8.1-alpha.3"
8
+ },
9
+ "dependencies": {
10
+ "@amap/amap-jsapi-loader": "^1.0.1",
11
+ "@amap/amap-jsapi-types": "^0.0.10",
12
+ "@emotion/css": "^11.7.1",
13
+ "@formily/react": "2.0.20",
14
+ "ahooks": "^3.7.2",
15
+ "antd": "~4.19.5",
16
+ "sequelize": "^6.26.0"
17
+ },
18
+ "gitHead": "e03df3df5962b99d9fbf5b6e33fbe2b23f14f3d3"
19
+ }
package/server.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ // @ts-nocheck
2
+ export * from './lib/server';
3
+ export { default } from './lib/server';
4
+
package/server.js ADDED
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+
3
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
4
+
5
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
6
+
7
+ var _index = _interopRequireWildcard(require("./lib/server"));
8
+
9
+ Object.defineProperty(exports, "__esModule", {
10
+ value: true
11
+ });
12
+ var _exportNames = {};
13
+ Object.defineProperty(exports, "default", {
14
+ enumerable: true,
15
+ get: function get() {
16
+ return _index.default;
17
+ }
18
+ });
19
+
20
+ Object.keys(_index).forEach(function (key) {
21
+ if (key === "default" || key === "__esModule") return;
22
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
23
+ if (key in exports && exports[key] === _index[key]) return;
24
+ Object.defineProperty(exports, key, {
25
+ enumerable: true,
26
+ get: function get() {
27
+ return _index[key];
28
+ }
29
+ });
30
+ });
@@ -0,0 +1,369 @@
1
+ import React from 'react';
2
+ import { useEffect, useRef, useState } from 'react';
3
+ import AMapLoader from '@amap/amap-jsapi-loader';
4
+ import '@amap/amap-jsapi-types';
5
+ import { useFieldSchema } from '@formily/react';
6
+ import { useCollection } from '@nocobase/client';
7
+ import { css } from '@emotion/css';
8
+ import { Alert, Button, Modal } from 'antd';
9
+ import { useMapTranslation } from '../locales';
10
+ import Search from './Search';
11
+ import { useMemoizedFn } from 'ahooks';
12
+ import { useMapConfiguration } from '../hooks';
13
+ import { useHistory } from 'react-router';
14
+ import { SyncOutlined } from '@ant-design/icons';
15
+
16
+ interface AMapComponentProps {
17
+ accessKey: string;
18
+ securityJsCode: string;
19
+ value: any;
20
+ onChange: (value: number[]) => void;
21
+ disabled?: boolean;
22
+ mapType: string;
23
+ zoom: number;
24
+ }
25
+
26
+ const methodMapping = {
27
+ point: {
28
+ mouseTool: 'marker',
29
+ propertyKey: 'position',
30
+ overlay: 'Marker',
31
+ },
32
+ polygon: {
33
+ mouseTool: 'polygon',
34
+ editor: 'PolygonEditor',
35
+ propertyKey: 'path',
36
+ overlay: 'Polygon',
37
+ },
38
+ lineString: {
39
+ mouseTool: 'polyline',
40
+ editor: 'PolylineEditor',
41
+ propertyKey: 'path',
42
+ overlay: 'Polyline',
43
+ },
44
+ circle: {
45
+ mouseTool: 'circle',
46
+ editor: 'CircleEditor',
47
+ transformOptions(value) {
48
+ return {
49
+ center: value.slice(0, 2),
50
+ radius: value[2],
51
+ };
52
+ },
53
+ overlay: 'Circle',
54
+ },
55
+ };
56
+
57
+ const AMapComponent: React.FC<AMapComponentProps> = (props) => {
58
+ const { accessKey, securityJsCode } = useMapConfiguration(props.mapType) || {};
59
+ const { value, onChange, disabled, zoom = 13 } = props;
60
+ const { t } = useMapTranslation();
61
+ const fieldSchema = useFieldSchema();
62
+ const aMap = useRef<any>();
63
+ const map = useRef<AMap.Map>();
64
+ const mouseTool = useRef<any>();
65
+ const [needUpdateFlag, forceUpdate] = useState([]);
66
+ const [errMessage, setErrMessage] = useState('');
67
+ const { getField } = useCollection();
68
+ const collectionField = getField(fieldSchema.name);
69
+ const type = collectionField?.interface;
70
+ const overlay = useRef<any>();
71
+ const editor = useRef(null);
72
+ const history = useHistory();
73
+ const id = useRef(`nocobase-map-${type}-${Date.now().toString(32)}`);
74
+
75
+ const [commonOptions] = useState<AMap.PolylineOptions & AMap.PolygonOptions>({
76
+ strokeWeight: 5,
77
+ strokeColor: '#4e9bff',
78
+ fillColor: '#4e9bff',
79
+ strokeOpacity: 1,
80
+ });
81
+
82
+ const toRemoveOverlay = useMemoizedFn(() => {
83
+ if (overlay.current) {
84
+ map.current?.remove(overlay.current);
85
+ }
86
+ });
87
+
88
+ const setTarget = useMemoizedFn(() => {
89
+ if (!disabled && type !== 'point' && editor.current) {
90
+ editor.current.setTarget(overlay.current);
91
+ editor.current.open();
92
+ }
93
+ });
94
+
95
+ const onMapChange = useMemoizedFn((target, onlyChange = false) => {
96
+ let nextValue = null;
97
+
98
+ if (type === 'point') {
99
+ const { lat, lng } = (target as AMap.Marker).getPosition();
100
+ nextValue = [lng, lat];
101
+ } else if (type === 'polygon' || type === 'lineString') {
102
+ nextValue = (target as AMap.Polygon).getPath().map((item) => [item.lng, item.lat]);
103
+ if (nextValue.length < 2) {
104
+ return;
105
+ }
106
+ } else if (type === 'circle') {
107
+ const center = target.getCenter();
108
+ const radius = target.getRadius();
109
+ nextValue = [center.lng, center.lat, radius];
110
+ }
111
+
112
+ if (!onlyChange) {
113
+ toRemoveOverlay();
114
+ overlay.current = target;
115
+ setTarget();
116
+ }
117
+ onChange(nextValue);
118
+ });
119
+
120
+ const createEditor = useMemoizedFn(() => {
121
+ const mapping = methodMapping[type as keyof typeof methodMapping];
122
+ if (mapping && 'editor' in mapping && !editor.current) {
123
+ editor.current = new aMap.current[mapping.editor](map.current);
124
+ editor.current.on('adjust', function ({ target }) {
125
+ onMapChange(target, true);
126
+ });
127
+ editor.current.on('move', function ({ target }) {
128
+ onMapChange(target, true);
129
+ });
130
+ }
131
+ });
132
+
133
+ const executeMouseTool = useMemoizedFn(() => {
134
+ if (!mouseTool.current || editor.current?.getTarget()) return;
135
+ const mapping = methodMapping[type as keyof typeof methodMapping];
136
+ if (!mapping) {
137
+ return;
138
+ }
139
+ mouseTool.current[mapping.mouseTool]({
140
+ ...commonOptions,
141
+ } as AMap.PolylineOptions);
142
+ });
143
+
144
+ const createMouseTool = useMemoizedFn(() => {
145
+ if (mouseTool.current) return;
146
+
147
+ mouseTool.current = new aMap.current.MouseTool(map.current);
148
+ mouseTool.current.on('draw', function ({ obj }) {
149
+ onMapChange(obj);
150
+ });
151
+
152
+ executeMouseTool();
153
+ });
154
+
155
+ const toCenter = (position, imm?: boolean) => {
156
+ if (map.current) {
157
+ map.current.setZoomAndCenter(18, position, imm);
158
+ }
159
+ };
160
+
161
+ const onReset = () => {
162
+ const ok = () => {
163
+ toRemoveOverlay();
164
+ if (editor.current) {
165
+ editor.current.setTarget();
166
+ editor.current.close();
167
+ }
168
+ onChange(null);
169
+ };
170
+ Modal.confirm({
171
+ title: t('Clear the canvas'),
172
+ content: t('Are you sure to clear the canvas?'),
173
+ okText: t('Confirm'),
174
+ cancelText: t('Cancel'),
175
+ onOk() {
176
+ ok();
177
+ },
178
+ });
179
+ };
180
+
181
+ const onFocusOverlay = () => {
182
+ if (overlay.current) {
183
+ map.current.setFitView([overlay.current]);
184
+ }
185
+ };
186
+
187
+ // 编辑时
188
+ useEffect(() => {
189
+ if (!aMap.current) return;
190
+ if (!value || overlay.current) {
191
+ return;
192
+ }
193
+ const mapping = methodMapping[type as keyof typeof methodMapping];
194
+ if (!mapping) {
195
+ return;
196
+ }
197
+ const options = { ...commonOptions };
198
+ if ('transformOptions' in mapping) {
199
+ Object.assign(options, mapping.transformOptions(value));
200
+ } else if ('propertyKey' in mapping) {
201
+ options[mapping.propertyKey] = value;
202
+ }
203
+ const nextOverlay = new aMap.current[mapping.overlay](options);
204
+
205
+ // 聚焦在编辑的位置
206
+ map.current.setFitView([nextOverlay]);
207
+
208
+ nextOverlay.setMap(map.current);
209
+ overlay.current = nextOverlay;
210
+
211
+ createEditor();
212
+ setTarget();
213
+ }, [value, needUpdateFlag, type, commonOptions]);
214
+
215
+ // 当在编辑时,关闭 mouseTool
216
+ useEffect(() => {
217
+ if (!mouseTool.current) return;
218
+
219
+ if (disabled) {
220
+ mouseTool.current?.close();
221
+ editor.current?.close();
222
+ } else {
223
+ executeMouseTool();
224
+ editor.current?.open();
225
+ }
226
+ }, [disabled]);
227
+
228
+ // AMap.MouseTool & AMap.XXXEditor
229
+ useEffect(() => {
230
+ if (!aMap.current || !type || disabled) return;
231
+ createMouseTool();
232
+ createEditor();
233
+ }, [disabled, needUpdateFlag, type]);
234
+
235
+ useEffect(() => {
236
+ if (!mouseTool.current || !editor.current) return;
237
+ const target = editor.current.getTarget();
238
+ if (target) {
239
+ mouseTool.current.close?.();
240
+ } else {
241
+ executeMouseTool();
242
+ }
243
+ }, [type, value]);
244
+
245
+ useEffect(() => {
246
+ if (!accessKey || map.current) return;
247
+
248
+ if (securityJsCode) {
249
+ (window as any)._AMapSecurityConfig = {
250
+ [securityJsCode.endsWith('_AMapService') ? 'serviceHOST' : 'securityJsCode']: securityJsCode,
251
+ };
252
+ }
253
+
254
+ AMapLoader.load({
255
+ key: accessKey,
256
+ version: '2.0',
257
+ plugins: ['AMap.MouseTool', 'AMap.PolygonEditor', 'AMap.PolylineEditor', 'AMap.CircleEditor'],
258
+ })
259
+ .then((amap) => {
260
+ setTimeout(() => {
261
+ map.current = new amap.Map(id.current, {
262
+ resizeEnable: true,
263
+ zoom,
264
+ } as AMap.MapOptions);
265
+ aMap.current = amap;
266
+ setErrMessage('');
267
+ forceUpdate([]);
268
+ }, Math.random() * 300);
269
+ })
270
+ .catch((err) => {
271
+ if (err.includes('多个不一致的 key')) {
272
+ setErrMessage(t('The AccessKey is incorrect, please check it'));
273
+ } else {
274
+ setErrMessage(err);
275
+ }
276
+ });
277
+
278
+ return () => {
279
+ map.current?.destroy();
280
+ aMap.current = null;
281
+ map.current = null;
282
+ mouseTool.current = null;
283
+ editor.current = null;
284
+ };
285
+ }, [accessKey, type, securityJsCode]);
286
+
287
+ if (!accessKey || errMessage) {
288
+ return (
289
+ <Alert
290
+ action={
291
+ <Button type="primary" onClick={() => history.push('/admin/settings/map-configuration/configuration')}>
292
+ {t('Go to the configuration page')}
293
+ </Button>
294
+ }
295
+ message={errMessage || t('Please configure the AccessKey and SecurityJsCode first')}
296
+ type="error"
297
+ />
298
+ );
299
+ }
300
+
301
+ return (
302
+ <div
303
+ className={css`
304
+ position: relative;
305
+ `}
306
+ id={id.current}
307
+ style={{
308
+ height: '500px',
309
+ }}
310
+ >
311
+ {/* bottom: 20px; right: 50%; transform: translateX(50%); z-index: 2; */}
312
+ <div
313
+ className={css`
314
+ position: absolute;
315
+ bottom: 80px;
316
+ right: 20px;
317
+ z-index: 10;
318
+ `}
319
+ >
320
+ <Button
321
+ onClick={onFocusOverlay}
322
+ disabled={!overlay.current}
323
+ type="primary"
324
+ shape="round"
325
+ size="large"
326
+ icon={<SyncOutlined />}
327
+ ></Button>
328
+ </div>
329
+ {!disabled ? (
330
+ <>
331
+ <Search toCenter={toCenter} aMap={aMap.current} />
332
+ <div
333
+ className={css`
334
+ position: absolute;
335
+ bottom: 20px;
336
+ left: 10px;
337
+ z-index: 2;
338
+ pointer-events: none;
339
+ `}
340
+ >
341
+ <Alert message={t('Click to select the starting point and double-click to end the drawing')} type="info" />
342
+ </div>
343
+ <div
344
+ className={css`
345
+ position: absolute;
346
+ bottom: 20px;
347
+ right: 20px;
348
+ z-index: 2;
349
+ `}
350
+ >
351
+ <Button
352
+ disabled={!value}
353
+ style={{
354
+ height: '40px',
355
+ }}
356
+ onClick={onReset}
357
+ type="primary"
358
+ danger
359
+ >
360
+ {t('Clear')}
361
+ </Button>
362
+ </div>
363
+ </>
364
+ ) : null}
365
+ </div>
366
+ );
367
+ };
368
+
369
+ export default AMapComponent;