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)