增加分销功能
This commit is contained in:
parent
1dcd822b5f
commit
e9f6fddfb7
26
common/sale-ratio.go
Normal file
26
common/sale-ratio.go
Normal file
@ -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
|
||||||
|
}
|
@ -226,6 +226,7 @@
|
|||||||
"键为模型名称": "Key is model name",
|
"键为模型名称": "Key is model name",
|
||||||
"值为倍率": "Value is the rate",
|
"值为倍率": "Value is the rate",
|
||||||
"分组倍率": "Group rate",
|
"分组倍率": "Group rate",
|
||||||
|
"分销倍率": "Sale rate",
|
||||||
"键为分组名称": "Key is group name",
|
"键为分组名称": "Key is group name",
|
||||||
"保存倍率设置": "Save Rate Settings",
|
"保存倍率设置": "Save Rate Settings",
|
||||||
"已是最新版本": "Is the latest version",
|
"已是最新版本": "Is the latest version",
|
||||||
|
@ -28,6 +28,7 @@ const (
|
|||||||
LogTypeConsume
|
LogTypeConsume
|
||||||
LogTypeManage
|
LogTypeManage
|
||||||
LogTypeSystem
|
LogTypeSystem
|
||||||
|
LogTypeSale
|
||||||
)
|
)
|
||||||
|
|
||||||
func RecordLog(userId int, logType int, content string) {
|
func RecordLog(userId int, logType int, content string) {
|
||||||
|
@ -68,6 +68,7 @@ func InitOptionMap() {
|
|||||||
common.OptionMap["PreConsumedQuota"] = strconv.Itoa(common.PreConsumedQuota)
|
common.OptionMap["PreConsumedQuota"] = strconv.Itoa(common.PreConsumedQuota)
|
||||||
common.OptionMap["ModelRatio"] = common.ModelRatio2JSONString()
|
common.OptionMap["ModelRatio"] = common.ModelRatio2JSONString()
|
||||||
common.OptionMap["GroupRatio"] = common.GroupRatio2JSONString()
|
common.OptionMap["GroupRatio"] = common.GroupRatio2JSONString()
|
||||||
|
common.OptionMap["SaleRatio"] = common.SaleRatio2JSONString()
|
||||||
common.OptionMap["TopUpLink"] = common.TopUpLink
|
common.OptionMap["TopUpLink"] = common.TopUpLink
|
||||||
common.OptionMap["ChatLink"] = common.ChatLink
|
common.OptionMap["ChatLink"] = common.ChatLink
|
||||||
common.OptionMap["QuotaPerUnit"] = strconv.FormatFloat(common.QuotaPerUnit, 'f', -1, 64)
|
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)
|
err = common.UpdateModelRatioByJSONString(value)
|
||||||
case "GroupRatio":
|
case "GroupRatio":
|
||||||
err = common.UpdateGroupRatioByJSONString(value)
|
err = common.UpdateGroupRatioByJSONString(value)
|
||||||
|
case "SaleRatio":
|
||||||
|
err = common.UpdateSaleRatioByJSONString(value)
|
||||||
case "TopUpLink":
|
case "TopUpLink":
|
||||||
common.TopUpLink = value
|
common.TopUpLink = value
|
||||||
case "ChatLink":
|
case "ChatLink":
|
||||||
|
@ -54,7 +54,12 @@ func Redeem(key string, userId int) (quota int, err error) {
|
|||||||
if common.UsingPostgreSQL {
|
if common.UsingPostgreSQL {
|
||||||
keyCol = `"key"`
|
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 = DB.Transaction(func(tx *gorm.DB) error {
|
||||||
err := tx.Set("gorm:query_option", "FOR UPDATE").Where(keyCol+" = ?", key).First(redemption).Error
|
err := tx.Set("gorm:query_option", "FOR UPDATE").Where(keyCol+" = ?", key).First(redemption).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -70,12 +75,22 @@ func Redeem(key string, userId int) (quota int, err error) {
|
|||||||
redemption.RedeemedTime = common.GetTimestamp()
|
redemption.RedeemedTime = common.GetTimestamp()
|
||||||
redemption.Status = common.RedemptionCodeStatusUsed
|
redemption.Status = common.RedemptionCodeStatusUsed
|
||||||
err = tx.Save(redemption).Error
|
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
|
return err
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, errors.New("兑换失败," + err.Error())
|
return 0, errors.New("兑换失败," + err.Error())
|
||||||
}
|
}
|
||||||
RecordLog(userId, LogTypeTopup, fmt.Sprintf("通过兑换码充值 %s", common.LogQuota(redemption.Quota)))
|
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
|
return redemption.Quota, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +36,8 @@ function renderType(type) {
|
|||||||
return <Label basic color='orange'> 管理 </Label>;
|
return <Label basic color='orange'> 管理 </Label>;
|
||||||
case 4:
|
case 4:
|
||||||
return <Label basic color='purple'> 系统 </Label>;
|
return <Label basic color='purple'> 系统 </Label>;
|
||||||
|
case 5:
|
||||||
|
return <Label basic color='green'> 分销 </Label>;
|
||||||
default:
|
default:
|
||||||
return <Label basic color='black'> 未知 </Label>;
|
return <Label basic color='black'> 未知 </Label>;
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ const OperationSetting = () => {
|
|||||||
PreConsumedQuota: 0,
|
PreConsumedQuota: 0,
|
||||||
ModelRatio: '',
|
ModelRatio: '',
|
||||||
GroupRatio: '',
|
GroupRatio: '',
|
||||||
|
SaleRatio: '{}',
|
||||||
TopUpLink: '',
|
TopUpLink: '',
|
||||||
ChatLink: '',
|
ChatLink: '',
|
||||||
QuotaPerUnit: 0,
|
QuotaPerUnit: 0,
|
||||||
@ -34,7 +35,7 @@ const OperationSetting = () => {
|
|||||||
if (success) {
|
if (success) {
|
||||||
let newInputs = {};
|
let newInputs = {};
|
||||||
data.forEach((item) => {
|
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);
|
item.value = JSON.stringify(JSON.parse(item.value), null, 2);
|
||||||
}
|
}
|
||||||
newInputs[item.key] = item.value;
|
newInputs[item.key] = item.value;
|
||||||
@ -101,6 +102,13 @@ const OperationSetting = () => {
|
|||||||
}
|
}
|
||||||
await updateOption('GroupRatio', inputs.GroupRatio);
|
await updateOption('GroupRatio', inputs.GroupRatio);
|
||||||
}
|
}
|
||||||
|
if (originInputs['SaleRatio'] !== inputs.SaleRatio) {
|
||||||
|
if (!verifyJSON(inputs.SaleRatio)) {
|
||||||
|
showError('分销倍率不是合法的 JSON 字符串');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await updateOption('SaleRatio', inputs.SaleRatio);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'quota':
|
case 'quota':
|
||||||
if (originInputs['QuotaForNewUser'] !== inputs.QuotaForNewUser) {
|
if (originInputs['QuotaForNewUser'] !== inputs.QuotaForNewUser) {
|
||||||
@ -355,6 +363,17 @@ const OperationSetting = () => {
|
|||||||
placeholder='为一个 JSON 文本,键为分组名称,值为倍率'
|
placeholder='为一个 JSON 文本,键为分组名称,值为倍率'
|
||||||
/>
|
/>
|
||||||
</Form.Group>
|
</Form.Group>
|
||||||
|
<Form.Group widths='equal'>
|
||||||
|
<Form.TextArea
|
||||||
|
label='分销倍率'
|
||||||
|
name='SaleRatio'
|
||||||
|
onChange={handleInputChange}
|
||||||
|
style={{ minHeight: 250, fontFamily: 'JetBrains Mono, Consolas' }}
|
||||||
|
autoComplete='new-password'
|
||||||
|
value={inputs.SaleRatio}
|
||||||
|
placeholder='为一个 JSON 文本,键为分组名称,值为分销倍率,如果不设置默认不分销'
|
||||||
|
/>
|
||||||
|
</Form.Group>
|
||||||
<Form.Button onClick={() => {
|
<Form.Button onClick={() => {
|
||||||
submitConfig('ratio').then();
|
submitConfig('ratio').then();
|
||||||
}}>保存倍率设置</Form.Button>
|
}}>保存倍率设置</Form.Button>
|
||||||
|
Loading…
Reference in New Issue
Block a user