Skip to content

Commit e259688

Browse files
authored
Merge pull request #9 from Reaper622/dev
添加侧边栏热榜功能
2 parents 9210756 + b94c557 commit e259688

File tree

11 files changed

+127
-9
lines changed

11 files changed

+127
-9
lines changed

.eslintrc.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ module.exports = {
1919
"react/jsx-uses-react": 1, // 防止在 JSX 中使用的变量被错误的标记为未使用
2020
"react/jsx-uses-vars": 1, // 防止 React 被错误的标记为未使用
2121
"react/react-in-jsx-scope": 2, // 使用 JSX 时防止丢失 React
22+
'no-tabs': 'off',
23+
'indent': 'tab'
2224
},
2325
"plugins": [
2426
"react"

server/controllers/articles-handler.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
const path = require('path')
22
const fs = require('fs')
3-
const { insertBlogs, getData, getBlogPage, getBlogCount, getSingleBlog, setBlogRead } = require('../services/db')
3+
const { insertBlogs, getData, getBlogPage, getBlogCount, getSingleBlog, setBlogRead, getHotArticle } = require('../services/db')
44

55
const sourceHandler = require('../utils/source-handler')
66
const articleRoot = path.join(__dirname, '../../articles')
@@ -45,11 +45,16 @@ async function getSingleBlogContent(id) {
4545

4646
async function plusVisit(id) {
4747
const result = await setBlogRead(id)
48-
console.log(result)
48+
return result
49+
}
50+
51+
// 获取热榜
52+
async function hotArticle() {
53+
const result = await getHotArticle()
4954
return result
5055
}
5156

5257

5358

5459

55-
module.exports = { updateBlog, getBlogs, getBlogByPage, getSingleBlogContent, plusVisit }
60+
module.exports = { updateBlog, getBlogs, getBlogByPage, getSingleBlogContent, plusVisit, hotArticle }

server/routers/blog-router.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ router.get('/plusvisit/:id', async (ctx) => {
2222
ctx.body = await articleHandler.plusVisit(id)
2323
})
2424

25+
router.get('/gethotarticle', async (ctx) => {
26+
ctx.body = await articleHandler.hotArticle()
27+
})
28+
2529
// router.get('/getarchives', async (ctx) => {
2630
// ctx.set('Content-Type', 'application')
2731
// ctx.body = await archives.getBlogsArchives()

server/services/db.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,19 +53,27 @@ async function getData() {
5353
return dataList
5454
}
5555

56-
56+
// 获取全部文章
5757
async function getArchives() {
5858
let sql = `select * from blog group by YEAR(time)`
5959
let result = await query(sql)
6060
return result
6161
}
6262

63+
// 获取文章热榜
64+
async function getHotArticle() {
65+
let sql = `select * from blog order by visit desc limit 5`
66+
let result = await query(sql)
67+
return result
68+
}
69+
6370
module.exports = {
6471
getData,
6572
insertBlogs,
6673
getArchives,
6774
getBlogPage,
6875
getBlogCount,
6976
getSingleBlog,
70-
setBlogRead
77+
setBlogRead,
78+
getHotArticle
7179
}

src/Pages/Index/Index.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ import React, { Component } from 'react'
22
import TheHeader from '@components/Header/Header'
33
import TheFooter from '@components/Footer/Footer'
44
import Blog from '@components/Blog/Blog'
5+
import SideMenu from '@components/SideMenu/SideMenu'
56
import Axios from 'axios'
67
import { Layout, Row, Col, Pagination } from 'antd'
78
import { connect } from 'react-redux'
8-
import { loadBlogsByPage } from '../../redux/store'
9+
import { loadBlogsByPage, loadHotArticles } from '../../redux/store'
910
import config from '../../../config.json'
1011
import { CSSTransition } from 'react-transition-group'
1112

@@ -15,7 +16,7 @@ const { Content } = Layout
1516

1617
@connect(
1718
state => state,
18-
{ loadBlogsByPage }
19+
{ loadBlogsByPage, loadHotArticles }
1920
)
2021
class Index extends Component {
2122
constructor (props) {
@@ -27,6 +28,7 @@ class Index extends Component {
2728

2829
componentDidMount () {
2930
this.getBlogs(0)
31+
this.getHotArticles()
3032
}
3133

3234
getBlogs (page) {
@@ -40,6 +42,13 @@ class Index extends Component {
4042
})
4143
}
4244

45+
getHotArticles () {
46+
Axios.get(`${config.server_url}/blog/gethotarticle`)
47+
.then(res => {
48+
this.props.loadHotArticles(res.data)
49+
})
50+
}
51+
4352
handlePageChange (page) {
4453
this.setState({ loaded: false })
4554
this.getBlogs(page - 1)
@@ -61,6 +70,9 @@ class Index extends Component {
6170
{ this.props.blogsToShow ? this.props.blogsToShow.map(blog => <Blog key={blog.id} {...blog} isPriview={true} />) : <div></div>}
6271
</Col>
6372
</CSSTransition>
73+
<Col xs={{ span: 0}} xl={{offset: 1, span: 5}} xxl={{offset: 1, span: 5}}>
74+
{this.props.hotArticles ? <SideMenu hotArticles={this.props.hotArticles} /> : null}
75+
</Col>
6476
</Row>
6577
<Row style={{ margin: '20px 0 50px' }}>
6678
<Col xs={{ span: 24 }} xl={{ offset: 4, span: 12 }} xxl={{ offset: 4, span: 12 }} style={{ padding: '20px 0', background: '#fff', display: 'flex', justifyContent: 'center' }}>

src/assets/bingguo.webp

1.27 MB
Binary file not shown.

src/components/ScrollTop/ScrollTop.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ function ScrollTop () {
2828
useEffect(() => {
2929
window.addEventListener('scroll', handleScroll, true)
3030
return () => {
31-
window, removeEventListener('scroll', handleScroll, true)
31+
window.removeEventListener('scroll', handleScroll, true)
3232
};
3333
}, [])
3434

src/components/ScrollTop/ScrollTop.styl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
z-index 10000
66
transition top .5s linear
77
cursor pointer
8-
right 10vw
8+
right 5vw
99
dont-display-mobile(960px)
1010
.showStyle
1111
top -30vh

src/components/SideMenu/SideMenu.jsx

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import React, {useState, useEffect, useRef, useCallback} from 'react'
2+
import './SideMenu.styl'
3+
import { Link } from 'react-router-dom'
4+
import BingGuoPic from '@assets/bingguo.webp'
5+
6+
function SideMenu ({hotArticles}) {
7+
const [affix, setAffix] = useState(false)
8+
const sidemenu = useRef(null)
9+
useEffect(() => {
10+
console.log(sidemenu)
11+
window.addEventListener('scroll', handleScroll, true)
12+
return () => {
13+
window.removeEventListener('scroll', handleScroll, true)
14+
}
15+
}, [])
16+
17+
const handleScroll = useCallback(
18+
() => {
19+
let scrollTop = document.documentElement.scrollTop
20+
if (scrollTop > 600) {
21+
setAffix(true)
22+
} else {
23+
setAffix(false)
24+
}
25+
}
26+
)
27+
28+
return (
29+
<div ref={sidemenu} className={ affix ? `side-menu affix` : `side-menu`}>
30+
<img src={BingGuoPic} alt="冰菓"/>
31+
<ul>
32+
{hotArticles.map(blog => (
33+
<li key={blog.id}><Link className='title' to={`articles/${blog.id}`}>{blog.title}</Link><span>{blog.visit}次阅读</span></li>
34+
))}
35+
</ul>
36+
</div>
37+
)
38+
}
39+
40+
export default SideMenu

src/components/SideMenu/SideMenu.styl

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
@import '~@utils/mixins'
2+
.side-menu
3+
margin 50px 0
4+
width 400px
5+
height 400px
6+
background #ffffff
7+
border-radius 5px
8+
dont-display-mobile(960px)
9+
img
10+
margin 10px 10%
11+
width 80%
12+
ul
13+
width 100%
14+
li
15+
height 20px
16+
line-height 14px
17+
justify-content space-between
18+
font-size 14px
19+
margin 5px 0
20+
.title
21+
display inline-block
22+
width 70%
23+
height 14px
24+
overflow hidden
25+
white-space nowrap
26+
text-overflow ellipsis
27+
span
28+
display inline-block
29+
width 30%
30+
.affix
31+
position fixed
32+
top 0
33+

src/redux/store.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import axios from 'axios'
33
// TYPE
44
const UPLOAD_BLOGS = 'UPLOAD_BLOGS'
55
const GET_BLOGS_BY_PAGE = 'GET_BLOGS_BY_PAGE'
6+
const UPLOAD_HOTARTICLES = 'UPLOAD_HOTARTICLES'
67

78
// 初始state
89
const initState = {
@@ -18,6 +19,9 @@ export function reducer (state = initState, action) {
1819
case GET_BLOGS_BY_PAGE: {
1920
return { ...state, blogsToShow: action.payload.blogs, blogsCount: action.payload.blogCount }
2021
}
22+
case UPLOAD_HOTARTICLES: {
23+
return {...state, hotArticles: action.payload}
24+
}
2125
default: return state
2226
}
2327
}
@@ -42,3 +46,13 @@ export function loadBlogsByPage (data) {
4246
})
4347
}
4448
}
49+
50+
// 加载热榜
51+
export function loadHotArticles (data) {
52+
return dispatch => {
53+
dispatch({
54+
type: UPLOAD_HOTARTICLES,
55+
payload: data
56+
})
57+
}
58+
}

0 commit comments

Comments
 (0)