nieyuge пре 1 недеља
родитељ
комит
a484455623

Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
src/assets/react.svg


+ 7 - 1
src/http/api.ts

@@ -29,4 +29,10 @@ export const gzhPlanSave = `${import.meta.env.VITE_API_URL}/contentPlatform/plan
 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 videoContentList = `${import.meta.env.VITE_API_URL}/contentPlatform/plan/videoContentList`
+
+/* 数据统计 */
+export const gzhDataList = `${import.meta.env.VITE_API_URL}/contentPlatform/datastat/gzh`
+export const gzhDataExport = `${import.meta.env.VITE_API_URL}/contentPlatform/datastat/gzh/export`
+export const qwDataList = `${import.meta.env.VITE_API_URL}/contentPlatform/datastat/qw`
+export const qwDataExport = `${import.meta.env.VITE_API_URL}/contentPlatform/datastat/qw/export`

+ 4 - 4
src/views/cooperationAccount/gzh/index.tsx

@@ -1,7 +1,7 @@
 import { Button, Table, Image, Modal, message, Select } from "antd";
 import type { TableProps } from 'antd';
 import { useState, useEffect, useRef } from "react";
-import { ExclamationCircleOutlined, CheckCircleFilled } from "@ant-design/icons";
+import { InfoCircleFilled, CheckCircleFilled } from "@ant-design/icons";
 import http from "@src/http";
 import { accountGetAuthQrCode, accountGetAuthResult, accountGetContentType, accountList, accountSave, accountDelete } from "@src/http/api";
 
@@ -233,7 +233,7 @@ const AccountDialog = ({ title, isOpen, handleOk: parentHandleOk, handleCancel,
       {authFailed ? (
         <div className={"p-[20px] text-[#333] text-center"}>
           <div className={"text-[#ff4d4f] mb-[10px]"}>
-            <ExclamationCircleOutlined className={"text-[140px]"} />
+            <InfoCircleFilled className={"text-[140px]"} />
           </div>
           <div className={"mt-[10px]"}>
             <p className={"text-[20px] font-medium"}>授权失败</p>
@@ -264,7 +264,7 @@ const AccountDialog = ({ title, isOpen, handleOk: parentHandleOk, handleCancel,
           />
           <div className={"mt-[10px]"}>
             <p className={"text-[16px]"}>请用微信扫码授权</p>
-            <p className={"text-[12px]"}>二维码将在1小时内失效</p>
+            <p className={"text-[12px] text-[#ff4d4f]"}><InfoCircleFilled /> 二维码将在1小时内失效</p>
           </div>
         </div>
       )}
@@ -366,7 +366,7 @@ const Gzh: React.FC = () => {
   const deleteAccount = (record: DataType) => {
     Modal.confirm({
       title: '确认删除',
-      icon: <ExclamationCircleOutlined />,
+      icon: <InfoCircleFilled />,
       content: `确定要删除公众号「${record.name}」吗?`,
       okText: '确定',
       okType: 'danger',

+ 209 - 0
src/views/weData/gzh/index.tsx

@@ -0,0 +1,209 @@
+import { useState, useEffect } from 'react';
+import { Tabs, Table, Button, message } from "antd";
+import type { TableProps } from 'antd';
+import { DownloadOutlined } from '@ant-design/icons';
+import http from '@src/http';
+import { gzhDataList, gzhDataExport } from '@src/http/api.ts';
+
+interface GzhDataItem {
+	dateStr: string;
+	fansIncreaseCount: number;
+	firstLevel: number;
+	name: string;
+	openRate: number;
+	score: number;
+}
+
+interface GzhDataResponse {
+	curPageFirstRecNum: number;
+	curPageLastRecNum: number;
+	currentPage: number;
+	nextPage: number;
+	obj: GzhDataItem;
+	objs: GzhDataItem[];
+	offset: number;
+	pageSize: number;
+	prePage: number;
+	totalPage: number;
+	totalSize: number;
+}
+
+const Gzh: React.FC = () => {
+	const [allDataSource, setAllDataSource] = useState<GzhDataItem[]>([]);
+	const [separateDataSource, setSeparateDataSource] = useState<GzhDataItem[]>([]);
+	const [loading, setLoading] = useState<boolean>(false);
+	const [downloadLoading, setDownloadLoading] = useState<boolean>(false);
+	const [pagination, setPagination] = useState({
+		current: 1,
+		pageSize: 10,
+		total: 0
+	});
+	const [activeKey, setActiveKey] = useState("0");
+
+	const columns:TableProps['columns'] = [
+		{
+			title: '日期',
+			dataIndex: 'dateStr',
+			key: 'dateStr',
+		},
+		{
+			title: '新增粉丝',
+			dataIndex: 'fansIncreaseCount',
+			key: 'fansIncreaseCount',
+		},
+		{
+			title: '小程序访问人数',
+			dataIndex: 'firstLevel',
+			key: 'firstLevel',
+		},
+		{
+			title: '打开率',
+			dataIndex: 'openRate',
+			key: 'openRate',
+			render: (text) => `${text}%`
+		},
+		{
+			title: '传播得分',
+			dataIndex: 'score',
+			key: 'score',
+		},
+	];
+
+	const fetchGzhData = async (page = 1, pageSize = 10, type = 0) => {
+		try {
+			setLoading(true);
+			const res = await http.post<GzhDataResponse>(gzhDataList, {
+				pageNum: page,
+				pageSize: pageSize,
+				type: type
+			});
+			
+			if (res.success && res.data) {
+				if (type === 0) {
+					setAllDataSource(res.data.objs || []);
+				} else {
+					setSeparateDataSource(res.data.objs || []);
+				}
+				
+				setPagination({
+					current: res.data.currentPage,
+					pageSize: res.data.pageSize,
+					total: res.data.totalSize
+				});
+			}
+		} catch (error) {
+			console.error('获取公众号数据失败:', error);
+		} finally {
+			setLoading(false);
+		}
+	};
+
+	useEffect(() => {
+		fetchGzhData(1, 10, 0);
+	}, []);
+
+	const onChange = (key: string) => {
+		console.log(key);
+		fetchGzhData(1, 10, Number(key));
+	};
+	
+	const handleTableChange = (pagination: any) => {
+		const { current, pageSize } = pagination;
+		fetchGzhData(current, pageSize, activeKey === "0" ? 0 : 1);
+	};
+	
+	const handleDownload = async () => {
+		try {
+			setDownloadLoading(true);
+			// 根据当前选中的标签页设置type参数
+			const type = activeKey === "0" ? 0 : 1;
+			
+			// 使用当前分页信息
+			const response = await http.post(gzhDataExport, {
+				pageNum: pagination.current,
+				pageSize: pagination.pageSize,
+				type: type
+			}, { responseType: 'blob' });
+			
+			if (response.success && response.data) {
+				message.success('下载成功');
+			} else {
+				message.error('下载失败');
+			}
+		} catch {
+			message.error('下载失败');
+		} finally {
+			setDownloadLoading(false);
+		}
+	};
+
+  return (
+    <>
+      <div className={"flex mb-[10px]"}>
+        <div className={"flex-1 leading-[32px]"}>公众号数据统计</div>
+      </div>
+			<Tabs
+				defaultActiveKey="0"
+				type="card"
+				tabBarExtraContent={{
+					right: <Button 
+						type="link" 
+						icon={<DownloadOutlined />}
+						loading={downloadLoading}
+						onClick={handleDownload}
+					>
+						下载数据
+					</Button>
+				}}
+				onChange={(key) => {
+				setActiveKey(key);
+				onChange(key);
+			}}
+				items={[
+					{
+						key: "0",
+						label: "账号累计",
+						children: (
+							<Table 
+							dataSource={allDataSource} 
+							columns={columns} 
+							rowKey="dateStr"
+							loading={loading}
+							pagination={{
+								current: pagination.current,
+								pageSize: pagination.pageSize,
+								total: pagination.total,
+								showSizeChanger: true,
+								showTotal: (total) => `共 ${total} 条`,
+							}}
+							onChange={handleTableChange}
+						/>
+						),
+					},
+					{
+						key: "1",
+						label: "分账号",
+						children: (
+							<Table 
+							dataSource={separateDataSource} 
+							columns={columns} 
+							rowKey="dateStr"
+							loading={loading}
+							pagination={{
+								current: pagination.current,
+								pageSize: pagination.pageSize,
+								total: pagination.total,
+								showSizeChanger: true,
+								showTotal: (total) => `共 ${total} 条`,
+							}}
+							onChange={handleTableChange}
+						/>
+						),
+					},
+				]}
+			/>
+    </>
+  )
+}
+
+export default Gzh

+ 11 - 0
src/views/weData/qw/index.tsx

@@ -0,0 +1,11 @@
+const Qw = () => {
+  return (
+    <>
+      <div className={"flex mb-[10px]"}>
+        <div className={"flex-1 leading-[32px]"}>企微数据统计</div>
+      </div>
+    </>
+  )
+}
+
+export default Qw

+ 40 - 0
src/views/weData/weData.router.tsx

@@ -0,0 +1,40 @@
+import { TeamOutlined } from '@ant-design/icons'
+import { AdminRouterItem } from "../../router";
+import { Outlet } from "react-router-dom";
+import GZH from './gzh';
+import QW from './qw';
+
+const demoRoutes: AdminRouterItem[] = [
+  {
+    path: 'weData',
+    element: <Outlet />,
+		meta: {
+			label: "数据统计",
+			title: "数据统计",
+			key: "/weData",
+			icon: <TeamOutlined />,
+		},
+		children: [
+			{
+				path: 'gzh',
+				element: <GZH />,
+				meta: {
+					label: "公众号",
+					title: "公众号",
+					key: "/weData/gzh",
+				},
+			},
+			{
+				path: 'qw',
+				element: <QW />,
+				meta: {
+					label: "企微",
+					title: "企微",
+					key: "/weData/qw",
+				},
+			}
+		]
+  }
+]
+
+export default demoRoutes;

Неке датотеке нису приказане због велике количине промена