// src/pages/list/basic-list/components/AddTimeLineItemModal.tsx import chinaRegion, { code2Location } from '@/commonConstant/chinaRegion'; import { addStoryItem } from '@/pages/story/service'; import { getImagesList } from '@/services/file/api'; // 引入获取图库图片的API import { PlusOutlined, SearchOutlined } from '@ant-design/icons'; import { useRequest } from '@umijs/max'; import { Button, Card, Cascader, Checkbox, DatePicker, Form, Image, Input, InputRef, message, Modal, Pagination, Spin, Tabs, Upload, } from 'antd'; import dayjs from 'dayjs'; import moment from 'moment'; import React, { useEffect, useRef, useState } from 'react'; interface ModalProps { visible: boolean; onCancel: () => void; onOk: () => void; storyId: string | number | undefined; initialValues?: any; storyItemId?: string; // 是否根节点 option: 'add' | 'edit' | 'addSubItem' | 'editSubItem'; } const AddTimeLineItemModal: React.FC = ({ visible, onCancel, onOk, storyId, initialValues, storyItemId, option, }) => { const [form] = Form.useForm(); const [fileList, setFileList] = useState([]); const [imageList, setImageList] = useState(initialValues?.images || []); const [galleryImages, setGalleryImages] = useState([]); // 图库图片列表 const [selectedGalleryImages, setSelectedGalleryImages] = useState( initialValues?.galleryImageIds || [], ); // 选中的图库图片 const [galleryLoading, setGalleryLoading] = useState(false); const [activeTab, setActiveTab] = useState('upload'); // 图片选择标签页 const [currentPage, setCurrentPage] = useState(1); const [pageSize] = useState(20); const [total, setTotal] = useState(0); const [searchKeyword, setSearchKeyword] = useState(''); const searchInputRef = useRef(null); useEffect(() => { if (initialValues && option.startsWith('edit')) { form.setFieldsValue({ title: initialValues.title, date: initialValues.storyItemTime ? moment(initialValues.storyItemTime) : undefined, location: initialValues.location, description: initialValues.description, }); } }, [initialValues, option]); // 获取图库图片 const fetchGalleryImages = async (page: number = 1, keyword: string = '') => { if (visible) { setGalleryLoading(true); try { const response = await getImagesList({ current: page, pageSize: pageSize, keyword: keyword, }); const images = response.data.list.map((img: any) => ({ instanceId: img.instanceId, imageName: img.imageName, url: `/file/image-low-res/${img.instanceId}`, })); setGalleryImages(images); setTotal(response.data.total); setCurrentPage(page); } catch (error) { message.error('获取图库图片失败'); } finally { setGalleryLoading(false); } } }; useEffect(() => { if (visible && activeTab === 'gallery') { fetchGalleryImages(1, searchKeyword); } }, [visible, activeTab, searchKeyword]); const { run: submitItem, loading } = useRequest((newItem) => addStoryItem(newItem), { manual: true, onSuccess: (data) => { console.log(data); if (data.code === 200) { onOk(); message.success(initialValues ? '时间点已更新' : '时间点已保存'); } }, onError: (error) => { message.error('保存失败'); console.error('保存失败:', error); }, }); const handleOk = async () => { try { const values = await form.validateFields(); const location = code2Location(values.location); const newItem = { storyItemTime: dayjs(values.date).format('YYYY-MM-DDTHH:mm:ss'), title: values.title, description: values.description, masterItemId: initialValues?.masterItemId, subItems: initialValues?.subItems || [], storyInstanceId: storyId, location, instanceId: initialValues?.instanceId, // 添加选中的图库图片ID relatedImageInstanceIds: selectedGalleryImages, }; // 构建 FormData const formData = new FormData(); // 添加 storyItem 作为 JSON 字符串 formData.append('storyItem', JSON.stringify(newItem)); // 添加封面文件 if (fileList.length > 0 && fileList[0].originFileObj instanceof File) { formData.append('cover', fileList[0].originFileObj); } // 添加上传的图片文件 if (imageList.length > 0) { imageList.forEach((file) => { if (file.originFileObj && file.originFileObj instanceof File) { formData.append('images', file.originFileObj); } }); } console.log(formData); // 提交 submitItem(formData); } catch (error) { console.error('表单验证失败:', error); message.error('请检查表单内容'); } }; const uploadImagesProps = { beforeUpload: () => false, onChange: ({ fileList }) => { const updatedFileList = fileList.map((file) => { if (file.originFileObj && !(file.originFileObj instanceof File)) { file.originFileObj = new File([file.originFileObj], file.name, { type: file.type }); } return file; }); setImageList(updatedFileList); }, listType: 'picture-card', multiple: true, defaultFileList: initialValues?.images?.map((url) => ({ url })), }; // 切换图库图片选择状态 const toggleGalleryImageSelection = (instanceId: string) => { setSelectedGalleryImages((prev) => { if (prev.includes(instanceId)) { return prev.filter((id) => id !== instanceId); } else { return [...prev, instanceId]; } }); }; // 处理分页变化 const handlePageChange = (page: number) => { fetchGalleryImages(page, searchKeyword); }; // 处理搜索 const handleSearch = (value: string) => { setSearchKeyword(value); fetchGalleryImages(1, value); }; // 渲染图库图片选择器 const renderGallerySelector = () => (
{/* 搜索框 */}
} onPressEnter={(e) => handleSearch(e.currentTarget.value)} style={{ width: 200 }} allowClear />
{galleryLoading ? (
) : ( <>
{galleryImages.map((image) => ( toggleGalleryImageSelection(image.instanceId)} style={{ border: selectedGalleryImages.includes(image.instanceId) ? '2px solid #1890ff' : '1px solid #f0f0f0', position: 'relative', }} >
{image.imageName} e.stopPropagation()} />
{image.imageName}
))}
{galleryImages.length === 0 && !galleryLoading && (
{searchKeyword ? '未找到相关图片' : '图库中暂无图片'}
)} {/* 分页器 */} {total > 0 && (
)} )}
); return ( { form.resetFields(); setSelectedGalleryImages([]); setSearchKeyword(''); setCurrentPage(1); setGalleryImages([]); onCancel(); }} width={800} footer={[ , , ]} >
{['editSubItem', 'addSubItem'].includes(option) && ( {initialValues.title} )} {/* 时刻图库 */} { setActiveTab(key); if (key === 'gallery' && galleryImages.length === 0) { fetchGalleryImages(1, searchKeyword); } }} items={[ { key: 'upload', label: '上传图片', children: (
上传图片
), }, { key: 'gallery', label: `从图库选择${selectedGalleryImages.length > 0 ? ` (${selectedGalleryImages.length})` : ''}`, children: renderGallerySelector(), }, ]} />
); }; export default AddTimeLineItemModal;