|
@@ -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>
|
|
|
);
|
|
);
|