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 }