From 3202ca9f3e2a5337e75b1bd0b4f467e8487e9a00 Mon Sep 17 00:00:00 2001
From: CaIon <1808837298@qq.com>
Date: Sun, 12 Nov 2023 18:51:26 +0800
Subject: [PATCH 1/3] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BD=99=E9=A2=9D?=
=?UTF-8?q?=E4=B8=8D=E8=B6=B3=E9=82=AE=E4=BB=B6=E6=8F=90=E9=86=92bug?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
controller/relay-audio.go | 4 +--
controller/relay-image.go | 2 +-
controller/relay-mj.go | 2 +-
controller/relay-text.go | 6 ++--
model/token.go | 65 ++++++++++++++++++++-------------------
5 files changed, 40 insertions(+), 39 deletions(-)
diff --git a/controller/relay-audio.go b/controller/relay-audio.go
index bf6a0dfe..fe91dbc6 100644
--- a/controller/relay-audio.go
+++ b/controller/relay-audio.go
@@ -44,7 +44,7 @@ func relayAudioHelper(c *gin.Context, relayMode int) *OpenAIErrorWithStatusCode
preConsumedQuota = 0
}
if preConsumedQuota > 0 {
- err := model.PreConsumeTokenQuota(tokenId, preConsumedQuota)
+ userQuota, err = model.PreConsumeTokenQuota(tokenId, preConsumedQuota)
if err != nil {
return errorWrapper(err, "pre_consume_token_quota_failed", http.StatusForbidden)
}
@@ -99,7 +99,7 @@ func relayAudioHelper(c *gin.Context, relayMode int) *OpenAIErrorWithStatusCode
go func() {
quota := countTokenText(audioResponse.Text, audioModel)
quotaDelta := quota - preConsumedQuota
- err := model.PostConsumeTokenQuota(tokenId, quotaDelta)
+ err := model.PostConsumeTokenQuota(tokenId, userQuota, quotaDelta, preConsumedQuota)
if err != nil {
common.SysError("error consuming token remain quota: " + err.Error())
}
diff --git a/controller/relay-image.go b/controller/relay-image.go
index 89dc8212..5cebcdb1 100644
--- a/controller/relay-image.go
+++ b/controller/relay-image.go
@@ -147,7 +147,7 @@ func relayImageHelper(c *gin.Context, relayMode int) *OpenAIErrorWithStatusCode
var textResponse ImageResponse
defer func(ctx context.Context) {
if consumeQuota {
- err := model.PostConsumeTokenQuota(tokenId, quota)
+ err := model.PostConsumeTokenQuota(tokenId, userId, quota, 0)
if err != nil {
common.SysError("error consuming token remain quota: " + err.Error())
}
diff --git a/controller/relay-mj.go b/controller/relay-mj.go
index 4f852341..948c57c0 100644
--- a/controller/relay-mj.go
+++ b/controller/relay-mj.go
@@ -359,7 +359,7 @@ func relayMidjourneySubmit(c *gin.Context, relayMode int) *MidjourneyResponse {
defer func(ctx context.Context) {
if consumeQuota {
- err := model.PostConsumeTokenQuota(tokenId, quota)
+ err := model.PostConsumeTokenQuota(tokenId, userQuota, quota, 0)
if err != nil {
common.SysError("error consuming token remain quota: " + err.Error())
}
diff --git a/controller/relay-text.go b/controller/relay-text.go
index 84dc5822..6f56be8f 100644
--- a/controller/relay-text.go
+++ b/controller/relay-text.go
@@ -233,7 +233,7 @@ func relayTextHelper(c *gin.Context, relayMode int) *OpenAIErrorWithStatusCode {
//common.LogInfo(c.Request.Context(), fmt.Sprintf("user %d has enough quota %d, trusted and no need to pre-consume", userId, userQuota))
}
if consumeQuota && preConsumedQuota > 0 {
- err := model.PreConsumeTokenQuota(tokenId, preConsumedQuota)
+ userQuota, err = model.PreConsumeTokenQuota(tokenId, preConsumedQuota)
if err != nil {
return errorWrapper(err, "pre_consume_token_quota_failed", http.StatusForbidden)
}
@@ -400,7 +400,7 @@ func relayTextHelper(c *gin.Context, relayMode int) *OpenAIErrorWithStatusCode {
if preConsumedQuota != 0 {
go func(ctx context.Context) {
// return pre-consumed quota
- err := model.PostConsumeTokenQuota(tokenId, -preConsumedQuota)
+ err := model.PostConsumeTokenQuota(tokenId, userQuota, -preConsumedQuota, 0)
if err != nil {
common.LogError(ctx, "error return pre-consumed quota: "+err.Error())
}
@@ -434,7 +434,7 @@ func relayTextHelper(c *gin.Context, relayMode int) *OpenAIErrorWithStatusCode {
quota = 0
}
quotaDelta := quota - preConsumedQuota
- err := model.PostConsumeTokenQuota(tokenId, quotaDelta)
+ err := model.PostConsumeTokenQuota(tokenId, userQuota, quotaDelta, preConsumedQuota)
if err != nil {
common.LogError(ctx, "error consuming token remain quota: "+err.Error())
}
diff --git a/model/token.go b/model/token.go
index 41746d9a..06b97750 100644
--- a/model/token.go
+++ b/model/token.go
@@ -178,59 +178,60 @@ func decreaseTokenQuota(id int, quota int) (err error) {
return err
}
-func PreConsumeTokenQuota(tokenId int, quota int) (err error) {
+func PreConsumeTokenQuota(tokenId int, quota int) (userQuota int, err error) {
if quota < 0 {
- return errors.New("quota 不能为负数!")
+ return 0, errors.New("quota 不能为负数!")
}
token, err := GetTokenById(tokenId)
if err != nil {
- return err
+ return 0, err
}
if !token.UnlimitedQuota && token.RemainQuota < quota {
- return errors.New("令牌额度不足")
+ return 0, errors.New("令牌额度不足")
}
- userQuota, err := GetUserQuota(token.UserId)
+ userQuota, err = GetUserQuota(token.UserId)
if err != nil {
- return err
+ return 0, err
}
if userQuota < quota {
- return errors.New("用户额度不足")
- }
- quotaTooLow := userQuota >= common.QuotaRemindThreshold && userQuota-quota < common.QuotaRemindThreshold
- noMoreQuota := userQuota-quota <= 0
- if quotaTooLow || noMoreQuota {
- go func() {
- email, err := GetUserEmail(token.UserId)
- if err != nil {
- common.SysError("failed to fetch user email: " + err.Error())
- }
- prompt := "您的额度即将用尽"
- if noMoreQuota {
- prompt = "您的额度已用尽"
- }
- if email != "" {
- topUpLink := fmt.Sprintf("%s/topup", common.ServerAddress)
- err = common.SendEmail(prompt, email,
- fmt.Sprintf("%s,当前剩余额度为 %d,为了不影响您的使用,请及时充值。
充值链接:%s", prompt, userQuota, topUpLink, topUpLink))
- if err != nil {
- common.SysError("failed to send email" + err.Error())
- }
- }
- }()
+ return userQuota, errors.New(fmt.Sprintf("用户额度不足,剩余额度为 %d", userQuota))
}
if !token.UnlimitedQuota {
err = DecreaseTokenQuota(tokenId, quota)
if err != nil {
- return err
+ return userQuota, err
}
}
err = DecreaseUserQuota(token.UserId, quota)
- return err
+ return userQuota, err
}
-func PostConsumeTokenQuota(tokenId int, quota int) (err error) {
+func PostConsumeTokenQuota(tokenId int, userQuota int, quota int, preConsumedQuota int) (err error) {
token, err := GetTokenById(tokenId)
+
if quota > 0 {
+ quotaTooLow := userQuota >= common.QuotaRemindThreshold && userQuota-(quota+preConsumedQuota) < common.QuotaRemindThreshold
+ noMoreQuota := userQuota-(quota+preConsumedQuota) <= 0
+ if quotaTooLow || noMoreQuota {
+ go func() {
+ email, err := GetUserEmail(token.UserId)
+ if err != nil {
+ common.SysError("failed to fetch user email: " + err.Error())
+ }
+ prompt := "您的额度即将用尽"
+ if noMoreQuota {
+ prompt = "您的额度已用尽"
+ }
+ if email != "" {
+ topUpLink := fmt.Sprintf("%s/topup", common.ServerAddress)
+ err = common.SendEmail(prompt, email,
+ fmt.Sprintf("%s,当前剩余额度为 %d,为了不影响您的使用,请及时充值。
充值链接:%s", prompt, userQuota, topUpLink, topUpLink))
+ if err != nil {
+ common.SysError("failed to send email" + err.Error())
+ }
+ }
+ }()
+ }
err = DecreaseUserQuota(token.UserId, quota)
} else {
err = IncreaseUserQuota(token.UserId, -quota)
From 49136f29f9880465749316f9f40affb67e961a44 Mon Sep 17 00:00:00 2001
From: Calcium-Ion <61247483+Calcium-Ion@users.noreply.github.com>
Date: Fri, 10 Nov 2023 13:53:04 -0600
Subject: [PATCH 2/3] Update README.md
(cherry picked from commit 31d3fd1eb67538f472b10dadb1ba21ac13d2e384)
---
README.md | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/README.md b/README.md
index 699551d2..89dfba3b 100644
--- a/README.md
+++ b/README.md
@@ -29,3 +29,14 @@
5. 渠道显示已使用额度,支持指定组织访问
6. 分页支持选择每页显示数量
+## 界面截图
+
+
+
+
+夜间模式
+
+
+
+
+
From d788c05621e5cbce5aa0d91c7d20aec96a4657b1 Mon Sep 17 00:00:00 2001
From: CaIon <1808837298@qq.com>
Date: Sun, 12 Nov 2023 19:04:05 +0800
Subject: [PATCH 3/3] delete workflow file
---
.github/workflows/docker-image.yml | 32 ------------------------------
1 file changed, 32 deletions(-)
delete mode 100644 .github/workflows/docker-image.yml
diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml
deleted file mode 100644
index 7b6d3fda..00000000
--- a/.github/workflows/docker-image.yml
+++ /dev/null
@@ -1,32 +0,0 @@
-name: Docker Image CI
-
-on:
- push:
- branches: [ "main" ]
- pull_request:
- branches: [ "main" ]
-
-jobs:
-
- build:
-
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@v3
- - uses: docker/login-action@v3.0.0
- with:
- username: ${{ secrets.DOCKERHUB_USERNAME }}
- password: ${{ secrets.DOCKERHUB_TOKEN }}
- - name: Extract metadata (tags, labels) for Docker
- id: meta
- uses: docker/metadata-action@v3
- with:
- images: calciumion/neko-api
- - name: Build the Docker image
- uses: docker/build-push-action@v5.0.0
- with:
- context: .
- push: true
- tags: ${{ steps.meta.outputs.tags }}
- labels: ${{ steps.meta.outputs.labels }}