diff --git a/models/migration.go b/models/migration.go index b990171..fc25ca4 100644 --- a/models/migration.go +++ b/models/migration.go @@ -90,11 +90,10 @@ func addDefaultSettings() { {Name: "smtpPass", Value: ``, Type: "mail"}, {Name: "over_used_template", Value: `容量超额提醒
容量超额警告
亲爱的{userName}
由于{notifyReason},您在{siteTitle}的账户的容量使用超出配额,您将无法继续上传新文件,请尽快清理文件,否则我们将会禁用您的账户。
登录{siteTitle}
感谢您选择{siteTitle}。
`, Type: "mail_template"}, - {Name: "ban_time", Value: `10`, Type: "storage_policy"}, - {Name: "maxEditSize", Value: `100000`, Type: "file_edit"}, - {Name: "oss_timeout", Value: `3600`, Type: "timeout"}, - {Name: "archive_timeout", Value: `30`, Type: "timeout"}, - {Name: "download_timeout", Value: `30`, Type: "timeout"}, + {Name: "ban_time", Value: `604800`, Type: "storage_policy"}, + {Name: "maxEditSize", Value: `4194304`, Type: "file_edit"}, + {Name: "archive_timeout", Value: `60`, Type: "timeout"}, + {Name: "download_timeout", Value: `60`, Type: "timeout"}, {Name: "preview_timeout", Value: `60`, Type: "timeout"}, {Name: "doc_preview_timeout", Value: `60`, Type: "timeout"}, {Name: "upload_credential_timeout", Value: `1800`, Type: "timeout"}, @@ -137,7 +136,6 @@ Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; verti {Name: "appkey", Value: ``, Type: "payment"}, {Name: "shopid", Value: ``, Type: "payment"}, {Name: "hot_share_num", Value: `10`, Type: "share"}, - {Name: "allow_buy_group", Value: `1`, Type: "group_sell"}, {Name: "group_sell_data", Value: `[]`, Type: "group_sell"}, {Name: "gravatar_server", Value: `https://gravatar.loli.net/`, Type: "avatar"}, {Name: "defaultTheme", Value: `#3f51b5`, Type: "basic"}, diff --git a/routers/controllers/admin.go b/routers/controllers/admin.go index a0cbfb5..a0c1349 100644 --- a/routers/controllers/admin.go +++ b/routers/controllers/admin.go @@ -81,3 +81,36 @@ func AdminSendTestMail(c *gin.Context) { c.JSON(200, ErrorResponse(err)) } } + +// AdminListRedeems 列出激活码 +func AdminListRedeems(c *gin.Context) { + var service admin.AdminListService + if err := c.ShouldBindJSON(&service); err == nil { + res := service.Redeems() + c.JSON(200, res) + } else { + c.JSON(200, ErrorResponse(err)) + } +} + +// AdminGenerateRedeems 生成激活码 +func AdminGenerateRedeems(c *gin.Context) { + var service admin.GenerateRedeemsService + if err := c.ShouldBindJSON(&service); err == nil { + res := service.Generate() + c.JSON(200, res) + } else { + c.JSON(200, ErrorResponse(err)) + } +} + +// AdminDeleteRedeem 删除激活码 +func AdminDeleteRedeem(c *gin.Context) { + var service admin.SingleIDService + if err := c.ShouldBindUri(&service); err == nil { + res := service.DeleteRedeem() + c.JSON(200, res) + } else { + c.JSON(200, ErrorResponse(err)) + } +} diff --git a/routers/router.go b/routers/router.go index e9dae1d..1d7e45e 100644 --- a/routers/router.go +++ b/routers/router.go @@ -303,6 +303,18 @@ func InitMasterRouter() *gin.Engine { admin.GET("reload/:service", controllers.AdminReloadService) // 重新加载子服务 admin.POST("mailTest", controllers.AdminSendTestMail) + + // 兑换码相关 + redeem := admin.Group("redeem") + { + // 列出激活码 + redeem.POST("list", controllers.AdminListRedeems) + // 生成激活码 + redeem.POST("", controllers.AdminGenerateRedeems) + // 删除激活码 + redeem.DELETE(":id", controllers.AdminDeleteRedeem) + } + } // 用户 diff --git a/service/admin/list.go b/service/admin/list.go index 2debfd5..b8a0141 100644 --- a/service/admin/list.go +++ b/service/admin/list.go @@ -5,6 +5,15 @@ import ( "github.com/HFO4/cloudreve/pkg/serializer" ) +// AdminListService 仪表盘列条目服务 +type AdminListService struct { + Page int `json:"page" binding:"min=1,required"` + PageSize int `json:"page_size" binding:"min=1,required"` + OrderBy string `json:"order_by"` + Conditions map[string]string `form:"conditions"` + Searches map[string]string `form:"searches"` +} + // GroupList 获取用户组列表 func (service *NoParamService) GroupList() serializer.Response { var res []model.Group diff --git a/service/admin/vas.go b/service/admin/vas.go new file mode 100644 index 0000000..612672e --- /dev/null +++ b/service/admin/vas.go @@ -0,0 +1,98 @@ +package admin + +import ( + model "github.com/HFO4/cloudreve/models" + "github.com/HFO4/cloudreve/pkg/serializer" + "github.com/gofrs/uuid" +) + +// GenerateRedeemsService 兑换码生成服务 +type GenerateRedeemsService struct { + Num int `json:"num" binding:"required,min=1,max=100"` + ID int64 `json:"id"` + Time int `json:"time" binding:"required,min=1"` + Type int `json:"type" binding:"min=0,max=2"` +} + +// SingleIDService 单ID服务 +type SingleIDService struct { + ID uint `uri:"id" binding:"required"` +} + +// DeleteRedeem 删除兑换码 +func (service *SingleIDService) DeleteRedeem() serializer.Response { + if err := model.DB.Where("id = ?", service.ID).Delete(&model.Redeem{}).Error; err != nil { + return serializer.DBErr("无法删除兑换码", err) + } + + return serializer.Response{} +} + +// Generate 生成兑换码 +func (service *GenerateRedeemsService) Generate() serializer.Response { + res := make([]string, service.Num) + redeem := model.Redeem{} + + // 开始事务 + tx := model.DB.Begin() + if err := tx.Error; err != nil { + return serializer.DBErr("无法开启事务", err) + } + + // 创建每个兑换码 + for i := 0; i < service.Num; i++ { + redeem.Model.ID = 0 + redeem.Num = service.Time + redeem.Type = service.Type + redeem.ProductID = service.ID + redeem.Used = false + + // 生成唯一兑换码 + u2, err := uuid.NewV4() + if err != nil { + tx.Rollback() + return serializer.Err(serializer.CodeInternalSetting, "无法生成兑换码", err) + } + + redeem.Code = u2.String() + if err := tx.Create(&redeem).Error; err != nil { + tx.Rollback() + return serializer.DBErr("无法创建兑换码记录", err) + } + + res[i] = redeem.Code + } + + if err := tx.Commit().Error; err != nil { + return serializer.DBErr("无法创建兑换码记录", err) + } + + return serializer.Response{Data: res} + +} + +// Redeems 列出激活码 +func (service *AdminListService) Redeems() serializer.Response { + var res []model.Redeem + total := 0 + + tx := model.DB.Model(&model.Redeem{}) + if service.OrderBy != "" { + tx = tx.Order(service.OrderBy) + } + + for k, v := range service.Conditions { + tx = tx.Where("? = ?", k, v) + } + + // 计算总数用于分页 + tx.Count(&total) + + // 查询记录 + tx.Limit(service.PageSize).Offset((service.Page - 1) * service.PageSize).Find(&res) + + return serializer.Response{Data: map[string]interface{}{ + "total": total, + "items": res, + }} +} diff --git a/service/vas/purchase.go b/service/vas/purchase.go index 363eaa3..a1b3864 100644 --- a/service/vas/purchase.go +++ b/service/vas/purchase.go @@ -61,6 +61,11 @@ func (service *RedeemService) Redeem(c *gin.Context, user *model.User) serialize break } } + + if group == nil { + return serializer.Err(serializer.CodeNotFound, "商品已失效", err) + } + } else if redeem.Type == model.PackOrderType { for _, v := range packs { if v.ID == redeem.ProductID { @@ -68,6 +73,11 @@ func (service *RedeemService) Redeem(c *gin.Context, user *model.User) serialize break } } + + if pack == nil { + return serializer.Err(serializer.CodeNotFound, "商品已失效", err) + } + } err = payment.GiveProduct(user, pack, group, redeem.Num)