Sfoglia il codice sorgente

gzh详情页修改

jihuaqiang 2 settimane fa
parent
commit
7288d13b9a

+ 1 - 0
src/views/publishContent/weCom/components/linkDetailModal/index.tsx

@@ -7,6 +7,7 @@ import { getShareQrPic } from '@src/http/api';
 import http from '@src/http';
 import modal from 'antd/es/modal';
 import VideoPlayModal from '../videoPlayModal';
+
 // import QRCode from 'qrcode.react'; // Consider adding this dependency if not present
 
 const { Text } = Typography;

+ 125 - 19
src/views/publishContent/weGZH/components/PunlishPlanDetailModal/index.tsx

@@ -1,7 +1,15 @@
-import React from 'react';
-import { Modal, Descriptions } from 'antd';
-import { GzhPlanDataType } from '../../hooks/useGzhPlanList';
-import dayjs from 'dayjs';
+import React, { useState } from 'react';
+import { Modal, Descriptions, Space, Button, Tooltip, message, Table } from 'antd';
+import { GzhPlanDataType, GzhPlanType } from '../../hooks/useGzhPlanList';
+import { CopyOutlined, PlayCircleOutlined, DownloadOutlined, LinkOutlined, QrcodeOutlined } from '@ant-design/icons';
+import { VideoItem } from '../types';
+import VideoPlayModal from '@src/views/publishContent/weCom/components/videoPlayModal';
+import modal from 'antd/es/modal';
+import http from '@src/http';
+import { getShareQrPic } from '@src/http/api';
+import copy from 'copy-to-clipboard';
+import { Typography } from 'antd';
+const { Text } = Typography;
 interface PunlishPlanDetailModalProps {
   visible: boolean;
   onCancel: () => void;
@@ -13,6 +21,95 @@ const PunlishPlanDetailModal: React.FC<PunlishPlanDetailModalProps> = ({
   onCancel,
   planData,
 }) => {
+	const [isVideoPlayModalVisible, setIsVideoPlayModalVisible] = useState(false);
+	const [activeVideo, setActiveVideo] = useState<VideoItem | null>(null);
+
+	const columns = [
+    {
+      title: '视频标题',
+      dataIndex: 'title',
+      key: 'title',
+      render: (title: string) => (
+        <Space>
+          <Text style={{ maxWidth: 200 }} ellipsis={{ tooltip: title }}>{title}</Text>
+          <Tooltip title="复制标题">
+            <Button
+              type="text"
+              icon={<CopyOutlined />}
+              onClick={() => {
+                if (copy(title)) {
+                  message.success('标题已复制');
+                } else {
+                  message.error('复制失败');
+                }
+              }}
+              size="small"
+            />
+          </Tooltip>
+        </Space>
+      ),
+    },
+    {
+      title: '操作',
+      key: 'action',
+      render: (_: any, record: VideoItem) => (
+        <Space wrap size="small">
+          <Button type="link" icon={<PlayCircleOutlined />} onClick={() => playVideo(record)} size="small">播放</Button>
+          <Button type="link" icon={<DownloadOutlined />} onClick={() => downloadCover(record)} size="small">下载封面</Button>
+          <Button type="link" icon={<LinkOutlined />} onClick={() => copyPushLink(record)} size="small">复制推送链接</Button>
+          <Button type="link" icon={<QrcodeOutlined />} onClick={() => showQRCode(record)} size="small">二维码</Button>
+        </Space>
+      ),
+    },
+	];
+	const playVideo = (video: VideoItem) => {
+		setActiveVideo(video);
+		setIsVideoPlayModalVisible(true);
+	};
+
+	const downloadCover = (video: VideoItem) => {
+		if (video.cover) {
+			const link = document.createElement('a');
+			link.href = video.cover;
+			// Attempt to infer filename, might need refinement
+			const filename = video.cover.substring(video.cover.lastIndexOf('/') + 1) || `cover_${video.id}.jpg`;
+			link.download = filename;
+			link.target = '_blank'; // Open in new tab might be safer for some browsers
+			link.rel = 'noopener noreferrer';
+			document.body.appendChild(link);
+			link.click();
+			document.body.removeChild(link);
+		} else {
+			message.warning('No cover image URL available.');
+		}
+	};
+	
+	const copyPushLink = (video: VideoItem) => {
+		// Assuming video object might have a 'pushLink' property added by the parent component
+		const linkToCopy = video.pageUrl || 'Push link not available'; // Updated placeholder
+		if (video.pageUrl && copy(linkToCopy)) {
+			message.success('推送链接已复制');
+		} else if (!video.pageUrl) {
+			message.warning('没有可复制的推送链接');
+		} else {
+			message.error('复制失败');
+		}
+	};
+	
+	const showQRCode = (video: VideoItem) => {
+		http.get<string>(getShareQrPic, {
+			params: {
+				pageUrl: video.pageUrl,
+			}
+		}).then(res => {
+			modal.info({
+				title: '二维码',
+				content: <img src={res.data} alt="二维码" />,
+			});
+		}).catch(err => {
+			message.error(err.msg || '获取二维码失败');
+		});
+	};
 
   return (
     planData && visible && <Modal
@@ -23,23 +120,32 @@ const PunlishPlanDetailModal: React.FC<PunlishPlanDetailModalProps> = ({
       footer={null}
       width={800}
     >
-      <Descriptions column={1} bordered>
+			<Descriptions column={1} className='mb-4'>
+				<Descriptions.Item label="发布计划类型">{planData.type === GzhPlanType.自动回复 ? '自动回复' : '关键词回复'}</Descriptions.Item>
 				<Descriptions.Item label="场景">{planData?.scene === 0 ? '关注回复' : '自动回复'}</Descriptions.Item>
+				<Descriptions.Item label="发布方式">{planData?.publishStage === 0 ? '平台发布' : '用户获取路径'}</Descriptions.Item>
+				<Descriptions.Item label="视频选取方式">{planData?.selectVideoType === 0 ? '手动选取' : '自动选取'}</Descriptions.Item>
         <Descriptions.Item label="公众号名称">{planData.accountName}</Descriptions.Item>
-        <Descriptions.Item label="视频列表">
-          {planData.videoList?.map((video, index) => (
-            <div key={video.videoId} style={{ marginBottom: '16px' }}>
-              <p>视频 {index + 1}: {video.customTitle || video.title}</p>
-              <img 
-                src={video.customCover || video.cover} 
-                alt={`视频${index + 1}封面`} 
-                style={{ maxWidth: '150px' }} 
-              />
-            </div>
-          ))}
-        </Descriptions.Item>
-        <Descriptions.Item label="发布时间">{dayjs(planData.createTimestamp).format('YYYY-MM-DD HH:mm:ss')}</Descriptions.Item>
-        <Descriptions.Item label="发布方">{planData.publishStage === 0 ? '平台发布' : '用户发布'}</Descriptions.Item>
+				{ 
+					planData.videoList?.length > 0 ?
+						<Descriptions.Item label="发布内容" >
+							<Table
+								columns={columns}
+								dataSource={planData.videoList?.map(v => ({ ...v, key: v.videoId }))} // Ensure each item has a unique key
+								pagination={false} // Disable pagination if the list is expected to be short
+								size="small"
+							/>
+							<VideoPlayModal
+								visible={isVideoPlayModalVisible}
+								onClose={() => setIsVideoPlayModalVisible(false)}
+								videoUrl={activeVideo?.video || ''}
+								title={activeVideo?.title || ''}
+							/>
+						</Descriptions.Item>
+						: <Descriptions.Item label="发布内容">
+							<Text className='text-gray-500'>视频由系统自动选取</Text>
+						</Descriptions.Item>
+				}
 			</Descriptions>
     </Modal>
   );

+ 68 - 53
src/views/publishContent/weGZH/components/publishPlanModal/index.tsx

@@ -44,7 +44,15 @@ const AddPunlishPlanModal: React.FC<AddPunlishPlanModalProps> = ({
 			setSelectedVideos(editPlanData?.videoList || []);
 		} else {
 			setSelectedVideos([]);
-			form.setFieldsValue({ type: planType, publishStage: 1, selectVideoType: 0 });
+			form.setFieldsValue({
+				id: undefined,
+				type: planType,
+				publishStage: 1,
+				selectVideoType: 0,
+				accountId: undefined,
+				scene: 0,
+				videoList: []
+			});
 		}
 	}, [actionType, editPlanData, visible]);
 
@@ -233,59 +241,66 @@ const AddPunlishPlanModal: React.FC<AddPunlishPlanModalProps> = ({
 							<Option value={1} disabled>自动选取</Option>
 						</Select>
 					</Form.Item>
-					<Form.Item label="发布内容" hidden={selectVideoType !== 0} 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.customTitle || video.title}>{video.customTitle || 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.customCover || 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">
-										<Button
-											icon={<EditOutlined />}
-											className="w-full mt-2"
-											onClick={() => openEditModal(video)} // Open edit modal
+					<Form.Item label="发布内容" required>
+						{ 
+							selectVideoType === 0 ?
+								(<div className="flex flex-wrap gap-4">
+									{selectedVideos.map((video) => (
+										<Card
+											key={video.videoId}
+											className="w-[240px] relative group"
 										>
-											编辑标题/封面
-										</Button>
-									</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>
+											<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.customTitle || video.title}>{video.customTitle || 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.customCover || 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">
+												<Button
+													icon={<EditOutlined />}
+													className="w-full mt-2"
+													onClick={() => openEditModal(video)} // Open edit modal
+												>
+													编辑标题/封面
+												</Button>
+											</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>)
+								: (<div>
+								<Paragraph>视频由系统自动选取,不可手动选择</Paragraph>
+							</div>)
+						}
+						
 					</Form.Item>
 				</Form>
 			</Modal>

+ 1 - 0
src/views/publishContent/weGZH/components/types.ts

@@ -5,6 +5,7 @@ export interface VideoItem {
 	score: number,
 	title: string,
 	customTitle: string,
+	pageUrl: string,
 	video: string,
 	videoId: number,
 }