@ecoding/components.antd 0.3.63 → 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.
- package/lib/core/form.list/index.bak.d.ts +34 -0
- package/lib/core/form.list/index.bak.js +104 -0
- package/lib/core/form.list/index.d.ts +2 -0
- package/lib/core/form.list/index.js +83 -35
- package/lib/core/length-input/index.js +7 -7
- package/lib/core/length-input-textarea/index.d.ts +17 -0
- package/lib/core/length-input-textarea/index.js +82 -0
- package/lib/core/{multiple-upload → multiple-file-upload}/index.js +1 -1
- package/lib/core/multiple-img-upload/index.d.ts +6 -0
- package/lib/core/multiple-img-upload/index.js +51 -15
- package/lib/core/multiple-single-img-upload/index.d.ts +6 -0
- package/lib/core/multiple-single-img-upload/index.js +17 -11
- package/lib/core/single-file-upload/index.js +1 -1
- package/lib/core/single-img-upload/index.d.ts +6 -0
- package/lib/core/single-img-upload/index.js +46 -13
- package/lib/core/tree.select/index.d.ts +51 -0
- package/lib/core/tree.select/index.js +54 -0
- package/lib/index.d.ts +3 -1
- package/lib/index.js +3 -1
- package/package.json +2 -2
- /package/lib/core/{multiple-upload → multiple-file-upload}/index.d.ts +0 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { FormListFieldData } from 'antd';
|
|
3
|
+
interface IC {
|
|
4
|
+
type?: "operation";
|
|
5
|
+
title?: string;
|
|
6
|
+
tooltip?: string;
|
|
7
|
+
require?: boolean;
|
|
8
|
+
name?: string;
|
|
9
|
+
rules?: any;
|
|
10
|
+
width?: number;
|
|
11
|
+
hideRemove?: boolean | ((field: FormListFieldData, index: number) => boolean);
|
|
12
|
+
render?: (field: FormListFieldData, index: number, { add, remove }: {
|
|
13
|
+
add: any;
|
|
14
|
+
remove: any;
|
|
15
|
+
}) => React.ReactNode;
|
|
16
|
+
}
|
|
17
|
+
interface IProps {
|
|
18
|
+
columns: IC[];
|
|
19
|
+
name: string | string[];
|
|
20
|
+
rules?: any;
|
|
21
|
+
i18n?: any;
|
|
22
|
+
hideBottom?: boolean;
|
|
23
|
+
hideHeader?: boolean;
|
|
24
|
+
afterRemove?: (index: any) => void;
|
|
25
|
+
afterAdd?: (index: any) => void;
|
|
26
|
+
tStyle?: React.CSSProperties;
|
|
27
|
+
operation?: {
|
|
28
|
+
hide?: boolean;
|
|
29
|
+
width?: number;
|
|
30
|
+
title?: string;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
declare const C: React.FC<IProps>;
|
|
34
|
+
export default C;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import React, { useMemo, useRef } from 'react';
|
|
2
|
+
import { Typography, Form, Button, Space, Tooltip } from 'antd';
|
|
3
|
+
import { PlusCircleOutlined, QuestionCircleOutlined } from '@ant-design/icons';
|
|
4
|
+
const C = ({ columns, rules, tStyle, name, hideHeader, hideBottom, operation, i18n, afterRemove, afterAdd }) => {
|
|
5
|
+
const tbodyRef = useRef(null);
|
|
6
|
+
const tdStyle = {
|
|
7
|
+
verticalAlign: 'top',
|
|
8
|
+
lineHeight: '32px',
|
|
9
|
+
padding: '10px'
|
|
10
|
+
};
|
|
11
|
+
const thStyle = {
|
|
12
|
+
textAlign: 'left',
|
|
13
|
+
backgroundColor: '#fafafa',
|
|
14
|
+
padding: '8px',
|
|
15
|
+
position: "sticky",
|
|
16
|
+
top: 0,
|
|
17
|
+
zIndex: 1
|
|
18
|
+
};
|
|
19
|
+
const trStyle = {
|
|
20
|
+
borderBottom: '1px solid #eee'
|
|
21
|
+
};
|
|
22
|
+
const widths = useMemo(() => {
|
|
23
|
+
let w = 60;
|
|
24
|
+
columns.forEach((column) => {
|
|
25
|
+
w += column.width || 200;
|
|
26
|
+
});
|
|
27
|
+
if (operation) {
|
|
28
|
+
w += operation.width || 150;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
w += 150;
|
|
32
|
+
}
|
|
33
|
+
return w;
|
|
34
|
+
}, []);
|
|
35
|
+
const needDefaultOperation = useMemo(() => {
|
|
36
|
+
return columns.findIndex(column => column.type == "operation") == -1;
|
|
37
|
+
}, []);
|
|
38
|
+
return (React.createElement(Form.List, { name: name, rules: rules || [] }, (fields, { add, remove }, { errors }) => {
|
|
39
|
+
return (React.createElement("div", { className: 'm-form-list' },
|
|
40
|
+
React.createElement("div", { ref: tbodyRef, className: "m-form-list-table", style: Object.assign({}, { marginBottom: '4px', paddingBottom: '12px', overflow: "auto", position: 'relative' }, tStyle) },
|
|
41
|
+
React.createElement("table", { style: { width: widths } },
|
|
42
|
+
React.createElement("colgroup", null,
|
|
43
|
+
React.createElement("col", { style: Object.assign({}, { width: 60 }) }),
|
|
44
|
+
columns.map((column) => {
|
|
45
|
+
if (column.type == "operation") {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
return (React.createElement("col", { style: Object.assign({}, { width: column.width || 200 }) }));
|
|
49
|
+
}),
|
|
50
|
+
(operation === null || operation === void 0 ? void 0 : operation.hide) ? null : (React.createElement("col", { style: Object.assign({}, { width: (operation === null || operation === void 0 ? void 0 : operation.width) || 150 }) }))),
|
|
51
|
+
React.createElement("thead", null, hideHeader ? null : (React.createElement("tr", null,
|
|
52
|
+
React.createElement("th", { style: thStyle }, i18n ? i18n.$t("global.num", "序号") : "序号"),
|
|
53
|
+
columns.map((column, i) => {
|
|
54
|
+
if (column.type == "operation") {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
if (column.require) {
|
|
58
|
+
return (React.createElement("th", { style: thStyle },
|
|
59
|
+
React.createElement("span", { style: { color: '#ff4d4f' } }, "*"),
|
|
60
|
+
column.title,
|
|
61
|
+
column.tooltip ? (React.createElement(Tooltip, { placement: "top", title: column.tooltip || undefined },
|
|
62
|
+
React.createElement(QuestionCircleOutlined, { style: { paddingLeft: 4, color: "rgba(0, 0, 0, 0.45)" } }))) : null));
|
|
63
|
+
}
|
|
64
|
+
return (React.createElement("th", { style: thStyle },
|
|
65
|
+
column.title,
|
|
66
|
+
column.tooltip ? (React.createElement(Tooltip, { placement: "top", title: column.tooltip || undefined },
|
|
67
|
+
React.createElement(QuestionCircleOutlined, { style: { paddingLeft: 4, color: "rgba(0, 0, 0, 0.45)" } }))) : null));
|
|
68
|
+
}),
|
|
69
|
+
(operation === null || operation === void 0 ? void 0 : operation.hide) ? null : (React.createElement("th", { style: Object.assign({}, thStyle, { right: 0 }) }, i18n ? i18n.$t("global.operation", "操作") : "操作"))))),
|
|
70
|
+
React.createElement("tbody", null, fields.map((field, index) => {
|
|
71
|
+
return (React.createElement("tr", { style: trStyle },
|
|
72
|
+
React.createElement("td", { style: tdStyle }, index + 1),
|
|
73
|
+
columns.map((column, i) => {
|
|
74
|
+
if (column.type == "operation") {
|
|
75
|
+
return (React.createElement("td", { style: Object.assign({}, tdStyle, { right: 0, position: "sticky", backgroundColor: "#fff" }) },
|
|
76
|
+
React.createElement(Space, null,
|
|
77
|
+
column.render && column.render(field, index, { add, remove }),
|
|
78
|
+
(typeof column.hideRemove == "function" && column.hideRemove(field, index)) || (typeof column.hideRemove == "boolean" && column.hideRemove) ? (React.createElement(Typography.Text, { disabled: true }, i18n ? i18n.$t("global.del", '删除') : '删除')) : (React.createElement(Typography.Text, { style: { cursor: 'pointer' }, type: "danger", onClick: () => {
|
|
79
|
+
remove(field.name);
|
|
80
|
+
afterRemove && afterRemove(field.name);
|
|
81
|
+
} }, i18n ? i18n.$t("global.del", '删除') : '删除')))));
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
return (React.createElement("td", { style: tdStyle },
|
|
85
|
+
React.createElement(Form.Item, { style: { marginBottom: 0 }, name: [field.name, column.name], rules: column.rules || [] }, column.render(field, index, { add, remove }))));
|
|
86
|
+
}
|
|
87
|
+
}),
|
|
88
|
+
needDefaultOperation ? (React.createElement("td", { style: Object.assign({}, tdStyle, { right: 0, position: "sticky", backgroundColor: "#fff" }) },
|
|
89
|
+
React.createElement(Typography.Text, { style: { cursor: 'pointer' }, type: "danger", onClick: () => {
|
|
90
|
+
remove(field.name);
|
|
91
|
+
afterRemove && afterRemove(field.name);
|
|
92
|
+
} }, i18n ? i18n.$t("global.del", '删除') : '删除'))) : null));
|
|
93
|
+
})))),
|
|
94
|
+
hideBottom ? null : (React.createElement("div", null,
|
|
95
|
+
React.createElement(Button, { icon: React.createElement(PlusCircleOutlined, null), type: "dashed", onClick: () => {
|
|
96
|
+
add();
|
|
97
|
+
setTimeout(() => {
|
|
98
|
+
tbodyRef.current.scrollTop = tbodyRef.current.scrollHeight;
|
|
99
|
+
}, 10);
|
|
100
|
+
afterAdd && afterAdd(fields.length);
|
|
101
|
+
} }, i18n ? i18n.$t("global.add", "添加") : "添加")))));
|
|
102
|
+
}));
|
|
103
|
+
};
|
|
104
|
+
export default C;
|
|
@@ -21,9 +21,11 @@ interface IProps {
|
|
|
21
21
|
i18n?: any;
|
|
22
22
|
hideBottom?: boolean;
|
|
23
23
|
hideHeader?: boolean;
|
|
24
|
+
max?: number;
|
|
24
25
|
afterRemove?: (index: any) => void;
|
|
25
26
|
afterAdd?: (index: any) => void;
|
|
26
27
|
tStyle?: React.CSSProperties;
|
|
28
|
+
enableSort?: boolean;
|
|
27
29
|
operation?: {
|
|
28
30
|
hide?: boolean;
|
|
29
31
|
width?: number;
|
|
@@ -1,13 +1,73 @@
|
|
|
1
1
|
import React, { useMemo, useRef } from 'react';
|
|
2
|
-
import { Typography, Form, Button, Space, Tooltip } from 'antd';
|
|
3
|
-
import { PlusCircleOutlined, QuestionCircleOutlined } from '@ant-design/icons';
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
import { Typography, Form, Button, Space, Tooltip, message } from 'antd';
|
|
3
|
+
import { PlusCircleOutlined, QuestionCircleOutlined, UnorderedListOutlined } from '@ant-design/icons';
|
|
4
|
+
import { DndContext, closestCenter, PointerSensor, useSensor, useSensors } from '@dnd-kit/core';
|
|
5
|
+
import { SortableContext, verticalListSortingStrategy, useSortable } from '@dnd-kit/sortable';
|
|
6
|
+
import { CSS } from '@dnd-kit/utilities';
|
|
7
|
+
const SortableItem = (props) => {
|
|
8
|
+
const { columns, i18n, field, index, add, remove, afterRemove, enableSort } = props;
|
|
9
|
+
const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({
|
|
10
|
+
id: props.id
|
|
11
|
+
});
|
|
12
|
+
const trStyle = enableSort ? {
|
|
13
|
+
borderBottom: '1px solid #eee',
|
|
14
|
+
transform: CSS.Transform.toString(transform),
|
|
15
|
+
transition,
|
|
16
|
+
opacity: isDragging ? 0.5 : 1,
|
|
17
|
+
cursor: 'grab',
|
|
18
|
+
marginBottom: 16,
|
|
19
|
+
} : {
|
|
20
|
+
borderBottom: '1px solid #eee',
|
|
21
|
+
};
|
|
6
22
|
const tdStyle = {
|
|
7
23
|
verticalAlign: 'top',
|
|
8
24
|
lineHeight: '32px',
|
|
9
|
-
padding: '10px'
|
|
25
|
+
padding: '10px',
|
|
26
|
+
position: 'relative',
|
|
10
27
|
};
|
|
28
|
+
const needDefaultOperation = useMemo(() => {
|
|
29
|
+
return columns.findIndex(column => column.type == "operation") == -1;
|
|
30
|
+
}, []);
|
|
31
|
+
return (React.createElement("tr", { style: trStyle, ref: setNodeRef },
|
|
32
|
+
React.createElement("td", { style: tdStyle },
|
|
33
|
+
React.createElement("div", { style: enableSort ? { paddingLeft: 20, position: "relative", height: '32px', lineHeight: '32px' } : { height: '32px', lineHeight: '32px' } },
|
|
34
|
+
enableSort ? (React.createElement("span", Object.assign({}, attributes, listeners, { style: {
|
|
35
|
+
position: 'absolute',
|
|
36
|
+
top: '6px',
|
|
37
|
+
left: '-4px',
|
|
38
|
+
width: '20px',
|
|
39
|
+
height: '20px',
|
|
40
|
+
cursor: 'grab',
|
|
41
|
+
display: 'flex',
|
|
42
|
+
alignItems: 'center',
|
|
43
|
+
justifyContent: 'center'
|
|
44
|
+
} }),
|
|
45
|
+
React.createElement(UnorderedListOutlined, { style: { fontSize: 14 } }))) : null,
|
|
46
|
+
index + 1)),
|
|
47
|
+
columns.map((column, i) => {
|
|
48
|
+
if (column.type == "operation") {
|
|
49
|
+
return (React.createElement("td", { style: Object.assign({}, tdStyle, { right: 0, position: "sticky", backgroundColor: "#fff" }) },
|
|
50
|
+
React.createElement(Space, null,
|
|
51
|
+
column.render && column.render(field, index, { add, remove }),
|
|
52
|
+
(typeof column.hideRemove == "function" && column.hideRemove(field, index)) || (typeof column.hideRemove == "boolean" && column.hideRemove) ? (React.createElement(Typography.Text, { disabled: true }, i18n ? i18n.$t("global.del", '删除') : '删除')) : (React.createElement(Typography.Text, { style: { cursor: 'pointer' }, type: "danger", onClick: () => {
|
|
53
|
+
remove(field.name);
|
|
54
|
+
afterRemove && afterRemove(field.name);
|
|
55
|
+
} }, i18n ? i18n.$t("global.del", '删除') : '删除')))));
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
return (React.createElement("td", { style: tdStyle },
|
|
59
|
+
React.createElement(Form.Item, { style: { marginBottom: 0 }, name: [field.name, column.name], rules: column.rules || [] }, column.render(field, index, { add, remove }))));
|
|
60
|
+
}
|
|
61
|
+
}),
|
|
62
|
+
needDefaultOperation ? (React.createElement("td", { style: Object.assign({}, tdStyle, { right: 0, position: "sticky", backgroundColor: "#fff" }) },
|
|
63
|
+
React.createElement(Typography.Text, { style: { cursor: 'pointer' }, type: "danger", onClick: () => {
|
|
64
|
+
remove(field.name);
|
|
65
|
+
afterRemove && afterRemove(field.name);
|
|
66
|
+
} }, i18n ? i18n.$t("global.del", '删除') : '删除'))) : null));
|
|
67
|
+
};
|
|
68
|
+
const C = ({ columns, rules, tStyle, name, hideHeader, hideBottom, operation, i18n, afterRemove, afterAdd, enableSort, max }) => {
|
|
69
|
+
const sensors = useSensors(useSensor(PointerSensor));
|
|
70
|
+
const tbodyRef = useRef(null);
|
|
11
71
|
const thStyle = {
|
|
12
72
|
textAlign: 'left',
|
|
13
73
|
backgroundColor: '#fafafa',
|
|
@@ -16,9 +76,6 @@ const C = ({ columns, rules, tStyle, name, hideHeader, hideBottom, operation, i1
|
|
|
16
76
|
top: 0,
|
|
17
77
|
zIndex: 1
|
|
18
78
|
};
|
|
19
|
-
const trStyle = {
|
|
20
|
-
borderBottom: '1px solid #eee'
|
|
21
|
-
};
|
|
22
79
|
const widths = useMemo(() => {
|
|
23
80
|
let w = 60;
|
|
24
81
|
columns.forEach((column) => {
|
|
@@ -32,10 +89,7 @@ const C = ({ columns, rules, tStyle, name, hideHeader, hideBottom, operation, i1
|
|
|
32
89
|
}
|
|
33
90
|
return w;
|
|
34
91
|
}, []);
|
|
35
|
-
|
|
36
|
-
return columns.findIndex(column => column.type == "operation") == -1;
|
|
37
|
-
}, []);
|
|
38
|
-
return (React.createElement(Form.List, { name: name, rules: rules || [] }, (fields, { add, remove }, { errors }) => {
|
|
92
|
+
return (React.createElement(Form.List, { name: name, rules: rules || [] }, (fields, { add, remove, move }, { errors }) => {
|
|
39
93
|
return (React.createElement("div", { className: 'm-form-list' },
|
|
40
94
|
React.createElement("div", { ref: tbodyRef, className: "m-form-list-table", style: Object.assign({}, { marginBottom: '4px', paddingBottom: '12px', overflow: "auto", position: 'relative' }, tStyle) },
|
|
41
95
|
React.createElement("table", { style: { width: widths } },
|
|
@@ -67,32 +121,23 @@ const C = ({ columns, rules, tStyle, name, hideHeader, hideBottom, operation, i1
|
|
|
67
121
|
React.createElement(QuestionCircleOutlined, { style: { paddingLeft: 4, color: "rgba(0, 0, 0, 0.45)" } }))) : null));
|
|
68
122
|
}),
|
|
69
123
|
(operation === null || operation === void 0 ? void 0 : operation.hide) ? null : (React.createElement("th", { style: Object.assign({}, thStyle, { right: 0 }) }, i18n ? i18n.$t("global.operation", "操作") : "操作"))))),
|
|
70
|
-
React.createElement("tbody", null,
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
React.createElement(Space, null,
|
|
77
|
-
column.render && column.render(field, index, { add, remove }),
|
|
78
|
-
(typeof column.hideRemove == "function" && column.hideRemove(field, index)) || (typeof column.hideRemove == "boolean" && column.hideRemove) ? (React.createElement(Typography.Text, { disabled: true }, i18n ? i18n.$t("global.del", '删除') : '删除')) : (React.createElement(Typography.Text, { style: { cursor: 'pointer' }, type: "danger", onClick: () => {
|
|
79
|
-
remove(field.name);
|
|
80
|
-
afterRemove && afterRemove(field.name);
|
|
81
|
-
} }, i18n ? i18n.$t("global.del", '删除') : '删除')))));
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
return (React.createElement("td", { style: tdStyle },
|
|
85
|
-
React.createElement(Form.Item, { style: { marginBottom: 0 }, name: [field.name, column.name], rules: column.rules || [] }, column.render(field, index, { add, remove }))));
|
|
124
|
+
React.createElement("tbody", null,
|
|
125
|
+
React.createElement(DndContext, { sensors: sensors, collisionDetection: closestCenter, onDragEnd: ({ active, over }) => {
|
|
126
|
+
if (active.id !== (over === null || over === void 0 ? void 0 : over.id)) {
|
|
127
|
+
const oldIndex = fields.findIndex((field) => field.key === active.id);
|
|
128
|
+
const newIndex = fields.findIndex((field) => field.key === (over === null || over === void 0 ? void 0 : over.id));
|
|
129
|
+
move(oldIndex, newIndex);
|
|
86
130
|
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
React.createElement(
|
|
90
|
-
|
|
91
|
-
afterRemove && afterRemove(field.name);
|
|
92
|
-
} }, i18n ? i18n.$t("global.del", '删除') : '删除'))) : null));
|
|
93
|
-
})))),
|
|
131
|
+
} },
|
|
132
|
+
React.createElement(SortableContext, { items: fields.map(field => field.key), strategy: verticalListSortingStrategy }, fields.map((field, index) => {
|
|
133
|
+
return (React.createElement(SortableItem, { columns: columns, index: index, key: field.key, id: field.key, i18n: i18n, field: field, add: add, remove: remove, afterRemove: afterRemove, enableSort: enableSort }));
|
|
134
|
+
})))))),
|
|
94
135
|
hideBottom ? null : (React.createElement("div", null,
|
|
95
136
|
React.createElement(Button, { icon: React.createElement(PlusCircleOutlined, null), type: "dashed", onClick: () => {
|
|
137
|
+
if (max && fields.length >= max) {
|
|
138
|
+
message.error(i18n ? `i18n.$t("global.max.add", "最多添加条数为:") ${max}` : `最多添加条数为: ${max}`);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
96
141
|
add();
|
|
97
142
|
setTimeout(() => {
|
|
98
143
|
tbodyRef.current.scrollTop = tbodyRef.current.scrollHeight;
|
|
@@ -101,4 +146,7 @@ const C = ({ columns, rules, tStyle, name, hideHeader, hideBottom, operation, i1
|
|
|
101
146
|
} }, i18n ? i18n.$t("global.add", "添加") : "添加")))));
|
|
102
147
|
}));
|
|
103
148
|
};
|
|
149
|
+
C.defaultProps = {
|
|
150
|
+
enableSort: false,
|
|
151
|
+
};
|
|
104
152
|
export default C;
|
|
@@ -3,7 +3,7 @@ import { Input } from "antd";
|
|
|
3
3
|
const LengthInput = (props) => {
|
|
4
4
|
const isCompositionStart = useRef(false);
|
|
5
5
|
const [n, setN] = useState(0);
|
|
6
|
-
const [v, setV] = useState(
|
|
6
|
+
const [v, setV] = useState("");
|
|
7
7
|
const setString = useCallback((str, len) => {
|
|
8
8
|
let strlen = 0;
|
|
9
9
|
let s = "";
|
|
@@ -16,10 +16,10 @@ const LengthInput = (props) => {
|
|
|
16
16
|
else {
|
|
17
17
|
strlen++;
|
|
18
18
|
}
|
|
19
|
-
|
|
20
|
-
if (strlen >= len) {
|
|
19
|
+
if (strlen > len) {
|
|
21
20
|
return s;
|
|
22
21
|
}
|
|
22
|
+
s += str.charAt(i);
|
|
23
23
|
}
|
|
24
24
|
return s;
|
|
25
25
|
}, []);
|
|
@@ -54,13 +54,13 @@ const LengthInput = (props) => {
|
|
|
54
54
|
props.onChange(e);
|
|
55
55
|
}, []);
|
|
56
56
|
useEffect(() => {
|
|
57
|
-
if (props.value) {
|
|
57
|
+
if (props.value && !v) {
|
|
58
58
|
const vs = props.value || "";
|
|
59
59
|
const len = getLen(vs);
|
|
60
|
-
setN(len);
|
|
61
|
-
setV(vs);
|
|
60
|
+
setN(len >= props.max ? props.max : len);
|
|
61
|
+
setV(setString(vs, props.max));
|
|
62
62
|
}
|
|
63
|
-
}, [props]);
|
|
63
|
+
}, [props.value]);
|
|
64
64
|
const compositionStartHandler = useCallback(() => {
|
|
65
65
|
isCompositionStart.current = true;
|
|
66
66
|
}, []);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
interface IProps {
|
|
3
|
+
placeholder?: string;
|
|
4
|
+
value?: string;
|
|
5
|
+
max?: number;
|
|
6
|
+
onChange?: any;
|
|
7
|
+
className?: string;
|
|
8
|
+
style?: React.CSSProperties;
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
autoSize?: boolean | {
|
|
11
|
+
minRows: number;
|
|
12
|
+
maxRows: number;
|
|
13
|
+
};
|
|
14
|
+
autoComplete?: "off" | "new-password" | "on";
|
|
15
|
+
}
|
|
16
|
+
declare const LengthInputTextArea: React.FC<IProps>;
|
|
17
|
+
export default LengthInputTextArea;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import React, { useCallback, useEffect, useState, useRef } from "react";
|
|
2
|
+
import { Input } from "antd";
|
|
3
|
+
const LengthInputTextArea = (props) => {
|
|
4
|
+
const isCompositionStart = useRef(false);
|
|
5
|
+
const [n, setN] = useState(0);
|
|
6
|
+
const [v, setV] = useState("");
|
|
7
|
+
const setString = useCallback((str, len) => {
|
|
8
|
+
let strlen = 0;
|
|
9
|
+
let s = "";
|
|
10
|
+
for (let i = 0; i < str.length; i++) {
|
|
11
|
+
// eslint-disable-next-line no-control-regex
|
|
12
|
+
const m = str.charAt(i).match(/[^\x00-\x80]/g); // 利用match方法检索出中文字符并返回一个存放中文的数
|
|
13
|
+
if (m != null && m.length > 0) {
|
|
14
|
+
strlen += 2;
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
strlen++;
|
|
18
|
+
}
|
|
19
|
+
if (strlen > len) {
|
|
20
|
+
return s;
|
|
21
|
+
}
|
|
22
|
+
s += str.charAt(i);
|
|
23
|
+
}
|
|
24
|
+
return s;
|
|
25
|
+
}, []);
|
|
26
|
+
const getLen = useCallback((str) => {
|
|
27
|
+
// 获取字符串的真实长度(字节长度)
|
|
28
|
+
if (!str) {
|
|
29
|
+
return 0;
|
|
30
|
+
}
|
|
31
|
+
const len = str.length;
|
|
32
|
+
let truelen = 0;
|
|
33
|
+
for (let x = 0; x < len; x++) {
|
|
34
|
+
if (str.charCodeAt(x) > 128) {
|
|
35
|
+
truelen += 2;
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
truelen += 1;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return truelen;
|
|
42
|
+
}, []);
|
|
43
|
+
const keyUpHandler = useCallback((e) => {
|
|
44
|
+
let vs = e.target.value;
|
|
45
|
+
let len = getLen(vs);
|
|
46
|
+
if (!isCompositionStart.current && len >= props.max) {
|
|
47
|
+
vs = setString(vs, props.max);
|
|
48
|
+
len = getLen(vs);
|
|
49
|
+
}
|
|
50
|
+
setV(vs);
|
|
51
|
+
setN(len);
|
|
52
|
+
e.target.value = vs;
|
|
53
|
+
// 估计form表单会默认有onChange事件
|
|
54
|
+
props.onChange(e);
|
|
55
|
+
}, []);
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
if (props.value && !v) {
|
|
58
|
+
const vs = props.value || "";
|
|
59
|
+
const len = getLen(vs);
|
|
60
|
+
setN(len >= props.max ? props.max : len);
|
|
61
|
+
setV(setString(vs, props.max));
|
|
62
|
+
}
|
|
63
|
+
}, [props.value]);
|
|
64
|
+
const compositionStartHandler = useCallback(() => {
|
|
65
|
+
isCompositionStart.current = true;
|
|
66
|
+
}, []);
|
|
67
|
+
const compositionEndHandler = useCallback((e) => {
|
|
68
|
+
isCompositionStart.current = false;
|
|
69
|
+
keyUpHandler(e);
|
|
70
|
+
}, []);
|
|
71
|
+
return (React.createElement("div", null,
|
|
72
|
+
React.createElement(Input.TextArea, Object.assign({}, props, { value: v, onCompositionStart: compositionStartHandler, onCompositionEnd: compositionEndHandler, onChange: keyUpHandler })),
|
|
73
|
+
React.createElement("div", { style: { color: "#666", textAlign: "right" } },
|
|
74
|
+
n,
|
|
75
|
+
React.createElement("span", { style: { padding: "0 2px" } }, "/"),
|
|
76
|
+
props.max)));
|
|
77
|
+
};
|
|
78
|
+
LengthInputTextArea.defaultProps = {
|
|
79
|
+
max: 300,
|
|
80
|
+
autoSize: { minRows: 4, maxRows: 6 }
|
|
81
|
+
};
|
|
82
|
+
export default LengthInputTextArea;
|
|
@@ -137,7 +137,7 @@ MultipleUpload.defaultProps = {
|
|
|
137
137
|
maxCount: 10,
|
|
138
138
|
headers: undefined,
|
|
139
139
|
buttonText: 'Upload',
|
|
140
|
-
type: 'jpg, jpeg, png, gif, bmp, wbmp, webp, tif, woff, woff2, ttf, otf, txt, psd, svg, js, jsx, json, css, less, html, htm, xml, pdf, zip, gz, tgz, gzip, mp3, mp4, avi, xlsx, xls, doc, docx, ppt, pptx, rar, 7z',
|
|
140
|
+
type: 'jpg, jpeg, png, gif, bmp, wbmp, webp, tif, woff, woff2, ttf, otf, txt, psd, svg, js, jsx, json, css, less, html, htm, xml, pdf, zip, gz, tgz, gzip, mp3, mp4, mkv, mov, avi, xlsx, xls, doc, docx, ppt, pptx, rar, 7z',
|
|
141
141
|
style: {}
|
|
142
142
|
};
|
|
143
143
|
export default MultipleUpload;
|
|
@@ -8,7 +8,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import React, { useState, useCallback, useMemo } from 'react';
|
|
11
|
-
import { Upload, Image as Img, Alert, Flex, message } from 'antd';
|
|
11
|
+
import { Upload, Image as Img, Alert, Flex, message, Space } from 'antd';
|
|
12
12
|
import { PlusOutlined } from '@ant-design/icons';
|
|
13
13
|
import { buildURL } from "@ecoding/helper.url";
|
|
14
14
|
import { DndContext, PointerSensor, useSensor } from '@dnd-kit/core';
|
|
@@ -33,6 +33,7 @@ const DraggableUploadListItem = ({ originNode, file }) => {
|
|
|
33
33
|
* @returns 返回地址的string
|
|
34
34
|
*/
|
|
35
35
|
const MultipleImgUpload = (props) => {
|
|
36
|
+
var _a, _b, _c, _d;
|
|
36
37
|
const { name, buttonText, maxCount, disabled, value, onChange } = props;
|
|
37
38
|
const [previewOpen, setPreviewOpen] = useState(false);
|
|
38
39
|
const [previewImage, setPreviewImage] = useState('');
|
|
@@ -96,7 +97,7 @@ const MultipleImgUpload = (props) => {
|
|
|
96
97
|
setPreviewImage(file.url || file.preview);
|
|
97
98
|
setPreviewOpen(true);
|
|
98
99
|
});
|
|
99
|
-
const uploadButton = (React.createElement("button", { style: { border: 0, background: 'none' }, type: "button" },
|
|
100
|
+
const uploadButton = (React.createElement("button", { style: Object.assign({ border: 0, background: 'none' }, disabled ? { cursor: 'not-allowed', opacity: 0.4 } : {}), type: "button" },
|
|
100
101
|
React.createElement(PlusOutlined, null),
|
|
101
102
|
React.createElement("div", { style: { marginTop: 8 } }, buttonText ? buttonText : '上传')));
|
|
102
103
|
const sensor = useSensor(PointerSensor, {
|
|
@@ -131,33 +132,63 @@ const MultipleImgUpload = (props) => {
|
|
|
131
132
|
}, []);
|
|
132
133
|
const beforeUpload = useCallback((file) => {
|
|
133
134
|
return new Promise((resolve, reject) => __awaiter(void 0, void 0, void 0, function* () {
|
|
134
|
-
const ary = ["jpg", "jpeg", "png"];
|
|
135
|
+
const ary = ["jpg", "jpeg", "png", "webp"];
|
|
135
136
|
if (props.gif) {
|
|
136
137
|
ary.push("gif");
|
|
137
138
|
}
|
|
138
139
|
if (ary.indexOf(file.type.toLowerCase().replace(/image\//g, "")) === -1) {
|
|
139
|
-
message.error(
|
|
140
|
+
message.error(`支持图片格式为:${ary.join(",")}`);
|
|
140
141
|
reject();
|
|
141
142
|
return;
|
|
142
143
|
}
|
|
143
144
|
const isLt2M = file.size / 1024 / 1024 < (props.opts.size || 1);
|
|
144
145
|
if (!isLt2M) {
|
|
145
|
-
message.error(`图片大小必须小于${props.opts.size} MB
|
|
146
|
+
message.error(`图片大小必须小于${props.opts.size} MB`);
|
|
146
147
|
reject();
|
|
147
148
|
return;
|
|
148
149
|
}
|
|
149
150
|
const base64 = yield getBase64(file);
|
|
150
151
|
const wh = yield getImgwh(base64);
|
|
151
152
|
if (props.opts.w && props.opts.w !== wh.w) {
|
|
152
|
-
message.error(`图片宽度不符合 ${props.opts.w}px
|
|
153
|
+
message.error(`图片宽度不符合 ${props.opts.w}px`);
|
|
153
154
|
reject();
|
|
154
155
|
return;
|
|
155
156
|
}
|
|
156
157
|
if (props.opts.h && props.opts.h !== wh.h) {
|
|
157
|
-
message.error(`图片高度不符合 ${props.opts.h}px
|
|
158
|
+
message.error(`图片高度不符合 ${props.opts.h}px`);
|
|
158
159
|
reject();
|
|
159
160
|
return;
|
|
160
161
|
}
|
|
162
|
+
if (props.opts.maxH && props.opts.maxH < wh.h) {
|
|
163
|
+
message.error(`图片高度不能大于 ${props.opts.maxH}px`);
|
|
164
|
+
reject();
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
if (props.opts.minH && props.opts.minH > wh.h) {
|
|
168
|
+
message.error(`图片高度不能小于 ${props.opts.minH}px`);
|
|
169
|
+
reject();
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
if (props.opts.maxW && props.opts.maxW < wh.w) {
|
|
173
|
+
message.error(`图片宽度不能大于 ${props.opts.maxW}px`);
|
|
174
|
+
reject();
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
if (props.opts.minW && props.opts.minW > wh.w) {
|
|
178
|
+
message.error(`图片宽度不能小于 ${props.opts.minW}px`);
|
|
179
|
+
reject();
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
if (props.opts.ratioW && props.opts.ratioH) {
|
|
183
|
+
// 保留2位小数进行比例计算
|
|
184
|
+
const ratio = Number((wh.w / wh.h).toFixed(2));
|
|
185
|
+
const targetRatio = Number((props.opts.ratioW / props.opts.ratioH).toFixed(2));
|
|
186
|
+
if (ratio !== targetRatio) {
|
|
187
|
+
message.error(`图片宽度与高度比例必须是 ${props.opts.ratioW} x ${props.opts.ratioH}`);
|
|
188
|
+
reject();
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
161
192
|
resolve();
|
|
162
193
|
}));
|
|
163
194
|
}, []);
|
|
@@ -170,18 +201,23 @@ const MultipleImgUpload = (props) => {
|
|
|
170
201
|
" ",
|
|
171
202
|
props.opts.size || 1,
|
|
172
203
|
"MB;"),
|
|
173
|
-
React.createElement("div", null,
|
|
174
|
-
props.i18n ? props.i18n.$t("global.dimension", "尺寸") :
|
|
175
|
-
"
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
";"),
|
|
204
|
+
props.opts.w && props.opts.h ? (React.createElement("div", null,
|
|
205
|
+
props.i18n ? `${props.i18n.$t("global.dimension", "尺寸")}: ${props.opts.w}px * ${props.opts.h}px` : `尺寸: ${props.opts.w}px x ${props.opts.h}px`,
|
|
206
|
+
";")) : null,
|
|
207
|
+
props.opts.ratioW && props.opts.ratioH ? (React.createElement("div", null,
|
|
208
|
+
props.i18n ? `${props.i18n.$t("global.ratio", "比例")}: ${props.opts.ratioW} x ${props.opts.ratioH}` : `比例: ${props.opts.ratioW} x ${props.opts.ratioH}`,
|
|
209
|
+
";")) : null,
|
|
180
210
|
React.createElement("div", null,
|
|
181
211
|
props.i18n ? props.i18n.$t("global.support", "支持") : "支持",
|
|
182
212
|
"\uFF1Ajpg\u3001jpeg\u3001png",
|
|
183
213
|
props.gif ? "、gif" : "",
|
|
184
|
-
";")
|
|
214
|
+
";"),
|
|
215
|
+
props.opts.minH || props.opts.minW || props.opts.maxH || props.opts.maxW ? (React.createElement("div", null,
|
|
216
|
+
React.createElement(Space, { split: "," },
|
|
217
|
+
!((_a = props.opts) === null || _a === void 0 ? void 0 : _a.minH) ? null : (React.createElement("span", null, props.i18n ? `${props.i18n.$t("global.minH", "最小高")}:${props.opts.minH}` : `最小高:${props.opts.minH}`)),
|
|
218
|
+
!((_b = props.opts) === null || _b === void 0 ? void 0 : _b.maxH) ? null : (React.createElement("span", null, props.i18n ? `${props.i18n.$t("global.maxH", "最大高")}:${props.opts.maxH}` : `最大高:${props.opts.maxH}`)),
|
|
219
|
+
!((_c = props.opts) === null || _c === void 0 ? void 0 : _c.minW) ? null : (React.createElement("span", null, props.i18n ? `${props.i18n.$t("global.minW", "最小宽")}:${props.opts.minW}` : `最小宽:${props.opts.minW}`)),
|
|
220
|
+
!((_d = props.opts) === null || _d === void 0 ? void 0 : _d.maxH) ? null : (React.createElement("span", null, props.i18n ? `${props.i18n.$t("global.maxH", "最大高")}:${props.opts.maxH}` : `最大高:${props.opts.maxH}`))))) : null)), type: "warning", showIcon: true })),
|
|
185
221
|
React.createElement(DndContext, { sensors: [sensor], onDragEnd: onDragEnd },
|
|
186
222
|
React.createElement(SortableContext, { items: imgList === null || imgList === void 0 ? void 0 : imgList.map((i) => i.uid), strategy: horizontalListSortingStrategy },
|
|
187
223
|
React.createElement(Upload, { listType: "picture-card", fileList: imgList, action: action, beforeUpload: beforeUpload, onPreview: handlePreview, onChange: handleChange, onRemove: handleRemove, name: name, data: props.data, multiple: true, disabled: disabled, withCredentials: true, itemRender: (originNode, file) => (React.createElement(DraggableUploadListItem, { originNode: originNode, file: file })) }, maxCount && imgList.length >= maxCount ? null : uploadButton),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useEffect, useState } from 'react';
|
|
2
|
-
import { Flex, Alert } from 'antd';
|
|
2
|
+
import { Flex, Alert, Space } from 'antd';
|
|
3
3
|
import { DragOutlined } from '@ant-design/icons';
|
|
4
4
|
import { DndContext, closestCenter, PointerSensor, useSensor, useSensors } from '@dnd-kit/core';
|
|
5
5
|
import { arrayMove, SortableContext, horizontalListSortingStrategy, useSortable } from '@dnd-kit/sortable';
|
|
@@ -23,7 +23,7 @@ const SortableItem = (props) => {
|
|
|
23
23
|
updateItems(newItems);
|
|
24
24
|
};
|
|
25
25
|
return (React.createElement("div", { ref: setNodeRef, style: style },
|
|
26
|
-
React.createElement("div", Object.assign({}, attributes, listeners, { style: {
|
|
26
|
+
props.disabled ? null : (React.createElement("div", Object.assign({}, attributes, listeners, { style: {
|
|
27
27
|
position: 'absolute',
|
|
28
28
|
top: '4px',
|
|
29
29
|
left: '4px',
|
|
@@ -37,7 +37,7 @@ const SortableItem = (props) => {
|
|
|
37
37
|
alignItems: 'center',
|
|
38
38
|
justifyContent: 'center'
|
|
39
39
|
} }),
|
|
40
|
-
React.createElement(DragOutlined, { style: { fontSize: 14 } })),
|
|
40
|
+
React.createElement(DragOutlined, { style: { fontSize: 14 } }))),
|
|
41
41
|
index == 0 ? (React.createElement("div", { style: {
|
|
42
42
|
position: 'absolute',
|
|
43
43
|
bottom: 0,
|
|
@@ -49,6 +49,7 @@ const SortableItem = (props) => {
|
|
|
49
49
|
React.createElement(ImgUpload, Object.assign({}, props, { value: props.value, onChange: handleChange }))));
|
|
50
50
|
};
|
|
51
51
|
const MultiPileImgUpload = (props) => {
|
|
52
|
+
var _a, _b, _c, _d;
|
|
52
53
|
const [items, setItems] = useState([]);
|
|
53
54
|
const sensors = useSensors(useSensor(PointerSensor));
|
|
54
55
|
const handleDragEnd = (event) => {
|
|
@@ -100,18 +101,23 @@ const MultiPileImgUpload = (props) => {
|
|
|
100
101
|
" ",
|
|
101
102
|
props.opts.size || 1,
|
|
102
103
|
"MB;"),
|
|
103
|
-
React.createElement("div", null,
|
|
104
|
-
props.i18n ? props.i18n.$t("global.dimension", "尺寸") :
|
|
105
|
-
"
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
";"),
|
|
104
|
+
props.opts.w && props.opts.h ? (React.createElement("div", null,
|
|
105
|
+
props.i18n ? `${props.i18n.$t("global.dimension", "尺寸")}: ${props.opts.w}px * ${props.opts.h}px` : `尺寸: ${props.opts.w}px x ${props.opts.h}px`,
|
|
106
|
+
";")) : null,
|
|
107
|
+
props.opts.ratioW && props.opts.ratioH ? (React.createElement("div", null,
|
|
108
|
+
props.i18n ? `${props.i18n.$t("global.ratio", "比例")}: ${props.opts.ratioW} x ${props.opts.ratioH}` : `比例: ${props.opts.ratioW} x ${props.opts.ratioH}`,
|
|
109
|
+
";")) : null,
|
|
110
110
|
React.createElement("div", null,
|
|
111
111
|
props.i18n ? props.i18n.$t("global.support", "支持") : "支持",
|
|
112
112
|
"\uFF1Ajpg\u3001jpeg\u3001png",
|
|
113
113
|
props.gif ? "、gif" : "",
|
|
114
|
-
";")
|
|
114
|
+
";"),
|
|
115
|
+
props.opts.minH || props.opts.minW || props.opts.maxH || props.opts.maxW ? (React.createElement("div", null,
|
|
116
|
+
React.createElement(Space, { split: "," },
|
|
117
|
+
!((_a = props.opts) === null || _a === void 0 ? void 0 : _a.minH) ? null : (React.createElement("span", null, props.i18n ? `${props.i18n.$t("global.minH", "最小高")}:${props.opts.minH}` : `最小高:${props.opts.minH}`)),
|
|
118
|
+
!((_b = props.opts) === null || _b === void 0 ? void 0 : _b.maxH) ? null : (React.createElement("span", null, props.i18n ? `${props.i18n.$t("global.maxH", "最大高")}:${props.opts.maxH}` : `最大高:${props.opts.maxH}`)),
|
|
119
|
+
!((_c = props.opts) === null || _c === void 0 ? void 0 : _c.minW) ? null : (React.createElement("span", null, props.i18n ? `${props.i18n.$t("global.minW", "最小宽")}:${props.opts.minW}` : `最小宽:${props.opts.minW}`)),
|
|
120
|
+
!((_d = props.opts) === null || _d === void 0 ? void 0 : _d.maxH) ? null : (React.createElement("span", null, props.i18n ? `${props.i18n.$t("global.maxH", "最大高")}:${props.opts.maxH}` : `最大高:${props.opts.maxH}`))))) : null)), type: "warning", showIcon: true })),
|
|
115
121
|
React.createElement(DndContext, { sensors: sensors, collisionDetection: closestCenter, onDragEnd: handleDragEnd },
|
|
116
122
|
React.createElement(SortableContext, { items: items, strategy: horizontalListSortingStrategy },
|
|
117
123
|
React.createElement(Flex, { wrap: true, align: "start" }, items.map((item, index) => (React.createElement(SortableItem, Object.assign({}, props, { index: index, items: items, updateItems: updateItems, value: item.url, key: item.id, id: item.id })))))))));
|
|
@@ -102,7 +102,7 @@ SingleFileUpload.defaultProps = {
|
|
|
102
102
|
data: {},
|
|
103
103
|
actionParams: {},
|
|
104
104
|
buttonText: "Upload",
|
|
105
|
-
type: "jpg, jpeg, png, gif, bmp, wbmp, webp, tif, woff, woff2, ttf, otf, txt, psd, svg, js, jsx, json, css, less, html, htm, xml, pdf, zip, gz, tgz, gzip, mp3, mp4, avi, xlsx, xls, doc, docx, ppt, pptx, rar, 7z",
|
|
105
|
+
type: "jpg, jpeg, png, gif, bmp, wbmp, webp, tif, woff, woff2, ttf, otf, txt, psd, svg, js, jsx, json, css, less, html, htm, xml, pdf, zip, gz, tgz, gzip, mp3, mp4, mkv, mov, avi, xlsx, xls, doc, docx, ppt, pptx, rar, 7z",
|
|
106
106
|
style: {}
|
|
107
107
|
};
|
|
108
108
|
export default SingleFileUpload;
|
|
@@ -8,11 +8,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
|
11
|
-
import { Upload, message, Flex, Image as Img } from "antd";
|
|
11
|
+
import { Upload, message, Flex, Image as Img, Space } from "antd";
|
|
12
12
|
import { LoadingOutlined, PlusOutlined, DeleteOutlined } from "@ant-design/icons";
|
|
13
13
|
import { buildURL } from "@ecoding/helper.url";
|
|
14
14
|
import Toast from "../../core/toast";
|
|
15
15
|
const ImgUpload = (props) => {
|
|
16
|
+
var _a, _b, _c, _d;
|
|
16
17
|
const [loading, setLoading] = useState(false);
|
|
17
18
|
const [imageUrl, setImageUrl] = useState(props.value || "");
|
|
18
19
|
const action = useMemo(() => {
|
|
@@ -85,33 +86,63 @@ const ImgUpload = (props) => {
|
|
|
85
86
|
};
|
|
86
87
|
const beforeUpload = useCallback((file) => {
|
|
87
88
|
return new Promise((resolve, reject) => __awaiter(void 0, void 0, void 0, function* () {
|
|
88
|
-
const ary = ["jpg", "jpeg", "png"];
|
|
89
|
+
const ary = ["jpg", "jpeg", "png", "webp"];
|
|
89
90
|
if (props.gif) {
|
|
90
91
|
ary.push("gif");
|
|
91
92
|
}
|
|
92
93
|
if (ary.indexOf(file.type.toLowerCase().replace(/image\//g, "")) === -1) {
|
|
93
|
-
message.error(
|
|
94
|
+
message.error(`支持图片格式为:${ary.join(",")}`);
|
|
94
95
|
reject();
|
|
95
96
|
return;
|
|
96
97
|
}
|
|
97
98
|
const isLt2M = file.size / 1024 / 1024 < (props.opts.size || 1);
|
|
98
99
|
if (!isLt2M) {
|
|
99
|
-
message.error(`图片大小必须小于${props.opts.size} MB
|
|
100
|
+
message.error(`图片大小必须小于${props.opts.size} MB`);
|
|
100
101
|
reject();
|
|
101
102
|
return;
|
|
102
103
|
}
|
|
103
104
|
const base64 = yield getBase64(file);
|
|
104
105
|
const wh = yield getImgwh(base64);
|
|
105
106
|
if (props.opts.w && props.opts.w !== wh.w) {
|
|
106
|
-
message.error(`图片宽度不符合 ${props.opts.w}px
|
|
107
|
+
message.error(`图片宽度不符合 ${props.opts.w}px`);
|
|
107
108
|
reject();
|
|
108
109
|
return;
|
|
109
110
|
}
|
|
110
111
|
if (props.opts.h && props.opts.h !== wh.h) {
|
|
111
|
-
message.error(`图片高度不符合 ${props.opts.h}px
|
|
112
|
+
message.error(`图片高度不符合 ${props.opts.h}px`);
|
|
112
113
|
reject();
|
|
113
114
|
return;
|
|
114
115
|
}
|
|
116
|
+
if (props.opts.maxH && props.opts.maxH < wh.h) {
|
|
117
|
+
message.error(`图片高度不能大于 ${props.opts.maxH}px`);
|
|
118
|
+
reject();
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
if (props.opts.minH && props.opts.minH > wh.h) {
|
|
122
|
+
message.error(`图片高度不能小于 ${props.opts.minH}px`);
|
|
123
|
+
reject();
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
if (props.opts.maxW && props.opts.maxW < wh.w) {
|
|
127
|
+
message.error(`图片宽度不能大于 ${props.opts.maxW}px`);
|
|
128
|
+
reject();
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
if (props.opts.minW && props.opts.minW > wh.w) {
|
|
132
|
+
message.error(`图片宽度不能小于 ${props.opts.minW}px`);
|
|
133
|
+
reject();
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
if (props.opts.ratioW && props.opts.ratioH) {
|
|
137
|
+
// 保留2位小数进行比例计算
|
|
138
|
+
const ratio = Number((wh.w / wh.h).toFixed(2));
|
|
139
|
+
const targetRatio = Number((props.opts.ratioW / props.opts.ratioH).toFixed(2));
|
|
140
|
+
if (ratio !== targetRatio) {
|
|
141
|
+
message.error(`图片宽度与高度比例必须是 ${props.opts.ratioW} x ${props.opts.ratioH}`);
|
|
142
|
+
reject();
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
115
146
|
resolve();
|
|
116
147
|
}));
|
|
117
148
|
}, []);
|
|
@@ -140,7 +171,7 @@ const ImgUpload = (props) => {
|
|
|
140
171
|
} },
|
|
141
172
|
React.createElement(DeleteOutlined, { style: { fontSize: 14 } })),
|
|
142
173
|
React.createElement(Img, { style: { width: "102px", height: "102px", objectFit: "contain", cursor: "pointer" }, src: imageUrl }))) : (React.createElement(Upload, { withCredentials: true, beforeUpload: beforeUpload, name: props.name, data: props.data, headers: props.headers, disabled: props.disabled, listType: "picture-card", showUploadList: false, action: action, onChange: handleChange }, uploadButton)),
|
|
143
|
-
props.isTip ? (React.createElement("div", { style: { fontSize: '13px', marginLeft: '18px', lineHeight: '
|
|
174
|
+
props.isTip ? (React.createElement("div", { style: { fontSize: '13px', marginLeft: '18px', lineHeight: '22px' } },
|
|
144
175
|
React.createElement("p", null,
|
|
145
176
|
props.i18n ? props.i18n.$t("global.size", "大小") : "大小",
|
|
146
177
|
"\uFF1A",
|
|
@@ -148,12 +179,14 @@ const ImgUpload = (props) => {
|
|
|
148
179
|
" ",
|
|
149
180
|
props.opts.size || 1,
|
|
150
181
|
"MB"),
|
|
151
|
-
React.createElement("p", null,
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
182
|
+
props.opts.w && props.opts.h ? (React.createElement("p", null, props.i18n ? `${props.i18n.$t("global.dimension", "尺寸")}: ${props.opts.w}px * ${props.opts.h}px` : `尺寸: ${props.opts.w}px x ${props.opts.h}px`)) : null,
|
|
183
|
+
props.opts.ratioW && props.opts.ratioH ? (React.createElement("p", null, props.i18n ? `${props.i18n.$t("global.ratio", "比例")}: ${props.opts.ratioW} x ${props.opts.ratioH}` : `比例: ${props.opts.ratioW} x ${props.opts.ratioH}`)) : null,
|
|
184
|
+
props.opts.minH || props.opts.minW || props.opts.maxH || props.opts.maxW ? (React.createElement("p", null,
|
|
185
|
+
React.createElement(Space, { split: "," },
|
|
186
|
+
!((_a = props.opts) === null || _a === void 0 ? void 0 : _a.minH) ? "" : (React.createElement("span", null, props.i18n ? `${props.i18n.$t("global.minH", "最小高")}:${props.opts.minH}` : `最小高:${props.opts.minH}`)),
|
|
187
|
+
!((_b = props.opts) === null || _b === void 0 ? void 0 : _b.maxH) ? "" : (React.createElement("span", null, props.i18n ? `${props.i18n.$t("global.maxH", "最大高")}:${props.opts.maxH}` : `最大高:${props.opts.maxH}`)),
|
|
188
|
+
!((_c = props.opts) === null || _c === void 0 ? void 0 : _c.minW) ? "" : (React.createElement("span", null, props.i18n ? `${props.i18n.$t("global.minW", "最小宽")}:${props.opts.minW}` : `最小宽:${props.opts.minW}`)),
|
|
189
|
+
!((_d = props.opts) === null || _d === void 0 ? void 0 : _d.maxH) ? "" : (React.createElement("span", null, props.i18n ? `${props.i18n.$t("global.maxH", "最大高")}:${props.opts.maxH}` : `最大高:${props.opts.maxH}`))))) : null,
|
|
157
190
|
React.createElement("p", null,
|
|
158
191
|
props.i18n ? props.i18n.$t("global.support", "支持") : "支持",
|
|
159
192
|
"\uFF1Ajpg\u3001jpeg\u3001png",
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface IProps {
|
|
3
|
+
i18n?: any;
|
|
4
|
+
disabled?: boolean;
|
|
5
|
+
treeData: any[];
|
|
6
|
+
disabledParent?: boolean;
|
|
7
|
+
fieldNames: {
|
|
8
|
+
label: string;
|
|
9
|
+
value: string;
|
|
10
|
+
children?: string;
|
|
11
|
+
};
|
|
12
|
+
value?: any;
|
|
13
|
+
treeNodeFilterProp?: string;
|
|
14
|
+
multiple?: boolean;
|
|
15
|
+
treeCheckable?: boolean;
|
|
16
|
+
onChange?: (value: any) => void;
|
|
17
|
+
}
|
|
18
|
+
declare const C: React.FC<IProps>;
|
|
19
|
+
export default C;
|
|
20
|
+
/**
|
|
21
|
+
*
|
|
22
|
+
<TreeSelect
|
|
23
|
+
disabled={operateDisabled}
|
|
24
|
+
fieldNames={{
|
|
25
|
+
label: 'label',
|
|
26
|
+
value: 'value',
|
|
27
|
+
children: 'children'
|
|
28
|
+
}}
|
|
29
|
+
treeNodeFilterProp="label"
|
|
30
|
+
treeData={[
|
|
31
|
+
{
|
|
32
|
+
label: '虎标颈肩舒',
|
|
33
|
+
value: '虎标颈肩舒'
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
label: '虎标镇痛药布',
|
|
37
|
+
value: '虎标镇痛药布',
|
|
38
|
+
children: [
|
|
39
|
+
{
|
|
40
|
+
label: '清凉型',
|
|
41
|
+
value: '清凉型',
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
label: '温感型',
|
|
45
|
+
value: '温感型',
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
]}
|
|
50
|
+
/>
|
|
51
|
+
*/
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { TreeSelect } from 'antd';
|
|
3
|
+
const processTreeData = (data) => {
|
|
4
|
+
return data.map((node) => {
|
|
5
|
+
const processedNode = Object.assign({}, node);
|
|
6
|
+
// 当节点有children且children数量大于1时,设置selectable为false
|
|
7
|
+
if (node.children && node.children.length > 0) {
|
|
8
|
+
processedNode.selectable = false;
|
|
9
|
+
processedNode.children = processTreeData(node.children);
|
|
10
|
+
}
|
|
11
|
+
return processedNode;
|
|
12
|
+
});
|
|
13
|
+
};
|
|
14
|
+
const C = ({ treeCheckable, i18n, disabledParent, treeData, fieldNames, onChange, treeNodeFilterProp, multiple, value, disabled }) => {
|
|
15
|
+
// 是否禁用父级
|
|
16
|
+
const treeDataFormat = disabledParent ? processTreeData(treeData || []) : treeData || [];
|
|
17
|
+
return (React.createElement(TreeSelect, { fieldNames: fieldNames, treeData: treeDataFormat, treeCheckable: treeCheckable, showSearch: true, style: { width: '100%' }, placeholder: i18n.$t('global.please.select'), allowClear: true, treeDefaultExpandAll: true, onChange: onChange, treeNodeFilterProp: treeNodeFilterProp, multiple: multiple, value: value, disabled: disabled || false }));
|
|
18
|
+
};
|
|
19
|
+
C.defaultProps = {
|
|
20
|
+
disabledParent: true
|
|
21
|
+
};
|
|
22
|
+
export default C;
|
|
23
|
+
/**
|
|
24
|
+
*
|
|
25
|
+
<TreeSelect
|
|
26
|
+
disabled={operateDisabled}
|
|
27
|
+
fieldNames={{
|
|
28
|
+
label: 'label',
|
|
29
|
+
value: 'value',
|
|
30
|
+
children: 'children'
|
|
31
|
+
}}
|
|
32
|
+
treeNodeFilterProp="label"
|
|
33
|
+
treeData={[
|
|
34
|
+
{
|
|
35
|
+
label: '虎标颈肩舒',
|
|
36
|
+
value: '虎标颈肩舒'
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
label: '虎标镇痛药布',
|
|
40
|
+
value: '虎标镇痛药布',
|
|
41
|
+
children: [
|
|
42
|
+
{
|
|
43
|
+
label: '清凉型',
|
|
44
|
+
value: '清凉型',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
label: '温感型',
|
|
48
|
+
value: '温感型',
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
]}
|
|
53
|
+
/>
|
|
54
|
+
*/
|
package/lib/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export { default as InjectNotification } from "./core/inject-notification";
|
|
|
6
6
|
export { default as Confirm } from "./core/confirm";
|
|
7
7
|
export { default as AsyncCascader } from "./core/async-cascader";
|
|
8
8
|
export { default as LengthInput } from "./core/length-input";
|
|
9
|
+
export { default as LengthInputTextArea } from "./core/length-input-textarea";
|
|
9
10
|
export { default as SearchInput } from "./core/search.input";
|
|
10
11
|
export { default as PhoneInput } from "./core/phone-input";
|
|
11
12
|
export { default as RangePicker } from "./core/range-picker";
|
|
@@ -14,11 +15,12 @@ export { default as SingleImgUpload } from "./core/single-img-upload";
|
|
|
14
15
|
export { default as MultipleSingleImgUpload } from "./core/multiple-single-img-upload";
|
|
15
16
|
export { default as MultipleImgUpload } from "./core/multiple-img-upload";
|
|
16
17
|
export { default as SingleFileUpload } from "./core/single-file-upload";
|
|
17
|
-
export { default as
|
|
18
|
+
export { default as MultipleFileUpload } from "./core/multiple-file-upload";
|
|
18
19
|
export { default as FormLabel } from "./core/form.label";
|
|
19
20
|
export { default as FormLabelAttachment } from "./core/form.label.attachment";
|
|
20
21
|
export { default as FormList } from "./core/form.list";
|
|
21
22
|
export { default as AsyncSelect } from "./core/async-select";
|
|
23
|
+
export { default as TreeSelect } from "./core/tree.select";
|
|
22
24
|
export { default as AsyncTransfer } from "./core/async-transfer";
|
|
23
25
|
export { default as TagItems } from "./core/tag.items";
|
|
24
26
|
export { default as TablePro } from "./core/table-pro";
|
package/lib/index.js
CHANGED
|
@@ -6,6 +6,7 @@ export { default as InjectNotification } from "./core/inject-notification";
|
|
|
6
6
|
export { default as Confirm } from "./core/confirm";
|
|
7
7
|
export { default as AsyncCascader } from "./core/async-cascader";
|
|
8
8
|
export { default as LengthInput } from "./core/length-input";
|
|
9
|
+
export { default as LengthInputTextArea } from "./core/length-input-textarea";
|
|
9
10
|
export { default as SearchInput } from "./core/search.input";
|
|
10
11
|
export { default as PhoneInput } from "./core/phone-input";
|
|
11
12
|
export { default as RangePicker } from "./core/range-picker";
|
|
@@ -14,11 +15,12 @@ export { default as SingleImgUpload } from "./core/single-img-upload";
|
|
|
14
15
|
export { default as MultipleSingleImgUpload } from "./core/multiple-single-img-upload";
|
|
15
16
|
export { default as MultipleImgUpload } from "./core/multiple-img-upload";
|
|
16
17
|
export { default as SingleFileUpload } from "./core/single-file-upload";
|
|
17
|
-
export { default as
|
|
18
|
+
export { default as MultipleFileUpload } from "./core/multiple-file-upload";
|
|
18
19
|
export { default as FormLabel } from "./core/form.label";
|
|
19
20
|
export { default as FormLabelAttachment } from "./core/form.label.attachment";
|
|
20
21
|
export { default as FormList } from "./core/form.list";
|
|
21
22
|
export { default as AsyncSelect } from "./core/async-select";
|
|
23
|
+
export { default as TreeSelect } from "./core/tree.select";
|
|
22
24
|
export { default as AsyncTransfer } from "./core/async-transfer";
|
|
23
25
|
export { default as TagItems } from "./core/tag.items";
|
|
24
26
|
export { default as TablePro } from "./core/table-pro";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ecoding/components.antd",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"author": "cxc",
|
|
5
5
|
"homepage": "",
|
|
6
6
|
"license": "MIT",
|
|
@@ -47,5 +47,5 @@
|
|
|
47
47
|
"antd": "5.27.0",
|
|
48
48
|
"axios": "^1.1.2"
|
|
49
49
|
},
|
|
50
|
-
"gitHead": "
|
|
50
|
+
"gitHead": "03794f7f95481697dbad2c9868a39f8facb68c98"
|
|
51
51
|
}
|
|
File without changes
|