frontend-template/src/pages/Work/Edit/index.tsx

290 lines
9.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useState, useEffect } from 'react';
import { createForm } from '@formily/core';
import { createSchemaField } from '@formily/react';
import {
Form,
FormItem,
Input,
Select,
Submit,
FormGrid,
ArrayItems,
Editable,
Switch,
ArrayTable,
FormButtonGroup,
NumberPicker,
} from '@formily/antd';
import { observable } from '@formily/reactive';
import Upload from '@/components/Upload';
import { WorkType } from '@/constants/enum/work';
import { message, Button, Spin } from 'antd';
import Editor from '@/components/Editor';
import DetailPageContainer from '@/components/DetailPageContainer';
import { addWork, updateWork, queryWorkDetail } from '@/services/work';
import { useLocation } from 'umi';
import { UploadBizType } from '@/constants/enum/uploadBizType';
import AuthorSelect, { Options } from './components/AuthorSelector';
const SchemaField = createSchemaField({
components: {
FormItem,
FormGrid,
Input,
Select,
ArrayTable,
Upload,
Switch,
ArrayItems,
NumberPicker,
Editable,
Editor,
AuthorSelect,
},
});
const obs: { authorDefaultOption: Options[] } = observable({
authorDefaultOption: [],
});
const workTypeList = [
{
label: '视频',
value: WorkType.VIDEO,
},
{
label: '音频',
value: WorkType.AUDIO,
},
{
label: '图片',
value: WorkType.PICTURE,
},
];
const form = createForm({});
const WorkEdit = () => {
const { id } = useLocation().query;
const [loading, setLoading] = useState(false);
const getWorkDetail = async () => {
const res: any = await queryWorkDetail({ id });
const resourseList = res.resource_arr.map((item) => ({
...item,
img: [{ uid: item.path, path: item.path, url: item.url }],
}));
const newValue = { ...res, resource_arr: resourseList, author_id: res.author?.id };
obs.authorDefaultOption = [
{ label: `${res.author?.first_name} ${res.author?.last_name}`, value: res.author?.id },
];
form.setValues(newValue);
};
const handleSubmit = async (val) => {
const params = { ...val };
if (params.resource_arr.filter((item) => item.cover).length > 1) {
message.warning('只能设置一张图片为封面');
return;
}
if (params.resource_arr.filter((item) => item.cover).length === 0) {
message.warning('请设置一张图片为封面');
return;
}
if (params.resource_arr.filter((item) => item.avatar).length > 1) {
message.warning('只能设置一个为nft资源');
return;
}
if (params.resource_arr.filter((item) => item.avatar).length === 0) {
message.warning('请设置一个为nft资源');
return;
}
params.resource_arr.forEach((item, index) => {
item.path = item.img[0].path;
item.order_num = index;
});
setLoading(true);
try {
if (id) {
await updateWork(params);
} else {
await addWork(params);
}
message.success('操作成功');
setLoading(false);
history.back();
} catch (e) {
setLoading(false);
}
};
const handleAddResoruce = () => {
const resourceList = form.getFieldState('resource_arr').value;
if (resourceList.length >= 5) {
message.warning('只能添加5个资源');
return;
}
form.setFieldState('resource_arr', (state) => {
state.value = [...resourceList, {}];
});
};
useEffect(() => {
id && getWorkDetail();
return () => {
form.setValues({}, 'overwrite');
obs.authorDefaultOption = [];
};
}, []);
return (
<DetailPageContainer>
<Spin spinning={loading}>
<Form form={form} labelCol={4} wrapperCol={18} onAutoSubmit={handleSubmit}>
<SchemaField>
<SchemaField.String
name="title"
title="标题"
required
x-decorator="FormItem"
x-component="Input"
/>
<SchemaField.String
name="sub_title"
title="副标题"
required
x-component-props={{ maxLength: 100, showCount: true }}
x-decorator="FormItem"
x-component="Input.TextArea"
/>
<SchemaField.String
name="series"
title="系列"
required
x-decorator="FormItem"
x-component="Input"
/>
<SchemaField.Number
name="rarity"
title="等级"
required
description="rarity < 0 极度稀有 UR,
rarity >= 0 && rarity < 100 较高级的超级稀有 SSR,
rarity > =100 && rarity < 1000 超级稀有 SR,
rarity >= 1000 && rarity < 10000 稀有 R,
rarity >= 10000 普通 N"
x-validator="number"
x-decorator="FormItem"
x-component="NumberPicker"
/>
<SchemaField.String
name="author_id"
title="作者"
required
x-component-props={{
defaultOptions: obs.authorDefaultOption,
}}
x-reactions={(field) => {
field.component[1].defaultOptions = obs.authorDefaultOption;
}}
x-decorator="FormItem"
x-component="AuthorSelect"
/>
<SchemaField.String
name="type"
title="类型"
required
x-component-props={{
options: workTypeList,
}}
x-decorator="FormItem"
x-component="Select"
/>
<SchemaField.String
name="introduction"
title="描述"
required
x-decorator="FormItem"
x-component="Editor"
/>
<SchemaField.Array
name="resource_arr"
title="资源"
required
// description="资源推荐尺寸420x325"
x-decorator="FormItem"
x-component="ArrayTable"
x-component-props={{
pagination: { pageSize: 10 },
}}
>
<SchemaField.Object>
<SchemaField.Void
x-component="ArrayTable.Column"
x-component-props={{ width: 60, title: '拖动排序', align: 'center' }}
>
<SchemaField.Void
x-decorator="FormItem"
required
x-component="ArrayTable.SortHandle"
/>
</SchemaField.Void>
<SchemaField.Void
x-component="ArrayTable.Column"
x-component-props={{ width: 80, title: '序号', align: 'center' }}
>
<SchemaField.String x-decorator="FormItem" x-component="ArrayTable.Index" />
</SchemaField.Void>
<SchemaField.Void
x-component="ArrayTable.Column"
x-component-props={{ width: 200, title: '资源', align: 'center' }}
>
<SchemaField.String
required
x-decorator="FormItem"
name="img"
x-component-props={{ accept: 'image/*,video/mp4', bizType: UploadBizType.WORK }}
x-component="Upload"
/>
</SchemaField.Void>
<SchemaField.Void
x-component="ArrayTable.Column"
x-component-props={{ width: 200, title: '设置为封面', align: 'center' }}
>
<SchemaField.String x-decorator="FormItem" name="cover" x-component="Switch" />
</SchemaField.Void>
<SchemaField.Void
x-component="ArrayTable.Column"
x-component-props={{ width: 200, title: '设置为NFT资源', align: 'center' }}
>
<SchemaField.String x-decorator="FormItem" name="avatar" x-component="Switch" />
</SchemaField.Void>
<SchemaField.Void
x-component="ArrayTable.Column"
x-component-props={{
title: '操作',
dataIndex: 'operations',
width: 200,
fixed: 'right',
}}
>
<SchemaField.Void x-component="FormItem">
<SchemaField.Void x-component="ArrayTable.Remove" />
</SchemaField.Void>
</SchemaField.Void>
</SchemaField.Object>
</SchemaField.Array>
</SchemaField>
<FormButtonGroup.FormItem style={{ marginBottom: 20 }}>
<Button type="dashed" onClick={handleAddResoruce} block>
</Button>
</FormButtonGroup.FormItem>
<FormButtonGroup.FormItem>
<Submit block size="large">
</Submit>
</FormButtonGroup.FormItem>
</Form>
</Spin>
</DetailPageContainer>
);
};
export default WorkEdit;