| 
					
				 | 
			
			
				@@ -0,0 +1,192 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 添加计划弹窗 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import React, { useEffect, useState } from 'react'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import { Modal, Form, Input, Select, Button, Card, Typography, message } from 'antd'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import { WeComPlanType, WeVideoItem, AddWeComPlanParam } from '../../type'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import { CloseOutlined, PlusOutlined, CaretRightFilled } from '@ant-design/icons'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import VideoSelectModal from '../videoSelectModal'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import VideoPlayModal from '../videoPlayModal'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const { Paragraph } = Typography; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const AddPlanModal: React.FC<{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	initType: string; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	visible: boolean; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	onClose: () => void; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	onOk: (param: AddWeComPlanParam) => void; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	isLoading: boolean; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}> = ({ initType, visible, onClose, onOk, isLoading }) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const [form] = Form.useForm(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const type = Form.useWatch(['type'], form); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const [selectedVideos, setSelectedVideos] = useState<WeVideoItem[]>([]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const [isVideoSelectVisible, setIsVideoSelectVisible] = useState(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const [playingVideo, setPlayingVideo] = useState<WeVideoItem | null>(null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	useEffect(() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		form.setFieldsValue({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			type: initType, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			subChannel: '', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		setSelectedVideos([]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	}, [visible]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const handleSelectVideo = (videos: WeVideoItem[]) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		setSelectedVideos(videos); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		setIsVideoSelectVisible(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const removeVideo = (videoId: number) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		setSelectedVideos(selectedVideos.filter((video) => video.videoId !== videoId)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const openVideoSelector = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		setIsVideoSelectVisible(true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const handleChangeSelectVideo = (videoId: number, scene: 0 | 1) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		setSelectedVideos(selectedVideos.map((video) => video.videoId === videoId ? { ...video, scene } : video)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const playVideo = (video: WeVideoItem) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		setPlayingVideo(video); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const handleOk = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		form.validateFields().then((values) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (selectedVideos.length === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				message.error('请选择发布内容'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			onOk({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				type: values.type, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				subChannel: values.subChannel, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				videoList: selectedVideos, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const handleChangeType = (value: string) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		form.setFieldsValue({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			type: value, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		setSelectedVideos(selectedVideos.map((video) => ({ ...video, scene: 0 }))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return <> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	<Modal 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		width={1000} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		open={visible} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		onCancel={onClose} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		title="创建企微发布内容" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		destroyOnClose 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			onOk={handleOk} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			okText="创建" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			cancelText="取消" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			confirmLoading={isLoading} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		<Form form={form} layout="vertical"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			<Form.Item label="发布类型" name="type"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				<Select onChange={ handleChangeType }> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					<Select.Option value="0">社群</Select.Option> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					<Select.Option value="1">自动回复</Select.Option> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				</Select> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			</Form.Item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			<Form.Item  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				label="子渠道"  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				name="subChannel" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				rules={[ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						pattern: /^[a-zA-Z0-9]*$/, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						message: '只能输入英文和数字', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						max: 20, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						message: '最长不超过20个字符', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				]} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				<Input  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					placeholder="请输入子渠道"  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					allowClear  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					maxLength={20} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					onKeyPress={(e) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						if (!/[a-zA-Z0-9]/.test(e.key)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							e.preventDefault(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					}} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				/> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			</Form.Item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			<Form.Item label="发布内容" required> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				<div className="flex flex-wrap gap-4"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						{selectedVideos.map((video) => ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							<Card 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+								key={video.videoId} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+								className="w-[240px] relative group" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+								<Button 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+									shape="circle" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+									icon={<CloseOutlined />} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+									className="!absolute top-1 right-1 z-10 bg-gray-400 bg-opacity-50 border-none text-white hidden group-hover:inline-flex justify-center items-center" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+									size="small" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+									onClick={() => removeVideo(video.videoId)} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+								/> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+								<div className="p-0"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+									<Paragraph className="mt-1 !mb-1" ellipsis={{ rows: 2, tooltip: true }} title={video.title}>{video.title}</Paragraph> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+								</div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+								<div 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+									className="relative" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+									style={{ paddingBottom: '79.8%' }} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+									onClick={(e) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+										e.stopPropagation(); // Prevent card selection if clicking thumbnail/play 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+										playVideo(video); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+									}} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+								> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+									<img src={video.cover} referrerPolicy="no-referrer" className="absolute inset-0 w-full h-full object-cover" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+									<div className="absolute inset-0 flex justify-center items-center cursor-pointer"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+										<CaretRightFilled className="!text-white text-4xl bg-black/20 rounded-full p-1 pl-2" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+									</div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+								</div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+								<div className="p-3 flex justify-between items-center relative z-10"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+									<Select 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+										placeholder="选择场景" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+										style={{ width: 180 }} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+										defaultValue={video.scene ?? 0} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+										value={video.scene} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+										onChange={(value: 0 | 1) => handleChangeSelectVideo(video.videoId, value)} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+										options={ type === WeComPlanType.社群 ? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+											[{ label: '群发', value: 0 }, { label: '单发', value: 1 }] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+											: [{ label: '关注回复', value: 0 }] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+										} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+										onClick={(e) => e.stopPropagation()} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+									/> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+								</div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							</Card> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						))} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						{/* Add Video Button - Conditionally Rendered */} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						{selectedVideos.length < 3 && ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							<div 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+								className="w-[240px] h-[316px] flex flex-col justify-center items-center  border border-dashed border-gray-300 rounded cursor-pointer dark:border-gray-600  hover:border-blue-500 hover:text-blue-500" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+								onClick={openVideoSelector} // Open the drawer on click 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+								<PlusOutlined className="text-2xl mb-2" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+								<Typography.Text>添加视频</Typography.Text> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							</div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						)} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					</div>	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			</Form.Item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		</Form> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	</Modal> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	<VideoSelectModal 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		visible={isVideoSelectVisible} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		onClose={() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			setIsVideoSelectVisible(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		}} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		onOk={handleSelectVideo} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		initialSelectedIds={selectedVideos.map((video) => video.videoId)} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		planType={type} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		/> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		<VideoPlayModal 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			visible={!!playingVideo} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			onClose={() => setPlayingVideo(null)} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			videoUrl={playingVideo?.video || ''} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			title={playingVideo?.title || ''} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		/> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	</> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+export default AddPlanModal; 
			 |