记录token已使用量

This commit is contained in:
quzard 2023-05-19 00:48:10 +08:00
parent 481ba41fbd
commit ee998dcc25
5 changed files with 54 additions and 14 deletions

View File

@ -96,6 +96,8 @@ func GetTokenStatus(c *gin.Context) {
"total_used": 0, // not supported currently
"total_available": token.RemainQuota,
"expires_at": expiredAt * 1000,
"hard_limit_usd": token.RemainQuota, // 兼容openai的接口
"total_usage": token.TotalUsage * 100, // 兼容openai的接口
})
}
@ -125,6 +127,7 @@ func AddToken(c *gin.Context) {
ExpiredTime: token.ExpiredTime,
RemainQuota: token.RemainQuota,
UnlimitedQuota: token.UnlimitedQuota,
TotalUsage: token.TotalUsage,
}
err = cleanToken.Insert()
if err != nil {
@ -203,6 +206,7 @@ func UpdateToken(c *gin.Context) {
cleanToken.ExpiredTime = token.ExpiredTime
cleanToken.RemainQuota = token.RemainQuota
cleanToken.UnlimitedQuota = token.UnlimitedQuota
cleanToken.TotalUsage = token.TotalUsage
}
err = cleanToken.Update()
if err != nil {

View File

@ -19,6 +19,7 @@ type Token struct {
ExpiredTime int64 `json:"expired_time" gorm:"bigint;default:-1"` // -1 means never expired
RemainQuota int `json:"remain_quota" gorm:"default:0"`
UnlimitedQuota bool `json:"unlimited_quota" gorm:"default:false"`
TotalUsage float64 `json:"total_usage" gorm:"default:0"`
}
func GetAllUserTokens(userId int, startIdx int, num int) ([]*Token, error) {
@ -100,7 +101,7 @@ func (token *Token) Insert() error {
// Update Make sure your token's fields is completed, because this will update non-zero values
func (token *Token) Update() error {
var err error
err = DB.Model(token).Select("name", "status", "expired_time", "remain_quota", "unlimited_quota").Updates(token).Error
err = DB.Model(token).Select("name", "status", "expired_time", "remain_quota", "unlimited_quota", "total_usage").Updates(token).Error
return err
}
@ -132,7 +133,13 @@ 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
err = DB.Model(&Token{}).Where("id = ?", id).Updates(
map[string]interface{}{
"remain_quota": gorm.Expr("remain_quota + ?", quota),
"total_usage": gorm.Expr("total_usage - ?", quota),
},
).Error
return err
}
@ -140,7 +147,12 @@ 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
err = DB.Model(&Token{}).Where("id = ?", id).Updates(
map[string]interface{}{
"remain_quota": gorm.Expr("remain_quota - ?", quota),
"total_usage": gorm.Expr("total_usage + ?", quota),
},
).Error
return err
}

View File

@ -14,5 +14,7 @@ func SetDashboardRouter(router *gin.Engine) {
apiRouter.Use(middleware.TokenAuth())
{
apiRouter.GET("/billing/credit_grants", controller.GetTokenStatus)
apiRouter.GET("/billing/subscription", controller.GetTokenStatus)
apiRouter.GET("/billing/usage", controller.GetTokenStatus)
}
}

View File

@ -196,6 +196,14 @@ const TokensTable = () => {
>
额度
</Table.HeaderCell>
<Table.HeaderCell
style={{ cursor: 'pointer' }}
onClick={() => {
sortToken('total_usage');
}}
>
已使用
</Table.HeaderCell>
<Table.HeaderCell
style={{ cursor: 'pointer' }}
onClick={() => {
@ -230,6 +238,7 @@ const TokensTable = () => {
<Table.Cell>{token.name ? token.name : '无'}</Table.Cell>
<Table.Cell>{renderStatus(token.status)}</Table.Cell>
<Table.Cell>{token.unlimited_quota ? '无限制' : token.remain_quota}</Table.Cell>
<Table.Cell>{token.total_usage}</Table.Cell>
<Table.Cell>{renderTimestamp(token.created_time)}</Table.Cell>
<Table.Cell>{token.expired_time === -1 ? '永不过期' : renderTimestamp(token.expired_time)}</Table.Cell>
<Table.Cell>

View File

@ -11,11 +11,12 @@ const EditToken = () => {
const originInputs = {
name: '',
remain_quota: 0,
total_usage: 0,
expired_time: -1,
unlimited_quota: false
};
const [inputs, setInputs] = useState(originInputs);
const { name, remain_quota, expired_time, unlimited_quota } = inputs;
const { name, remain_quota, total_usage, expired_time, unlimited_quota } = inputs;
const handleInputChange = (e, { name, value }) => {
setInputs((inputs) => ({ ...inputs, [name]: value }));
@ -63,6 +64,7 @@ const EditToken = () => {
if (!isEdit && inputs.name === '') return;
let localInputs = inputs;
localInputs.remain_quota = parseInt(localInputs.remain_quota);
localInputs.total_usage = parseInt(localInputs.total_usage);
if (localInputs.expired_time !== -1) {
let time = Date.parse(localInputs.expired_time);
if (isNaN(time)) {
@ -106,6 +108,17 @@ const EditToken = () => {
required={!isEdit}
/>
</Form.Field>
<Form.Field>
<Form.Input
label='已使用额度'
name='total_usage'
placeholder={'请输入额度'}
onChange={handleInputChange}
value={total_usage}
autoComplete='new-password'
type='number'
/>
</Form.Field>
<Message>注意令牌的额度仅用于限制令牌本身的最大额度使用量实际的使用受到账户的剩余额度限制</Message>
<Form.Field>
<Form.Input