mirror of https://github.com/cloudreve/Cloudreve
Fix: get site summary in dashboard
parent
22cec36751
commit
49f784104e
|
@ -310,3 +310,17 @@ func COSCallbackAuth() gin.HandlerFunc {
|
||||||
c.Next()
|
c.Next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsAdmin 必须为管理员用户组
|
||||||
|
func IsAdmin() gin.HandlerFunc {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
user, _ := c.Get("user")
|
||||||
|
if user.(*model.User).Group.ID != 1 {
|
||||||
|
c.JSON(200, serializer.Err(serializer.CodeAdminRequired, "您不是管理组成员", nil))
|
||||||
|
c.Abort()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -200,6 +200,8 @@ func addDefaultGroups() {
|
||||||
ArchiveDownload: true,
|
ArchiveDownload: true,
|
||||||
ArchiveTask: true,
|
ArchiveTask: true,
|
||||||
ShareDownload: true,
|
ShareDownload: true,
|
||||||
|
ShareFree: true,
|
||||||
|
Aria2: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if err := DB.Create(&defaultAdminGroup).Error; err != nil {
|
if err := DB.Create(&defaultAdminGroup).Error; err != nil {
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
package rpc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestWebsocketCaller(t *testing.T) {
|
|
||||||
time.Sleep(time.Second)
|
|
||||||
c, err := newWebsocketCaller(context.Background(), "ws://localhost:6800/jsonrpc", time.Second, &DummyNotifier{})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err.Error())
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
var info VersionInfo
|
|
||||||
if err := c.Call(aria2GetVersion, []interface{}{}, &info); err != nil {
|
|
||||||
t.Error(err.Error())
|
|
||||||
} else {
|
|
||||||
println(info.Version)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,125 +0,0 @@
|
||||||
package rpc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestHTTPAll(t *testing.T) {
|
|
||||||
const targetURL = "https://nodejs.org/dist/index.json"
|
|
||||||
rpc, err := New(context.Background(), "http://localhost:6800/jsonrpc", "", time.Second, &DummyNotifier{})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer rpc.Close()
|
|
||||||
g, err := rpc.AddURI(targetURL)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
println(g)
|
|
||||||
if _, err = rpc.TellActive(); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
if _, err = rpc.PauseAll(); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
if _, err = rpc.TellStatus(g); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
if _, err = rpc.GetURIs(g); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
if _, err = rpc.GetFiles(g); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
if _, err = rpc.GetPeers(g); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
if _, err = rpc.TellActive(); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
if _, err = rpc.TellWaiting(0, 1); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
if _, err = rpc.TellStopped(0, 1); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
if _, err = rpc.GetOption(g); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
if _, err = rpc.GetGlobalOption(); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
if _, err = rpc.GetGlobalStat(); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
if _, err = rpc.GetSessionInfo(); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
if _, err = rpc.Remove(g); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
if _, err = rpc.TellActive(); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestWebsocketAll(t *testing.T) {
|
|
||||||
const targetURL = "https://nodejs.org/dist/index.json"
|
|
||||||
rpc, err := New(context.Background(), "ws://localhost:6800/jsonrpc", "", time.Second, &DummyNotifier{})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer rpc.Close()
|
|
||||||
g, err := rpc.AddURI(targetURL)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
println(g)
|
|
||||||
if _, err = rpc.TellActive(); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
if _, err = rpc.PauseAll(); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
if _, err = rpc.TellStatus(g); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
if _, err = rpc.GetURIs(g); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
if _, err = rpc.GetFiles(g); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
if _, err = rpc.GetPeers(g); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
if _, err = rpc.TellActive(); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
if _, err = rpc.TellWaiting(0, 1); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
if _, err = rpc.TellStopped(0, 1); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
if _, err = rpc.GetOption(g); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
if _, err = rpc.GetGlobalOption(); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
if _, err = rpc.GetGlobalStat(); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
if _, err = rpc.GetSessionInfo(); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
if _, err = rpc.Remove(g); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
if _, err = rpc.TellActive(); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,7 +1,13 @@
|
||||||
package conf
|
package conf
|
||||||
|
|
||||||
// BackendVersion 当前后端版本号
|
// BackendVersion 当前后端版本号
|
||||||
const BackendVersion = string("3.0.0-beta1")
|
var BackendVersion = "3.0.0-beta1"
|
||||||
|
|
||||||
// RequiredDBVersion 与当前版本匹配的数据库版本
|
// RequiredDBVersion 与当前版本匹配的数据库版本
|
||||||
const RequiredDBVersion = string("3.0.0-beta1")
|
var RequiredDBVersion = "3.0.0-beta1"
|
||||||
|
|
||||||
|
// IsPro 是否为Pro版本
|
||||||
|
var IsPro = "true"
|
||||||
|
|
||||||
|
// LastCommit 最后commit id
|
||||||
|
var LastCommit = ""
|
||||||
|
|
|
@ -62,6 +62,8 @@ const (
|
||||||
CodePolicyNotAllowed = 40006
|
CodePolicyNotAllowed = 40006
|
||||||
// CodeGroupNotAllowed 用户组无法进行此操作
|
// CodeGroupNotAllowed 用户组无法进行此操作
|
||||||
CodeGroupNotAllowed = 40007
|
CodeGroupNotAllowed = 40007
|
||||||
|
// CodeAdminRequired 非管理用户组
|
||||||
|
CodeAdminRequired = 40008
|
||||||
// CodeDBError 数据库操作失败
|
// CodeDBError 数据库操作失败
|
||||||
CodeDBError = 50001
|
CodeDBError = 50001
|
||||||
// CodeEncryptError 加密失败
|
// CodeEncryptError 加密失败
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
package controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/HFO4/cloudreve/service/admin"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AdminSummary 获取管理站点概况
|
||||||
|
func AdminSummary(c *gin.Context) {
|
||||||
|
var service admin.NoParamService
|
||||||
|
if err := c.ShouldBindUri(&service); err == nil {
|
||||||
|
res := service.Summary()
|
||||||
|
c.JSON(200, res)
|
||||||
|
} else {
|
||||||
|
c.JSON(200, ErrorResponse(err))
|
||||||
|
}
|
||||||
|
}
|
|
@ -277,6 +277,13 @@ func InitMasterRouter() *gin.Engine {
|
||||||
auth := v3.Group("")
|
auth := v3.Group("")
|
||||||
auth.Use(middleware.AuthRequired())
|
auth.Use(middleware.AuthRequired())
|
||||||
{
|
{
|
||||||
|
// 管理
|
||||||
|
admin := auth.Group("admin", middleware.IsAdmin())
|
||||||
|
{
|
||||||
|
// 获取站点概况
|
||||||
|
admin.GET("summary", controllers.AdminSummary)
|
||||||
|
}
|
||||||
|
|
||||||
// 用户
|
// 用户
|
||||||
user := auth.Group("user")
|
user := auth.Group("user")
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
package admin
|
||||||
|
|
||||||
|
import (
|
||||||
|
model "github.com/HFO4/cloudreve/models"
|
||||||
|
"github.com/HFO4/cloudreve/pkg/conf"
|
||||||
|
"github.com/HFO4/cloudreve/pkg/serializer"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NoParamService 无需参数的服务
|
||||||
|
type NoParamService struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Summary 获取站点统计概况
|
||||||
|
func (service *NoParamService) Summary() serializer.Response {
|
||||||
|
// 统计每日概况
|
||||||
|
total := 12
|
||||||
|
files := make([]int, total)
|
||||||
|
users := make([]int, total)
|
||||||
|
shares := make([]int, total)
|
||||||
|
date := make([]string, total)
|
||||||
|
|
||||||
|
toRound := time.Now()
|
||||||
|
timeBase := time.Date(toRound.Year(), toRound.Month(), toRound.Day()+1, 0, 0, 0, 0, toRound.Location())
|
||||||
|
for day := range files {
|
||||||
|
start := timeBase.Add(-time.Duration(total-day) * time.Hour * 24)
|
||||||
|
end := timeBase.Add(-time.Duration(total-day-1) * time.Hour * 24)
|
||||||
|
date[day] = start.Format("1月2日")
|
||||||
|
model.DB.Model(&model.User{}).Where("created_at BETWEEN ? AND ?", start, end).Count(&users[day])
|
||||||
|
model.DB.Model(&model.File{}).Where("created_at BETWEEN ? AND ?", start, end).Count(&files[day])
|
||||||
|
model.DB.Model(&model.Share{}).Where("created_at BETWEEN ? AND ?", start, end).Count(&shares[day])
|
||||||
|
}
|
||||||
|
|
||||||
|
// 统计总数
|
||||||
|
fileTotal := 0
|
||||||
|
userTotal := 0
|
||||||
|
publicShareTotal := 0
|
||||||
|
secretShareTotal := 0
|
||||||
|
model.DB.Model(&model.User{}).Count(&userTotal)
|
||||||
|
model.DB.Model(&model.File{}).Count(&fileTotal)
|
||||||
|
model.DB.Model(&model.Share{}).Where("password = ?", "").Count(&publicShareTotal)
|
||||||
|
model.DB.Model(&model.Share{}).Where("password <> ?", "").Count(&secretShareTotal)
|
||||||
|
|
||||||
|
// 获取版本信息
|
||||||
|
versions := map[string]string{
|
||||||
|
"backend": conf.BackendVersion,
|
||||||
|
"db": conf.RequiredDBVersion,
|
||||||
|
"commit": conf.LastCommit,
|
||||||
|
"is_pro": conf.IsPro,
|
||||||
|
}
|
||||||
|
|
||||||
|
return serializer.Response{
|
||||||
|
Data: map[string]interface{}{
|
||||||
|
"date": date,
|
||||||
|
"files": files,
|
||||||
|
"users": users,
|
||||||
|
"shares": shares,
|
||||||
|
"version": versions,
|
||||||
|
"siteURL": model.GetSettingByName("siteURL"),
|
||||||
|
"fileTotal": fileTotal,
|
||||||
|
"userTotal": userTotal,
|
||||||
|
"publicShareTotal": publicShareTotal,
|
||||||
|
"secretShareTotal": secretShareTotal,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue