mirror of
				https://github.com/songquanpeng/one-api.git
				synced 2025-10-31 05:43:42 +08:00 
			
		
		
		
	Compare commits
	
		
			2 Commits
		
	
	
		
			v0.3.0-alp
			...
			v0.3.0-alp
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 4d6172a242 | ||
|  | 8afdc56b11 | 
| @@ -54,6 +54,7 @@ var QuotaForNewUser = 0 | |||||||
| var ChannelDisableThreshold = 5.0 | var ChannelDisableThreshold = 5.0 | ||||||
| var AutomaticDisableChannelEnabled = false | var AutomaticDisableChannelEnabled = false | ||||||
| var QuotaRemindThreshold = 1000 | var QuotaRemindThreshold = 1000 | ||||||
|  | var PreConsumedQuota = 500 | ||||||
|  |  | ||||||
| var RootUserEmail = "" | var RootUserEmail = "" | ||||||
|  |  | ||||||
|   | |||||||
| @@ -128,6 +128,14 @@ func relayHelper(c *gin.Context) error { | |||||||
| 		model_ = strings.TrimSuffix(model_, "-0314") | 		model_ = strings.TrimSuffix(model_, "-0314") | ||||||
| 		fullRequestURL = fmt.Sprintf("%s/openai/deployments/%s/%s", baseURL, model_, task) | 		fullRequestURL = fmt.Sprintf("%s/openai/deployments/%s/%s", baseURL, model_, task) | ||||||
| 	} | 	} | ||||||
|  | 	ratio := common.GetModelRatio(textRequest.Model) | ||||||
|  | 	preConsumedQuota := int(float64(common.PreConsumedQuota) * ratio) | ||||||
|  | 	if consumeQuota { | ||||||
|  | 		err := model.PreConsumeTokenQuota(tokenId, preConsumedQuota) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| 	req, err := http.NewRequest(c.Request.Method, fullRequestURL, c.Request.Body) | 	req, err := http.NewRequest(c.Request.Method, fullRequestURL, c.Request.Body) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| @@ -177,9 +185,9 @@ func relayHelper(c *gin.Context) error { | |||||||
| 			} else { | 			} else { | ||||||
| 				quota = textResponse.Usage.PromptTokens + textResponse.Usage.CompletionTokens*completionRatio | 				quota = textResponse.Usage.PromptTokens + textResponse.Usage.CompletionTokens*completionRatio | ||||||
| 			} | 			} | ||||||
| 			ratio := common.GetModelRatio(textRequest.Model) |  | ||||||
| 			quota = int(float64(quota) * ratio) | 			quota = int(float64(quota) * ratio) | ||||||
| 			err := model.DecreaseTokenQuota(tokenId, quota) | 			quotaDelta := quota - preConsumedQuota | ||||||
|  | 			err := model.PostConsumeTokenQuota(tokenId, quotaDelta) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				common.SysError("Error consuming token remain quota: " + err.Error()) | 				common.SysError("Error consuming token remain quota: " + err.Error()) | ||||||
| 			} | 			} | ||||||
|   | |||||||
| @@ -111,7 +111,7 @@ func TokenAuth() func(c *gin.Context) { | |||||||
| 		c.Set("id", token.UserId) | 		c.Set("id", token.UserId) | ||||||
| 		c.Set("token_id", token.Id) | 		c.Set("token_id", token.Id) | ||||||
| 		requestURL := c.Request.URL.String() | 		requestURL := c.Request.URL.String() | ||||||
| 		consumeQuota := !token.UnlimitedQuota | 		consumeQuota := true | ||||||
| 		if strings.HasPrefix(requestURL, "/v1/models") { | 		if strings.HasPrefix(requestURL, "/v1/models") { | ||||||
| 			consumeQuota = false | 			consumeQuota = false | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -55,6 +55,7 @@ func InitOptionMap() { | |||||||
| 	common.OptionMap["TurnstileSecretKey"] = "" | 	common.OptionMap["TurnstileSecretKey"] = "" | ||||||
| 	common.OptionMap["QuotaForNewUser"] = strconv.Itoa(common.QuotaForNewUser) | 	common.OptionMap["QuotaForNewUser"] = strconv.Itoa(common.QuotaForNewUser) | ||||||
| 	common.OptionMap["QuotaRemindThreshold"] = strconv.Itoa(common.QuotaRemindThreshold) | 	common.OptionMap["QuotaRemindThreshold"] = strconv.Itoa(common.QuotaRemindThreshold) | ||||||
|  | 	common.OptionMap["PreConsumedQuota"] = strconv.Itoa(common.PreConsumedQuota) | ||||||
| 	common.OptionMap["ModelRatio"] = common.ModelRatio2JSONString() | 	common.OptionMap["ModelRatio"] = common.ModelRatio2JSONString() | ||||||
| 	common.OptionMap["TopUpLink"] = common.TopUpLink | 	common.OptionMap["TopUpLink"] = common.TopUpLink | ||||||
| 	common.OptionMapRWMutex.Unlock() | 	common.OptionMapRWMutex.Unlock() | ||||||
| @@ -159,6 +160,8 @@ func updateOptionMap(key string, value string) (err error) { | |||||||
| 		common.QuotaForNewUser, _ = strconv.Atoi(value) | 		common.QuotaForNewUser, _ = strconv.Atoi(value) | ||||||
| 	case "QuotaRemindThreshold": | 	case "QuotaRemindThreshold": | ||||||
| 		common.QuotaRemindThreshold, _ = strconv.Atoi(value) | 		common.QuotaRemindThreshold, _ = strconv.Atoi(value) | ||||||
|  | 	case "PreConsumedQuota": | ||||||
|  | 		common.PreConsumedQuota, _ = strconv.Atoi(value) | ||||||
| 	case "ModelRatio": | 	case "ModelRatio": | ||||||
| 		err = common.UpdateModelRatioByJSONString(value) | 		err = common.UpdateModelRatioByJSONString(value) | ||||||
| 	case "TopUpLink": | 	case "TopUpLink": | ||||||
|   | |||||||
| @@ -130,7 +130,23 @@ func DeleteTokenById(id int, userId int) (err error) { | |||||||
| 	return token.Delete() | 	return token.Delete() | ||||||
| } | } | ||||||
|  |  | ||||||
| func DecreaseTokenQuota(tokenId int, quota int) (err error) { | func IncreaseTokenQuota(id int, quota int) (err error) { | ||||||
|  | 	if quota < 0 { | ||||||
|  | 		return errors.New("quota 不能为负数!") | ||||||
|  | 	} | ||||||
|  | 	err = DB.Model(&Token{}).Where("id = ?", id).Update("remain_quota", gorm.Expr("remain_quota + ?", quota)).Error | ||||||
|  | 	return err | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func DecreaseTokenQuota(id int, quota int) (err error) { | ||||||
|  | 	if quota < 0 { | ||||||
|  | 		return errors.New("quota 不能为负数!") | ||||||
|  | 	} | ||||||
|  | 	err = DB.Model(&Token{}).Where("id = ?", id).Update("remain_quota", gorm.Expr("remain_quota - ?", quota)).Error | ||||||
|  | 	return err | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func PreConsumeTokenQuota(tokenId int, quota int) (err error) { | ||||||
| 	if quota < 0 { | 	if quota < 0 { | ||||||
| 		return errors.New("quota 不能为负数!") | 		return errors.New("quota 不能为负数!") | ||||||
| 	} | 	} | ||||||
| @@ -138,7 +154,7 @@ func DecreaseTokenQuota(tokenId int, quota int) (err error) { | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	if token.RemainQuota < quota { | 	if !token.UnlimitedQuota && token.RemainQuota < quota { | ||||||
| 		return errors.New("令牌额度不足") | 		return errors.New("令牌额度不足") | ||||||
| 	} | 	} | ||||||
| 	userQuota, err := GetUserQuota(token.UserId) | 	userQuota, err := GetUserQuota(token.UserId) | ||||||
| @@ -163,17 +179,42 @@ func DecreaseTokenQuota(tokenId int, quota int) (err error) { | |||||||
| 			if email != "" { | 			if email != "" { | ||||||
| 				topUpLink := fmt.Sprintf("%s/topup", common.ServerAddress) | 				topUpLink := fmt.Sprintf("%s/topup", common.ServerAddress) | ||||||
| 				err = common.SendEmail(prompt, email, | 				err = common.SendEmail(prompt, email, | ||||||
| 					fmt.Sprintf("%s,剩余额度为 %d,为了不影响您的使用,请及时充值。<br/>充值链接:<a href='%s'>%s</a>", prompt, userQuota-quota, topUpLink, topUpLink)) | 					fmt.Sprintf("%s,当前剩余额度为 %d,为了不影响您的使用,请及时充值。<br/>充值链接:<a href='%s'>%s</a>", prompt, userQuota, topUpLink, topUpLink)) | ||||||
| 				if err != nil { | 				if err != nil { | ||||||
| 					common.SysError("发送邮件失败:" + err.Error()) | 					common.SysError("发送邮件失败:" + err.Error()) | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		}() | 		}() | ||||||
| 	} | 	} | ||||||
| 	err = DB.Model(&Token{}).Where("id = ?", tokenId).Update("remain_quota", gorm.Expr("remain_quota - ?", quota)).Error | 	if !token.UnlimitedQuota { | ||||||
| 	if err != nil { | 		err = DecreaseTokenQuota(tokenId, quota) | ||||||
| 		return err | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 	err = DecreaseUserQuota(token.UserId, quota) | 	err = DecreaseUserQuota(token.UserId, quota) | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func PostConsumeTokenQuota(tokenId int, quota int) (err error) { | ||||||
|  | 	token, err := GetTokenById(tokenId) | ||||||
|  | 	if quota > 0 { | ||||||
|  | 		err = DecreaseUserQuota(token.UserId, quota) | ||||||
|  | 	} else { | ||||||
|  | 		err = IncreaseUserQuota(token.UserId, -quota) | ||||||
|  | 	} | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	if !token.UnlimitedQuota { | ||||||
|  | 		if quota > 0 { | ||||||
|  | 			err = DecreaseTokenQuota(tokenId, quota) | ||||||
|  | 		} else { | ||||||
|  | 			err = IncreaseTokenQuota(tokenId, -quota) | ||||||
|  | 		} | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|   | |||||||
| @@ -28,6 +28,7 @@ const SystemSetting = () => { | |||||||
|     RegisterEnabled: '', |     RegisterEnabled: '', | ||||||
|     QuotaForNewUser: 0, |     QuotaForNewUser: 0, | ||||||
|     QuotaRemindThreshold: 0, |     QuotaRemindThreshold: 0, | ||||||
|  |     PreConsumedQuota: 0, | ||||||
|     ModelRatio: '', |     ModelRatio: '', | ||||||
|     TopUpLink: '', |     TopUpLink: '', | ||||||
|     AutomaticDisableChannelEnabled: '', |     AutomaticDisableChannelEnabled: '', | ||||||
| @@ -98,6 +99,7 @@ const SystemSetting = () => { | |||||||
|       name === 'TurnstileSecretKey' || |       name === 'TurnstileSecretKey' || | ||||||
|       name === 'QuotaForNewUser' || |       name === 'QuotaForNewUser' || | ||||||
|       name === 'QuotaRemindThreshold' || |       name === 'QuotaRemindThreshold' || | ||||||
|  |       name === 'PreConsumedQuota' || | ||||||
|       name === 'ModelRatio' || |       name === 'ModelRatio' || | ||||||
|       name === 'TopUpLink' |       name === 'TopUpLink' | ||||||
|     ) { |     ) { | ||||||
| @@ -119,6 +121,9 @@ const SystemSetting = () => { | |||||||
|     if (originInputs['QuotaRemindThreshold'] !== inputs.QuotaRemindThreshold) { |     if (originInputs['QuotaRemindThreshold'] !== inputs.QuotaRemindThreshold) { | ||||||
|       await updateOption('QuotaRemindThreshold', inputs.QuotaRemindThreshold); |       await updateOption('QuotaRemindThreshold', inputs.QuotaRemindThreshold); | ||||||
|     } |     } | ||||||
|  |     if (originInputs['PreConsumedQuota'] !== inputs.PreConsumedQuota) { | ||||||
|  |       await updateOption('PreConsumedQuota', inputs.PreConsumedQuota); | ||||||
|  |     } | ||||||
|     if (originInputs['ModelRatio'] !== inputs.ModelRatio) { |     if (originInputs['ModelRatio'] !== inputs.ModelRatio) { | ||||||
|       if (!verifyJSON(inputs.ModelRatio)) { |       if (!verifyJSON(inputs.ModelRatio)) { | ||||||
|         showError('模型倍率不是合法的 JSON 字符串'); |         showError('模型倍率不是合法的 JSON 字符串'); | ||||||
| @@ -272,7 +277,7 @@ const SystemSetting = () => { | |||||||
|           <Header as='h3'> |           <Header as='h3'> | ||||||
|             运营设置 |             运营设置 | ||||||
|           </Header> |           </Header> | ||||||
|           <Form.Group widths={3}> |           <Form.Group widths={4}> | ||||||
|             <Form.Input |             <Form.Input | ||||||
|               label='新用户初始配额' |               label='新用户初始配额' | ||||||
|               name='QuotaForNewUser' |               name='QuotaForNewUser' | ||||||
| @@ -302,6 +307,16 @@ const SystemSetting = () => { | |||||||
|               min='0' |               min='0' | ||||||
|               placeholder='低于此额度时将发送邮件提醒用户' |               placeholder='低于此额度时将发送邮件提醒用户' | ||||||
|             /> |             /> | ||||||
|  |             <Form.Input | ||||||
|  |               label='请求预扣费额度' | ||||||
|  |               name='PreConsumedQuota' | ||||||
|  |               onChange={handleInputChange} | ||||||
|  |               autoComplete='new-password' | ||||||
|  |               value={inputs.PreConsumedQuota} | ||||||
|  |               type='number' | ||||||
|  |               min='0' | ||||||
|  |               placeholder='请求结束后多退少补' | ||||||
|  |             /> | ||||||
|           </Form.Group> |           </Form.Group> | ||||||
|           <Form.Group widths='equal'> |           <Form.Group widths='equal'> | ||||||
|             <Form.TextArea |             <Form.TextArea | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user