diff --git a/common/sale-ratio.go b/common/sale-ratio.go new file mode 100644 index 00000000..671d6eda --- /dev/null +++ b/common/sale-ratio.go @@ -0,0 +1,26 @@ +package common + +import "encoding/json" + +var SaleRatio = map[string]float64{} + +func SaleRatio2JSONString() string { + jsonBytes, err := json.Marshal(SaleRatio) + if err != nil { + SysError("error marshalling model ratio: " + err.Error()) + } + return string(jsonBytes) +} + +func UpdateSaleRatioByJSONString(jsonStr string) error { + GroupRatio = make(map[string]float64) + return json.Unmarshal([]byte(jsonStr), &SaleRatio) +} + +func GetSaleRatio(name string) float64 { + ratio, ok := SaleRatio[name] + if !ok { + return 0 + } + return ratio +} diff --git a/i18n/en.json b/i18n/en.json index b0deb83a..1a178e35 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -226,6 +226,7 @@ "键为模型名称": "Key is model name", "值为倍率": "Value is the rate", "分组倍率": "Group rate", + "分销倍率": "Sale rate", "键为分组名称": "Key is group name", "保存倍率设置": "Save Rate Settings", "已是最新版本": "Is the latest version", diff --git a/model/log.go b/model/log.go index 3d3ffae3..2fbd7945 100644 --- a/model/log.go +++ b/model/log.go @@ -28,6 +28,7 @@ const ( LogTypeConsume LogTypeManage LogTypeSystem + LogTypeSale ) func RecordLog(userId int, logType int, content string) { diff --git a/model/option.go b/model/option.go index bb8b709c..694f4d4b 100644 --- a/model/option.go +++ b/model/option.go @@ -68,6 +68,7 @@ func InitOptionMap() { common.OptionMap["PreConsumedQuota"] = strconv.Itoa(common.PreConsumedQuota) common.OptionMap["ModelRatio"] = common.ModelRatio2JSONString() common.OptionMap["GroupRatio"] = common.GroupRatio2JSONString() + common.OptionMap["SaleRatio"] = common.SaleRatio2JSONString() common.OptionMap["TopUpLink"] = common.TopUpLink common.OptionMap["ChatLink"] = common.ChatLink common.OptionMap["QuotaPerUnit"] = strconv.FormatFloat(common.QuotaPerUnit, 'f', -1, 64) @@ -212,6 +213,8 @@ func updateOptionMap(key string, value string) (err error) { err = common.UpdateModelRatioByJSONString(value) case "GroupRatio": err = common.UpdateGroupRatioByJSONString(value) + case "SaleRatio": + err = common.UpdateSaleRatioByJSONString(value) case "TopUpLink": common.TopUpLink = value case "ChatLink": diff --git a/model/redemption.go b/model/redemption.go index f16412b5..e9e2a7c6 100644 --- a/model/redemption.go +++ b/model/redemption.go @@ -54,7 +54,12 @@ func Redeem(key string, userId int) (quota int, err error) { if common.UsingPostgreSQL { keyCol = `"key"` } - + //获取用户分组 + user, err := GetUserById(userId, false) + if err != nil { + return 0, err + } + extendQuota := common.LogQuota(int(float64(redemption.Quota) * common.GetSaleRatio(user.Group))) err = DB.Transaction(func(tx *gorm.DB) error { err := tx.Set("gorm:query_option", "FOR UPDATE").Where(keyCol+" = ?", key).First(redemption).Error if err != nil { @@ -70,12 +75,22 @@ func Redeem(key string, userId int) (quota int, err error) { redemption.RedeemedTime = common.GetTimestamp() redemption.Status = common.RedemptionCodeStatusUsed err = tx.Save(redemption).Error + if user.InviterId != 0 { + err = tx.Model(&User{}).Where("id = ?", user.InviterId).Update("quota", gorm.Expr("quota + ?", extendQuota)).Error + if err != nil { + return err + } + } + return err }) if err != nil { return 0, errors.New("兑换失败," + err.Error()) } RecordLog(userId, LogTypeTopup, fmt.Sprintf("通过兑换码充值 %s", common.LogQuota(redemption.Quota))) + if user.InviterId != 0 { + RecordLog(user.InviterId, LogTypeSale, fmt.Sprintf("通过分销赠送 %s", extendQuota)) + } return redemption.Quota, nil } diff --git a/web/src/components/LogsTable.js b/web/src/components/LogsTable.js index e266d79a..d34db6ae 100644 --- a/web/src/components/LogsTable.js +++ b/web/src/components/LogsTable.js @@ -36,6 +36,8 @@ function renderType(type) { return ; case 4: return ; + case 5: + return ; default: return ; } diff --git a/web/src/components/OperationSetting.js b/web/src/components/OperationSetting.js index 3b52bb27..7876cb7d 100644 --- a/web/src/components/OperationSetting.js +++ b/web/src/components/OperationSetting.js @@ -12,6 +12,7 @@ const OperationSetting = () => { PreConsumedQuota: 0, ModelRatio: '', GroupRatio: '', + SaleRatio: '{}', TopUpLink: '', ChatLink: '', QuotaPerUnit: 0, @@ -34,7 +35,7 @@ const OperationSetting = () => { if (success) { let newInputs = {}; data.forEach((item) => { - if (item.key === 'ModelRatio' || item.key === 'GroupRatio') { + if (item.key === 'ModelRatio' || item.key === 'GroupRatio' || item.key === 'SaleRatio') { item.value = JSON.stringify(JSON.parse(item.value), null, 2); } newInputs[item.key] = item.value; @@ -101,6 +102,13 @@ const OperationSetting = () => { } await updateOption('GroupRatio', inputs.GroupRatio); } + if (originInputs['SaleRatio'] !== inputs.SaleRatio) { + if (!verifyJSON(inputs.SaleRatio)) { + showError('分销倍率不是合法的 JSON 字符串'); + return; + } + await updateOption('SaleRatio', inputs.SaleRatio); + } break; case 'quota': if (originInputs['QuotaForNewUser'] !== inputs.QuotaForNewUser) { @@ -355,6 +363,17 @@ const OperationSetting = () => { placeholder='为一个 JSON 文本,键为分组名称,值为倍率' /> +