|
|
|
package admin
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/gob"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
model "github.com/cloudreve/Cloudreve/v3/models"
|
|
|
|
"github.com/cloudreve/Cloudreve/v3/pkg/cache"
|
|
|
|
"github.com/cloudreve/Cloudreve/v3/pkg/conf"
|
|
|
|
"github.com/cloudreve/Cloudreve/v3/pkg/email"
|
|
|
|
"github.com/cloudreve/Cloudreve/v3/pkg/serializer"
|
|
|
|
"github.com/cloudreve/Cloudreve/v3/pkg/thumb"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
)
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
gob.Register(map[string]interface{}{})
|
|
|
|
gob.Register(map[string]string{})
|
|
|
|
}
|
|
|
|
|
|
|
|
// NoParamService 无需参数的服务
|
|
|
|
type NoParamService struct {
|
|
|
|
}
|
|
|
|
|
|
|
|
// BatchSettingChangeService 设定批量更改服务
|
|
|
|
type BatchSettingChangeService struct {
|
|
|
|
Options []SettingChangeService `json:"options"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// SettingChangeService 设定更改服务
|
|
|
|
type SettingChangeService struct {
|
|
|
|
Key string `json:"key" binding:"required"`
|
|
|
|
Value string `json:"value"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// BatchSettingGet 设定批量获取服务
|
|
|
|
type BatchSettingGet struct {
|
|
|
|
Keys []string `json:"keys"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// MailTestService 邮件测试服务
|
|
|
|
type MailTestService struct {
|
|
|
|
Email string `json:"to" binding:"email"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// Send 发送测试邮件
|
|
|
|
func (service *MailTestService) Send() serializer.Response {
|
|
|
|
if err := email.Send(service.Email, "Cloudreve Email delivery test", "This is a test Email, to test Cloudreve Email delivery settings"); err != nil {
|
|
|
|
return serializer.Err(serializer.CodeFailedSendEmail, err.Error(), nil)
|
|
|
|
}
|
|
|
|
return serializer.Response{}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get 获取设定值
|
|
|
|
func (service *BatchSettingGet) Get() serializer.Response {
|
|
|
|
options := model.GetSettingByNames(service.Keys...)
|
|
|
|
return serializer.Response{Data: options}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Change 批量更改站点设定
|
|
|
|
func (service *BatchSettingChangeService) Change() serializer.Response {
|
|
|
|
cacheClean := make([]string, 0, len(service.Options))
|
|
|
|
tx := model.DB.Begin()
|
|
|
|
|
|
|
|
for _, setting := range service.Options {
|
|
|
|
|
|
|
|
if err := tx.Model(&model.Setting{}).Where("name = ?", setting.Key).Update("value", setting.Value).Error; err != nil {
|
|
|
|
cache.Deletes(cacheClean, "setting_")
|
|
|
|
tx.Rollback()
|
|
|
|
return serializer.Err(serializer.CodeUpdateSetting, "Setting "+setting.Key+" failed to update", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
cacheClean = append(cacheClean, setting.Key)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := tx.Commit().Error; err != nil {
|
|
|
|
return serializer.DBErr("Failed to update setting", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
cache.Deletes(cacheClean, "setting_")
|
|
|
|
|
|
|
|
return serializer.Response{}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Summary 获取站点统计概况
|
|
|
|
func (service *NoParamService) Summary() serializer.Response {
|
|
|
|
// 获取版本信息
|
|
|
|
versions := map[string]string{
|
|
|
|
"backend": conf.BackendVersion,
|
|
|
|
"db": conf.RequiredDBVersion,
|
|
|
|
"commit": conf.LastCommit,
|
|
|
|
"is_pro": conf.IsPro,
|
|
|
|
}
|
|
|
|
|
|
|
|
if res, ok := cache.Get("admin_summary"); ok {
|
|
|
|
resMap := res.(map[string]interface{})
|
|
|
|
resMap["version"] = versions
|
|
|
|
resMap["siteURL"] = model.GetSettingByName("siteURL")
|
|
|
|
return serializer.Response{Data: resMap}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 统计每日概况
|
|
|
|
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)
|
|
|
|
|
|
|
|
resp := 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,
|
|
|
|
}
|
|
|
|
|
|
|
|
cache.Set("admin_summary", resp, 86400)
|
|
|
|
return serializer.Response{
|
|
|
|
Data: resp,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ThumbGeneratorTestService 缩略图生成测试服务
|
|
|
|
type ThumbGeneratorTestService struct {
|
|
|
|
Name string `json:"name" binding:"required"`
|
|
|
|
Executable string `json:"executable" binding:"required"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test 通过获取生成器版本来测试
|
|
|
|
func (s *ThumbGeneratorTestService) Test(c *gin.Context) serializer.Response {
|
|
|
|
version, err := thumb.TestGenerator(c, s.Name, s.Executable)
|
|
|
|
if err != nil {
|
|
|
|
return serializer.Err(serializer.CodeParamErr, err.Error(), err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return serializer.Response{
|
|
|
|
Data: version,
|
|
|
|
}
|
|
|
|
}
|