290 lines
9.1 KiB
TypeScript
290 lines
9.1 KiB
TypeScript
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;
|