diff --git a/pages/notifications.tsx b/pages/notifications.tsx
index 98a6d6f6..663ab48b 100644
--- a/pages/notifications.tsx
+++ b/pages/notifications.tsx
@@ -27,6 +27,7 @@ import { getUserName } from "utils/user"
import moment from 'moment'
import userCustomTheme from "theme/user-custom"
import Link from "next/link"
+import Notifications from "components/notifications"
const filters = [
{icon: 'bell',label:'All',type: 0},
@@ -39,26 +40,22 @@ const filters = [
const NotificationPage = () => {
const [filter, setFilter]= useState(filters[0])
- const [notifications,setNotifications]: [Notification[],any] = useState([])
- const stackBorderColor = useColorModeValue(userCustomTheme.borderColor.light, userCustomTheme.borderColor.dark)
useEffect(() => {
initData()
},[])
const initData = async () => {
- await getNotifications()
await requestApi.post(`/notifications/unread`)
}
- const getNotifications = async (f?) => {
- const res = await requestApi.get(`/notifications/list/${f ? f.type : filter.type}`)
- setNotifications(res.data)
+ const getNotifications = async (p) => {
+ const res = await requestApi.get(`/notifications/list/${filter.type}?page=${p}`)
+ return res
}
const onFilterChange = (f) => {
setFilter(f)
- getNotifications(f)
}
return (
@@ -88,25 +85,7 @@ const filters = [
}
}
- {notifications.length !== 0
- ?
- }>
- {notifications.map((p,i) =>
-
-
-
-
- {getUserName(p.user)}
- {p.title}
-
- {p.subTitle && {p.subTitle}}
- {moment(p.created).fromNow()} {!p.read&& unread}
-
- )}
-
- :
-
- }
+
diff --git a/server/internal/api/notification.go b/server/internal/api/notification.go
index ca1c2a71..57f8dfbd 100644
--- a/server/internal/api/notification.go
+++ b/server/internal/api/notification.go
@@ -14,7 +14,11 @@ func GetNotifications(c *gin.Context) {
tp, _ := strconv.Atoi(c.Param("type"))
u := user.CurrentUser(c)
- nos, err := notification.Query(u, tp)
+ page, err0 := strconv.Atoi(c.Query("page"))
+ if err0 != nil {
+ page = 1
+ }
+ nos, err := notification.Query(u, tp, page)
if err != nil {
c.JSON(err.Status, common.RespError(err.Message))
return
diff --git a/server/internal/notification/notification.go b/server/internal/notification/notification.go
index 2c4ae297..46f0cc07 100644
--- a/server/internal/notification/notification.go
+++ b/server/internal/notification/notification.go
@@ -31,15 +31,17 @@ func Send(userID, orgID string, noType int, noID string, operatorID string) {
}
}
-func Query(user *models.User, tp int) ([]*models.Notification, *e.Error) {
+const perPage = 10
+
+func Query(user *models.User, tp int, page int) ([]*models.Notification, *e.Error) {
var rows *sql.Rows
var err error
if tp == 0 {
- rows, err = db.Conn.Query("SELECT operator_id,notifiable_type,notifiable_id,read,created FROM user_notification WHERE user_id=? ORDER BY created DESC", user.ID)
+ rows, err = db.Conn.Query("SELECT operator_id,notifiable_type,notifiable_id,read,created FROM user_notification WHERE user_id=? ORDER BY created DESC LIMIT ?,?", user.ID, (page-1)*perPage, page*perPage)
} else if tp == models.NotificationComment {
- rows, err = db.Conn.Query("SELECT operator_id,notifiable_type,notifiable_id,read,created FROM user_notification WHERE user_id=? and notifiable_type in ('1','6') ORDER BY created DESC", user.ID)
+ rows, err = db.Conn.Query("SELECT operator_id,notifiable_type,notifiable_id,read,created FROM user_notification WHERE user_id=? and notifiable_type in ('1','6') ORDER BY created DESC LIMIT ?,?", user.ID, (page-1)*perPage, page*perPage)
} else {
- rows, err = db.Conn.Query("SELECT operator_id,notifiable_type,notifiable_id,read,created FROM user_notification WHERE user_id=? and notifiable_type=? ORDER BY created DESC", user.ID, tp)
+ rows, err = db.Conn.Query("SELECT operator_id,notifiable_type,notifiable_id,read,created FROM user_notification WHERE user_id=? and notifiable_type=? ORDER BY created DESC LIMIT ?,?", user.ID, tp, (page-1)*perPage, page*perPage)
}
if err != nil {
diff --git a/src/components/notifications.tsx b/src/components/notifications.tsx
new file mode 100644
index 00000000..c30e6006
--- /dev/null
+++ b/src/components/notifications.tsx
@@ -0,0 +1,98 @@
+import React, { useEffect, useState } from "react"
+import { Box, Center, Heading, HStack, Image, Link, StackDivider, Tag, Text, useColorModeValue, VStack } from "@chakra-ui/react"
+
+import userCustomTheme from "theme/user-custom"
+import useInfiniteScroll from 'src/hooks/use-infinite-scroll'
+import { concat } from "lodash"
+import Empty from "src/components/empty"
+import { Notification } from "src/types/notification"
+import moment from 'moment'
+import { getUserName } from "utils/user"
+
+interface Props {
+ onLoad?: any
+ filter?: any
+}
+
+
+export const Notifications = (props: Props) => {
+ const { onLoad, filter } = props
+ const [notifications,setNotifications]: [Notification[],any] = useState([])
+ const [noMore, setNoMore] = useState(false)
+
+ const [isFetching, setIsFetching] = useInfiniteScroll(fetchMoreListItems);
+ const [page, setPage] = useState(1)
+ const stackBorderColor = useColorModeValue(userCustomTheme.borderColor.light, userCustomTheme.borderColor.dark)
+
+ useEffect(() => {
+ setNotifications([])
+ setNoMore(false)
+ setPage(1)
+ onLoad(1).then(res => {
+ if (res.data.length < 10) {
+ setNoMore(true)
+ }
+ setNotifications(res.data)
+ })
+ }, [filter])
+
+ function fetchMoreListItems() {
+ if (page === 1 && notifications.length === 0) {
+ // 走到这里面说明视图逻辑出问题了,你可以这样触发
+ // 进入tag或者个人页面,然后把文章拉到第二页
+ // 此时点击tag,会瞬间同时加载第一页和第二页的文章
+ // 因为第一页的文章还没加载完毕,没有更新posts,第二页的文章就会覆盖掉第一页的数据
+ // 这样第一页的数据就丢失了
+
+ // 走到该函数意味着已经是第二页的加载逻辑了,在此时posts不应该为空
+ //@ts-ignore
+ setIsFetching(false)
+ return
+ }
+ if (noMore) {
+ //@ts-ignore
+ setIsFetching(false)
+ return
+ }
+ setPage(page + 1)
+ onLoad(page + 1).then(res => {
+ if (res.data.length < 5) {
+ setNoMore(true)
+ }
+ setNotifications(concat(notifications, ...res.data))
+ }
+ )
+ //@ts-ignore
+ setIsFetching(false)
+ }
+
+
+ return (
+ <>
+ {notifications.length !== 0
+ ?
+ <>
+ }>
+ {notifications.map((p,i) =>
+
+
+
+
+ {getUserName(p.user)}
+ {p.title}
+
+ {p.subTitle && {p.subTitle}}
+ {moment(p.created).fromNow()} {!p.read&& unread}
+
+ )}
+
+ {noMore && 没有更多消息了}
+ >
+ :
+
+ }
+ >
+ )
+}
+
+export default Notifications