@hzab/form-render 0.3.0 → 0.4.0

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 (36) hide show
  1. package/lib/index.js +1 -1
  2. package/lib/static/imgs/marker-icon_ab8bbcc8cb.svg +4 -0
  3. package/lib/static/imgs/picker-icon_24d725ef02.svg +5 -0
  4. package/lib/static/imgs/position-icon_5bcb8a742e.svg +6 -0
  5. package/lib/static/imgs/reset-icon_9edad62306.svg +5 -0
  6. package/package.json +4 -3
  7. package/src/common/location-utils.ts +21 -0
  8. package/src/components/DatePicker/index.tsx +89 -0
  9. package/src/components/LocationPicker/Map/AMap/common/loader.ts +59 -0
  10. package/src/components/LocationPicker/Map/AMap/common/utils.ts +137 -0
  11. package/src/components/LocationPicker/Map/AMap/index.jsx +44 -0
  12. package/src/components/LocationPicker/Map/AMap/index.less +4 -0
  13. package/src/components/LocationPicker/README.md +35 -0
  14. package/src/components/LocationPicker/assets/marker-icon.svg +4 -0
  15. package/src/components/LocationPicker/assets/picker-icon.svg +5 -0
  16. package/src/components/LocationPicker/assets/position-icon.svg +6 -0
  17. package/src/components/LocationPicker/assets/reset-icon.svg +5 -0
  18. package/src/components/LocationPicker/common/utils.ts +45 -0
  19. package/src/components/LocationPicker/components/MapSearch/index.jsx +61 -0
  20. package/src/components/LocationPicker/components/MapSearch/index.less +10 -0
  21. package/src/components/LocationPicker/components/ModalContent/index.less +81 -0
  22. package/src/components/LocationPicker/components/ModalContent/index.tsx +258 -0
  23. package/src/components/LocationPicker/components/Notice/index.tsx +14 -0
  24. package/src/components/LocationPicker/components/PickerInfo/index.less +21 -0
  25. package/src/components/LocationPicker/components/PickerInfo/index.tsx +100 -0
  26. package/src/components/LocationPicker/components/ResInfo/index.less +25 -0
  27. package/src/components/LocationPicker/components/ResInfo/index.tsx +58 -0
  28. package/src/components/LocationPicker/components/ResInfo/picker-icon.svg +5 -0
  29. package/src/components/LocationPicker/index.less +17 -0
  30. package/src/components/LocationPicker/index.tsx +199 -0
  31. package/src/components/LocationPicker/marker-icon.png +0 -0
  32. package/src/components/LocationPicker/servers/index.ts +121 -0
  33. package/src/components/TreeCheckbox/common/utils.ts +29 -40
  34. package/src/components/TreeCheckbox/index.tsx +13 -3
  35. package/src/components/UserSelect/index.tsx +1 -1
  36. package/src/components/index.tsx +3 -0
@@ -0,0 +1,121 @@
1
+ /**
2
+ * 根据经纬度获取定义的地址
3
+ * @param lon
4
+ * @param lat
5
+ * @returns
6
+ */
7
+ export function getAddress(lon, lat) {
8
+ return new Promise((resolve, reject) => {
9
+ if (!window.AMap) {
10
+ reject(Error("Error getAddress window.AMap is not defined."));
11
+ return;
12
+ }
13
+ const geocoder = new window.AMap.Geocoder({});
14
+ geocoder.getAddress([lon, lat], function (status, result) {
15
+ if (status === "complete" && result.info === "OK") {
16
+ const formattedAddress = result?.regeocode?.formattedAddress;
17
+ resolve(formattedAddress);
18
+ return formattedAddress;
19
+ } else if (result === "USER_DAILY_QUERY_OVER_LIMIT") {
20
+ // 超出限制,使用 webServer 进行请求
21
+ if (!window._AMapLoaderTemp.serverKey) {
22
+ reject(new Error("超出使用限制,请联系管理员"));
23
+ return;
24
+ }
25
+ fetch(
26
+ `https://restapi.amap.com/v3/geocode/regeo?location=${lon?.toFixed(6)},${lat?.toFixed(6)}&key=${
27
+ window._AMapLoaderTemp.serverKey
28
+ }`,
29
+ {
30
+ mode: "cors",
31
+ },
32
+ )
33
+ .then((res) => res.json())
34
+ .then((res) => {
35
+ if (res.status === "1") {
36
+ resolve(res.regeocode?.formatted_address);
37
+ } else {
38
+ console.warn("Warn getAddress fetch: ", res);
39
+ reject(new Error(res.info));
40
+ }
41
+ })
42
+ .catch(reject);
43
+ } else {
44
+ reject(result);
45
+ }
46
+ });
47
+ });
48
+ }
49
+
50
+ /**
51
+ * 获取搜索提示
52
+ * @param search
53
+ * @param cityCode
54
+ * @returns
55
+ */
56
+ export function getSearchTips(search, cityCode = "0571") {
57
+ return new Promise((resolve, reject) => {
58
+ if (!window.AMap) {
59
+ reject(Error("Error getAddress window.AMap is not defined."));
60
+ return;
61
+ }
62
+ const autoComplete = new window.AMap.Autocomplete({
63
+ // city 限定城市,默认全国
64
+ city: cityCode,
65
+ });
66
+ autoComplete.search(search, function (status, result) {
67
+ if (status === "complete" && result.info === "OK") {
68
+ resolve(
69
+ result.tips?.map((it) => {
70
+ const { lng, lat } = it?.location || {};
71
+ return {
72
+ ...it,
73
+ label: it.name,
74
+ value: it.id,
75
+ lon: +lng,
76
+ lng: +lng,
77
+ lat: +lat,
78
+ };
79
+ }),
80
+ );
81
+ } else if (result === "USER_DAILY_QUERY_OVER_LIMIT") {
82
+ // 超出限制,使用 webServer 进行请求
83
+ if (!window._AMapLoaderTemp.serverKey) {
84
+ reject(new Error("超出使用限制,请联系管理员"));
85
+ return;
86
+ }
87
+ fetch(
88
+ `https://restapi.amap.com/v3/assistant/inputtips?key=${window._AMapLoaderTemp.serverKey}&keywords=${search}&city=${cityCode}`,
89
+ {
90
+ mode: "cors",
91
+ },
92
+ )
93
+ .then((res) => res.json())
94
+ .then((res) => {
95
+ if (res.status === "1") {
96
+ resolve(
97
+ res.tips?.map((it) => {
98
+ const [lng, lat] = it.location?.split(",");
99
+
100
+ return {
101
+ ...it,
102
+ label: it.name,
103
+ value: it.id,
104
+ lng: +lng,
105
+ lon: +lng,
106
+ lat: +lat,
107
+ };
108
+ }),
109
+ );
110
+ } else {
111
+ console.warn("Warn getSearchTips fetch: ", res);
112
+ reject(new Error(res.info));
113
+ }
114
+ })
115
+ .catch(reject);
116
+ } else {
117
+ reject(result);
118
+ }
119
+ });
120
+ });
121
+ }
@@ -46,6 +46,8 @@ export type optT = {
46
46
  export function transformTreeData(treeData = [], opt: optT = {}) {
47
47
  const { resList = [], preCol = 0, mergeLast, level = 0, childrenKey = "children" } = opt || {};
48
48
  let maxCol = preCol + 1;
49
+ // 统计当前项包含的最大行数(当前项的行数等于所有子项行数之和),用于合并行的值
50
+ let maxRow = 0;
49
51
 
50
52
  // 是否有子项
51
53
  let hasChildren = false;
@@ -61,71 +63,58 @@ export function transformTreeData(treeData = [], opt: optT = {}) {
61
63
  return {
62
64
  resList,
63
65
  maxCol,
66
+ // 合并之后视为 1 行
67
+ maxRow: 1,
64
68
  };
65
69
  }
66
70
 
67
71
  treeData.forEach((it, i) => {
68
- const children = it[childrenKey] || [];
72
+ const item = { ...it };
73
+ const children = item[childrenKey] || [];
69
74
  const childrenLen = children?.length;
70
75
  // 当 mergeLast !== true && children 长度大于1时,子项下标大于 0 的项需要另起一行,同时补充之前空的列。
71
76
  if (i > 0) {
72
- resList.push(fillArrByPush(preCol));
77
+ resList.push(fillArrByPush(preCol, [], { content: false }));
73
78
  }
74
79
  lastRowIdx = resList.length > 0 ? resList.length - 1 : 0;
75
80
  // 解决首次进来第一行数组空的问题
76
81
  if (!resList[lastRowIdx]) {
77
82
  resList[lastRowIdx] = [];
78
83
  }
79
- resList[lastRowIdx].push({ ...it });
84
+ resList[lastRowIdx].push(item);
80
85
  if (childrenLen > 0) {
81
- const res = transformTreeData(children, { ...opt, resList, preCol: preCol + 1, level: level + 1 });
82
- maxCol = res.maxCol;
86
+ const res = transformTreeData(children, {
87
+ ...opt,
88
+ resList,
89
+ preCol: preCol + 1,
90
+ level: level + 1,
91
+ });
92
+ if (maxCol < res.maxCol) {
93
+ maxCol = res.maxCol;
94
+ }
95
+ // 当前的最大行数加上子项的行数
96
+ maxRow = maxRow + res.maxRow;
97
+ // 每项的最大行数为子项的最大行数之和
98
+ item._maxRow = res.maxRow;
99
+ } else {
100
+ item._maxRow = 1;
101
+ maxRow += 1;
83
102
  }
84
103
  });
104
+
85
105
  return {
86
106
  resList,
87
107
  maxCol,
108
+ maxRow,
88
109
  };
89
110
  }
90
111
 
91
- export function fillArrByPush(len, arr = []) {
112
+ export function fillArrByPush(len, arr = [], opt: any = {}) {
113
+ const { content } = opt || {};
92
114
  if (arr.length < len) {
93
115
  for (let i = arr.length; i < len; i++) {
94
- arr.push(null);
116
+ arr.push(content);
95
117
  }
96
118
  }
97
119
  return arr;
98
120
  }
99
-
100
- const d = [
101
- {
102
- key: 1,
103
- label: 1,
104
- value: 1,
105
- children: [
106
- { key: 11, label: 11, value: 11 },
107
- { key: 12, label: 12, value: 12 },
108
- ],
109
- },
110
- {
111
- key: 2,
112
- label: 2,
113
- value: 2,
114
- children: [
115
- {
116
- key: 21,
117
- label: 21,
118
- value: 21,
119
- children: [
120
- { key: 211, label: 211, value: 211 },
121
- { key: 212, label: 212, value: 212 },
122
- ],
123
- },
124
- { key: 22, label: 22, value: 22 },
125
- { key: 23, label: 23, value: 23 },
126
- ],
127
- },
128
- ];
129
-
130
- // const res = handleDataSource(d);
131
- // console.log(JSON.stringify(res, null, 2));
@@ -1,13 +1,15 @@
1
1
  import { useMemo } from "react";
2
2
  import { Checkbox } from "antd";
3
+ import { useField } from "@formily/react";
3
4
 
4
5
  import { handleDataSource } from "./common/utils";
5
6
 
6
7
  import "./index.less";
7
8
 
8
9
  export const TreeCheckbox = (props) => {
10
+ const field: any = useField();
9
11
  const {
10
- dataSource = [],
12
+ dataSource = field.dataSource || [],
11
13
  disabled,
12
14
  readOnly,
13
15
  value,
@@ -26,10 +28,18 @@ export const TreeCheckbox = (props) => {
26
28
  <tbody>
27
29
  {showDataSource?.map((row, rowIdx) => {
28
30
  return (
29
- <tr className="tree-checkbox-row" key={rowIdx}>
31
+ <tr className={`tree-checkbox-row tree-checkbox-row-${rowIdx}`} key={rowIdx}>
30
32
  {row?.map((col, colIdx) => {
33
+ // 隐藏合并项
34
+ if (col === false) {
35
+ return null;
36
+ }
31
37
  return (
32
- <td className="tree-checkbox-col" key={colIdx}>
38
+ <td
39
+ className={`tree-checkbox-col tree-checkbox-col-${colIdx}`}
40
+ key={colIdx}
41
+ rowSpan={col?._maxRow > 1 ? col?._maxRow : null}
42
+ >
33
43
  {Array.isArray(col) ? (
34
44
  <>
35
45
  {col.map((it) => {
@@ -65,7 +65,7 @@ export const UserSelect: React.FC<UserSelectProps> = observer((props) => {
65
65
 
66
66
  return (
67
67
  <AntdSelect
68
- defaultOpen
68
+ // defaultOpen
69
69
  className={styles["user-select"]}
70
70
  {...resetProps}
71
71
  value={field.value}
@@ -5,5 +5,8 @@ export * from "./Upload";
5
5
  export * from "./UserSelect";
6
6
 
7
7
  export * from "./TreeCheckbox";
8
+ export * from "./DatePicker";
9
+
10
+ export * from "./LocationPicker";
8
11
 
9
12
  export { Text };