排版

现在做首页的排版,依旧是偷antd里面的东西

使用card包裹list的样式

import React from 'react'
import 'axios'
import { Card, Col, Row, List } from 'antd'
import { EditOutlined, EllipsisOutlined, SettingOutlined } from '@ant-design/icons';
import { Avatar } from 'antd';
const { Meta } = Card;function Home() {return (<div><Row gutter={16}><Col span={8}><Card title="用户最常浏览" variant="border"><Listsize="small"dataSource={['qq', 'wx', 'dy']}renderItem={(item) => <List.Item>{item}</List.Item>}/></Card></Col><Col span={8}><Card title="用户点赞最多" variant="border"><Listsize="small"dataSource={['qq', 'wx', 'dy']}renderItem={(item) => <List.Item>{item}</List.Item>}/></Card></Col><Col span={8}><Cardcover={<imgalt="example"src="https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png"/>}actions={[<SettingOutlined key="setting" />,<EditOutlined key="edit" />,<EllipsisOutlined key="ellipsis" />,]}><Metaavatar={<Avatar src="https://api.dicebear.com/7.x/miniavs/svg?seed=8" />}title="Card title"description="This is the description"/></Card></Col></Row></div>)
}export default Home

数据

接下来就是写数据请求之类的了

做后端数据请求+显示:

import React, { useEffect } from 'react'
import 'axios'
import { Card, Col, Row, List } from 'antd'
import { EditOutlined, EllipsisOutlined, SettingOutlined } from '@ant-design/icons';
import { Avatar } from 'antd';
import axios from 'axios';
import { useState } from'react'
const { Meta } = Card;function Home() {const [viewList, setviewList] = useState([])const [starList, setstarList] = useState([])useEffect(()=>{axios.get("http://localhost:3000/news?publishState=2&_expand=category&_sort=view&_order=desc&_limit=6").then(res=>{setviewList(res.data)}).catch(err => {console.error('Request failed', err)})},[])useEffect(()=>{axios.get("http://localhost:3000/news?publishState=2&_expand=category&_sort=star&_order=desc&_limit=6").then(res=>{setstarList(res.data)}).catch(err => {console.error('Request failed', err)})},[])const {username,region,role:{roleName}} = JSON.parse(localStorage.getItem('token'))return (<div><Row gutter={16}><Col span={8}><Card title="用户最常浏览" variant="border"><Listsize="small"dataSource={viewList}renderItem={(item) => <List.Item><a href={`#/news-manage/preview/${item.id}`}>{item.title}</a></List.Item>}/></Card></Col><Col span={8}><Card title="用户点赞最多" variant="border"><Listsize="small"dataSource={starList}renderItem={(item) => <List.Item><a href={`#/news-manage/preview/${item.id}`}>{item.title}</a></List.Item>}/></Card></Col><Col span={8}><Cardcover={<imgalt="example"src="https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png"/>}actions={[<SettingOutlined key="setting" />,<EditOutlined key="edit" />,<EllipsisOutlined key="ellipsis" />,]}><Metaavatar={<Avatar src="https://api.dicebear.com/7.x/miniavs/svg?seed=8" />}title={username}description={<div><b>{region?region:'全球'}</b><span style={{paddingLeft:"30px" }}>{roleName}</span> </div>}/></Card></Col></Row></div>)
}export default Home

柱状图

要做柱状图,需要用到一个开源的可视化的库:Apache EChartshttps://echarts.apache.org/zh/index.html

echarts也是需要下载的:

npm i --save echarts

使用相对来说简单,先做好模块的初始化,然后进行导入,复制粘贴就好了:

import React, { useEffect } from 'react'
import 'axios'
import { Card, Col, Row, List } from 'antd'
import { EditOutlined, EllipsisOutlined, SettingOutlined } from '@ant-design/icons';
import { Avatar } from 'antd';
import axios from 'axios';
import * as Echarts from 'echarts';
// 把所有东西都导进打模块中
import { useState } from'react'
const { Meta } = Card;function Home() {const [viewList, setviewList] = useState([])const [starList, setstarList] = useState([])useEffect(()=>{axios.get("http://localhost:3000/news?publishState=2&_expand=category&_sort=view&_order=desc&_limit=6").then(res=>{setviewList(res.data)}).catch(err => {console.error('Request failed', err)})},[])useEffect(()=>{axios.get("http://localhost:3000/news?publishState=2&_expand=category&_sort=star&_order=desc&_limit=6").then(res=>{setstarList(res.data)}).catch(err => {console.error('Request failed', err)})},[])useEffect(()=>{var myChart = Echarts.init(document.getElementById('main'));// 指定图表的配置项和数据var option = {title: {text: 'ECharts 入门示例'},tooltip: {},legend: {data: ['销量']},xAxis: {data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']},yAxis: {},series: [{name: '销量',type: 'bar',data: [5, 20, 36, 10, 10, 20]}]};// 使用刚指定的配置项和数据显示图表。myChart.setOption(option);},[])const {username,region,role:{roleName}} = JSON.parse(localStorage.getItem('token'))return (<div><Row gutter={16}><Col span={8}><Card title="用户最常浏览" variant="border"><Listsize="small"dataSource={viewList}renderItem={(item) => <List.Item><a href={`#/news-manage/preview/${item.id}`}>{item.title}</a></List.Item>}/></Card></Col><Col span={8}><Card title="用户点赞最多" variant="border"><Listsize="small"dataSource={starList}renderItem={(item) => <List.Item><a href={`#/news-manage/preview/${item.id}`}>{item.title}</a></List.Item>}/></Card></Col><Col span={8}><Cardcover={<imgalt="example"src="https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png"/>}actions={[<SettingOutlined key="setting" />,<EditOutlined key="edit" />,<EllipsisOutlined key="ellipsis" />,]}><Metaavatar={<Avatar src="https://api.dicebear.com/7.x/miniavs/svg?seed=8" />}title={username}description={<div><b>{region?region:'全球'}</b><span style={{paddingLeft:"30px" }}>{roleName}</span> </div>}/></Card></Col></Row><div id="main" style={{width:"100%",height:"400px",marginTop:"30px",}}></div></div>)
}export default Home

接下来做样式的统一处理,引入lodash库

import React, { useEffect, useRef } from 'react'
import 'axios'
import { Card, Col, Row, List } from 'antd'
import {EditOutlined,EllipsisOutlined,SettingOutlined,
} from '@ant-design/icons'
import { Avatar } from 'antd'
import axios from 'axios'
import * as Echarts from 'echarts'
// 把所有东西都导进打模块中
import { useState } from 'react'
import _ from 'lodash'
const { Meta } = Cardfunction Home() {const [viewList, setviewList] = useState([])const [starList, setstarList] = useState([])const barRef = useRef(null)useEffect(() => {axios.get('http://localhost:3000/news?publishState=2&_expand=category&_sort=view&_order=desc&_limit=6').then((res) => {setviewList(res.data)}).catch((err) => {console.error('Request failed', err)})}, [])useEffect(() => {axios.get('http://localhost:3000/news?publishState=2&_expand=category&_sort=star&_order=desc&_limit=6').then((res) => {setstarList(res.data)}).catch((err) => {console.error('Request failed', err)})}, [])useEffect(() => {axios.get('/news?publishState=2&_expand=category').then((res) => {console.log(res.data)renderBarView(_.groupBy(res.data, (item) => item.category.title))}).catch((err) => {console.error('Request failed', err)})const renderBarView = (obj) => {var myChart = Echarts.init(barRef.current)// 指定图表的配置项和数据var option = {title: {text: '新闻分类图示',},tooltip: {},legend: {data: ['数量'],},xAxis: {data: Object.keys(obj),},yAxis: {},series: [{name: '数量',type: 'bar',// 把数组映射成长度data: Object.values(obj).map((item) => item.length),},],}// 使用刚指定的配置项和数据显示图表。myChart.setOption(option)return () => {myChart.dispose()}}}, [])const {username,region,role: { roleName },} = JSON.parse(localStorage.getItem('token'))return (<div><Row gutter={16}><Col span={8}><Card title="用户最常浏览" variant="border"><Listsize="small"dataSource={viewList}renderItem={(item) => (<List.Item><a href={`#/news-manage/preview/${item.id}`}>{item.title}</a></List.Item>)}/></Card></Col><Col span={8}><Card title="用户点赞最多" variant="border"><Listsize="small"dataSource={starList}renderItem={(item) => (<List.Item><a href={`#/news-manage/preview/${item.id}`}>{item.title}</a></List.Item>)}/></Card></Col><Col span={8}><Cardcover={<imgalt="example"src="https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png"/>}actions={[<SettingOutlined key="setting" />,<EditOutlined key="edit" />,<EllipsisOutlined key="ellipsis" />,]}><Metaavatar={<Avatar src="https://api.dicebear.com/7.x/miniavs/svg?seed=8" />}title={username}description={<div><b>{region ? region : '全球'}</b><spanstyle={{paddingLeft: '30px',}}>{roleName}</span></div>}/></Card></Col></Row><divref={barRef}style={{width: '100%',height: '400px',marginTop: '30px',}}></div></div>)
}export default Home

现在的分类做出来了,但是没有做响应式,所以优化一下

响应式

 进行响应式的优化:

import React, { useEffect, useRef } from 'react'
import { Card, Col, Row, List } from 'antd'
import {EditOutlined,EllipsisOutlined,SettingOutlined,
} from '@ant-design/icons'
import { Avatar } from 'antd'
import axios from 'axios'
import * as Echarts from 'echarts'
// 把所有东西都导进打模块中
import { useState } from 'react'
import _ from 'lodash'
const { Meta } = Cardfunction Home() {const [viewList, setviewList] = useState([])const [starList, setstarList] = useState([])const barRef = useRef(null)useEffect(() => {axios.get('http://localhost:3000/news?publishState=2&_expand=category&_sort=view&_order=desc&_limit=6').then((res) => {setviewList(res.data)}).catch((err) => {console.error('Request failed', err)})}, [])useEffect(() => {axios.get('http://localhost:3000/news?publishState=2&_expand=category&_sort=star&_order=desc&_limit=6').then((res) => {setstarList(res.data)}).catch((err) => {console.error('Request failed', err)})}, [])useEffect(() => {axios.get('/news?publishState=2&_expand=category').then((res) => {renderBarView(_.groupBy(res.data, (item) => item.category.title))})return ()=>{window.onresize = null}}, [])const renderBarView = (obj) => {var myChart = Echarts.init(barRef.current)// 指定图表的配置项和数据var option = {title: {text: '新闻分类图示',},tooltip: {},legend: {data: ['数量'],},xAxis: {data: Object.keys(obj),axisLabel: {rotate: "60",//强制显示interval: 0,},},yAxis: {// 让显示全是整数minInterval: 1},series: [{name: '数量',type: 'bar',// 把数组映射成长度data: Object.values(obj).map((item) => item.length),},],}// 使用刚指定的配置项和数据显示图表。myChart.setOption(option)window.onresize =()=>{//每次自动触发myChart.resize()} return () => {myChart.dispose()}}const {username,region,role: { roleName },} = JSON.parse(localStorage.getItem('token'))return (<div><Row gutter={16}><Col span={8}><Card title="用户最常浏览" variant="border"><Listsize="small"dataSource={viewList}renderItem={(item) => (<List.Item><a href={`#/news-manage/preview/${item.id}`}>{item.title}</a></List.Item>)}/></Card></Col><Col span={8}><Card title="用户点赞最多" variant="border"><Listsize="small"dataSource={starList}renderItem={(item) => (<List.Item><a href={`#/news-manage/preview/${item.id}`}>{item.title}</a></List.Item>)}/></Card></Col><Col span={8}><Cardcover={<imgalt="example"src="https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png"/>}actions={[<SettingOutlined key="setting" />,<EditOutlined key="edit" />,<EllipsisOutlined key="ellipsis" />,]}><Metaavatar={<Avatar src="https://api.dicebear.com/7.x/miniavs/svg?seed=8" />}title={username}description={<div><b>{region ? region : '全球'}</b><spanstyle={{paddingLeft: '30px',}}>{roleName}</span></div>}/></Card></Col></Row><divref={barRef}style={{width: '100%',height: '400px',marginTop: '30px',}}></div></div>)
}export default Home

用onresize即可

饼状图

最开始写的代码有问题,会出现显示不及时或者显示出来的格式是错的的问题:

// import React, { useEffect, useRef, useState } from 'react';
// import { Card, Col, Row, List, Drawer } from 'antd';
// import {
//   EditOutlined,
//   EllipsisOutlined,
//   SettingOutlined,
// } from '@ant-design/icons';
// import { Avatar } from 'antd';
// import axios from 'axios';
// import * as Echarts from 'echarts';
// import _ from 'lodash';// const { Meta } = Card;// function Home() {
//   const [viewList, setviewList] = useState([]);
//   const [starList, setstarList] = useState([]);
//   const [visible, setvisible] = useState(false);//   const barRef = useRef(null);
//   const pieRef = useRef(null);//   useEffect(() => {
//     axios
//       .get(
//         'http://localhost:3000/news?publishState=2&_expand=category&_sort=view&_order=desc&_limit=6'
//       )
//       .then((res) => {
//         setviewList(res.data);
//       })
//       .catch((err) => {
//         console.error('Request failed', err);
//       });
//   }, []);//   useEffect(() => {
//     axios
//       .get(
//         'http://localhost:3000/news?publishState=2&_expand=category&_sort=star&_order=desc&_limit=6'
//       )
//       .then((res) => {
//         setstarList(res.data);
//       })
//       .catch((err) => {
//         console.error('Request failed', err);
//       });
//   }, []);//   useEffect(() => {
//     let barCleanup;
//     let barResizeHandler;
//     let pieCleanup;
//     let pieResizeHandler;//     const fetchDataAndRender = async () => {
//       try {
//         const res = await axios.get('/news?publishState=2&_expand=category');
//         if (barRef.current) {
//           barCleanup = renderBarView(
//             _.groupBy(res.data, (item) => item.category.title)
//           );
//           barResizeHandler = () => {
//             if (barCleanup) {
//               const myChart = Echarts.getInstanceByDom(barRef.current);
//               if (myChart) {
//                 myChart.resize();
//               }
//             }
//           };
//           window.addEventListener('resize', barResizeHandler);
//         }
//       } catch (err) {
//         console.error('Request failed', err);
//       }
//     };//     fetchDataAndRender();//     return () => {
//       if (typeof barCleanup === 'function') {
//         barCleanup();
//       }
//       if (barResizeHandler) {
//         window.removeEventListener('resize', barResizeHandler);
//       }
//       if (typeof pieCleanup === 'function') {
//         pieCleanup();
//       }
//       if (pieResizeHandler) {
//         window.removeEventListener('resize', pieResizeHandler);
//       }
//     };
//   }, []);//   const renderBarView = (obj) => {
//     if (!barRef.current) return;
//     var myChart = Echarts.init(barRef.current);//     // 指定图表的配置项和数据
//     var option = {
//       title: {
//         text: '新闻分类图示',
//       },
//       tooltip: {},
//       legend: {
//         data: ['数量'],
//       },
//       xAxis: {
//         data: Object.keys(obj),
//         axisLabel: {
//           rotate: 60,
//           // 强制显示
//           interval: 0,
//         },
//       },
//       yAxis: {
//         // 让显示全是整数
//         minInterval: 1,
//       },
//       series: [
//         {
//           name: '数量',
//           type: 'bar',
//           // 把数组映射成长度
//           data: Object.values(obj).map((item) => item.length),
//         },
//       ],
//     };
//     // 使用刚指定的配置项和数据显示图表。
//     myChart.setOption(option);//     return () => {
//       myChart.dispose();
//     };
//   };//   const renderPieView = (obj) => {
//     if (!pieRef.current) return;
//     var myChart = Echarts.init(pieRef.current);//     var option = {
//       title: {
//         text: 'Referer of a Website',
//         subtext: 'Fake Data',
//         left: 'center',
//       },
//       tooltip: {
//         trigger: 'item',
//       },
//       legend: {
//         orient: 'vertical',
//         left: 'left',
//       },
//       series: [
//         {
//           name: 'Access From',
//           type: 'pie',
//           radius: '50%',
//           data: [
//             { value: 1048, name: 'Search Engine' },
//             { value: 735, name: 'Direct' },
//             { value: 580, name: 'Email' },
//             { value: 484, name: 'Union Ads' },
//             { value: 300, name: 'Video Ads' },
//           ],
//           emphasis: {
//             itemStyle: {
//               shadowBlur: 10,
//               shadowOffsetX: 0,
//               shadowColor: 'rgba(0, 0, 0, 0.5)',
//             },
//           },
//         },
//       ],
//     };
//     option && myChart.setOption(option);//     const resizeHandler = () => {
//       myChart.resize();
//     };
//     window.addEventListener('resize', resizeHandler);//     return () => {
//       window.removeEventListener('resize', resizeHandler);
//       myChart.dispose();
//     };
//   };//   const tokenData = localStorage.getItem('token');
//   const {
//     username = '',
//     region = '',
//     role: { roleName = '' } = {},
//   } = tokenData ? JSON.parse(tokenData) : {};//   return (
//     <div>
//       <Row gutter={16}>
//         <Col span={8}>
//           <Card title="用户最常浏览" variant="border">
//             <List
//               size="small"
//               dataSource={viewList}
//               renderItem={(item) => (
//                 <List.Item>
//                   <a href={`#/news-manage/preview/${item.id}`}>{item.title}</a>
//                 </List.Item>
//               )}
//             />
//           </Card>
//         </Col>
//         <Col span={8}>
//           <Card title="用户点赞最多" variant="border">
//             <List
//               size="small"
//               dataSource={starList}
//               renderItem={(item) => (
//                 <List.Item>
//                   <a href={`#/news-manage/preview/${item.id}`}>{item.title}</a>
//                 </List.Item>
//               )}
//             />
//           </Card>
//         </Col>
//         <Col span={8}>
//           <Card
//             cover={
//               <img
//                 alt="example"
//                 src="https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png"
//               />
//             }
//             actions={[
//               <SettingOutlined
//                 key="setting"
//                 onClick={() => {
//                   setTimeout(() => {
//                     setvisible(true);
//                     //init初始化
//                     renderPieView();
//                   }, 0);
//                 }}
//               />,
//               <EditOutlined key="edit" />,
//               <EllipsisOutlined key="ellipsis" />,
//             ]}
//           >
//             <Meta
//               avatar={
//                 <Avatar src="https://api.dicebear.com/7.x/miniavs/svg?seed=8" />
//               }
//               title={username}
//               description={
//                 <div>
//                   <b>{region ? region : '全球'}</b>
//                   <span
//                     style={{
//                       paddingLeft: '30px',
//                     }}
//                   >
//                     {roleName}
//                   </span>
//                 </div>
//               }
//             />
//           </Card>
//         </Col>
//       </Row>//       <Drawer
//         width="500px"
//         title="个人新闻分类"
//         placement="right"
//         closable={true}
//         onClose={() => {
//           setvisible(false);
//         }}
//         visible={visible}
//       >
//         <div
//           ref={pieRef}
//           style={{
//             width: '100%',
//             height: '400px',
//             marginTop: '30px',
//           }}
//         ></div>
//       </Drawer>//       <div
//         ref={barRef}
//         style={{
//           width: '100%',
//           height: '400px',
//           marginTop: '30px',
//         }}
//       ></div>
//     </div>
//   );
// }// export default Home;

拆特鸡皮替告诉我是两个问题导致的,一是我没有传数据给renderPieView(先获取数据再分组),二是DOM没有准备好(所以要延时):

<SettingOutlinedkey="setting"onClick={async () => {setvisible(true);// 延迟一点,等 Drawer 动画打开再渲染图表setTimeout(async () => {const token = JSON.parse(localStorage.getItem('token'));const username = token?.username;try {const res = await axios.get(`/news?author=${username}&publishState=2&_expand=category`);const groupedData = _.groupBy(res.data, (item) => item.category.title);const pieData = Object.keys(groupedData).map((key) => ({name: key,value: groupedData[key].length,}));renderPieView(pieData);} catch (err) {console.error('Failed to fetch pie data', err);}}, 300); // 等 Drawer 动画展开后再绘制图表}}
/>

 点击图标时触发这个异步函数(async),它将打开抽屉并加载图表数据。打开 Drawer,这是控制抽屉显示的 visible 状态。

Drawer 打开时有动画,如果立即渲染图表,容器尺寸可能为 0,Echarts 会渲染失败或图表不显示

setTimeout(..., 300) 延迟 300ms 再渲染图表,确保 Drawer 打开完成、DOM 有尺寸

从本地存储获取当前用户 token 并解析出用户名,用于之后的请求过滤(只看当前用户发布的新闻)

使用 lodash 的 groupBy 对新闻按分类标题进行分组,便于做饼图

修改 renderPieView 函数接收参数为 data(数组形式) 

const renderPieView = (data) => {if (!pieRef.current) return;const myChart = Echarts.init(pieRef.current);const option = {title: {text: '个人新闻分类',subtext: '按分类统计',left: 'center',},tooltip: {trigger: 'item',},legend: {orient: 'vertical',left: 'left',},series: [{name: '新闻数量',type: 'pie',radius: '50%',data: data,emphasis: {itemStyle: {shadowBlur: 10,shadowOffsetX: 0,shadowColor: 'rgba(0, 0, 0, 0.5)',},},},],};myChart.setOption(option);const resizeHandler = () => {myChart.resize();};window.addEventListener('resize', resizeHandler);return () => {window.removeEventListener('resize', resizeHandler);myChart.dispose();};
};

完整代码:

import React, { useEffect, useRef, useState } from 'react';
import { Card, Col, Row, List, Drawer } from 'antd';
import {EditOutlined,EllipsisOutlined,SettingOutlined,
} from '@ant-design/icons';
import { Avatar } from 'antd';
import axios from 'axios';
import * as Echarts from 'echarts';
import _ from 'lodash';const { Meta } = Card;function Home() {const [viewList, setviewList] = useState([]);const [starList, setstarList] = useState([]);const [visible, setvisible] = useState(false);const barRef = useRef(null);const pieRef = useRef(null);useEffect(() => {axios.get('/news?publishState=2&_expand=category&_sort=view&_order=desc&_limit=6').then((res) => {setviewList(res.data);}).catch((err) => {console.error('Request failed', err);});}, []);useEffect(() => {axios.get('/news?publishState=2&_expand=category&_sort=star&_order=desc&_limit=6').then((res) => {setstarList(res.data);}).catch((err) => {console.error('Request failed', err);});}, []);useEffect(() => {let barCleanup;let barResizeHandler;const fetchDataAndRender = async () => {try {const res = await axios.get('/news?publishState=2&_expand=category');if (barRef.current) {barCleanup = renderBarView(_.groupBy(res.data, (item) => item.category.title));barResizeHandler = () => {if (barCleanup) {const myChart = Echarts.getInstanceByDom(barRef.current);if (myChart) {myChart.resize();}}};window.addEventListener('resize', barResizeHandler);}} catch (err) {console.error('Request failed', err);}};fetchDataAndRender();return () => {if (typeof barCleanup === 'function') {barCleanup();}if (barResizeHandler) {window.removeEventListener('resize', barResizeHandler);}};}, []);const renderBarView = (obj) => {if (!barRef.current) return;var myChart = Echarts.init(barRef.current);var option = {title: {text: '新闻分类图示',},tooltip: {},legend: {data: ['数量'],},xAxis: {data: Object.keys(obj),axisLabel: {rotate: 60,interval: 0,},},yAxis: {minInterval: 1,},series: [{name: '数量',type: 'bar',data: Object.values(obj).map((item) => item.length),},],};myChart.setOption(option);return () => {myChart.dispose();};};const renderPieView = (data) => {if (!pieRef.current) return;const myChart = Echarts.init(pieRef.current);const option = {title: {text: '个人新闻分类',subtext: '按分类统计',left: 'center',},tooltip: {trigger: 'item',},legend: {orient: 'vertical',left: 'left',},series: [{name: '新闻数量',type: 'pie',radius: '50%',data: data,emphasis: {itemStyle: {shadowBlur: 10,shadowOffsetX: 0,shadowColor: 'rgba(0, 0, 0, 0.5)',},},},],};myChart.setOption(option);const resizeHandler = () => {myChart.resize();};window.addEventListener('resize', resizeHandler);return () => {window.removeEventListener('resize', resizeHandler);myChart.dispose();};};const tokenData = localStorage.getItem('token');const {username = '',region = '',role: { roleName = '' } = {},} = tokenData ? JSON.parse(tokenData) : {};return (<div><Row gutter={16}><Col span={8}><Card title="用户最常浏览" variant="border"><Listsize="small"dataSource={viewList}renderItem={(item) => (<List.Item><a href={`#/news-manage/preview/${item.id}`}>{item.title}</a></List.Item>)}/></Card></Col><Col span={8}><Card title="用户点赞最多" variant="border"><Listsize="small"dataSource={starList}renderItem={(item) => (<List.Item><a href={`#/news-manage/preview/${item.id}`}>{item.title}</a></List.Item>)}/></Card></Col><Col span={8}><Cardcover={<imgalt="example"src="https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png"/>}actions={[<SettingOutlinedkey="setting"onClick={async () => {setvisible(true);setTimeout(async () => {const token = JSON.parse(localStorage.getItem('token'));const username = token?.username;try {const res = await axios.get(`/news?author=${username}&publishState=2&_expand=category`);const groupedData = _.groupBy(res.data,(item) => item.category.title);const pieData = Object.keys(groupedData).map((key) => ({name: key,value: groupedData[key].length,}));renderPieView(pieData);} catch (err) {console.error('Failed to fetch pie data', err);}}, 300);}}/>,<EditOutlined key="edit" />,<EllipsisOutlined key="ellipsis" />,]}><Metaavatar={<Avatar src="https://api.dicebear.com/7.x/miniavs/svg?seed=8" />}title={username}description={<div><b>{region ? region : '全球'}</b><spanstyle={{paddingLeft: '30px',}}>{roleName}</span></div>}/></Card></Col></Row><Drawerwidth="500px"title="个人新闻分类"placement="right"closable={true}onClose={() => {setvisible(false);}}visible={visible}><divref={pieRef}style={{width: '100%',height: '400px',marginTop: '30px',}}></div></Drawer><divref={barRef}style={{width: '100%',height: '400px',marginTop: '30px',}}></div></div>);
}export default Home;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/78983.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/78983.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/78983.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用Set和Map解题思路

前言 Set和Map这两种数据结构,在解决一些题上&#xff0c;效率很高。跟大家简单分享一些题以及如何使用Set和Map去解决这些题目。 题目链接 136. 只出现一次的数字 - 力扣&#xff08;LeetCode&#xff09; 138. 随机链表的复制 - 力扣&#xff08;LeetCode&#xff09; 旧…

尝试leaflet+webassemly

前言 笔者在github发现rust版本的leaflet&#xff0c;发现是用wasm-bindgen包装的&#xff0c;尝试使用一下 Issues slowtec/leaflet-rshttps://github.com/slowtec/leaflet-rs 正文 准备 新建一个react项目&#xff0c;安装rsw依赖 pnpm i -D vite-plugin-rsw cargo ins…

机器学习实战,天猫双十一销量与中国人寿保费预测,使用多项式回归,梯度下降,EDA数据探索,弹性网络等技术

前言 很多同学学机器学习时总感觉&#xff1a;“公式推导我会&#xff0c;代码也能看懂&#xff0c;但自己从头做项目就懵”。 这次我们选了两个小数据集&#xff0c;降低复杂度&#xff0c;带大家从头开始进行分析&#xff0c;建模&#xff0c;预测&#xff0c;可视化等&…

SQL数据库系统全解析:从入门到实践

一、数据库世界入门指南 在数字时代&#xff0c;数据就像新时代的石油&#xff0c;而数据库系统就是储存和管理这些宝贵资源的仓库。对于初学者来说&#xff0c;理解数据库的基本概念是迈入这个领域的第一步。 数据库本质上是一个有组织的数据集合&#xff0c;它允许我们高效…

【大模型】图像生成:StyleGAN3:生成对抗网络的革命性进化

深度解析StyleGAN3&#xff1a;生成对抗网络的革命性进化 技术演进与架构创新代际技术对比StyleGAN3架构解析 环境配置与快速入门硬件要求安装步骤预训练模型下载 实战全流程解析1. 图像生成示例2. 自定义数据集训练3. 潜在空间操作 核心技术深度解析1. 连续信号建模2. 傅里叶特…

PHP-Cookie

Cookie 是什么&#xff1f; cookie 常用于识别用户。cookie 是一种服务器留在用户计算机上的小文件。每当同一台计算机通过浏览器请求页面时&#xff0c;这台计算机将会发送 cookie。通过 PHP&#xff0c;您能够创建并取回 cookie 的值。 设置Cookie 在PHP中&#xff0c;你可…

“Everything“工具 是 Windows 上文件名搜索引擎神奇

01 Everything 和其他搜索引擎有何不同 轻量安装文件。 干净简洁的用户界面。 快速文件索引。 快速搜索。 快速启动。 最小资源使用。 轻量数据库。 实时更新。 官网&#xff1a;https://www.voidtools.com/zh-cn/downloads/ 通过网盘分享的文件&#xff1a;Every…

CSS:选择器-基本选择器

文章目录 1、通配选择器2、元素选择器3、类选择器4、ID选择器 1、通配选择器 2、元素选择器 3、类选择器 4、ID选择器

一种动态分配内存错误的解决办法

1、项目背景 一款2年前开发的无线网络通信软件在最近的使用过程中出现网络中传感器离线的问题&#xff0c;此软件之前已经使用的几年了&#xff0c;基本功能还算稳定。这次为什么出了问题。 先派工程师去现场调试一下&#xff0c;初步的结果是网络信号弱&#xff0c;并且有个别…

React 第三十四节 Router 开发中 useLocation Hook 的用法以及案例详解

一、useLocation基础用法 作用&#xff1a;获取当前路由的 location 对象 返回对象结构&#xff1a; {pathname: "/about", // 当前路径search: "?namejohn", // 查询参数&#xff08;URL参数&#xff09;hash: "#contact", …

DeepSeek-Prover-V2-671B最新体验地址:Prover版仅适合解决专业数学证明问题

DeepSeek-Prover-V2-671B最新体验地址&#xff1a;Prover版仅适合解决专业数学证明问题 DeepSeek 团队于 2025 年 4 月 30 日正式在Hugging Face开源了其重量级新作 —— DeepSeek-Prover-V2-671B&#xff0c;这是一款专为解决数学定理证明和形式化推理任务而设计的超大规模语…

tornado_登录页面(案例)

目录 1.基础知识​编辑 2.脚手架&#xff08;模版&#xff09; 3.登录流程图&#xff08;processon&#xff09; 4.登录表单 4.1后&#xff08;返回值&#xff09;任何值&#xff1a;username/password &#xff08;4.1.1&#xff09;app.py &#xff08;4.1.2&#xff…

Android学习总结之自定义view设计模式理解

面试题 1&#xff1a;请举例说明自定义 View 中模板方法模式的应用 考点分析 此问题主要考查对模板方法模式的理解&#xff0c;以及该模式在 Android 自定义 View 生命周期方法里的实际运用。 回答内容 模板方法模式定义了一个操作的算法骨架&#xff0c;把一些步骤的实现延…

【Scrapy】简单项目实战--爬取dangdang图书信息

目录 一、基本步骤 1、新建项目 &#xff1a;新建一个新的爬虫项目 2、明确目标 &#xff08;items.py&#xff09;&#xff1a;明确你想要抓取的目标 3、制作爬虫 &#xff08;spiders/xxspider.py&#xff09;&#xff1a;制作爬虫开始爬取网页 4、存储内容 &#xff08;p…

开源CMS系统的SEO优化功能主要依赖哪些插件?

在当今互联网时代&#xff0c;搜索引擎优化&#xff08;SEO&#xff09;是网站获取流量的核心手段之一。开源内容管理系统&#xff08;CMS&#xff09;因其灵活性和丰富的插件生态&#xff0c;成为许多开发者和企业的首选。本文将以主流开源CMS为例&#xff0c;深入解析其SEO优…

在 JMeter 中使用 BeanShell 获取 HTTP 请求体中的 JSON 数据

在 JMeter 中&#xff0c;您可以使用 BeanShell 处理器来获取 HTTP 请求体中的 JSON 数据。以下是几种方法&#xff1a; 方法一&#xff1a;使用前置处理器获取请求体 如果您需要在发送请求前访问请求体&#xff1a; 添加一个 BeanShell PreProcessor 到您的 HTTP 请求采样器…

在 WSL (Windows Subsystem for Linux) 中配置和安装 Linux 环境

在 WSL (Windows Subsystem for Linux) 中配置和安装 Linux 环境 WSL 允许你在 Windows 上运行 Linux 环境&#xff0c;以下是详细的配置和安装指南。 1. 安装前的准备工作 系统要求 Windows 10 版本 2004 及更高版本(内部版本 19041 及更高版本)或 Windows 11 64 位系统 虚…

AlphaFold蛋白质结构数据库介绍

AlphaFold Protein Structure Database (AlphaFold DB) 是 DeepMind + EMBL-EBI 合作开发的公开蛋白质结构预测数据库,是利用 AlphaFold2/AlphaFold3 AI模型 预测的全基因组级蛋白质三维结构库。 网址: https://alphafold.ebi.ac.uk 项目内容主办单位DeepMind + EMBL-EBI上线…

3.2goweb框架GORM

GORM 是 Go 语言中功能强大的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;支持 MySQL、PostgreSQL、SQLite、SQL Server 等主流数据库。以下是 GORM 的核心概念和用法详解&#xff1a; ​​一、基础入门​​ 1. 安装 go get -u gorm.io/gorm go get -u gorm.io…

第三部分:特征提取与目标检测

像边缘、角点、特定的纹理模式等都是图像的特征。提取这些特征是许多计算机视觉任务的关键第一步&#xff0c;例如图像匹配、对象识别、图像拼接等。目标检测则是在图像中找到特定对象&#xff08;如人脸、汽车等&#xff09;的位置。 本部分将涵盖以下关键主题&#xff1a; …