Bladeren bron

内容发布联调

jihuaqiang 1 week geleden
bovenliggende
commit
5d6cfc4b1b

+ 9 - 6
src/http/api.ts

@@ -24,9 +24,12 @@ export const accountDelete = `${import.meta.env.VITE_API_URL}/contentPlatform/co
 
 
 
 
 /* 内容管理 */
 /* 内容管理 */
-export const gzhPlanList = `${import.meta.env.VITE_API_URL}/contentPlatform/plan/gzh/list`
-export const gzhPlanSave = `${import.meta.env.VITE_API_URL}/contentPlatform/plan/gzh/save`
-export const qwPlanList = `${import.meta.env.VITE_API_URL}/contentPlatform/plan/qw/list`
-export const qwPlanSave = `${import.meta.env.VITE_API_URL}/contentPlatform/plan/qw/save`
-export const videoContentCoverFrameList = `${import.meta.env.VITE_API_URL}/contentPlatform/plan/videoContentCoverFrameList`
-export const videoContentList = `${import.meta.env.VITE_API_URL}/contentPlatform/plan/videoContentList`
+export const getGzhAccountOptionsApi = `${import.meta.env.VITE_API_URL}/contentPlatform/cooperateAccount/gzh/accountList`
+export const getGzhContentTypeApi = `${import.meta.env.VITE_API_URL}/contentPlatform/cooperateAccount/gzh/getContentType`
+export const getGzhPlanListApi = `${import.meta.env.VITE_API_URL}/contentPlatform/plan/gzh/list`
+export const saveGzhPlanApi = `${import.meta.env.VITE_API_URL}/contentPlatform/plan/gzh/save`
+export const getQwPlanListApi = `${import.meta.env.VITE_API_URL}/contentPlatform/plan/qw/list`
+export const saveQwPlanApi = `${import.meta.env.VITE_API_URL}/contentPlatform/plan/qw/save`
+export const getVideoContentCategoryListApi = `${import.meta.env.VITE_API_URL}/contentPlatform/plan/videoContentCategoryList`
+export const getVideoContentCoverFrameListApi = `${import.meta.env.VITE_API_URL}/contentPlatform/plan/videoContentCoverFrameList`
+export const getVideoContentListApi = `${import.meta.env.VITE_API_URL}/contentPlatform/plan/videoContentList`

+ 2 - 3
src/main.tsx

@@ -1,11 +1,10 @@
-import React from 'react'
 import ReactDOM from 'react-dom/client'
 import ReactDOM from 'react-dom/client'
 import router from './router/index.tsx'
 import router from './router/index.tsx'
 import { RouterProvider } from "react-router-dom";
 import { RouterProvider } from "react-router-dom";
 import './index.css'
 import './index.css'
 
 
 ReactDOM.createRoot(document.getElementById('root')!).render(
 ReactDOM.createRoot(document.getElementById('root')!).render(
-  <React.StrictMode>
+  // <React.StrictMode>
     <RouterProvider router={router} />
     <RouterProvider router={router} />
-  </React.StrictMode>,
+  // </React.StrictMode>,
 )
 )

+ 1 - 2
src/router/index.tsx

@@ -24,8 +24,7 @@ const loadRouteModules = async () => {
   })
   })
   const routeModules: AdminRouterItem[] = []
   const routeModules: AdminRouterItem[] = []
 
 
-  for await (const [key, module] of Object.entries(routeModuleFiles)) {
-    console.log('key = ', key, 'module = ', module)
+  for await (const [, module] of Object.entries(routeModuleFiles)) {
 
 
     if (module) {
     if (module) {
       const routes = Array.isArray(module) ? module : [module];
       const routes = Array.isArray(module) ? module : [module];

+ 1 - 2
src/views/publishContent/weCom/index.tsx

@@ -1,9 +1,8 @@
 import React, { useState } from 'react';
 import React, { useState } from 'react';
-import { Space, Table, Button, Input, Select, DatePicker, Tabs } from 'antd';
+import { Space, Table, Button, Input, Select, Tabs } from 'antd';
 import type { TableProps } from 'antd';
 import type { TableProps } from 'antd';
 import styles from './index.module.css';
 import styles from './index.module.css';
 import PunlishPlanModal from '../weGZH/components/publishPlanModal';
 import PunlishPlanModal from '../weGZH/components/publishPlanModal';
-const { RangePicker } = DatePicker;
 
 
 export interface PlanData {
 export interface PlanData {
 	// key: string;
 	// key: string;

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

@@ -235,7 +235,7 @@ const AddPunlishPlanModal: React.FC<AddPunlishPlanModalProps> = ({ visible, onCa
 				footer={null}
 				footer={null}
 				destroyOnClose // Unmount video element when closed
 				destroyOnClose // Unmount video element when closed
 				width={720} // Adjust as needed
 				width={720} // Adjust as needed
-				bodyStyle={{ padding: 0, background: '#000' }}
+				styles={{ body: { padding: 0, background: '#000' } }}
 				zIndex={20}
 				zIndex={20}
 			>
 			>
 				{playingVideo && (
 				{playingVideo && (

+ 3 - 3
src/views/publishContent/weGZH/components/videoSelectModal/index.tsx

@@ -97,7 +97,7 @@ const VideoSelectModal: React.FC<VideoSelectModalProps> = ({ visible, onClose, o
 				onClose={onClose}
 				onClose={onClose}
 				width={800}
 				width={800}
 				placement="right"
 				placement="right"
-				footerStyle={{ textAlign: 'right', padding: '10px 24px' }}
+				styles={{ footer: { textAlign: 'right', padding: '10px 24px' } }}
 				footer={
 				footer={
 					<div className="flex justify-between items-center">
 					<div className="flex justify-between items-center">
 						<Pagination
 						<Pagination
@@ -152,7 +152,7 @@ const VideoSelectModal: React.FC<VideoSelectModalProps> = ({ visible, onClose, o
 							<Card
 							<Card
 								key={video.id}
 								key={video.id}
 								className={`relative ${isDisabled ? 'opacity-50' : 'cursor-pointer'} ${isSelected ? 'border-blue-500 border-2' : ''}`}
 								className={`relative ${isDisabled ? 'opacity-50' : 'cursor-pointer'} ${isSelected ? 'border-blue-500 border-2' : ''}`}
-								bodyStyle={{ padding: 0 }}
+								styles={{ body: { padding: 0 } }}
 								onClick={() => !isDisabled && handleSelectVideo(video.id)}
 								onClick={() => !isDisabled && handleSelectVideo(video.id)}
 							>
 							>
 								<div className="p-3">
 								<div className="p-3">
@@ -189,7 +189,7 @@ const VideoSelectModal: React.FC<VideoSelectModalProps> = ({ visible, onClose, o
 				footer={null}
 				footer={null}
 				destroyOnClose
 				destroyOnClose
 				width={720}
 				width={720}
-				bodyStyle={{ padding: 0, background: '#000' }}
+				styles={{ body: { padding: 0, background: '#000' } }}
 			>
 			>
 				{playingVideo && (
 				{playingVideo && (
 					<video controls autoPlay className="w-full h-auto max-h-[80vh] block" src={playingVideo.videoUrl}>
 					<video controls autoPlay className="w-full h-auto max-h-[80vh] block" src={playingVideo.videoUrl}>

+ 39 - 0
src/views/publishContent/weGZH/hooks/useAccountOptions.ts

@@ -0,0 +1,39 @@
+import { useState, useEffect } from 'react';
+import { getGzhAccountOptionsApi } from '@src/http/api';
+import request from '@src/http/index';
+
+interface Account {
+  id: string;
+  name: string;
+  // Add other account properties as needed
+}
+
+export const useAccountOptions = () => {
+  const [accountOptions, setAccountOptions] = useState<Account[]>([]);
+  const [loading, setLoading] = useState(false);
+  const [error, setError] = useState<string | null>(null);
+
+  const getAccountList = async () => {
+    try {
+      setLoading(true);
+      setError(null);
+			const data = await request.get(getGzhAccountOptionsApi);
+      setAccountOptions(data.data as Account[]);
+    } catch (err) {
+      setError(err instanceof Error ? err.message : 'Failed to fetch accounts');
+    } finally {
+      setLoading(false);
+    }
+  };
+
+  useEffect(() => {
+    getAccountList();
+  }, []);
+
+  return {
+    accountOptions,
+    getAccountList,
+    loading,
+    error
+  };
+}; 

+ 85 - 0
src/views/publishContent/weGZH/hooks/useGzhPlanList.ts

@@ -0,0 +1,85 @@
+import { useState } from 'react';
+import { getGzhPlanListApi } from '@src/http/api';
+import request from '@src/http/index';
+
+interface VideoType {
+  cover: string;
+	coverIsEdit: number;
+	score: number;
+	title: string;
+	titleIsEdit: number;
+	video: string;
+	videoId: number;
+}
+
+export interface GzhPlanType {
+  accountId: number;
+  accountName: string;
+  createTimestamp: number;
+  id: number;
+  publishStage: number;
+  scene: number;
+  title: string[];
+	videoCount: number;
+	videoList: VideoType[];
+}
+
+interface GzhPlanListParams {
+	accountId?: number;
+	createTimestampEnd?: number;
+	createTimestampStart?: number;
+	publishStage?: number;
+	title?: string;
+	pageNum: number;
+	pageSize: number;
+}
+
+interface GzhPlanListResponse {
+	objs: GzhPlanType[];
+	totalSize: number;
+}
+
+export const useGzhPlanList = () => {
+  const [gzhPlanList, setGzhPlanList] = useState<GzhPlanType[]>([]);
+  const [loading, setLoading] = useState(false);
+	const [error, setError] = useState<string | null>(null);
+	const [totalSize, setTotalSize] = useState(0);
+
+	const getGzhPlanList = async ({
+		accountId,
+		createTimestampEnd,
+		createTimestampStart,
+		publishStage,
+		title,
+		pageNum,
+		pageSize
+	}: GzhPlanListParams) => {
+    try {
+      setLoading(true);
+      setError(null);
+			const data = await request.post<GzhPlanListResponse>(getGzhPlanListApi, {
+				accountId: accountId,
+				createTimestampEnd,
+				createTimestampStart,
+				publishStage,
+				title,
+				pageNum,
+				pageSize,
+			});
+      setGzhPlanList(data.data.objs as GzhPlanType[]);
+			setTotalSize(data.data.totalSize);
+    } catch (err) {
+      setError(err instanceof Error ? err.message : 'Failed to fetch accounts');
+    } finally {
+      setLoading(false);
+    }
+  };
+
+  return {
+    gzhPlanList,
+		getGzhPlanList,
+		totalSize,
+    loading,
+    error
+  };
+}; 

+ 33 - 0
src/views/publishContent/weGZH/hooks/useVideoCategoryOptions.ts

@@ -0,0 +1,33 @@
+import { useState, useEffect } from 'react';
+import { getVideoContentCategoryListApi } from '@src/http/api';
+import request from '@src/http/index';
+
+export const useVideoCategoryOptions = () => {
+  const [videoCategoryOptions, setVideoCategoryOptions] = useState<string[]>([]);
+  const [loading, setLoading] = useState(false);
+  const [error, setError] = useState<string | null>(null);
+
+  const getVideoCategoryList = async () => {
+    try {
+      setLoading(true);
+      setError(null);
+			const data = await request.get(getVideoContentCategoryListApi);
+      setVideoCategoryOptions(data.data as string[]);
+    } catch (err) {
+      setError(err instanceof Error ? err.message : 'Failed to fetch accounts');
+    } finally {
+      setLoading(false);
+    }
+  };
+
+  useEffect(() => {
+    getVideoCategoryList();
+  }, []);
+
+  return {
+    videoCategoryOptions,
+    getVideoCategoryList,
+    loading,
+    error
+  };
+}; 

+ 32 - 50
src/views/publishContent/weGZH/index.tsx

@@ -1,20 +1,12 @@
-import React, { useState } from 'react';
+import React, { useEffect, useState } from 'react';
 import { Space, Table, Button, Input, Select, DatePicker, Tabs } from 'antd';
 import { Space, Table, Button, Input, Select, DatePicker, Tabs } from 'antd';
 import type { TableProps } from 'antd';
 import type { TableProps } from 'antd';
-import dayjs, { Dayjs } from 'dayjs';
+import { Dayjs } from 'dayjs';
 import styles from './index.module.css';
 import styles from './index.module.css';
 import PunlishPlanModal from './components/publishPlanModal';
 import PunlishPlanModal from './components/publishPlanModal';
 const { RangePicker } = DatePicker;
 const { RangePicker } = DatePicker;
-
-export interface PlanData {
-	// key: string;
-	officialAccount: string;
-	scene: string;
-	videoCount: number;
-	videoTitle: string;
-	planPublishTime: string;
-	publisher: string;
-}
+import { useAccountOptions } from '@src/views/publishContent/weGZH/hooks/useAccountOptions';
+import { useGzhPlanList, GzhPlanType } from '@src/views/publishContent/weGZH/hooks/useGzhPlanList';
 
 
 const WeGZHContent: React.FC = () => {
 const WeGZHContent: React.FC = () => {
 	// 状态管理
 	// 状态管理
@@ -24,15 +16,18 @@ const WeGZHContent: React.FC = () => {
 	const [dateRange, setDateRange] = useState<[Dayjs | null, Dayjs | null]>();
 	const [dateRange, setDateRange] = useState<[Dayjs | null, Dayjs | null]>();
 	const [isShowAddPunlishPlan, setIsShowAddPunlishPlan] = useState<boolean>(false);
 	const [isShowAddPunlishPlan, setIsShowAddPunlishPlan] = useState<boolean>(false);
 	const [actionType, setActionType] = useState<'add' | 'edit'>('add');
 	const [actionType, setActionType] = useState<'add' | 'edit'>('add');
-	const [editPlanData, setEditPlanData] = useState<PlanData>();
+	const [editPlanData, setEditPlanData] = useState<GzhPlanType>();
 	const [activeKey, setActiveKey] = useState<string>('1');
 	const [activeKey, setActiveKey] = useState<string>('1');
 
 
+	const { accountOptions } = useAccountOptions();
+	const { gzhPlanList, getGzhPlanList, totalSize } = useGzhPlanList();
+
 	// 表格列配置
 	// 表格列配置
-	const columns: TableProps<PlanData>['columns'] = [
+	const columns: TableProps<GzhPlanType>['columns'] = [
 		{
 		{
 			title: '公众号名称',
 			title: '公众号名称',
-			dataIndex: 'officialAccount',
-			key: 'officialAccount',
+			dataIndex: 'accountName',
+			key: 'accountName',
 			width: 200,
 			width: 200,
 		},
 		},
 		{
 		{
@@ -49,21 +44,24 @@ const WeGZHContent: React.FC = () => {
 		},
 		},
 		{
 		{
 			title: '视频标题',
 			title: '视频标题',
-			dataIndex: 'videoTitle',
-			key: 'videoTitle',
+			dataIndex: 'title',
+			key: 'title',
 			ellipsis: true,
 			ellipsis: true,
 		},
 		},
 		{
 		{
 			title: '计划创建时间',
 			title: '计划创建时间',
-			dataIndex: 'planPublishTime',
-			key: 'planPublishTime',
+			dataIndex: 'createTimestamp',
+			key: 'createTimestamp',
 			width: 200,
 			width: 200,
 		},
 		},
 		{
 		{
 			title: '发布方',
 			title: '发布方',
-			dataIndex: 'publisher',
-			key: 'publisher',
+			dataIndex: 'publishStage',
+			key: 'publishStage',
 			width: 120,
 			width: 120,
+			render: (_, record) => {
+				return record.publishStage === 1 ? '平台发布' : '用户发布';
+			}
 		},
 		},
 		{
 		{
 			title: '操作',
 			title: '操作',
@@ -78,37 +76,24 @@ const WeGZHContent: React.FC = () => {
 		},
 		},
 	];
 	];
 
 
-	const editPlan = (record: PlanData) => {
+	const editPlan = (record: GzhPlanType) => {
 		setEditPlanData(record);
 		setEditPlanData(record);
 		setActionType('edit');
 		setActionType('edit');
 		setIsShowAddPunlishPlan(true);
 		setIsShowAddPunlishPlan(true);
 	};
 	};
 
 
-	// 模拟数据
-	const data: PlanData[] = [
-		{
-			officialAccount: '小慧爱厨房',
-			scene: '关注回复',
-			videoCount: 3,
-			videoTitle: '养老金最新规定,快来看看养老金最新规定,快来看看...',
-			planPublishTime: '2024-08-13 13:32:07',
-			publisher: '平台发布',
-		},
-		{
-			officialAccount: '小阳看天下',
-			scene: '关注回复',
-			videoCount: 1,
-			videoTitle: '养老金最新规定,快来看看...',
-			planPublishTime: '2024-08-13 13:32:07',
-			publisher: '用户发布',
-		},
-	];
-
 	const addPunlishPlan = () => {
 	const addPunlishPlan = () => {
 		setActionType('add');
 		setActionType('add');
 		setIsShowAddPunlishPlan(true);
 		setIsShowAddPunlishPlan(true);
 	}
 	}
 
 
+	useEffect(() => {
+		getGzhPlanList({
+			pageNum: 1,
+			pageSize: 10,
+		});
+	}, []);
+
 	return (
 	return (
 		<div>
 		<div>
 			<div className="rounded-lg">
 			<div className="rounded-lg">
@@ -124,10 +109,7 @@ const WeGZHContent: React.FC = () => {
 							value={selectedAccount}
 							value={selectedAccount}
 							onChange={setSelectedAccount}
 							onChange={setSelectedAccount}
 							allowClear
 							allowClear
-							options={[
-								{ label: '小慧爱厨房', value: '小慧爱厨房' },
-								{ label: '小阳看天下', value: '小阳看天下' },
-							]}
+							options={accountOptions.map(item => ({ label: item.name, value: item.id }))}
 						/>
 						/>
 					</div>
 					</div>
 
 
@@ -186,12 +168,12 @@ const WeGZHContent: React.FC = () => {
 				/>
 				/>
 				{/* 表格区域 */}
 				{/* 表格区域 */}
 				<Table
 				<Table
-					rowKey={(record) => record.officialAccount}
+					rowKey={(record) => record.id}
 					className={styles.antTable}
 					className={styles.antTable}
 					columns={columns}
 					columns={columns}
-					dataSource={data}
+					dataSource={gzhPlanList}
 					pagination={{
 					pagination={{
-						total: data.length,
+						total: totalSize,
 						pageSize: 10,
 						pageSize: 10,
 						showTotal: (total) => `共 ${total} 条`,
 						showTotal: (total) => `共 ${total} 条`,
 					}}
 					}}