400 lines
12 KiB
TypeScript
400 lines
12 KiB
TypeScript
import { HTTPSTATUS } from '@/constants';
|
|
import {
|
|
apiCreateFishSpecies,
|
|
apiUpdateFishSpecies,
|
|
} from '@/services/slave/sgw/FishController';
|
|
import {
|
|
apiDeletePhoto,
|
|
apiUploadPhoto,
|
|
} from '@/services/slave/sgw/PhotoController';
|
|
import {
|
|
ModalForm,
|
|
ProForm,
|
|
ProFormInstance,
|
|
ProFormSelect,
|
|
ProFormText,
|
|
ProFormTextArea,
|
|
ProFormUploadButton,
|
|
} from '@ant-design/pro-components';
|
|
import { useIntl } from '@umijs/max';
|
|
import { MessageInstance } from 'antd/es/message/interface';
|
|
import type { UploadFile } from 'antd/es/upload/interface';
|
|
import { useRef, useState } from 'react';
|
|
|
|
export type AddOrUpdateFishProps = {
|
|
type: 'create' | 'update';
|
|
fish?: SgwModel.Fish;
|
|
isOpen?: boolean;
|
|
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
|
message: MessageInstance;
|
|
onReload?: (isSuccess: boolean) => void;
|
|
};
|
|
const AddOrUpdateFish = ({
|
|
type,
|
|
fish,
|
|
isOpen,
|
|
setIsOpen,
|
|
message,
|
|
onReload,
|
|
}: AddOrUpdateFishProps) => {
|
|
const formRef = useRef<ProFormInstance<SgwModel.Fish>>();
|
|
const [fileList, setFileList] = useState<UploadFile[]>([]);
|
|
const [originalFileList, setOriginalFileList] = useState<UploadFile[]>([]);
|
|
const intl = useIntl();
|
|
// Check ảnh có thay đổi so với ban đầu không
|
|
const hasImageChanged = () => {
|
|
const currentHasImage = fileList.length > 0;
|
|
const originalHasImage = originalFileList.length > 0;
|
|
|
|
// Nếu số lượng ảnh khác nhau → có thay đổi
|
|
if (currentHasImage !== originalHasImage) {
|
|
return true;
|
|
}
|
|
|
|
// Nếu cả 2 đều rỗng → không thay đổi
|
|
if (!currentHasImage) {
|
|
return false;
|
|
}
|
|
|
|
// Nếu có ảnh, check xem file có phải là file mới upload không
|
|
// (file gốc có uid = '-1', file mới upload có uid khác)
|
|
const currentFile = fileList[0];
|
|
const isOriginalImage =
|
|
currentFile.uid === '-1' && currentFile.status === 'done';
|
|
|
|
return !isOriginalImage;
|
|
};
|
|
|
|
return (
|
|
<ModalForm<SgwModel.Fish>
|
|
key={fish?.id || 'new'}
|
|
open={isOpen}
|
|
formRef={formRef}
|
|
title={
|
|
type === 'create'
|
|
? intl.formatMessage({
|
|
id: 'fish.create.title',
|
|
defaultMessage: 'Thêm cá mới',
|
|
})
|
|
: intl.formatMessage({
|
|
id: 'fish.update.title',
|
|
defaultMessage: 'Cập nhật cá',
|
|
})
|
|
}
|
|
onOpenChange={setIsOpen}
|
|
layout="vertical"
|
|
modalProps={{
|
|
destroyOnHidden: true,
|
|
}}
|
|
request={async () => {
|
|
if (type === 'update' && fish) {
|
|
return fish;
|
|
}
|
|
setFileList([]);
|
|
setOriginalFileList([]);
|
|
return {};
|
|
}}
|
|
onFinish={async (values) => {
|
|
// 1. Cập nhật thông tin cá
|
|
if (type === 'create') {
|
|
// TODO: Gọi API tạo cá mới
|
|
// const result = await apiCreateFish(values);
|
|
console.log('Create fish:', values);
|
|
try {
|
|
const resp = await apiCreateFishSpecies(values);
|
|
if (resp.status === HTTPSTATUS.HTTP_SUCCESS) {
|
|
message.success(
|
|
intl.formatMessage({
|
|
id: 'fish.create.success',
|
|
defaultMessage: 'Tạo cá thành công',
|
|
}),
|
|
);
|
|
onReload?.(true);
|
|
const id = resp.data.name_ids![0];
|
|
if (fileList.length > 0 && fileList[0].originFileObj && id) {
|
|
// TODO: Sau khi có result.id từ API create
|
|
// await apiUploadPhoto('fish', result.id, fileList[0].originFileObj);
|
|
console.log('Upload photo for new fish');
|
|
try {
|
|
const resp = await apiUploadPhoto(
|
|
'fish',
|
|
id.toString(),
|
|
fileList[0].originFileObj,
|
|
);
|
|
if (resp.status === HTTPSTATUS.HTTP_SUCCESS) {
|
|
message.success(
|
|
intl.formatMessage({
|
|
id: 'fish.create.image.success',
|
|
defaultMessage: 'Thêm ảnh cá thành công',
|
|
}),
|
|
);
|
|
onReload?.(true);
|
|
} else {
|
|
throw new Error('Thêm ảnh thất bại');
|
|
}
|
|
} catch (error) {
|
|
message.error(
|
|
intl.formatMessage({
|
|
id: 'fish.create.image.fail',
|
|
defaultMessage: 'Thêm ảnh cá thất bại',
|
|
}),
|
|
);
|
|
}
|
|
}
|
|
} else {
|
|
throw new Error('Tạo cá thất bại');
|
|
}
|
|
} catch (error) {
|
|
message.error(
|
|
intl.formatMessage({
|
|
id: 'fish.create.fail',
|
|
defaultMessage: 'Tạo cá thất bại',
|
|
}),
|
|
);
|
|
}
|
|
// 2. Upload ảnh (nếu có chọn ảnh)
|
|
onReload?.(true);
|
|
} else {
|
|
// TODO: Gọi API cập nhật cá
|
|
// await apiUpdateFish(fish!.id!, values);
|
|
console.log('Update fish:', fish?.id, values);
|
|
|
|
// Check nếu dữ liệu có thay đổi so với ban đầu
|
|
const hasDataChanged =
|
|
fish!.name !== values.name ||
|
|
fish!.scientific_name !== values.scientific_name ||
|
|
fish!.group_name !== values.group_name ||
|
|
fish!.rarity_level !== values.rarity_level ||
|
|
fish!.note !== values.note;
|
|
|
|
if (hasDataChanged) {
|
|
try {
|
|
const body = { ...values, id: fish!.id! };
|
|
const resp = await apiUpdateFishSpecies(body);
|
|
if (resp.status === HTTPSTATUS.HTTP_SUCCESS) {
|
|
message.success(
|
|
intl.formatMessage({
|
|
id: 'fish.update.success',
|
|
defaultMessage: 'Cập nhật cá thành công',
|
|
}),
|
|
);
|
|
onReload?.(true);
|
|
} else {
|
|
throw new Error('Cập nhật cá thất bại');
|
|
}
|
|
} catch (error) {
|
|
message.error(
|
|
intl.formatMessage({
|
|
id: 'fish.update.fail',
|
|
defaultMessage: 'Cập nhật cá thất bại',
|
|
}),
|
|
);
|
|
return true;
|
|
}
|
|
} else {
|
|
console.log('Dữ liệu không thay đổi, bỏ qua API update');
|
|
}
|
|
// 2. Upload ảnh (chỉ khi ảnh có thay đổi)
|
|
if (hasImageChanged()) {
|
|
if (fileList.length > 0 && fileList[0].originFileObj) {
|
|
// TODO: Upload ảnh mới
|
|
// await apiUploadPhoto('fish', fish!.id!, fileList[0].originFileObj);
|
|
try {
|
|
const resp = await apiUploadPhoto(
|
|
'fish',
|
|
fish!.id!.toString(),
|
|
fileList[0].originFileObj,
|
|
);
|
|
if (resp.status === HTTPSTATUS.HTTP_SUCCESS) {
|
|
message.success(
|
|
intl.formatMessage({
|
|
id: 'fish.update.image.success',
|
|
defaultMessage: 'Cập nhật ảnh cá thành công',
|
|
}),
|
|
);
|
|
onReload?.(true);
|
|
} else {
|
|
throw new Error('Cập nhật ảnh thất bại');
|
|
}
|
|
} catch (error) {
|
|
message.error(
|
|
intl.formatMessage({
|
|
id: 'fish.update.image.fail',
|
|
defaultMessage: 'Cập nhật ảnh cá thất bại',
|
|
}),
|
|
);
|
|
return true;
|
|
}
|
|
} else {
|
|
// TODO: Xóa ảnh (nếu có API delete)
|
|
console.log('Remove photo');
|
|
const resp = await apiDeletePhoto('fish', fish!.id!);
|
|
if (resp.status === HTTPSTATUS.HTTP_SUCCESS) {
|
|
message.success(
|
|
intl.formatMessage({
|
|
id: 'fish.delete.image.success',
|
|
defaultMessage: 'Xóa ảnh cá thành công',
|
|
}),
|
|
);
|
|
onReload?.(true);
|
|
} else {
|
|
message.error(
|
|
intl.formatMessage({
|
|
id: 'fish.delete.image.fail',
|
|
defaultMessage: 'Xóa ảnh cá thất bại',
|
|
}),
|
|
);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}}
|
|
>
|
|
{type === 'create' && (
|
|
<div
|
|
style={{
|
|
display: 'flex',
|
|
justifyContent: 'center',
|
|
marginBottom: 16,
|
|
}}
|
|
>
|
|
<ProFormUploadButton
|
|
name="upload"
|
|
label={null}
|
|
title="Chọn ảnh"
|
|
accept="image/*"
|
|
max={1}
|
|
transform={(value) => ({ upload: value })}
|
|
fieldProps={{
|
|
onChange(info) {
|
|
setFileList(info.fileList);
|
|
},
|
|
listType: 'picture-card',
|
|
fileList: fileList,
|
|
onRemove: () => {
|
|
setFileList([]);
|
|
},
|
|
}}
|
|
/>
|
|
</div>
|
|
)}
|
|
<ProForm.Group>
|
|
<ProFormText
|
|
name="name"
|
|
width="md"
|
|
label={intl.formatMessage({
|
|
id: 'common.name',
|
|
defaultMessage: 'Tên',
|
|
})}
|
|
tooltip={intl.formatMessage({
|
|
id: 'fish.name.tooltip',
|
|
defaultMessage: 'Tên loài cá',
|
|
})}
|
|
placeholder={intl.formatMessage({
|
|
id: 'fish.name.placeholder',
|
|
defaultMessage: 'Nhập tên cá',
|
|
})}
|
|
rules={[
|
|
{
|
|
required: true,
|
|
message: intl.formatMessage({
|
|
id: 'fish.name.required',
|
|
defaultMessage: 'Tên cá không được để trống',
|
|
}),
|
|
},
|
|
]}
|
|
/>
|
|
<ProFormText
|
|
name="scientific_name"
|
|
width="md"
|
|
label={intl.formatMessage({
|
|
id: 'fish.specific_name',
|
|
defaultMessage: 'Tên khoa học',
|
|
})}
|
|
placeholder={intl.formatMessage({
|
|
id: 'fish.specific_name.placeholder',
|
|
defaultMessage: 'Nhập tên khoa học',
|
|
})}
|
|
/>
|
|
</ProForm.Group>
|
|
<ProForm.Group>
|
|
<ProFormText
|
|
name="group_name"
|
|
label={intl.formatMessage({
|
|
id: 'fish.fish_group',
|
|
defaultMessage: 'Nhóm',
|
|
})}
|
|
width="md"
|
|
tooltip={intl.formatMessage({
|
|
id: 'fish.fish_group.tooltip',
|
|
defaultMessage: 'Nhóm cá',
|
|
})}
|
|
placeholder={intl.formatMessage({
|
|
id: 'fish.fish_group.placeholder',
|
|
defaultMessage: 'Nhập nhóm cá',
|
|
})}
|
|
/>
|
|
|
|
<ProFormSelect
|
|
name="rarity_level"
|
|
label={intl.formatMessage({
|
|
id: 'fish.rarity',
|
|
defaultMessage: 'Độ hiếm',
|
|
})}
|
|
width="md"
|
|
placeholder={intl.formatMessage({
|
|
id: 'fish.rarity.placeholder',
|
|
defaultMessage: 'Chọn độ hiếm',
|
|
})}
|
|
options={[
|
|
{
|
|
label: intl.formatMessage({
|
|
id: 'fish.rarity.normal',
|
|
defaultMessage: 'Phổ biến',
|
|
}),
|
|
value: 1,
|
|
},
|
|
{
|
|
label: intl.formatMessage({
|
|
id: 'fish.rarity.sensitive',
|
|
defaultMessage: 'Dễ bị tổn thương',
|
|
}),
|
|
value: 2,
|
|
},
|
|
{
|
|
label: intl.formatMessage({
|
|
id: 'fish.rarity.near_threatened',
|
|
defaultMessage: 'Gần bị đe dọa',
|
|
}),
|
|
value: 3,
|
|
},
|
|
{
|
|
label: intl.formatMessage({
|
|
id: 'fish.rarity.endangered',
|
|
defaultMessage: 'Nguy cấp',
|
|
}),
|
|
value: 4,
|
|
},
|
|
]}
|
|
/>
|
|
</ProForm.Group>
|
|
<ProFormTextArea
|
|
name="note"
|
|
label={intl.formatMessage({
|
|
id: 'common.description',
|
|
defaultMessage: 'Ghi chú',
|
|
})}
|
|
placeholder={intl.formatMessage({
|
|
id: 'common.description.placeholder',
|
|
defaultMessage: 'Nhập ghi chú',
|
|
})}
|
|
/>
|
|
</ModalForm>
|
|
);
|
|
};
|
|
|
|
export default AddOrUpdateFish;
|