Compare commits
4 Commits
v0.3.3-alp
...
v0.3.4-alp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
34bce5b464 | ||
|
|
d4794fc051 | ||
|
|
8b43e0dd3f | ||
|
|
92c88fa273 |
41
controller/billing.go
Normal file
41
controller/billing.go
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"one-api/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetSubscription(c *gin.Context) {
|
||||||
|
userId := c.GetInt("id")
|
||||||
|
quota, err := model.GetUserQuota(userId)
|
||||||
|
if err != nil {
|
||||||
|
openAIError := OpenAIError{
|
||||||
|
Message: err.Error(),
|
||||||
|
Type: "one_api_error",
|
||||||
|
}
|
||||||
|
c.JSON(200, gin.H{
|
||||||
|
"error": openAIError,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
subscription := OpenAISubscriptionResponse{
|
||||||
|
Object: "billing_subscription",
|
||||||
|
HasPaymentMethod: true,
|
||||||
|
SoftLimitUSD: float64(quota),
|
||||||
|
HardLimitUSD: float64(quota),
|
||||||
|
SystemHardLimitUSD: float64(quota),
|
||||||
|
}
|
||||||
|
c.JSON(200, subscription)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetUsage(c *gin.Context) {
|
||||||
|
//userId := c.GetInt("id")
|
||||||
|
// TODO: get usage from database
|
||||||
|
usage := OpenAIUsageResponse{
|
||||||
|
Object: "list",
|
||||||
|
TotalUsage: 0,
|
||||||
|
}
|
||||||
|
c.JSON(200, usage)
|
||||||
|
return
|
||||||
|
}
|
||||||
@@ -13,12 +13,27 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// https://github.com/songquanpeng/one-api/issues/79
|
||||||
|
|
||||||
type OpenAISubscriptionResponse struct {
|
type OpenAISubscriptionResponse struct {
|
||||||
HasPaymentMethod bool `json:"has_payment_method"`
|
Object string `json:"object"`
|
||||||
HardLimitUSD float64 `json:"hard_limit_usd"`
|
HasPaymentMethod bool `json:"has_payment_method"`
|
||||||
|
SoftLimitUSD float64 `json:"soft_limit_usd"`
|
||||||
|
HardLimitUSD float64 `json:"hard_limit_usd"`
|
||||||
|
SystemHardLimitUSD float64 `json:"system_hard_limit_usd"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type OpenAIUsageDailyCost struct {
|
||||||
|
Timestamp float64 `json:"timestamp"`
|
||||||
|
LineItems []struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Cost float64 `json:"cost"`
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type OpenAIUsageResponse struct {
|
type OpenAIUsageResponse struct {
|
||||||
|
Object string `json:"object"`
|
||||||
|
//DailyCosts []OpenAIUsageDailyCost `json:"daily_costs"`
|
||||||
TotalUsage float64 `json:"total_usage"` // unit: 0.01 dollar
|
TotalUsage float64 `json:"total_usage"` // unit: 0.01 dollar
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,11 @@ import (
|
|||||||
|
|
||||||
func Cache() func(c *gin.Context) {
|
func Cache() func(c *gin.Context) {
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
c.Header("Cache-Control", "max-age=604800") // one week
|
if c.Request.RequestURI == "/" {
|
||||||
|
c.Header("Cache-Control", "no-cache")
|
||||||
|
} else {
|
||||||
|
c.Header("Cache-Control", "max-age=604800") // one week
|
||||||
|
}
|
||||||
c.Next()
|
c.Next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,11 +8,14 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func SetDashboardRouter(router *gin.Engine) {
|
func SetDashboardRouter(router *gin.Engine) {
|
||||||
apiRouter := router.Group("/dashboard")
|
apiRouter := router.Group("/")
|
||||||
apiRouter.Use(gzip.Gzip(gzip.DefaultCompression))
|
apiRouter.Use(gzip.Gzip(gzip.DefaultCompression))
|
||||||
apiRouter.Use(middleware.GlobalAPIRateLimit())
|
apiRouter.Use(middleware.GlobalAPIRateLimit())
|
||||||
apiRouter.Use(middleware.TokenAuth())
|
apiRouter.Use(middleware.TokenAuth())
|
||||||
{
|
{
|
||||||
apiRouter.GET("/billing/credit_grants", controller.GetTokenStatus)
|
apiRouter.GET("/dashboard/billing/subscription", controller.GetSubscription)
|
||||||
|
apiRouter.GET("/v1/dashboard/billing/subscription", controller.GetSubscription)
|
||||||
|
apiRouter.GET("/dashboard/billing/usage", controller.GetUsage)
|
||||||
|
apiRouter.GET("/v1/dashboard/billing/usage", controller.GetUsage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ func SetWebRouter(router *gin.Engine, buildFS embed.FS, indexPage []byte) {
|
|||||||
router.Use(middleware.Cache())
|
router.Use(middleware.Cache())
|
||||||
router.Use(static.Serve("/", common.EmbedFolder(buildFS, "web/build")))
|
router.Use(static.Serve("/", common.EmbedFolder(buildFS, "web/build")))
|
||||||
router.NoRoute(func(c *gin.Context) {
|
router.NoRoute(func(c *gin.Context) {
|
||||||
c.Header("Cache-Control", "no-cache, no-store, must-revalidate")
|
c.Header("Cache-Control", "no-cache")
|
||||||
c.Data(http.StatusOK, "text/html; charset=utf-8", indexPage)
|
c.Data(http.StatusOK, "text/html; charset=utf-8", indexPage)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ const EditChannel = () => {
|
|||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
<Button onClick={submit}>提交</Button>
|
<Button positive onClick={submit}>提交</Button>
|
||||||
</Form>
|
</Form>
|
||||||
</Segment>
|
</Segment>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ const EditRedemption = () => {
|
|||||||
</Form.Field>
|
</Form.Field>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
<Button onClick={submit}>提交</Button>
|
<Button positive onClick={submit}>提交</Button>
|
||||||
</Form>
|
</Form>
|
||||||
</Segment>
|
</Segment>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -133,22 +133,24 @@ const EditToken = () => {
|
|||||||
type='datetime-local'
|
type='datetime-local'
|
||||||
/>
|
/>
|
||||||
</Form.Field>
|
</Form.Field>
|
||||||
<Button type={'button'} onClick={() => {
|
<div style={{ lineHeight: '40px' }}>
|
||||||
setExpiredTime(0, 0, 0, 0);
|
<Button type={'button'} onClick={() => {
|
||||||
}}>永不过期</Button>
|
setExpiredTime(0, 0, 0, 0);
|
||||||
<Button type={'button'} onClick={() => {
|
}}>永不过期</Button>
|
||||||
setExpiredTime(1, 0, 0, 0);
|
<Button type={'button'} onClick={() => {
|
||||||
}}>一个月后过期</Button>
|
setExpiredTime(1, 0, 0, 0);
|
||||||
<Button type={'button'} onClick={() => {
|
}}>一个月后过期</Button>
|
||||||
setExpiredTime(0, 1, 0, 0);
|
<Button type={'button'} onClick={() => {
|
||||||
}}>一天后过期</Button>
|
setExpiredTime(0, 1, 0, 0);
|
||||||
<Button type={'button'} onClick={() => {
|
}}>一天后过期</Button>
|
||||||
setExpiredTime(0, 0, 1, 0);
|
<Button type={'button'} onClick={() => {
|
||||||
}}>一小时后过期</Button>
|
setExpiredTime(0, 0, 1, 0);
|
||||||
<Button type={'button'} onClick={() => {
|
}}>一小时后过期</Button>
|
||||||
setExpiredTime(0, 0, 0, 1);
|
<Button type={'button'} onClick={() => {
|
||||||
}}>一分钟后过期</Button>
|
setExpiredTime(0, 0, 0, 1);
|
||||||
<Button onClick={submit}>提交</Button>
|
}}>一分钟后过期</Button>
|
||||||
|
</div>
|
||||||
|
<Button positive onClick={submit} style={{marginTop: '12px'}}>提交</Button>
|
||||||
</Form>
|
</Form>
|
||||||
</Segment>
|
</Segment>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ const AddUser = () => {
|
|||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</Form.Field>
|
</Form.Field>
|
||||||
<Button type={'submit'} onClick={submit}>
|
<Button positive type={'submit'} onClick={submit}>
|
||||||
提交
|
提交
|
||||||
</Button>
|
</Button>
|
||||||
</Form>
|
</Form>
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ const EditUser = () => {
|
|||||||
readOnly
|
readOnly
|
||||||
/>
|
/>
|
||||||
</Form.Field>
|
</Form.Field>
|
||||||
<Button onClick={submit}>提交</Button>
|
<Button positive onClick={submit}>提交</Button>
|
||||||
</Form>
|
</Form>
|
||||||
</Segment>
|
</Segment>
|
||||||
</>
|
</>
|
||||||
|
|||||||
Reference in New Issue
Block a user