Prechádzať zdrojové kódy

小程序投流列表操作列补齐:对齐企微入口,新增「播放/下载封面/二维码/复制链接」4 个按钮,复用 weCom 的 VideoPlayModal 和 getShareQrLink + QRCodeSVG 客户端 QR 生成。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
刘立冬 3 dní pred
rodič
commit
e033193754
1 zmenil súbory, kde vykonal 59 pridanie a 3 odobranie
  1. 59 3
      src/views/publishContent/xcxTouliu/index.tsx

+ 59 - 3
src/views/publishContent/xcxTouliu/index.tsx

@@ -2,13 +2,17 @@ import React, { useEffect, useState } from 'react';
 import { Space, Table, Button, Input, Select, DatePicker, message, Typography, Spin, Popconfirm } from 'antd';
 import { Space, Table, Button, Input, Select, DatePicker, message, Typography, Spin, Popconfirm } from 'antd';
 import type { TableProps } from 'antd';
 import type { TableProps } from 'antd';
 import dayjs, { Dayjs } from 'dayjs';
 import dayjs, { Dayjs } from 'dayjs';
+import copy from 'copy-to-clipboard';
+import { QRCodeSVG } from 'qrcode.react';
+import modal from 'antd/es/modal';
 import styles from './index.module.css';
 import styles from './index.module.css';
 import XcxPublishPlanModal from './components/publishPlanModal';
 import XcxPublishPlanModal from './components/publishPlanModal';
+import VideoPlayModal from '@src/views/publishContent/weCom/components/videoPlayModal';
 import { useXcxPlanList, XcxPlanDataType } from './hooks/useXcxPlanList';
 import { useXcxPlanList, XcxPlanDataType } from './hooks/useXcxPlanList';
 import { useAudiencePackageOptions } from './hooks/useAudiencePackageOptions';
 import { useAudiencePackageOptions } from './hooks/useAudiencePackageOptions';
 import { VideoItem } from '@src/views/publishContent/weGZH/components/types';
 import { VideoItem } from '@src/views/publishContent/weGZH/components/types';
 import http from '@src/http';
 import http from '@src/http';
-import { deleteXcxPlanApi, saveXcxPlanApi } from '@src/http/api';
+import { deleteXcxPlanApi, getShareQrLink, saveXcxPlanApi } from '@src/http/api';
 
 
 const { RangePicker } = DatePicker;
 const { RangePicker } = DatePicker;
 const TableHeight = window.innerHeight - 380;
 const TableHeight = window.innerHeight - 380;
@@ -22,6 +26,7 @@ const XcxTouliuContent: React.FC = () => {
 	const [isLoading, setIsLoading] = useState<boolean>(false);
 	const [isLoading, setIsLoading] = useState<boolean>(false);
 	const [pageNum, setPageNum] = useState<number>(1);
 	const [pageNum, setPageNum] = useState<number>(1);
 	const [pageSize, setPageSize] = useState<number>(10);
 	const [pageSize, setPageSize] = useState<number>(10);
+	const [playingPlan, setPlayingPlan] = useState<XcxPlanDataType | null>(null);
 	const { xcxPlanList, getXcxPlanList, totalSize } = useXcxPlanList();
 	const { xcxPlanList, getXcxPlanList, totalSize } = useXcxPlanList();
 	const { options: audiencePackageOptions } = useAudiencePackageOptions();
 	const { options: audiencePackageOptions } = useAudiencePackageOptions();
 
 
@@ -75,9 +80,13 @@ const XcxTouliuContent: React.FC = () => {
 			title: '操作',
 			title: '操作',
 			key: 'action',
 			key: 'action',
 			fixed: 'right',
 			fixed: 'right',
-			width: 80,
+			width: 460,
 			render: (_, record) => (
 			render: (_, record) => (
-				<Space size="middle">
+				<Space size="middle" wrap>
+					<Button type="link" onClick={() => setPlayingPlan(record)}>播放</Button>
+					<Button type="link" onClick={() => downloadFile(record.shareCover || record.cover, (record.title || 'cover') + '_cover')}>下载封面</Button>
+					<Button type="link" onClick={() => showQrCodeModal(record.pageUrl)}>二维码</Button>
+					<Button type="link" onClick={() => copyToClipboard(record.pageUrl)}>复制链接</Button>
 					<Popconfirm
 					<Popconfirm
 						title="确定删除该计划吗?"
 						title="确定删除该计划吗?"
 						okText="确定"
 						okText="确定"
@@ -91,6 +100,46 @@ const XcxTouliuContent: React.FC = () => {
 		},
 		},
 	];
 	];
 
 
+	const copyToClipboard = (text: string) => {
+		if (!text) {
+			message.warning('暂无链接');
+			return;
+		}
+		copy(text);
+		message.success('复制成功');
+	};
+
+	const downloadFile = (url: string, filename: string) => {
+		if (!url) {
+			message.warning('无可用文件下载');
+			return;
+		}
+		const link = document.createElement('a');
+		link.href = url;
+		link.download = filename || url.substring(url.lastIndexOf('/') + 1);
+		link.target = '_blank';
+		link.rel = 'noopener noreferrer';
+		document.body.appendChild(link);
+		link.click();
+		document.body.removeChild(link);
+		message.success('开始下载...');
+	};
+
+	const showQrCodeModal = (pageUrl: string) => {
+		if (!pageUrl) {
+			message.warning('暂无链接');
+			return;
+		}
+		http.get<string>(getShareQrLink, { params: { pageUrl } }).then(res => {
+			modal.info({
+				title: '二维码',
+				content: <QRCodeSVG value={res.data} size={256} />,
+			});
+		}).catch(err => {
+			message.error(err?.msg || '获取二维码失败');
+		});
+	};
+
 	const deletePlan = async (record: XcxPlanDataType) => {
 	const deletePlan = async (record: XcxPlanDataType) => {
 		setIsLoading(true);
 		setIsLoading(true);
 		const res = await http
 		const res = await http
@@ -245,6 +294,13 @@ const XcxTouliuContent: React.FC = () => {
 					onOk={handleAddPunlishPlan}
 					onOk={handleAddPunlishPlan}
 					isSubmiting={isSubmiting}
 					isSubmiting={isSubmiting}
 				/>
 				/>
+
+				<VideoPlayModal
+					visible={!!playingPlan}
+					onClose={() => setPlayingPlan(null)}
+					videoUrl={playingPlan?.video || ''}
+					title={playingPlan?.title || ''}
+				/>
 			</div>
 			</div>
 		</Spin>
 		</Spin>
 	);
 	);