ai-course/app/backend/src/pages/textbook/compenents/createTextbook.tsx
2025-11-28 20:04:15 +08:00

526 lines
17 KiB
TypeScript

import React, { useState, useEffect } from 'react';
import { Space, Button, Drawer, Form, Input, message, Tag, DatePicker, Spin } from 'antd';
import { SelectRange } from '../../../compenents';
import { useTranslation } from 'react-i18next';
import moment from 'moment/moment';
import { CreateTextbookApi, GetTextbookDetailApi, UpdateTextbookApi } from '../../../api/textbook';
import { ThumbUpload } from './Upload/UploadThumb';
import dayjs from 'dayjs';
const { TextArea } = Input;
interface CourseCreateProps {
isEdit: boolean;
open: boolean;
onCancel: () => void;
editId?: any;
}
// @ts-ignore
export const CreateTextbook: React.FC<CourseCreateProps> = ({ editId, isEdit, open, onCancel }) => {
const { t } = useTranslation();
const [form] = Form.useForm();
const [loading, setLoading] = useState<boolean>(false);
const [thumb, setThumb] = useState<string>(''); // 封面
const [allUrl, setAllUrl] = useState<string>(''); // 封面全部路径
// 范围指派
const [depIds, setDepIds] = useState<number[]>([]);
const [groupIds, setGroupIds] = useState<number[]>([]);
const [userIds, setUserIds] = useState<number[]>([]);
const [deps, setDeps] = useState<any[]>([]);
const [groups, setGroups] = useState<any[]>([]);
const [users, setUsers] = useState<any[]>([]);
const [idsVisible, setIdsVisible] = useState<boolean>(false);
const [spinInit, setSpinInit] = useState<boolean>(false);
const [isUploading, setIsUploading] = useState<boolean>(false);
const InitForm = () => {
form.setFieldsValue({
title: '',
thumb: undefined,
isbn: '',
dep_ids: undefined,
short_desc: '',
publish_time: undefined,
major: undefined,
author: undefined,
publish_unit: undefined,
create_time: undefined,
});
setThumb('');
setAllUrl('');
setDepIds([]);
setDeps([]);
setGroupIds([]);
setGroups([]);
setUserIds([]);
setUsers([]);
};
useEffect(() => {
if (editId && isEdit) {
setSpinInit(true);
getDetail();
} else if (!isEdit && open) {
InitForm();
}
}, [form, open, isEdit, editId]);
useEffect(() => {
return () => {
InitForm();
};
}, []);
// Edit信息回显
const getDetail = () => {
GetTextbookDetailApi(editId).then((res: any) => {
form.setFieldsValue({
title: res.data.textbook.title,
thumb: res.data.textbook.thumb,
short_desc: res.data.textbook.shortDesc,
author: res.data.textbook.author,
major: res.data.textbook.major,
publish_time: res.data.textbook.publishTime ? dayjs(res.data.textbook.publishTime) : '',
publish_unit: res.data.textbook.publishUnit,
create_time: res.data.textbook.createTime ? dayjs(res.data.textbook.createTime) : '',
isbn: res.data.textbook.isbn,
});
const deps = res.data.deps;
if (deps && JSON.stringify(deps) !== '{}') {
getDepsDetail(deps);
}
const groups = res.data.groups;
if (groups && JSON.stringify(groups) !== '{}') {
getGroupsDetail(groups);
}
const users = res.data.users;
if (users && JSON.stringify(users) !== '{}') {
getUsersDetail(users);
}
if (
(deps && JSON.stringify(deps) !== '{}') ||
(groups && JSON.stringify(groups) !== '{}') ||
(users && JSON.stringify(users) !== '{}')
) {
form.setFieldsValue({ ids: [1, 2] });
}
setThumb(res.data.textbook.thumb);
setAllUrl(res.data.textbook.allUrl);
setSpinInit(false);
});
};
const onFinish = (values: any) => {
if (loading) return;
const dep_ids: any[] = depIds;
const group_ids: any[] = groupIds;
const user_ids: any[] = userIds;
// 接口位置
setLoading(true);
if (isEdit) {
UpdateTextbookApi(
editId,
values.title,
thumb,
values.short_desc,
values.author,
values.major,
dep_ids,
group_ids,
user_ids,
values.publish_time,
values.publish_unit,
values.create_time,
values.isbn
)
.then((res: any) => {
setLoading(false);
message.success(t('commen.saveSuccess'));
onCancel();
})
.catch((e) => {
setLoading(false);
});
} else {
CreateTextbookApi(
values.title,
thumb,
values.short_desc,
values.author,
values.major,
dep_ids,
group_ids,
user_ids,
values.publish_time,
values.publish_unit,
values.create_time,
values.isbn
)
.then((res: any) => {
setLoading(false);
message.success(t('commen.saveSuccess'));
onCancel();
})
.catch((e) => {
setLoading(false);
});
}
};
const onFinishFailed = (errorInfo: any) => {
console.log('Failed:', errorInfo);
};
const disabledDate = (current: any) => {
return current && current >= moment().add(0, 'days');
};
const getDepsDetail = (deps: any) => {
const arr: any = [];
const arr2: any = [];
Object.keys(deps).map((v, i) => {
arr.push(Number(v));
arr2.push({
key: Number(v),
title: {
props: {
children: deps[v],
},
},
});
});
setDepIds(arr);
setDeps(arr2);
};
const getGroupsDetail = (groups: any) => {
const arr: any = [];
const arr2: any = [];
Object.keys(groups).map((v, i) => {
arr.push(Number(v));
arr2.push({
key: Number(v),
title: {
props: {
children: groups[v],
},
},
});
});
setGroupIds(arr);
setGroups(arr2);
};
const getUsersDetail = (users: any) => {
const arr: any = [];
const arr2: any = [];
Object.keys(users).map((v, i) => {
arr.push(Number(v));
arr2.push({
id: Number(v),
name: users[v],
});
});
setUserIds(arr);
setUsers(arr2);
};
return (
<>
<Drawer
title={isEdit ? t('course.updateTextbook') : t('course.createTextbook')}
onClose={onCancel}
maskClosable={false}
open={open}
footer={
<Space className="j-r-flex">
<Button onClick={() => onCancel()} disabled={isUploading}>
{t('commen.drawerCancel')}
</Button>
<Button
loading={loading}
disabled={isUploading}
onClick={() => form.submit()}
type="primary"
>
{t('commen.drawerOk')}
</Button>
</Space>
}
width={700}
>
<div className="float-left mt-24">
{spinInit ? (
<div className="text-center mt-30">
<Spin></Spin>
</div>
) : (
<Form
form={form}
name="create-basic"
labelCol={{ span: 5 }}
wrapperCol={{ span: 19 }}
initialValues={{ remember: true }}
onFinish={onFinish}
onFinishFailed={onFinishFailed}
autoComplete="off"
>
{/* 表单字段 */}
<Form.Item
label={t('textbook.create.name')}
name="title"
rules={[{ required: true, message: t('textbook.create.namePlaceholder') }]}
>
<Input
style={{ width: 424 }}
placeholder={t('textbook.create.namePlaceholder')}
allowClear
/>
</Form.Item>
<Form.Item
label={t('textbook.create.thumb')}
name="thumb"
rules={[{ required: true, message: t('textbook.create.thumbPlaceholder') }]}
>
<div className="d-flex">
<ThumbUpload
categoryIds={[]}
allowedFileTypes={['image/jpeg', 'image/png']}
type="IMAGE"
poster=""
label="上传图片"
note="支持 JPG、PNG 格式,大小不超过 2MB"
value={thumb}
onChange={setThumb}
ImageBorderRadius={5}
ImageHeight={290}
ImageWidth={217}
allUrl={allUrl}
isUploading={isUploading}
setIsUploading={setIsUploading}
/>
<span className="helper-text ml-16">{t('textbook.create.thumbTip')}</span>
</div>
</Form.Item>
{/*范围指派*/}
<Form.Item
label={t('textbook.create.assign')}
name="ids"
rules={[{ required: true, message: t('textbook.create.assignPlaceholder') }]}
>
<div
className="d-flex"
style={{ width: '100%', flexWrap: 'wrap', marginBottom: -8 }}
>
<Button
type="default"
style={{ marginBottom: 14 }}
onClick={() => setIdsVisible(true)}
>
{t('course.edit.idsText')}
</Button>
<div
className="d-flex"
style={{
width: '100%',
flexWrap: 'wrap',
marginBottom: -16,
}}
>
{deps.length > 0 &&
deps.map((item: any, i: number) => (
<Tag
key={i}
closable
style={{
height: 32,
lineHeight: '32px',
fontSize: 14,
color: '#FF4D4F',
background: 'rgba(255,77,79,0.1)',
marginRight: 16,
marginBottom: 16,
}}
onClose={(e) => {
e.preventDefault();
const arr = [...deps];
const arr2 = [...depIds];
arr.splice(i, 1);
arr2.splice(i, 1);
setDeps(arr);
setDepIds(arr2);
form.setFieldsValue({
ids: arr2.concat(groupIds).concat(userIds),
});
}}
>
{item.title.props.children}
</Tag>
))}
{groups.length > 0 &&
groups.map((item: any, i: number) => (
<Tag
key={i}
closable
style={{
height: 32,
lineHeight: '32px',
fontSize: 14,
color: '#FF4D4F',
background: 'rgba(255,77,79,0.1)',
marginRight: 16,
marginBottom: 16,
}}
onClose={(e) => {
e.preventDefault();
const arr = [...groups];
const arr2 = [...groupIds];
arr.splice(i, 1);
arr2.splice(i, 1);
setGroups(arr);
setGroupIds(arr2);
form.setFieldsValue({
ids: depIds.concat(arr2).concat(userIds),
});
}}
>
{item.title.props.children}
</Tag>
))}
{users.length > 0 &&
users.map((item: any, j: number) => (
<Tag
key={j}
closable
style={{
height: 32,
lineHeight: '32px',
fontSize: 14,
color: '#FF4D4F',
background: 'rgba(255,77,79,0.1)',
marginRight: 16,
marginBottom: 16,
}}
onClose={(e) => {
e.preventDefault();
const arr = [...users];
const arr2 = [...userIds];
arr.splice(j, 1);
arr2.splice(j, 1);
setUsers(arr);
setUserIds(arr2);
form.setFieldsValue({
dep_ids: depIds.concat(groupIds).concat(arr2),
});
}}
>
{item.name}
</Tag>
))}
</div>
</div>
</Form.Item>
<Form.Item
label={t('textbook.create.subject')}
name="major"
rules={[{ required: true, message: t('textbook.create.subjectPlaceholder') }]}
>
<Input
style={{ width: 424 }}
placeholder={t('textbook.create.subjectPlaceholder')}
allowClear
/>
</Form.Item>
<Form.Item
label={t('textbook.create.isbn')}
name="isbn"
rules={[{ required: true, message: t('textbook.create.isbnPlaceholder') }]}
>
<Input
style={{ width: 424 }}
placeholder={t('textbook.create.isbnPlaceholder')}
allowClear
/>
</Form.Item>
<Form.Item
label={t('textbook.create.author')}
name="author"
rules={[{ required: true, message: t('textbook.create.authorPlaceholder') }]}
>
<Input
style={{ width: 424 }}
placeholder={t('textbook.create.authorPlaceholder')}
allowClear
/>
</Form.Item>
<Form.Item
label={t('textbook.create.publisher')}
name="publish_unit"
rules={[{ required: true, message: t('textbook.create.publisherPlaceholder') }]}
>
<Input
style={{ width: 424 }}
placeholder={t('textbook.create.publisherPlaceholder')}
allowClear
/>
</Form.Item>
<Form.Item
label={t('textbook.create.publishTime')}
name="publish_time"
rules={[{ required: true, message: t('textbook.create.publishTimePlaceholder') }]}
>
<DatePicker
style={{ width: 424 }}
placeholder={t('textbook.create.publishTimePlaceholder')}
allowClear
format="YYYY-MM-DD"
disabledDate={disabledDate}
showNow={false}
/>
</Form.Item>
<Form.Item
label={t('textbook.create.desc')}
name="short_desc"
rules={[{ required: true, message: t('textbook.create.descPlaceholder') }]}
>
<TextArea
style={{ width: 424 }}
rows={6}
placeholder={t('textbook.create.descPlaceholder')}
allowClear
maxLength={300}
autoSize={{ minRows: 6, maxRows: 6 }}
/>
</Form.Item>
</Form>
)}
<SelectRange
defaultDepIds={depIds}
defaultGroupIds={groupIds}
defaultUserIds={userIds}
defaultDeps={deps}
defaultGroups={groups}
defaultUsers={users}
open={idsVisible}
onCancel={() => setIdsVisible(false)}
onSelected={(selDepIds, selDeps, selGroupIds, selGroups, selUserIds, selUsers) => {
setDepIds(selDepIds);
setDeps(selDeps);
setGroupIds(selGroupIds);
setGroups(selGroups);
setUserIds(selUserIds);
setUsers(selUsers);
form.setFieldsValue({
ids: selDepIds.concat(selGroupIds).concat(selUserIds),
});
setIdsVisible(false);
}}
/>
{/* 表单 */}
</div>
</Drawer>
</>
);
};