Skip to content

Commit 734b303

Browse files
committed
fix form
1 parent a83b55e commit 734b303

File tree

5 files changed

+215
-7
lines changed

5 files changed

+215
-7
lines changed

admin-pro-ui/src/components/form/checkbox.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,10 @@ const FormCheckbox: React.FC<FormItemProps> = (props) => {
6262
}}
6363
>
6464
<Space direction={props.checkboxDirection}>
65-
{options?.map(item => {
65+
{options?.map((item,index) => {
6666
return (
6767
<Checkbox
68+
key={index}
6869
disabled={item.disable}
6970
value={item.value}
7071
>{item.label}</Checkbox>

admin-pro-ui/src/components/form/factory.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import FormDate from "@/components/form/date";
1414
import FormCascader from "@/components/form/cascader";
1515
import FormSelect from "@/components/form/select";
1616
import FormSelector from "@/components/form/selector";
17+
import FormUploader from "@/components/form/uploder";
1718

1819

1920
class FormFactory {
@@ -147,9 +148,14 @@ class FormFactory {
147148
)
148149
}
149150

150-
return (
151-
<></>
152-
)
151+
if (type === 'uploader') {
152+
return (
153+
<FormUploader
154+
{...props}
155+
key={props.name}
156+
/>
157+
)
158+
}
153159
}
154160

155161
}

admin-pro-ui/src/components/form/radio.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,10 @@ const FormRadio: React.FC<FormItemProps> = (props) => {
4141
}}
4242
>
4343
<Space direction={props.radioDirection}>
44-
{options?.map(item => {
44+
{options?.map((item,index) => {
4545
return (
4646
<Radio
47+
key={index}
4748
value={item.value}
4849
disabled={item.disable}
4950
>{item.label}</Radio>
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
import React, {useEffect, useState} from "react";
2+
import {FormItemProps} from "@/components/form/types";
3+
import {Button, Form, Image, Upload} from "antd";
4+
import formFieldInit from "@/components/form/common";
5+
import {PlusOutlined, UploadOutlined} from "@ant-design/icons";
6+
import {RcFile} from "antd/es/upload";
7+
import {UploadFile} from "antd/lib";
8+
import {FormAction} from "@/components/form/index";
9+
import "./form.scss";
10+
11+
const fileToBase64 = (file: RcFile): Promise<string> => {
12+
return new Promise((resolve, reject) => {
13+
const reader = new FileReader();
14+
reader.readAsDataURL(file);
15+
reader.onload = () => resolve(reader.result as string);
16+
reader.onerror = error => reject(error);
17+
});
18+
}
19+
20+
const formToValue = (value: UploadFile[]) => {
21+
if (value && value.length > 0) {
22+
return value.map(item => {
23+
if (item.response) {
24+
return item.response.id;
25+
}
26+
}).join(',');
27+
}
28+
return value;
29+
}
30+
31+
interface UploaderProps extends FormItemProps {
32+
formAction?: FormAction;
33+
uploaderAccept: string
34+
}
35+
36+
37+
const Uploader: React.FC<UploaderProps> = (props) => {
38+
const formAction = props.formAction;
39+
const isImage = props.uploaderAccept === 'image/*';
40+
41+
const [fileList, setFileList] = React.useState<UploadFile[]>([]);
42+
const [previewImage, setPreviewImage] = useState('');
43+
const [previewOpen, setPreviewOpen] = useState(false);
44+
45+
const reloadFiles = () => {
46+
if (props.value) {
47+
if (props.onUploaderLoad) {
48+
props.onUploaderLoad(props.value).then(res => {
49+
setFileList(res.map((item: any) => {
50+
return {
51+
uid: item.id || '-1',
52+
name: item.name,
53+
status: 'done',
54+
url: item.url,
55+
response: {
56+
id: item.id,
57+
url: item.url,
58+
name: item.name
59+
},
60+
}
61+
}))
62+
});
63+
}
64+
}
65+
}
66+
67+
useEffect(() => {
68+
reloadFiles();
69+
}, [props.value]);
70+
71+
const handlePreview = async (file: UploadFile) => {
72+
setPreviewImage(file.response?.url);
73+
setPreviewOpen(true);
74+
};
75+
76+
return (
77+
<div>
78+
<Upload
79+
disabled={props.disabled}
80+
name={props.name}
81+
fileList={fileList}
82+
accept={props.uploaderAccept}
83+
listType={isImage ? 'picture-card' : undefined}
84+
maxCount={props.uploaderMaxCount}
85+
customRequest={async ({file, onSuccess}) => {
86+
const currentFile = file as RcFile;
87+
const base64 = await fileToBase64(currentFile);
88+
const filename = currentFile.name;
89+
if (props.onUploaderUpload) {
90+
const {id, name, url} = await props.onUploaderUpload(filename, base64);
91+
// @ts-ignore
92+
onSuccess({
93+
url: url,
94+
id: id,
95+
name: name
96+
});
97+
} else {
98+
const url = URL.createObjectURL(currentFile);
99+
// @ts-ignore
100+
onSuccess({
101+
url: url,
102+
id: Math.random(),
103+
name: currentFile.name
104+
});
105+
}
106+
}}
107+
onChange={(info) => {
108+
const currentValue = formToValue(info.fileList);
109+
formAction?.setFieldValue(props.name, currentValue);
110+
props.onChange && props.onChange(currentValue, formAction);
111+
setFileList(info.fileList);
112+
}}
113+
onPreview={isImage ? handlePreview : undefined}
114+
>
115+
{isImage && (
116+
<PlusOutlined/>
117+
)}
118+
{!isImage && (
119+
<Button icon={<UploadOutlined/>}>选择文件</Button>
120+
)}
121+
122+
</Upload>
123+
124+
{isImage && previewImage && (
125+
<Image
126+
wrapperStyle={{display: 'none'}}
127+
preview={{
128+
visible: previewOpen,
129+
onVisibleChange: (visible) => setPreviewOpen(visible),
130+
afterOpenChange: (visible) => !visible && setPreviewImage(''),
131+
}}
132+
src={previewImage}
133+
/>
134+
)}
135+
</div>
136+
)
137+
}
138+
139+
const FormUploader: React.FC<FormItemProps> = (props) => {
140+
const {formAction} = formFieldInit(props);
141+
const accept = props.uploaderAccept || "image/*";
142+
return (
143+
<Form.Item
144+
name={props.name}
145+
label={props.label}
146+
required={props.required}
147+
hidden={props.hidden}
148+
help={props.help}
149+
>
150+
<Uploader
151+
formAction={formAction}
152+
value={props.value}
153+
onChange={props.onChange}
154+
uploaderAccept={accept}
155+
{...props}
156+
/>
157+
</Form.Item>
158+
)
159+
}
160+
161+
export default FormUploader;

admin-pro-ui/src/pages/welcome/index.tsx

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,28 @@ import FormTextArea from "@/components/form/textarea";
1717
import FormDate from "@/components/form/date";
1818
import FormCascader from "@/components/form/cascader";
1919
import FormSelect from "@/components/form/select";
20+
import FormUploader from "@/components/form/uploder";
2021

2122

2223
const FooterButtons: React.FC<{ formAction: React.RefObject<FormAction> }> = ({formAction}) => {
24+
const data = {
25+
user: {
26+
name: '张三',
27+
age: 18,
28+
password: '123456',
29+
code: '123',
30+
checkbox: '1,2',
31+
radio: '1',
32+
rate: 3,
33+
slider: 50,
34+
switch: true,
35+
textarea: '这是一段文本',
36+
date: '2021-08-01',
37+
cascader: '1,1-1,1-1-1',
38+
select: '1,2',
39+
avatar: '1,2'
40+
}
41+
}
2342

2443
return (
2544
<div
@@ -67,6 +86,12 @@ const FooterButtons: React.FC<{ formAction: React.RefObject<FormAction> }> = ({f
6786
formAction.current?.reset();
6887
}}
6988
>重置表单</Button>
89+
90+
<Button
91+
onClick={async () => {
92+
formAction.current?.setFieldsValue(data);
93+
}}
94+
>表单赋值</Button>
7095
</div>
7196
)
7297
}
@@ -255,16 +280,25 @@ const WelcomePage = () => {
255280
required: true,
256281
name: ['user', 'select'],
257282
label: '选择器',
258-
selectMultiple:true,
283+
selectMultiple: true,
259284
options: [
260285
{label: '选项1', value: '1'},
261286
{label: '选项2', value: '2'},
262287
{label: '选项3', value: '3'},
263288
]
264289
}
265-
}
290+
},
291+
{
292+
type: 'uploader',
293+
props: {
294+
required: true,
295+
name: ['user', 'avatar'],
296+
label: '头像',
297+
}
298+
},
266299
] as FormField[];
267300

301+
268302
return (
269303
<PageContainer>
270304
<Row gutter={[24, 24]}>
@@ -437,6 +471,11 @@ const WelcomePage = () => {
437471
]}
438472
/>
439473

474+
<FormUploader
475+
required={true}
476+
name={["user", "avatar"]}
477+
label={"头像"}
478+
/>
440479
</Form>
441480
</Col>
442481

0 commit comments

Comments
 (0)