github.com/cloudreve/Cloudreve/v3@v3.0.0-20240224133659-3edb00a6484c/service/admin/site.go (about)

     1  package admin
     2  
     3  import (
     4  	"encoding/gob"
     5  	"time"
     6  
     7  	model "github.com/cloudreve/Cloudreve/v3/models"
     8  	"github.com/cloudreve/Cloudreve/v3/pkg/cache"
     9  	"github.com/cloudreve/Cloudreve/v3/pkg/conf"
    10  	"github.com/cloudreve/Cloudreve/v3/pkg/email"
    11  	"github.com/cloudreve/Cloudreve/v3/pkg/serializer"
    12  	"github.com/cloudreve/Cloudreve/v3/pkg/thumb"
    13  	"github.com/gin-gonic/gin"
    14  )
    15  
    16  func init() {
    17  	gob.Register(map[string]interface{}{})
    18  	gob.Register(map[string]string{})
    19  }
    20  
    21  // NoParamService 无需参数的服务
    22  type NoParamService struct {
    23  }
    24  
    25  // BatchSettingChangeService 设定批量更改服务
    26  type BatchSettingChangeService struct {
    27  	Options []SettingChangeService `json:"options"`
    28  }
    29  
    30  // SettingChangeService  设定更改服务
    31  type SettingChangeService struct {
    32  	Key   string `json:"key" binding:"required"`
    33  	Value string `json:"value"`
    34  }
    35  
    36  // BatchSettingGet 设定批量获取服务
    37  type BatchSettingGet struct {
    38  	Keys []string `json:"keys"`
    39  }
    40  
    41  // MailTestService 邮件测试服务
    42  type MailTestService struct {
    43  	Email string `json:"to" binding:"email"`
    44  }
    45  
    46  // Send 发送测试邮件
    47  func (service *MailTestService) Send() serializer.Response {
    48  	if err := email.Send(service.Email, "Cloudreve Email delivery test", "This is a test Email, to test Cloudreve Email delivery settings"); err != nil {
    49  		return serializer.Err(serializer.CodeFailedSendEmail, err.Error(), nil)
    50  	}
    51  	return serializer.Response{}
    52  }
    53  
    54  // Get 获取设定值
    55  func (service *BatchSettingGet) Get() serializer.Response {
    56  	options := model.GetSettingByNames(service.Keys...)
    57  	return serializer.Response{Data: options}
    58  }
    59  
    60  // Change 批量更改站点设定
    61  func (service *BatchSettingChangeService) Change() serializer.Response {
    62  	cacheClean := make([]string, 0, len(service.Options))
    63  	tx := model.DB.Begin()
    64  
    65  	for _, setting := range service.Options {
    66  
    67  		if err := tx.Model(&model.Setting{}).Where("name = ?", setting.Key).Update("value", setting.Value).Error; err != nil {
    68  			cache.Deletes(cacheClean, "setting_")
    69  			tx.Rollback()
    70  			return serializer.Err(serializer.CodeUpdateSetting, "Setting "+setting.Key+" failed to update", err)
    71  		}
    72  
    73  		cacheClean = append(cacheClean, setting.Key)
    74  	}
    75  
    76  	if err := tx.Commit().Error; err != nil {
    77  		return serializer.DBErr("Failed to update setting", err)
    78  	}
    79  
    80  	cache.Deletes(cacheClean, "setting_")
    81  
    82  	return serializer.Response{}
    83  }
    84  
    85  // Summary 获取站点统计概况
    86  func (service *NoParamService) Summary() serializer.Response {
    87  	// 获取版本信息
    88  	versions := map[string]string{
    89  		"backend": conf.BackendVersion,
    90  		"db":      conf.RequiredDBVersion,
    91  		"commit":  conf.LastCommit,
    92  		"is_pro":  conf.IsPro,
    93  	}
    94  
    95  	if res, ok := cache.Get("admin_summary"); ok {
    96  		resMap := res.(map[string]interface{})
    97  		resMap["version"] = versions
    98  		resMap["siteURL"] = model.GetSettingByName("siteURL")
    99  		return serializer.Response{Data: resMap}
   100  	}
   101  
   102  	// 统计每日概况
   103  	total := 12
   104  	files := make([]int, total)
   105  	users := make([]int, total)
   106  	shares := make([]int, total)
   107  	date := make([]string, total)
   108  
   109  	toRound := time.Now()
   110  	timeBase := time.Date(toRound.Year(), toRound.Month(), toRound.Day()+1, 0, 0, 0, 0, toRound.Location())
   111  	for day := range files {
   112  		start := timeBase.Add(-time.Duration(total-day) * time.Hour * 24)
   113  		end := timeBase.Add(-time.Duration(total-day-1) * time.Hour * 24)
   114  		date[day] = start.Format("1月2日")
   115  		model.DB.Model(&model.User{}).Where("created_at BETWEEN ? AND ?", start, end).Count(&users[day])
   116  		model.DB.Model(&model.File{}).Where("created_at BETWEEN ? AND ?", start, end).Count(&files[day])
   117  		model.DB.Model(&model.Share{}).Where("created_at BETWEEN ? AND ?", start, end).Count(&shares[day])
   118  	}
   119  
   120  	// 统计总数
   121  	fileTotal := 0
   122  	userTotal := 0
   123  	publicShareTotal := 0
   124  	secretShareTotal := 0
   125  	model.DB.Model(&model.User{}).Count(&userTotal)
   126  	model.DB.Model(&model.File{}).Count(&fileTotal)
   127  	model.DB.Model(&model.Share{}).Where("password = ?", "").Count(&publicShareTotal)
   128  	model.DB.Model(&model.Share{}).Where("password <> ?", "").Count(&secretShareTotal)
   129  
   130  	resp := map[string]interface{}{
   131  		"date":             date,
   132  		"files":            files,
   133  		"users":            users,
   134  		"shares":           shares,
   135  		"version":          versions,
   136  		"siteURL":          model.GetSettingByName("siteURL"),
   137  		"fileTotal":        fileTotal,
   138  		"userTotal":        userTotal,
   139  		"publicShareTotal": publicShareTotal,
   140  		"secretShareTotal": secretShareTotal,
   141  	}
   142  
   143  	cache.Set("admin_summary", resp, 86400)
   144  	return serializer.Response{
   145  		Data: resp,
   146  	}
   147  }
   148  
   149  // ThumbGeneratorTestService 缩略图生成测试服务
   150  type ThumbGeneratorTestService struct {
   151  	Name       string `json:"name" binding:"required"`
   152  	Executable string `json:"executable" binding:"required"`
   153  }
   154  
   155  // Test 通过获取生成器版本来测试
   156  func (s *ThumbGeneratorTestService) Test(c *gin.Context) serializer.Response {
   157  	version, err := thumb.TestGenerator(c, s.Name, s.Executable)
   158  	if err != nil {
   159  		return serializer.Err(serializer.CodeParamErr, err.Error(), err)
   160  	}
   161  
   162  	return serializer.Response{
   163  		Data: version,
   164  	}
   165  }