🚀 feat(pagination): unify backend-driven pagination & improve channel tag aggregation
SUMMARY • Migrated Token, Task, Midjourney, Channel, Redemption tables to true server-side pagination. • Added total / page / page_size metadata in API responses; switched all affected React tables to consume new structure. • Implemented counting helpers: – model/token.go CountUserTokens – model/task.go TaskCountAllTasks / TaskCountAllUserTask – model/midjourney.go CountAllTasks / CountAllUserTask – model/channel.go CountAllChannels / CountAllTags • Refactored controllers (token, task, midjourney, channel) for 1-based paging & aggregated returns. • Redesigned `ChannelsTable.js`: – `loadChannels`, `syncPageData`, `enrichChannels` for tag-mode grouping without recursion. – Fixed runtime white-screen (maximum call-stack) by removing child duplication. – Pagination, search, tag-mode, idSort all hot-reload correctly. • Removed unused `log` import in controller/midjourney.go. BREAKING CHANGES Front-end consumers must now expect data.items / total / page / page_size from list endpoints (`/api/channel`, `/api/task`, `/api/mj`, `/api/token`, etc.).
This commit is contained in:
@@ -43,22 +43,23 @@ type OpenAIModelsResponse struct {
|
|||||||
func GetAllChannels(c *gin.Context) {
|
func GetAllChannels(c *gin.Context) {
|
||||||
p, _ := strconv.Atoi(c.Query("p"))
|
p, _ := strconv.Atoi(c.Query("p"))
|
||||||
pageSize, _ := strconv.Atoi(c.Query("page_size"))
|
pageSize, _ := strconv.Atoi(c.Query("page_size"))
|
||||||
if p < 0 {
|
if p < 1 {
|
||||||
p = 0
|
p = 1
|
||||||
}
|
}
|
||||||
if pageSize < 0 {
|
if pageSize < 1 {
|
||||||
pageSize = common.ItemsPerPage
|
pageSize = common.ItemsPerPage
|
||||||
}
|
}
|
||||||
channelData := make([]*model.Channel, 0)
|
channelData := make([]*model.Channel, 0)
|
||||||
idSort, _ := strconv.ParseBool(c.Query("id_sort"))
|
idSort, _ := strconv.ParseBool(c.Query("id_sort"))
|
||||||
enableTagMode, _ := strconv.ParseBool(c.Query("tag_mode"))
|
enableTagMode, _ := strconv.ParseBool(c.Query("tag_mode"))
|
||||||
|
|
||||||
|
var total int64
|
||||||
|
|
||||||
if enableTagMode {
|
if enableTagMode {
|
||||||
tags, err := model.GetPaginatedTags(p*pageSize, pageSize)
|
// tag 分页:先分页 tag,再取各 tag 下 channels
|
||||||
|
tags, err := model.GetPaginatedTags((p-1)*pageSize, pageSize)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
c.JSON(http.StatusOK, gin.H{"success": false, "message": err.Error()})
|
||||||
"success": false,
|
|
||||||
"message": err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for _, tag := range tags {
|
for _, tag := range tags {
|
||||||
@@ -69,21 +70,27 @@ func GetAllChannels(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 计算 tag 总数用于分页
|
||||||
|
total, _ = model.CountAllTags()
|
||||||
} else {
|
} else {
|
||||||
channels, err := model.GetAllChannels(p*pageSize, pageSize, false, idSort)
|
channels, err := model.GetAllChannels((p-1)*pageSize, pageSize, false, idSort)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
c.JSON(http.StatusOK, gin.H{"success": false, "message": err.Error()})
|
||||||
"success": false,
|
|
||||||
"message": err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
channelData = channels
|
channelData = channels
|
||||||
|
total, _ = model.CountAllChannels()
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusOK, gin.H{
|
c.JSON(http.StatusOK, gin.H{
|
||||||
"success": true,
|
"success": true,
|
||||||
"message": "",
|
"message": "",
|
||||||
"data": channelData,
|
"data": gin.H{
|
||||||
|
"items": channelData,
|
||||||
|
"total": total,
|
||||||
|
"page": p,
|
||||||
|
"page_size": pageSize,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"one-api/common"
|
"one-api/common"
|
||||||
"one-api/dto"
|
"one-api/dto"
|
||||||
@@ -215,8 +214,12 @@ func checkMjTaskNeedUpdate(oldTask *model.Midjourney, newTask dto.MidjourneyDto)
|
|||||||
|
|
||||||
func GetAllMidjourney(c *gin.Context) {
|
func GetAllMidjourney(c *gin.Context) {
|
||||||
p, _ := strconv.Atoi(c.Query("p"))
|
p, _ := strconv.Atoi(c.Query("p"))
|
||||||
if p < 0 {
|
if p < 1 {
|
||||||
p = 0
|
p = 1
|
||||||
|
}
|
||||||
|
pageSize, _ := strconv.Atoi(c.Query("page_size"))
|
||||||
|
if pageSize <= 0 {
|
||||||
|
pageSize = common.ItemsPerPage
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析其他查询参数
|
// 解析其他查询参数
|
||||||
@@ -227,31 +230,38 @@ func GetAllMidjourney(c *gin.Context) {
|
|||||||
EndTimestamp: c.Query("end_timestamp"),
|
EndTimestamp: c.Query("end_timestamp"),
|
||||||
}
|
}
|
||||||
|
|
||||||
logs := model.GetAllTasks(p*common.ItemsPerPage, common.ItemsPerPage, queryParams)
|
items := model.GetAllTasks((p-1)*pageSize, pageSize, queryParams)
|
||||||
if logs == nil {
|
total := model.CountAllTasks(queryParams)
|
||||||
logs = make([]*model.Midjourney, 0)
|
|
||||||
}
|
|
||||||
if setting.MjForwardUrlEnabled {
|
if setting.MjForwardUrlEnabled {
|
||||||
for i, midjourney := range logs {
|
for i, midjourney := range items {
|
||||||
midjourney.ImageUrl = setting.ServerAddress + "/mj/image/" + midjourney.MjId
|
midjourney.ImageUrl = setting.ServerAddress + "/mj/image/" + midjourney.MjId
|
||||||
logs[i] = midjourney
|
items[i] = midjourney
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.JSON(200, gin.H{
|
c.JSON(200, gin.H{
|
||||||
"success": true,
|
"success": true,
|
||||||
"message": "",
|
"message": "",
|
||||||
"data": logs,
|
"data": gin.H{
|
||||||
|
"items": items,
|
||||||
|
"total": total,
|
||||||
|
"page": p,
|
||||||
|
"page_size": pageSize,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetUserMidjourney(c *gin.Context) {
|
func GetUserMidjourney(c *gin.Context) {
|
||||||
p, _ := strconv.Atoi(c.Query("p"))
|
p, _ := strconv.Atoi(c.Query("p"))
|
||||||
if p < 0 {
|
if p < 1 {
|
||||||
p = 0
|
p = 1
|
||||||
|
}
|
||||||
|
pageSize, _ := strconv.Atoi(c.Query("page_size"))
|
||||||
|
if pageSize <= 0 {
|
||||||
|
pageSize = common.ItemsPerPage
|
||||||
}
|
}
|
||||||
|
|
||||||
userId := c.GetInt("id")
|
userId := c.GetInt("id")
|
||||||
log.Printf("userId = %d \n", userId)
|
|
||||||
|
|
||||||
queryParams := model.TaskQueryParams{
|
queryParams := model.TaskQueryParams{
|
||||||
MjID: c.Query("mj_id"),
|
MjID: c.Query("mj_id"),
|
||||||
@@ -259,19 +269,23 @@ func GetUserMidjourney(c *gin.Context) {
|
|||||||
EndTimestamp: c.Query("end_timestamp"),
|
EndTimestamp: c.Query("end_timestamp"),
|
||||||
}
|
}
|
||||||
|
|
||||||
logs := model.GetAllUserTask(userId, p*common.ItemsPerPage, common.ItemsPerPage, queryParams)
|
items := model.GetAllUserTask(userId, (p-1)*pageSize, pageSize, queryParams)
|
||||||
if logs == nil {
|
total := model.CountAllUserTask(userId, queryParams)
|
||||||
logs = make([]*model.Midjourney, 0)
|
|
||||||
}
|
|
||||||
if setting.MjForwardUrlEnabled {
|
if setting.MjForwardUrlEnabled {
|
||||||
for i, midjourney := range logs {
|
for i, midjourney := range items {
|
||||||
midjourney.ImageUrl = setting.ServerAddress + "/mj/image/" + midjourney.MjId
|
midjourney.ImageUrl = setting.ServerAddress + "/mj/image/" + midjourney.MjId
|
||||||
logs[i] = midjourney
|
items[i] = midjourney
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.JSON(200, gin.H{
|
c.JSON(200, gin.H{
|
||||||
"success": true,
|
"success": true,
|
||||||
"message": "",
|
"message": "",
|
||||||
"data": logs,
|
"data": gin.H{
|
||||||
|
"items": items,
|
||||||
|
"total": total,
|
||||||
|
"page": p,
|
||||||
|
"page_size": pageSize,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -224,9 +224,14 @@ func checkTaskNeedUpdate(oldTask *model.Task, newTask dto.SunoDataResponse) bool
|
|||||||
|
|
||||||
func GetAllTask(c *gin.Context) {
|
func GetAllTask(c *gin.Context) {
|
||||||
p, _ := strconv.Atoi(c.Query("p"))
|
p, _ := strconv.Atoi(c.Query("p"))
|
||||||
if p < 0 {
|
if p < 1 {
|
||||||
p = 0
|
p = 1
|
||||||
}
|
}
|
||||||
|
pageSize, _ := strconv.Atoi(c.Query("page_size"))
|
||||||
|
if pageSize <= 0 {
|
||||||
|
pageSize = common.ItemsPerPage
|
||||||
|
}
|
||||||
|
|
||||||
startTimestamp, _ := strconv.ParseInt(c.Query("start_timestamp"), 10, 64)
|
startTimestamp, _ := strconv.ParseInt(c.Query("start_timestamp"), 10, 64)
|
||||||
endTimestamp, _ := strconv.ParseInt(c.Query("end_timestamp"), 10, 64)
|
endTimestamp, _ := strconv.ParseInt(c.Query("end_timestamp"), 10, 64)
|
||||||
// 解析其他查询参数
|
// 解析其他查询参数
|
||||||
@@ -237,24 +242,32 @@ func GetAllTask(c *gin.Context) {
|
|||||||
Action: c.Query("action"),
|
Action: c.Query("action"),
|
||||||
StartTimestamp: startTimestamp,
|
StartTimestamp: startTimestamp,
|
||||||
EndTimestamp: endTimestamp,
|
EndTimestamp: endTimestamp,
|
||||||
|
ChannelID: c.Query("channel_id"),
|
||||||
}
|
}
|
||||||
|
|
||||||
logs := model.TaskGetAllTasks(p*common.ItemsPerPage, common.ItemsPerPage, queryParams)
|
items := model.TaskGetAllTasks((p-1)*pageSize, pageSize, queryParams)
|
||||||
if logs == nil {
|
total := model.TaskCountAllTasks(queryParams)
|
||||||
logs = make([]*model.Task, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
c.JSON(200, gin.H{
|
c.JSON(200, gin.H{
|
||||||
"success": true,
|
"success": true,
|
||||||
"message": "",
|
"message": "",
|
||||||
"data": logs,
|
"data": gin.H{
|
||||||
|
"items": items,
|
||||||
|
"total": total,
|
||||||
|
"page": p,
|
||||||
|
"page_size": pageSize,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetUserTask(c *gin.Context) {
|
func GetUserTask(c *gin.Context) {
|
||||||
p, _ := strconv.Atoi(c.Query("p"))
|
p, _ := strconv.Atoi(c.Query("p"))
|
||||||
if p < 0 {
|
if p < 1 {
|
||||||
p = 0
|
p = 1
|
||||||
|
}
|
||||||
|
pageSize, _ := strconv.Atoi(c.Query("page_size"))
|
||||||
|
if pageSize <= 0 {
|
||||||
|
pageSize = common.ItemsPerPage
|
||||||
}
|
}
|
||||||
|
|
||||||
userId := c.GetInt("id")
|
userId := c.GetInt("id")
|
||||||
@@ -271,14 +284,17 @@ func GetUserTask(c *gin.Context) {
|
|||||||
EndTimestamp: endTimestamp,
|
EndTimestamp: endTimestamp,
|
||||||
}
|
}
|
||||||
|
|
||||||
logs := model.TaskGetAllUserTask(userId, p*common.ItemsPerPage, common.ItemsPerPage, queryParams)
|
items := model.TaskGetAllUserTask(userId, (p-1)*pageSize, pageSize, queryParams)
|
||||||
if logs == nil {
|
total := model.TaskCountAllUserTask(userId, queryParams)
|
||||||
logs = make([]*model.Task, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
c.JSON(200, gin.H{
|
c.JSON(200, gin.H{
|
||||||
"success": true,
|
"success": true,
|
||||||
"message": "",
|
"message": "",
|
||||||
"data": logs,
|
"data": gin.H{
|
||||||
|
"items": items,
|
||||||
|
"total": total,
|
||||||
|
"page": p,
|
||||||
|
"page_size": pageSize,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,15 +12,15 @@ func GetAllTokens(c *gin.Context) {
|
|||||||
userId := c.GetInt("id")
|
userId := c.GetInt("id")
|
||||||
p, _ := strconv.Atoi(c.Query("p"))
|
p, _ := strconv.Atoi(c.Query("p"))
|
||||||
size, _ := strconv.Atoi(c.Query("size"))
|
size, _ := strconv.Atoi(c.Query("size"))
|
||||||
if p < 0 {
|
if p < 1 {
|
||||||
p = 0
|
p = 1
|
||||||
}
|
}
|
||||||
if size <= 0 {
|
if size <= 0 {
|
||||||
size = common.ItemsPerPage
|
size = common.ItemsPerPage
|
||||||
} else if size > 100 {
|
} else if size > 100 {
|
||||||
size = 100
|
size = 100
|
||||||
}
|
}
|
||||||
tokens, err := model.GetAllUserTokens(userId, p*size, size)
|
tokens, err := model.GetAllUserTokens(userId, (p-1)*size, size)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
c.JSON(http.StatusOK, gin.H{
|
||||||
"success": false,
|
"success": false,
|
||||||
@@ -28,10 +28,18 @@ func GetAllTokens(c *gin.Context) {
|
|||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// Get total count for pagination
|
||||||
|
total, _ := model.CountUserTokens(userId)
|
||||||
|
|
||||||
c.JSON(http.StatusOK, gin.H{
|
c.JSON(http.StatusOK, gin.H{
|
||||||
"success": true,
|
"success": true,
|
||||||
"message": "",
|
"message": "",
|
||||||
"data": tokens,
|
"data": gin.H{
|
||||||
|
"items": tokens,
|
||||||
|
"total": total,
|
||||||
|
"page": p,
|
||||||
|
"page_size": size,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -583,3 +583,17 @@ func BatchSetChannelTag(ids []int, tag *string) error {
|
|||||||
// 提交事务
|
// 提交事务
|
||||||
return tx.Commit().Error
|
return tx.Commit().Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CountAllChannels returns total channels in DB
|
||||||
|
func CountAllChannels() (int64, error) {
|
||||||
|
var total int64
|
||||||
|
err := DB.Model(&Channel{}).Count(&total).Error
|
||||||
|
return total, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CountAllTags returns number of non-empty distinct tags
|
||||||
|
func CountAllTags() (int64, error) {
|
||||||
|
var total int64
|
||||||
|
err := DB.Model(&Channel{}).Where("tag is not null AND tag != ''").Distinct("tag").Count(&total).Error
|
||||||
|
return total, err
|
||||||
|
}
|
||||||
|
|||||||
@@ -166,3 +166,40 @@ func MjBulkUpdateByTaskIds(taskIDs []int, params map[string]any) error {
|
|||||||
Where("id in (?)", taskIDs).
|
Where("id in (?)", taskIDs).
|
||||||
Updates(params).Error
|
Updates(params).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CountAllTasks returns total midjourney tasks for admin query
|
||||||
|
func CountAllTasks(queryParams TaskQueryParams) int64 {
|
||||||
|
var total int64
|
||||||
|
query := DB.Model(&Midjourney{})
|
||||||
|
if queryParams.ChannelID != "" {
|
||||||
|
query = query.Where("channel_id = ?", queryParams.ChannelID)
|
||||||
|
}
|
||||||
|
if queryParams.MjID != "" {
|
||||||
|
query = query.Where("mj_id = ?", queryParams.MjID)
|
||||||
|
}
|
||||||
|
if queryParams.StartTimestamp != "" {
|
||||||
|
query = query.Where("submit_time >= ?", queryParams.StartTimestamp)
|
||||||
|
}
|
||||||
|
if queryParams.EndTimestamp != "" {
|
||||||
|
query = query.Where("submit_time <= ?", queryParams.EndTimestamp)
|
||||||
|
}
|
||||||
|
_ = query.Count(&total).Error
|
||||||
|
return total
|
||||||
|
}
|
||||||
|
|
||||||
|
// CountAllUserTask returns total midjourney tasks for user
|
||||||
|
func CountAllUserTask(userId int, queryParams TaskQueryParams) int64 {
|
||||||
|
var total int64
|
||||||
|
query := DB.Model(&Midjourney{}).Where("user_id = ?", userId)
|
||||||
|
if queryParams.MjID != "" {
|
||||||
|
query = query.Where("mj_id = ?", queryParams.MjID)
|
||||||
|
}
|
||||||
|
if queryParams.StartTimestamp != "" {
|
||||||
|
query = query.Where("submit_time >= ?", queryParams.StartTimestamp)
|
||||||
|
}
|
||||||
|
if queryParams.EndTimestamp != "" {
|
||||||
|
query = query.Where("submit_time <= ?", queryParams.EndTimestamp)
|
||||||
|
}
|
||||||
|
_ = query.Count(&total).Error
|
||||||
|
return total
|
||||||
|
}
|
||||||
|
|||||||
@@ -302,3 +302,64 @@ func SumUsedTaskQuota(queryParams SyncTaskQueryParams) (stat []TaskQuotaUsage, e
|
|||||||
err = query.Select("mode, sum(quota) as count").Group("mode").Find(&stat).Error
|
err = query.Select("mode, sum(quota) as count").Group("mode").Find(&stat).Error
|
||||||
return stat, err
|
return stat, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TaskCountAllTasks returns total tasks that match the given query params (admin usage)
|
||||||
|
func TaskCountAllTasks(queryParams SyncTaskQueryParams) int64 {
|
||||||
|
var total int64
|
||||||
|
query := DB.Model(&Task{})
|
||||||
|
if queryParams.ChannelID != "" {
|
||||||
|
query = query.Where("channel_id = ?", queryParams.ChannelID)
|
||||||
|
}
|
||||||
|
if queryParams.Platform != "" {
|
||||||
|
query = query.Where("platform = ?", queryParams.Platform)
|
||||||
|
}
|
||||||
|
if queryParams.UserID != "" {
|
||||||
|
query = query.Where("user_id = ?", queryParams.UserID)
|
||||||
|
}
|
||||||
|
if len(queryParams.UserIDs) != 0 {
|
||||||
|
query = query.Where("user_id in (?)", queryParams.UserIDs)
|
||||||
|
}
|
||||||
|
if queryParams.TaskID != "" {
|
||||||
|
query = query.Where("task_id = ?", queryParams.TaskID)
|
||||||
|
}
|
||||||
|
if queryParams.Action != "" {
|
||||||
|
query = query.Where("action = ?", queryParams.Action)
|
||||||
|
}
|
||||||
|
if queryParams.Status != "" {
|
||||||
|
query = query.Where("status = ?", queryParams.Status)
|
||||||
|
}
|
||||||
|
if queryParams.StartTimestamp != 0 {
|
||||||
|
query = query.Where("submit_time >= ?", queryParams.StartTimestamp)
|
||||||
|
}
|
||||||
|
if queryParams.EndTimestamp != 0 {
|
||||||
|
query = query.Where("submit_time <= ?", queryParams.EndTimestamp)
|
||||||
|
}
|
||||||
|
_ = query.Count(&total).Error
|
||||||
|
return total
|
||||||
|
}
|
||||||
|
|
||||||
|
// TaskCountAllUserTask returns total tasks for given user
|
||||||
|
func TaskCountAllUserTask(userId int, queryParams SyncTaskQueryParams) int64 {
|
||||||
|
var total int64
|
||||||
|
query := DB.Model(&Task{}).Where("user_id = ?", userId)
|
||||||
|
if queryParams.TaskID != "" {
|
||||||
|
query = query.Where("task_id = ?", queryParams.TaskID)
|
||||||
|
}
|
||||||
|
if queryParams.Action != "" {
|
||||||
|
query = query.Where("action = ?", queryParams.Action)
|
||||||
|
}
|
||||||
|
if queryParams.Status != "" {
|
||||||
|
query = query.Where("status = ?", queryParams.Status)
|
||||||
|
}
|
||||||
|
if queryParams.Platform != "" {
|
||||||
|
query = query.Where("platform = ?", queryParams.Platform)
|
||||||
|
}
|
||||||
|
if queryParams.StartTimestamp != 0 {
|
||||||
|
query = query.Where("submit_time >= ?", queryParams.StartTimestamp)
|
||||||
|
}
|
||||||
|
if queryParams.EndTimestamp != 0 {
|
||||||
|
query = query.Where("submit_time <= ?", queryParams.EndTimestamp)
|
||||||
|
}
|
||||||
|
_ = query.Count(&total).Error
|
||||||
|
return total
|
||||||
|
}
|
||||||
|
|||||||
@@ -320,3 +320,10 @@ func decreaseTokenQuota(id int, quota int) (err error) {
|
|||||||
).Error
|
).Error
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CountUserTokens returns total number of tokens for the given user, used for pagination
|
||||||
|
func CountUserTokens(userId int) (int64, error) {
|
||||||
|
var total int64
|
||||||
|
err := DB.Model(&Token{}).Where("user_id = ?", userId).Count(&total).Error
|
||||||
|
return total, err
|
||||||
|
}
|
||||||
|
|||||||
@@ -865,32 +865,22 @@ const ChannelsTable = () => {
|
|||||||
tagChannelDates.response_time = tagChannelDates.response_time / 2;
|
tagChannelDates.response_time = tagChannelDates.response_time / 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// data.key = '' + data.id
|
|
||||||
setChannels(channelDates);
|
setChannels(channelDates);
|
||||||
if (channelDates.length >= pageSize) {
|
|
||||||
setChannelCount(channelDates.length + pageSize);
|
|
||||||
} else {
|
|
||||||
setChannelCount(channelDates.length);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadChannels = async (startIdx, pageSize, idSort, enableTagMode) => {
|
const loadChannels = async (page, pageSize, idSort, enableTagMode) => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const res = await API.get(
|
const res = await API.get(
|
||||||
`/api/channel/?p=${startIdx}&page_size=${pageSize}&id_sort=${idSort}&tag_mode=${enableTagMode}`,
|
`/api/channel/?p=${page}&page_size=${pageSize}&id_sort=${idSort}&tag_mode=${enableTagMode}`,
|
||||||
);
|
);
|
||||||
if (res === undefined) {
|
if (res === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const { success, message, data } = res.data;
|
const { success, message, data } = res.data;
|
||||||
if (success) {
|
if (success) {
|
||||||
if (startIdx === 0) {
|
const { items, total } = data;
|
||||||
setChannelFormat(data, enableTagMode);
|
setChannelFormat(items, enableTagMode);
|
||||||
} else {
|
setChannelCount(total);
|
||||||
let newChannels = [...channels];
|
|
||||||
newChannels.splice(startIdx * pageSize, data.length, ...data);
|
|
||||||
setChannelFormat(newChannels, enableTagMode);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
showError(message);
|
showError(message);
|
||||||
}
|
}
|
||||||
@@ -903,7 +893,6 @@ const ChannelsTable = () => {
|
|||||||
channelToCopy.created_time = null;
|
channelToCopy.created_time = null;
|
||||||
channelToCopy.balance = 0;
|
channelToCopy.balance = 0;
|
||||||
channelToCopy.used_quota = 0;
|
channelToCopy.used_quota = 0;
|
||||||
// 删除可能导致类型不匹配的字段
|
|
||||||
delete channelToCopy.test_time;
|
delete channelToCopy.test_time;
|
||||||
delete channelToCopy.response_time;
|
delete channelToCopy.response_time;
|
||||||
if (!channelToCopy) {
|
if (!channelToCopy) {
|
||||||
@@ -927,7 +916,7 @@ const ChannelsTable = () => {
|
|||||||
const refresh = async () => {
|
const refresh = async () => {
|
||||||
const { searchKeyword, searchGroup, searchModel } = getFormValues();
|
const { searchKeyword, searchGroup, searchModel } = getFormValues();
|
||||||
if (searchKeyword === '' && searchGroup === '' && searchModel === '') {
|
if (searchKeyword === '' && searchGroup === '' && searchModel === '') {
|
||||||
await loadChannels(activePage - 1, pageSize, idSort, enableTagMode);
|
await loadChannels(activePage, pageSize, idSort, enableTagMode);
|
||||||
} else {
|
} else {
|
||||||
await searchChannels(enableTagMode);
|
await searchChannels(enableTagMode);
|
||||||
}
|
}
|
||||||
@@ -944,7 +933,7 @@ const ChannelsTable = () => {
|
|||||||
setPageSize(localPageSize);
|
setPageSize(localPageSize);
|
||||||
setEnableTagMode(localEnableTagMode);
|
setEnableTagMode(localEnableTagMode);
|
||||||
setEnableBatchDelete(localEnableBatchDelete);
|
setEnableBatchDelete(localEnableBatchDelete);
|
||||||
loadChannels(0, localPageSize, localIdSort, localEnableTagMode)
|
loadChannels(1, localPageSize, localIdSort, localEnableTagMode)
|
||||||
.then()
|
.then()
|
||||||
.catch((reason) => {
|
.catch((reason) => {
|
||||||
showError(reason);
|
showError(reason);
|
||||||
@@ -1052,7 +1041,6 @@ const ChannelsTable = () => {
|
|||||||
try {
|
try {
|
||||||
if (searchKeyword === '' && searchGroup === '' && searchModel === '') {
|
if (searchKeyword === '' && searchGroup === '' && searchModel === '') {
|
||||||
await loadChannels(activePage - 1, pageSize, idSort, enableTagMode);
|
await loadChannels(activePage - 1, pageSize, idSort, enableTagMode);
|
||||||
// setActivePage(1);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1191,24 +1179,18 @@ const ChannelsTable = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let pageData = channels.slice(
|
let pageData = channels;
|
||||||
(activePage - 1) * pageSize,
|
|
||||||
activePage * pageSize,
|
|
||||||
);
|
|
||||||
|
|
||||||
const handlePageChange = (page) => {
|
const handlePageChange = (page) => {
|
||||||
setActivePage(page);
|
setActivePage(page);
|
||||||
if (page === Math.ceil(channels.length / pageSize) + 1) {
|
loadChannels(page, pageSize, idSort, enableTagMode).then(() => { });
|
||||||
// In this case we have to load more data and then append them.
|
|
||||||
loadChannels(page - 1, pageSize, idSort, enableTagMode).then((r) => { });
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlePageSizeChange = async (size) => {
|
const handlePageSizeChange = async (size) => {
|
||||||
localStorage.setItem('page-size', size + '');
|
localStorage.setItem('page-size', size + '');
|
||||||
setPageSize(size);
|
setPageSize(size);
|
||||||
setActivePage(1);
|
setActivePage(1);
|
||||||
loadChannels(0, size, idSort, enableTagMode)
|
loadChannels(1, size, idSort, enableTagMode)
|
||||||
.then()
|
.then()
|
||||||
.catch((reason) => {
|
.catch((reason) => {
|
||||||
showError(reason);
|
showError(reason);
|
||||||
@@ -1218,8 +1200,6 @@ const ChannelsTable = () => {
|
|||||||
const fetchGroups = async () => {
|
const fetchGroups = async () => {
|
||||||
try {
|
try {
|
||||||
let res = await API.get(`/api/group/`);
|
let res = await API.get(`/api/group/`);
|
||||||
// add 'all' option
|
|
||||||
// res.data.data.unshift('all');
|
|
||||||
if (res === undefined) {
|
if (res === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1514,7 +1494,7 @@ const ChannelsTable = () => {
|
|||||||
onChange={(v) => {
|
onChange={(v) => {
|
||||||
localStorage.setItem('id-sort', v + '');
|
localStorage.setItem('id-sort', v + '');
|
||||||
setIdSort(v);
|
setIdSort(v);
|
||||||
loadChannels(0, pageSize, v, enableTagMode);
|
loadChannels(activePage, pageSize, v, enableTagMode);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -1541,7 +1521,8 @@ const ChannelsTable = () => {
|
|||||||
onChange={(v) => {
|
onChange={(v) => {
|
||||||
localStorage.setItem('enable-tag-mode', v + '');
|
localStorage.setItem('enable-tag-mode', v + '');
|
||||||
setEnableTagMode(v);
|
setEnableTagMode(v);
|
||||||
loadChannels(0, pageSize, idSort, v);
|
setActivePage(1);
|
||||||
|
loadChannels(1, pageSize, idSort, v);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -1703,7 +1684,7 @@ const ChannelsTable = () => {
|
|||||||
formatPageText: (page) => t('第 {{start}} - {{end}} 条,共 {{total}} 条', {
|
formatPageText: (page) => t('第 {{start}} - {{end}} 条,共 {{total}} 条', {
|
||||||
start: page.currentStart,
|
start: page.currentStart,
|
||||||
end: page.currentEnd,
|
end: page.currentEnd,
|
||||||
total: channels.length,
|
total: channelCount,
|
||||||
}),
|
}),
|
||||||
onPageSizeChange: (size) => {
|
onPageSizeChange: (size) => {
|
||||||
handlePageSizeChange(size);
|
handlePageSizeChange(size);
|
||||||
|
|||||||
@@ -601,7 +601,7 @@ const LogsTable = () => {
|
|||||||
const [logs, setLogs] = useState([]);
|
const [logs, setLogs] = useState([]);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [activePage, setActivePage] = useState(1);
|
const [activePage, setActivePage] = useState(1);
|
||||||
const [logCount, setLogCount] = useState(ITEMS_PER_PAGE);
|
const [logCount, setLogCount] = useState(0);
|
||||||
const [pageSize, setPageSize] = useState(ITEMS_PER_PAGE);
|
const [pageSize, setPageSize] = useState(ITEMS_PER_PAGE);
|
||||||
const [isModalOpenurl, setIsModalOpenurl] = useState(false);
|
const [isModalOpenurl, setIsModalOpenurl] = useState(false);
|
||||||
const [showBanner, setShowBanner] = useState(false);
|
const [showBanner, setShowBanner] = useState(false);
|
||||||
@@ -649,69 +649,53 @@ const LogsTable = () => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const setLogsFormat = (logs) => {
|
const enrichLogs = (items) => {
|
||||||
for (let i = 0; i < logs.length; i++) {
|
return items.map((log) => ({
|
||||||
logs[i].timestamp2string = timestamp2string(logs[i].created_at);
|
...log,
|
||||||
logs[i].key = '' + logs[i].id;
|
timestamp2string: timestamp2string(log.created_at),
|
||||||
}
|
key: '' + log.id,
|
||||||
// data.key = '' + data.id
|
}));
|
||||||
setLogs(logs);
|
|
||||||
setLogCount(logs.length + pageSize);
|
|
||||||
// console.log(logCount);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadLogs = async (startIdx, pageSize = ITEMS_PER_PAGE) => {
|
const syncPageData = (payload) => {
|
||||||
setLoading(true);
|
const items = enrichLogs(payload.items || []);
|
||||||
|
setLogs(items);
|
||||||
|
setLogCount(payload.total || 0);
|
||||||
|
setActivePage(payload.page || 1);
|
||||||
|
setPageSize(payload.page_size || pageSize);
|
||||||
|
};
|
||||||
|
|
||||||
let url = '';
|
const loadLogs = async (page = 1, size = pageSize) => {
|
||||||
|
setLoading(true);
|
||||||
const { channel_id, mj_id, start_timestamp, end_timestamp } = getFormValues();
|
const { channel_id, mj_id, start_timestamp, end_timestamp } = getFormValues();
|
||||||
let localStartTimestamp = Date.parse(start_timestamp);
|
let localStartTimestamp = Date.parse(start_timestamp);
|
||||||
let localEndTimestamp = Date.parse(end_timestamp);
|
let localEndTimestamp = Date.parse(end_timestamp);
|
||||||
if (isAdminUser) {
|
const url = isAdminUser
|
||||||
url = `/api/mj/?p=${startIdx}&page_size=${pageSize}&channel_id=${channel_id}&mj_id=${mj_id}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}`;
|
? `/api/mj/?p=${page}&page_size=${size}&channel_id=${channel_id}&mj_id=${mj_id}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}`
|
||||||
} else {
|
: `/api/mj/self/?p=${page}&page_size=${size}&mj_id=${mj_id}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}`;
|
||||||
url = `/api/mj/self/?p=${startIdx}&page_size=${pageSize}&mj_id=${mj_id}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}`;
|
|
||||||
}
|
|
||||||
const res = await API.get(url);
|
const res = await API.get(url);
|
||||||
const { success, message, data } = res.data;
|
const { success, message, data } = res.data;
|
||||||
if (success) {
|
if (success) {
|
||||||
if (startIdx === 0) {
|
syncPageData(data);
|
||||||
setLogsFormat(data);
|
|
||||||
} else {
|
|
||||||
let newLogs = [...logs];
|
|
||||||
newLogs.splice(startIdx * pageSize, data.length, ...data);
|
|
||||||
setLogsFormat(newLogs);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
showError(message);
|
showError(message);
|
||||||
}
|
}
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const pageData = logs.slice(
|
const pageData = logs;
|
||||||
(activePage - 1) * pageSize,
|
|
||||||
activePage * pageSize,
|
|
||||||
);
|
|
||||||
|
|
||||||
const handlePageChange = (page) => {
|
const handlePageChange = (page) => {
|
||||||
setActivePage(page);
|
loadLogs(page, pageSize).then();
|
||||||
if (page === Math.ceil(logs.length / pageSize) + 1) {
|
|
||||||
// In this case we have to load more data and then append them.
|
|
||||||
loadLogs(page - 1, pageSize).then((r) => { });
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlePageSizeChange = async (size) => {
|
const handlePageSizeChange = async (size) => {
|
||||||
localStorage.setItem('mj-page-size', size + '');
|
localStorage.setItem('mj-page-size', size + '');
|
||||||
setPageSize(size);
|
await loadLogs(1, size);
|
||||||
setActivePage(1);
|
|
||||||
await loadLogs(0, size);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const refresh = async () => {
|
const refresh = async () => {
|
||||||
// setLoading(true);
|
await loadLogs(1, pageSize);
|
||||||
setActivePage(1);
|
|
||||||
await loadLogs(0, pageSize);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const copyText = async (text) => {
|
const copyText = async (text) => {
|
||||||
@@ -726,7 +710,7 @@ const LogsTable = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const localPageSize = parseInt(localStorage.getItem('mj-page-size')) || ITEMS_PER_PAGE;
|
const localPageSize = parseInt(localStorage.getItem('mj-page-size')) || ITEMS_PER_PAGE;
|
||||||
setPageSize(localPageSize);
|
setPageSize(localPageSize);
|
||||||
loadLogs(0, localPageSize).then();
|
loadLogs(1, localPageSize).then();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -936,7 +920,7 @@ const LogsTable = () => {
|
|||||||
>
|
>
|
||||||
<Table
|
<Table
|
||||||
columns={getVisibleColumns()}
|
columns={getVisibleColumns()}
|
||||||
dataSource={pageData}
|
dataSource={logs}
|
||||||
rowKey='key'
|
rowKey='key'
|
||||||
loading={loading}
|
loading={loading}
|
||||||
scroll={{ x: 'max-content' }}
|
scroll={{ x: 'max-content' }}
|
||||||
@@ -962,9 +946,7 @@ const LogsTable = () => {
|
|||||||
total: logCount,
|
total: logCount,
|
||||||
pageSizeOptions: [10, 20, 50, 100],
|
pageSizeOptions: [10, 20, 50, 100],
|
||||||
showSizeChanger: true,
|
showSizeChanger: true,
|
||||||
onPageSizeChange: (size) => {
|
onPageSizeChange: handlePageSizeChange,
|
||||||
handlePageSizeChange(size);
|
|
||||||
},
|
|
||||||
onPageChange: handlePageChange,
|
onPageChange: handlePageChange,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -451,10 +451,16 @@ const LogsTable = () => {
|
|||||||
return allColumns.filter((column) => visibleColumns[column.key]);
|
return allColumns.filter((column) => visibleColumns[column.key]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const [logs, setLogs] = useState([]);
|
|
||||||
const [loading, setLoading] = useState(true);
|
|
||||||
const [activePage, setActivePage] = useState(1);
|
const [activePage, setActivePage] = useState(1);
|
||||||
const [logCount, setLogCount] = useState(ITEMS_PER_PAGE);
|
const [logCount, setLogCount] = useState(0);
|
||||||
|
const [logs, setLogs] = useState([]);
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const localPageSize = parseInt(localStorage.getItem('task-page-size')) || ITEMS_PER_PAGE;
|
||||||
|
setPageSize(localPageSize);
|
||||||
|
loadLogs(1, localPageSize).then();
|
||||||
|
}, []);
|
||||||
|
|
||||||
let now = new Date();
|
let now = new Date();
|
||||||
// 初始化start_timestamp为前一天
|
// 初始化start_timestamp为前一天
|
||||||
@@ -494,67 +500,53 @@ const LogsTable = () => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const setLogsFormat = (logs) => {
|
const enrichLogs = (items) => {
|
||||||
for (let i = 0; i < logs.length; i++) {
|
return items.map((log) => ({
|
||||||
logs[i].timestamp2string = timestamp2string(logs[i].created_at);
|
...log,
|
||||||
logs[i].key = '' + logs[i].id;
|
timestamp2string: timestamp2string(log.created_at),
|
||||||
}
|
key: '' + log.id,
|
||||||
// data.key = '' + data.id
|
}));
|
||||||
setLogs(logs);
|
|
||||||
setLogCount(logs.length + ITEMS_PER_PAGE);
|
|
||||||
// console.log(logCount);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadLogs = async (startIdx, pageSize = ITEMS_PER_PAGE) => {
|
const syncPageData = (payload) => {
|
||||||
setLoading(true);
|
const items = enrichLogs(payload.items || []);
|
||||||
|
setLogs(items);
|
||||||
|
setLogCount(payload.total || 0);
|
||||||
|
setActivePage(payload.page || 1);
|
||||||
|
setPageSize(payload.page_size || pageSize);
|
||||||
|
};
|
||||||
|
|
||||||
let url = '';
|
const loadLogs = async (page = 1, size = pageSize) => {
|
||||||
|
setLoading(true);
|
||||||
const { channel_id, task_id, start_timestamp, end_timestamp } = getFormValues();
|
const { channel_id, task_id, start_timestamp, end_timestamp } = getFormValues();
|
||||||
let localStartTimestamp = parseInt(Date.parse(start_timestamp) / 1000);
|
let localStartTimestamp = parseInt(Date.parse(start_timestamp) / 1000);
|
||||||
let localEndTimestamp = parseInt(Date.parse(end_timestamp) / 1000);
|
let localEndTimestamp = parseInt(Date.parse(end_timestamp) / 1000);
|
||||||
if (isAdminUser) {
|
let url = isAdminUser
|
||||||
url = `/api/task/?p=${startIdx}&page_size=${pageSize}&channel_id=${channel_id}&task_id=${task_id}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}`;
|
? `/api/task/?p=${page}&page_size=${size}&channel_id=${channel_id}&task_id=${task_id}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}`
|
||||||
} else {
|
: `/api/task/self?p=${page}&page_size=${size}&task_id=${task_id}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}`;
|
||||||
url = `/api/task/self?p=${startIdx}&page_size=${pageSize}&task_id=${task_id}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}`;
|
|
||||||
}
|
|
||||||
const res = await API.get(url);
|
const res = await API.get(url);
|
||||||
let { success, message, data } = res.data;
|
const { success, message, data } = res.data;
|
||||||
if (success) {
|
if (success) {
|
||||||
if (startIdx === 0) {
|
syncPageData(data);
|
||||||
setLogsFormat(data);
|
|
||||||
} else {
|
|
||||||
let newLogs = [...logs];
|
|
||||||
newLogs.splice(startIdx * pageSize, data.length, ...data);
|
|
||||||
setLogsFormat(newLogs);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
showError(message);
|
showError(message);
|
||||||
}
|
}
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const pageData = logs.slice(
|
const pageData = logs;
|
||||||
(activePage - 1) * pageSize,
|
|
||||||
activePage * pageSize,
|
|
||||||
);
|
|
||||||
|
|
||||||
const handlePageChange = (page) => {
|
const handlePageChange = (page) => {
|
||||||
setActivePage(page);
|
loadLogs(page, pageSize).then();
|
||||||
if (page === Math.ceil(logs.length / pageSize) + 1) {
|
|
||||||
loadLogs(page - 1, pageSize).then((r) => { });
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlePageSizeChange = async (size) => {
|
const handlePageSizeChange = async (size) => {
|
||||||
localStorage.setItem('task-page-size', size + '');
|
localStorage.setItem('task-page-size', size + '');
|
||||||
setPageSize(size);
|
await loadLogs(1, size);
|
||||||
setActivePage(1);
|
|
||||||
await loadLogs(0, size);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const refresh = async () => {
|
const refresh = async () => {
|
||||||
setActivePage(1);
|
await loadLogs(1, pageSize);
|
||||||
await loadLogs(0, pageSize);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const copyText = async (text) => {
|
const copyText = async (text) => {
|
||||||
@@ -565,12 +557,6 @@ const LogsTable = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const localPageSize = parseInt(localStorage.getItem('task-page-size')) || ITEMS_PER_PAGE;
|
|
||||||
setPageSize(localPageSize);
|
|
||||||
loadLogs(0, localPageSize).then();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
// 列选择器模态框
|
// 列选择器模态框
|
||||||
const renderColumnSelector = () => {
|
const renderColumnSelector = () => {
|
||||||
return (
|
return (
|
||||||
@@ -763,7 +749,7 @@ const LogsTable = () => {
|
|||||||
>
|
>
|
||||||
<Table
|
<Table
|
||||||
columns={getVisibleColumns()}
|
columns={getVisibleColumns()}
|
||||||
dataSource={pageData}
|
dataSource={logs}
|
||||||
rowKey='key'
|
rowKey='key'
|
||||||
loading={loading}
|
loading={loading}
|
||||||
scroll={{ x: 'max-content' }}
|
scroll={{ x: 'max-content' }}
|
||||||
@@ -789,9 +775,7 @@ const LogsTable = () => {
|
|||||||
total: logCount,
|
total: logCount,
|
||||||
pageSizeOptions: [10, 20, 50, 100],
|
pageSizeOptions: [10, 20, 50, 100],
|
||||||
showSizeChanger: true,
|
showSizeChanger: true,
|
||||||
onPageSizeChange: (size) => {
|
onPageSizeChange: handlePageSizeChange,
|
||||||
handlePageSizeChange(size);
|
|
||||||
},
|
|
||||||
onPageChange: handlePageChange,
|
onPageChange: handlePageChange,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -408,31 +408,20 @@ const TokensTable = () => {
|
|||||||
}, 500);
|
}, 500);
|
||||||
};
|
};
|
||||||
|
|
||||||
const setTokensFormat = (tokens) => {
|
// 将后端返回的数据写入状态
|
||||||
setTokens(tokens);
|
const syncPageData = (payload) => {
|
||||||
if (tokens.length >= pageSize) {
|
setTokens(payload.items || []);
|
||||||
setTokenCount(tokens.length + pageSize);
|
setTokenCount(payload.total || 0);
|
||||||
} else {
|
setActivePage(payload.page || 1);
|
||||||
setTokenCount(tokens.length);
|
setPageSize(payload.page_size || pageSize);
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let pageData = tokens.slice(
|
const loadTokens = async (page = 1, size = pageSize) => {
|
||||||
(activePage - 1) * pageSize,
|
|
||||||
activePage * pageSize,
|
|
||||||
);
|
|
||||||
const loadTokens = async (startIdx) => {
|
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const res = await API.get(`/api/token/?p=${startIdx}&size=${pageSize}`);
|
const res = await API.get(`/api/token/?p=${page}&size=${size}`);
|
||||||
const { success, message, data } = res.data;
|
const { success, message, data } = res.data;
|
||||||
if (success) {
|
if (success) {
|
||||||
if (startIdx === 0) {
|
syncPageData(data);
|
||||||
setTokensFormat(data);
|
|
||||||
} else {
|
|
||||||
let newTokens = [...tokens];
|
|
||||||
newTokens.splice(startIdx * pageSize, data.length, ...data);
|
|
||||||
setTokensFormat(newTokens);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
showError(message);
|
showError(message);
|
||||||
}
|
}
|
||||||
@@ -440,7 +429,7 @@ const TokensTable = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const refresh = async () => {
|
const refresh = async () => {
|
||||||
await loadTokens(activePage - 1);
|
await loadTokens(1);
|
||||||
};
|
};
|
||||||
|
|
||||||
const copyText = async (text) => {
|
const copyText = async (text) => {
|
||||||
@@ -473,7 +462,7 @@ const TokensTable = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
loadTokens(0)
|
loadTokens(1)
|
||||||
.then()
|
.then()
|
||||||
.catch((reason) => {
|
.catch((reason) => {
|
||||||
showError(reason);
|
showError(reason);
|
||||||
@@ -487,7 +476,7 @@ const TokensTable = () => {
|
|||||||
|
|
||||||
if (idx > -1) {
|
if (idx > -1) {
|
||||||
newDataSource.splice(idx, 1);
|
newDataSource.splice(idx, 1);
|
||||||
setTokensFormat(newDataSource);
|
setTokens(newDataSource);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -518,7 +507,7 @@ const TokensTable = () => {
|
|||||||
} else {
|
} else {
|
||||||
record.status = token.status;
|
record.status = token.status;
|
||||||
}
|
}
|
||||||
setTokensFormat(newTokens);
|
setTokens(newTokens);
|
||||||
} else {
|
} else {
|
||||||
showError(message);
|
showError(message);
|
||||||
}
|
}
|
||||||
@@ -528,8 +517,7 @@ const TokensTable = () => {
|
|||||||
const searchTokens = async () => {
|
const searchTokens = async () => {
|
||||||
const { searchKeyword, searchToken } = getFormValues();
|
const { searchKeyword, searchToken } = getFormValues();
|
||||||
if (searchKeyword === '' && searchToken === '') {
|
if (searchKeyword === '' && searchToken === '') {
|
||||||
await loadTokens(0);
|
await loadTokens(1);
|
||||||
setActivePage(1);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setSearching(true);
|
setSearching(true);
|
||||||
@@ -538,7 +526,8 @@ const TokensTable = () => {
|
|||||||
);
|
);
|
||||||
const { success, message, data } = res.data;
|
const { success, message, data } = res.data;
|
||||||
if (success) {
|
if (success) {
|
||||||
setTokensFormat(data);
|
setTokens(data);
|
||||||
|
setTokenCount(data.length);
|
||||||
setActivePage(1);
|
setActivePage(1);
|
||||||
} else {
|
} else {
|
||||||
showError(message);
|
showError(message);
|
||||||
@@ -561,10 +550,12 @@ const TokensTable = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handlePageChange = (page) => {
|
const handlePageChange = (page) => {
|
||||||
setActivePage(page);
|
loadTokens(page, pageSize).then();
|
||||||
if (page === Math.ceil(tokens.length / pageSize) + 1) {
|
};
|
||||||
loadTokens(page - 1).then((r) => { });
|
|
||||||
}
|
const handlePageSizeChange = async (size) => {
|
||||||
|
setPageSize(size);
|
||||||
|
await loadTokens(1, size);
|
||||||
};
|
};
|
||||||
|
|
||||||
const rowSelection = {
|
const rowSelection = {
|
||||||
@@ -707,7 +698,7 @@ const TokensTable = () => {
|
|||||||
>
|
>
|
||||||
<Table
|
<Table
|
||||||
columns={columns}
|
columns={columns}
|
||||||
dataSource={pageData}
|
dataSource={tokens}
|
||||||
scroll={{ x: 'max-content' }}
|
scroll={{ x: 'max-content' }}
|
||||||
pagination={{
|
pagination={{
|
||||||
currentPage: activePage,
|
currentPage: activePage,
|
||||||
@@ -719,12 +710,9 @@ const TokensTable = () => {
|
|||||||
t('第 {{start}} - {{end}} 条,共 {{total}} 条', {
|
t('第 {{start}} - {{end}} 条,共 {{total}} 条', {
|
||||||
start: page.currentStart,
|
start: page.currentStart,
|
||||||
end: page.currentEnd,
|
end: page.currentEnd,
|
||||||
total: tokens.length,
|
total: tokenCount,
|
||||||
}),
|
}),
|
||||||
onPageSizeChange: (size) => {
|
onPageSizeChange: handlePageSizeChange,
|
||||||
setPageSize(size);
|
|
||||||
setActivePage(1);
|
|
||||||
},
|
|
||||||
onPageChange: handlePageChange,
|
onPageChange: handlePageChange,
|
||||||
}}
|
}}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
|
|||||||
Reference in New Issue
Block a user