Files
SMATEC-FRONTEND/src/pages/Slave/SGW/Manager/Fish/component/AddOrUpdateFish.tsx

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;