Skip to content

Commit 1b11b60

Browse files
committed
feat: update version to 4.0.0
1 parent 929c8a7 commit 1b11b60

File tree

251 files changed

+27491
-9460
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

251 files changed

+27491
-9460
lines changed

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ access/*.json
2525
db
2626
redis
2727
config
28+
presets
2829

29-
# for opencommit
30+
key/*
31+
!key/.gitkeep
32+
33+
# for https://github.com/di-sukharev/opencommit
3034
.env
Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
package admin
1+
package analysis
22

33
import (
44
"chat/channel"
55
"chat/globals"
66
"chat/utils"
77
"database/sql"
8-
"github.com/go-redis/redis/v8"
98
"time"
9+
10+
"github.com/go-redis/redis/v8"
1011
)
1112

1213
type UserTypeForm struct {
@@ -28,6 +29,10 @@ func getFormat(t time.Time) string {
2829
return t.Format("2006-01-02")
2930
}
3031

32+
func getMinuteFormat(t time.Time) string {
33+
return t.Format("2006-01-02 15:04")
34+
}
35+
3136
func GetSubscriptionUsers(db *sql.DB) int64 {
3237
var count int64
3338
err := globals.QueryRowDb(db, `
@@ -44,10 +49,30 @@ func GetBillingToday(cache *redis.Client) float32 {
4449
return float32(utils.MustInt(cache, getBillingFormat(getDay()))) / 100
4550
}
4651

52+
func GetBillingYesterday(cache *redis.Client) float32 {
53+
return float32(utils.MustInt(cache, getBillingFormat(getLastDay()))) / 100
54+
}
55+
4756
func GetBillingMonth(cache *redis.Client) float32 {
4857
return float32(utils.MustInt(cache, getMonthBillingFormat(getMonth()))) / 100
4958
}
5059

60+
func GetBillingLastMonth(cache *redis.Client) float32 {
61+
return float32(utils.MustInt(cache, getMonthBillingFormat(getLastMonth()))) / 100
62+
}
63+
64+
func GetTpmToday(cache *redis.Client, user string) int64 {
65+
// this minute and last minute
66+
return utils.MustInt(cache, getTpmFormat(getMinuteFormat(time.Now()), user)) +
67+
utils.MustInt(cache, getTpmFormat(getMinuteFormat(time.Now().Add(-time.Minute)), user))
68+
}
69+
70+
func GetRpmToday(cache *redis.Client, user string) int64 {
71+
// this minute and last minute
72+
return utils.MustInt(cache, getRpmFormat(getMinuteFormat(time.Now()), user)) +
73+
utils.MustInt(cache, getRpmFormat(getMinuteFormat(time.Now().Add(-time.Minute)), user))
74+
}
75+
5176
func GetModelData(cache *redis.Client) ModelChartForm {
5277
dates := getDays(7)
5378

admin/analysis/format.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package analysis
2+
3+
import (
4+
"fmt"
5+
"time"
6+
)
7+
8+
func getMonth() string {
9+
date := time.Now()
10+
return date.Format("2006-01")
11+
}
12+
13+
func getLastMonth() string {
14+
date := time.Now().AddDate(0, -1, 0)
15+
return date.Format("2006-01")
16+
}
17+
18+
func getDay() string {
19+
date := time.Now()
20+
return date.Format("2006-01-02")
21+
}
22+
23+
func getLastDay() string {
24+
date := time.Now().AddDate(0, 0, -1)
25+
return date.Format("2006-01-02")
26+
}
27+
28+
func getDays(n int) []time.Time {
29+
current := time.Now()
30+
var days []time.Time
31+
for i := n; i > 0; i-- {
32+
days = append(days, current.AddDate(0, 0, -i+1))
33+
}
34+
35+
return days
36+
}
37+
38+
func getErrorFormat(t string) string {
39+
return fmt.Sprintf("nio:err-analysis-%s", t)
40+
}
41+
42+
func getBillingFormat(t string) string {
43+
return fmt.Sprintf("nio:billing-analysis-%s", t)
44+
}
45+
46+
func getMonthBillingFormat(t string) string {
47+
return fmt.Sprintf("nio:billing-analysis-%s", t)
48+
}
49+
50+
func getRequestFormat(t string) string {
51+
return fmt.Sprintf("nio:request-analysis-%s", t)
52+
}
53+
54+
func getModelFormat(t string, model string) string {
55+
return fmt.Sprintf("nio:model-analysis-%s-%s", model, t)
56+
}
57+
58+
func getTpmFormat(t string, user string) string {
59+
return fmt.Sprintf("nio:tpm-analysis-%s-%s", user, t)
60+
}
61+
62+
func getRpmFormat(t string, user string) string {
63+
return fmt.Sprintf("nio:rpm-analysis-%s-%s", user, t)
64+
}

admin/analysis/reflect.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package analysis
2+
3+
import "reflect"
4+
5+
var _ = reflect.TypeOf(UserTypeForm{})
6+
var _ = reflect.TypeOf(ModelData{})
7+
var _ = reflect.TypeOf(ModelChartForm{})
8+
var _ = reflect.TypeOf(RequestChartForm{})
9+
var _ = reflect.TypeOf(BillingChartForm{})
10+
var _ = reflect.TypeOf(ErrorChartForm{})

admin/analysis/statistic.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package analysis
2+
3+
import (
4+
"chat/adapter"
5+
"chat/connection"
6+
"chat/utils"
7+
"time"
8+
9+
"github.com/go-redis/redis/v8"
10+
)
11+
12+
func IncrErrorRequest(cache *redis.Client) {
13+
utils.IncrOnce(cache, getErrorFormat(getDay()), time.Hour*24*7*2)
14+
}
15+
16+
func IncrBillingRequest(cache *redis.Client, amount int64, isAdmin bool) {
17+
if isAdmin {
18+
// do not count billing for admin user
19+
return
20+
}
21+
22+
utils.IncrWithExpire(cache, getBillingFormat(getDay()), amount, time.Hour*24*90) // 90 days
23+
utils.IncrWithExpire(cache, getMonthBillingFormat(getMonth()), amount, time.Hour*24*90) // 90 days
24+
}
25+
26+
func IncrRequest(cache *redis.Client) {
27+
utils.IncrOnce(cache, getRequestFormat(getDay()), time.Hour*24*7*2)
28+
}
29+
30+
func IncrModelRequest(cache *redis.Client, model string, tokens int64) {
31+
utils.IncrWithExpire(cache, getModelFormat(getDay(), model), tokens, time.Hour*24*7*2)
32+
}
33+
34+
func AnalyseRequest(model string, user string, buffer *utils.Buffer, err error) {
35+
instance := connection.Cache
36+
37+
if adapter.IsAvailableError(err) {
38+
IncrErrorRequest(instance)
39+
return
40+
}
41+
42+
token := int64(buffer.CountInputToken() + buffer.CountOutputToken(false))
43+
44+
IncrRequest(instance)
45+
IncrModelRequest(instance, model, token)
46+
47+
if buffer != nil {
48+
IncrRpm(instance, user, 1)
49+
IncrTpm(instance, user, token)
50+
51+
// add rpm/tpm to root
52+
IncrRpm(instance, "root", 1)
53+
IncrTpm(instance, "root", token)
54+
}
55+
}
56+
57+
func IncrTpm(cache *redis.Client, user string, n int64) {
58+
utils.IncrWithExpire(cache, getTpmFormat(getMinuteFormat(time.Now()), user), n, time.Minute*5)
59+
}
60+
61+
func IncrRpm(cache *redis.Client, user string, n int64) {
62+
utils.IncrWithExpire(cache, getRpmFormat(getMinuteFormat(time.Now()), user), n, time.Minute*5)
63+
}

admin/analysis/types.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package analysis
2+
3+
type ModelData struct {
4+
Model string `json:"model"`
5+
Data []int64 `json:"data"`
6+
}
7+
8+
type ModelChartForm struct {
9+
Date []string `json:"date"`
10+
Value []ModelData `json:"value"`
11+
}
12+
13+
type RequestChartForm struct {
14+
Date []string `json:"date"`
15+
Value []int64 `json:"value"`
16+
}
17+
18+
type BillingChartForm struct {
19+
Date []string `json:"date"`
20+
Value []float32 `json:"value"`
21+
}
22+
23+
type ErrorChartForm struct {
24+
Date []string `json:"date"`
25+
Value []int64 `json:"value"`
26+
}

admin/controller.go

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package admin
22

33
import (
4+
"chat/admin/analysis"
45
"chat/utils"
56
"net/http"
67
"strconv"
@@ -48,7 +49,8 @@ type BanForm struct {
4849
type QuotaOperationForm struct {
4950
Id int64 `json:"id" binding:"required"`
5051
Quota *float32 `json:"quota" binding:"required"`
51-
Override bool `json:"override"`}
52+
Override bool `json:"override"`
53+
}
5254

5355
type SubscriptionOperationForm struct {
5456
Id int64 `json:"id" binding:"required"`
@@ -97,36 +99,39 @@ func InfoAPI(c *gin.Context) {
9799
cache := utils.GetCacheFromContext(c)
98100

99101
c.JSON(http.StatusOK, InfoForm{
100-
SubscriptionCount: GetSubscriptionUsers(db),
101-
BillingToday: GetBillingToday(cache),
102-
BillingMonth: GetBillingMonth(cache),
102+
OnlineChats: utils.GetConns(),
103+
SubscriptionCount: analysis.GetSubscriptionUsers(db),
104+
BillingToday: analysis.GetBillingToday(cache),
105+
BillingMonth: analysis.GetBillingMonth(cache),
106+
BillingYesterday: analysis.GetBillingYesterday(cache),
107+
BillingLastMonth: analysis.GetBillingLastMonth(cache),
103108
})
104109
}
105110

106111
func ModelAnalysisAPI(c *gin.Context) {
107112
cache := utils.GetCacheFromContext(c)
108-
c.JSON(http.StatusOK, GetSortedModelData(cache))
113+
c.JSON(http.StatusOK, analysis.GetSortedModelData(cache))
109114
}
110115

111116
func RequestAnalysisAPI(c *gin.Context) {
112117
cache := utils.GetCacheFromContext(c)
113-
c.JSON(http.StatusOK, GetRequestData(cache))
118+
c.JSON(http.StatusOK, analysis.GetRequestData(cache))
114119
}
115120

116121
func BillingAnalysisAPI(c *gin.Context) {
117122
cache := utils.GetCacheFromContext(c)
118-
c.JSON(http.StatusOK, GetBillingData(cache))
123+
c.JSON(http.StatusOK, analysis.GetBillingData(cache))
119124
}
120125

121126
func ErrorAnalysisAPI(c *gin.Context) {
122127
cache := utils.GetCacheFromContext(c)
123-
c.JSON(http.StatusOK, GetErrorData(cache))
128+
c.JSON(http.StatusOK, analysis.GetErrorData(cache))
124129
}
125130

126131
func UserTypeAnalysisAPI(c *gin.Context) {
127132
db := utils.GetDBFromContext(c)
128-
if form, err := GetUserTypeData(db); err != nil {
129-
c.JSON(http.StatusOK, &UserTypeForm{})
133+
if form, err := analysis.GetUserTypeData(db); err != nil {
134+
c.JSON(http.StatusOK, &analysis.UserTypeForm{})
130135
} else {
131136
c.JSON(http.StatusOK, form)
132137
}
@@ -364,26 +369,26 @@ func UserSubscriptionAPI(c *gin.Context) {
364369
return
365370
}
366371

367-
// convert to time
368-
if _, err := time.Parse("2006-01-02 15:04:05", form.Expired); err != nil {
369-
c.JSON(http.StatusOK, gin.H{
370-
"status": false,
371-
"message": err.Error(),
372-
})
373-
return
374-
}
372+
// convert to time
373+
if _, err := time.Parse("2006-01-02 15:04:05", form.Expired); err != nil {
374+
c.JSON(http.StatusOK, gin.H{
375+
"status": false,
376+
"message": err.Error(),
377+
})
378+
return
379+
}
380+
381+
if err := subscriptionMigration(db, form.Id, form.Expired); err != nil {
382+
c.JSON(http.StatusOK, gin.H{
383+
"status": false,
384+
"message": err.Error(),
385+
})
386+
return
387+
}
375388

376-
if err := subscriptionMigration(db, form.Id, form.Expired); err != nil {
377389
c.JSON(http.StatusOK, gin.H{
378-
"status": false,
379-
"message": err.Error(),
390+
"status": true,
380391
})
381-
return
382-
}
383-
384-
c.JSON(http.StatusOK, gin.H{
385-
"status": true,
386-
})
387392
}
388393

389394
func SubscriptionLevelAPI(c *gin.Context) {

admin/types.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ var pagination int64 = 10
55
type InfoForm struct {
66
BillingToday float32 `json:"billing_today"`
77
BillingMonth float32 `json:"billing_month"`
8+
BillingYesterday float32 `json:"billing_yesterday"`
9+
BillingLastMonth float32 `json:"billing_last_month"`
810
SubscriptionCount int64 `json:"subscription_count"`
11+
OnlineChats int64 `json:"online_chats"`
912
}
1013

1114
type ModelData struct {

0 commit comments

Comments
 (0)