123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 |
- import React, { useEffect, useState } from 'react';
- import { Space, Table, Button, Input, Select, Tabs, message } from 'antd';
- import type { TableProps } from 'antd';
- import styles from './index.module.css';
- import { WeComPlan, WeComPlanListResponse, WeComPlanType, WeVideoItem } from './type';
- import request from '@src/http/index';
- import { getQwPlanListApi, getShareQrPic, saveQwPlanApi } from "@src/http/api"
- import VideoSelectModal from './components/videoSelectModal';
- import LinkDetailModal from './components/linkDetailModal';
- import PlanDetailModal from './components/planDetailModal';
- import http from '@src/http/index';
- import copy from 'copy-to-clipboard';
- import VideoPlayModal from './components/videoPlayModal';
- import modal from 'antd/es/modal';
- // Define a type for the expected API response (adjust if needed based on actual API)
- const TableHeight = window.innerHeight - 380;
- const WeGZHContent: React.FC = () => {
- // 状态管理
- const [videoTitle, setVideoTitle] = useState<string>('');
- const [selectedPublisher, setSelectedPublisher] = useState<number>();
- const [isShowAddPunlishPlan, setIsShowAddPunlishPlan] = useState<boolean>(false);
- const [editPlanData, setEditPlanData] = useState<WeComPlan>();
- const [activeKey, setActiveKey] = useState<WeComPlanType>(WeComPlanType.每日推送);
- const [tableData, setTableData] = useState<WeComPlan[]>([]);
- const [totalSize, setTotalSize] = useState<number>(0);
- const [pageNum, setPageNum] = useState<number>(1);
- // State for the new modal
- const [isLinkDetailModalVisible, setIsLinkDetailModalVisible] = useState<boolean>(false);
- const [createdVideoLinks, setCreatedVideoLinks] = useState<WeComPlan[]>([]);
-
- // State for the Plan Detail modal
- const [isPlanDetailModalVisible, setIsPlanDetailModalVisible] = useState<boolean>(false);
- const [isVideoPlayModalVisible, setIsVideoPlayModalVisible] = useState<boolean>(false);
- const getTableData = (_pageNum?: number) => {
- setPageNum(_pageNum || 1);
- request.post<WeComPlanListResponse>(getQwPlanListApi, {
- pageNum: _pageNum || pageNum,
- pageSize: 10,
- scene: selectedPublisher,
- title: videoTitle,
- type: +activeKey,
- }
- ).then(res => {
- setTableData(res.data.objs || []);
- setTotalSize(res.data.totalSize);
- }).catch(err => {
- message.error(err.msg || '获取数据失败');
- });
- }
- useEffect(() => {
- getTableData(1);
- }, [activeKey]);
- // 表格列配置
- const columns: TableProps<WeComPlan>['columns'] = [
- {
- title: '创建时间',
- dataIndex: 'createTimestamp',
- key: 'createTimestamp',
- width: 200,
- render: (_, record) => {
- return record.createTimestamp ? new Date(record.createTimestamp).toLocaleString() : '';
- }
- },
- {
- title: '视频标题',
- dataIndex: 'title',
- key: 'title',
- ellipsis: true,
- },
- {
- title: '场景',
- dataIndex: 'scene',
- key: 'scene',
- width: 100,
- render: (_, record) => {
- if (activeKey === WeComPlanType.每日推送) {
- return record.scene === 0 ? '群发' : '单发';
- } else {
- return '自动回复';
- }
- }
- },
- {
- title: '操作',
- key: 'action',
- width: 500,
- render: (_, record) => (
- <Space size="middle" wrap>
- <Button type="link" onClick={() => playVideo(record)}>播放</Button>
- <Button type="link" onClick={() => downloadFile(record.cover, record.title + '_cover')}>下载封面</Button>
- <Button type="link" onClick={() => showQrCodeModal(record.pageUrl)}>二维码</Button>
- <Button type="link" onClick={() => copyToClipboard(record.pageUrl)}>复制链接</Button>
- <Button type="link" onClick={() => showDetailModal(record)}>详情</Button>
- </Space>
- ),
- },
- ];
- const playVideo = (record: WeComPlan) => {
- setEditPlanData(record);
- setIsVideoPlayModalVisible(true);
- }
- const showDetailModal = (record: WeComPlan) => {
- setEditPlanData(record);
- setIsPlanDetailModalVisible(true);
- }
- const copyToClipboard = (text: string) => {
- 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) => {
- http.get<string>(getShareQrPic, {
- params: {
- pageUrl,
- }
- }).then(res => {
- modal.info({
- title: '二维码',
- content: <img src={res.data} alt="二维码" />,
- });
- }).catch(err => {
- message.error(err.msg || '获取二维码失败');
- });
-
- };
- const addPunlishPlan = () => {
- setIsShowAddPunlishPlan(true);
- }
- const handleOk = (selectedVideos: WeVideoItem[]) => {
- http.post<WeComPlan[]>(saveQwPlanApi, {
- type: +activeKey,
- videoList: selectedVideos,
- }).then(res => {
- if (res.code === 0) {
- message.success('创建成功');
- setCreatedVideoLinks(res.data);
- setIsLinkDetailModalVisible(true);
- setIsShowAddPunlishPlan(false);
- getTableData();
- } else {
- message.error(res.msg || '创建失败');
- }
- }).catch(err => {
- message.error(err.msg || '创建失败');
- });
- }
- return (
- <div>
- <div className="rounded-lg">
- <div className="text-lg font-medium mb-3">企业微信内容库</div>
-
- {/* 搜索区域 */}
- <div className="flex flex-wrap gap-4 mb-3">
- <div className="flex items-center gap-2">
- <span className="text-gray-600">视频标题:</span>
- <Input
- placeholder="搜索视频标题"
- style={{ width: 200 }}
- value={videoTitle}
- allowClear
- onPressEnter={() => getTableData(1)}
- onChange={e => setVideoTitle(e.target.value)}
- />
- </div>
- <div className="flex items-center gap-2">
- <span className="text-gray-600">场景:</span>
- <Select
- placeholder="筛选场景"
- style={{ width: 200 }}
- value={selectedPublisher}
- onChange={setSelectedPublisher}
- allowClear
- options={activeKey === WeComPlanType.每日推送 ? [
- { label: '群发', value: 0 },
- { label: '单发', value: 1 },
- ] : [
- { label: '关注回复', value: 0 },
- ]}
- />
- </div>
- <Button type="primary" className="ml-2" onClick={() => getTableData(1)}>搜索</Button>
- </div>
- <Tabs
- defaultActiveKey="1"
- type="card"
- size="large"
- items={[
- { label: '每日推送', key: WeComPlanType.每日推送 },
- { label: '自动回复', key: WeComPlanType.自动回复 },
- ]}
- activeKey={activeKey}
- onChange={(key: string) => setActiveKey(key as WeComPlanType)}
- tabBarExtraContent={
- { right: <Button type="primary" onClick={addPunlishPlan}>+ 创建发布</Button> }}
- />
- {/* 表格区域 */}
- <Table
- rowKey={(record) => record.id}
- className={styles.antTable}
- columns={columns}
- dataSource={tableData}
- scroll={{ x: 'max-content', y: TableHeight }}
- pagination={{
- current: pageNum,
- total: totalSize,
- pageSize: 10,
- showTotal: (total) => `共 ${total} 条`,
- onChange: (page) => getTableData(page),
- }}
- />
- <VideoSelectModal
- visible={isShowAddPunlishPlan}
- onClose={() => {
- setIsShowAddPunlishPlan(false);
- setEditPlanData(undefined);
- }}
- onOk={handleOk}
- initialSelectedIds={editPlanData ? [editPlanData.id] : []}
- planType={activeKey}
- />
- <LinkDetailModal
- visible={isLinkDetailModalVisible}
- onClose={() => setIsLinkDetailModalVisible(false)}
- videos={createdVideoLinks}
- />
- <PlanDetailModal
- visible={isPlanDetailModalVisible}
- onClose={() => {
- setIsPlanDetailModalVisible(false);
- setEditPlanData(undefined);
- }}
- planData={editPlanData}
- />
- <VideoPlayModal
- visible={isVideoPlayModalVisible}
- onClose={() => setIsVideoPlayModalVisible(false)}
- videoUrl={editPlanData?.video || ''}
- title={editPlanData?.title || ''}
- />
- </div>
- </div>
- );
- };
- export default WeGZHContent;
|