├── .github └── workflows │ └── go.yml ├── .gitignore ├── LICENSE ├── README.md ├── cmd ├── gen │ └── main.go └── server │ └── main.go ├── common ├── aiClient │ ├── getter.go │ ├── init.go │ └── types.go ├── auth │ ├── auth.go │ ├── password │ │ ├── password.go │ │ └── password_test.go │ └── u_info.go ├── bizError │ └── biz_error.go ├── config │ ├── config.go │ ├── global.go │ └── init.go ├── constant │ └── constant.go ├── db │ ├── db.go │ └── gen.go ├── email │ ├── email.go │ └── template.go ├── env │ └── env.go ├── goUtil │ └── recover.go ├── inviteCodeGen │ ├── invite_code.go │ ├── invite_code2.go │ └── invite_code_test.go ├── logs │ └── log.go ├── random │ └── rand_number.go ├── redis │ ├── contents.go │ └── v6.go ├── regexp │ └── phone_email_regexp.go └── types │ ├── converter.go │ ├── dataTrance.go │ ├── id.go │ ├── slice.go │ └── time.go ├── config └── prod.yml ├── dao ├── action.gen.go ├── aikey.gen.go ├── amount_details.gen.go ├── carmi.gen.go ├── cashback.gen.go ├── config.gen.go ├── dialog.gen.go ├── draw_record.gen.go ├── gen.go ├── installed_plugin.gen.go ├── invite_record.gen.go ├── message.gen.go ├── mytables.gen.go ├── notification.gen.go ├── order.gen.go ├── payment.gen.go ├── persona.gen.go ├── plugin.gen.go ├── product.gen.go ├── reward.gen.go ├── signin.gen.go ├── turnover.gen.go ├── upload_record.gen.go ├── user.gen.go └── withdrawal_record.gen.go ├── docs ├── ChatGpt-Web-Api.md └── openai.svg ├── go.mod ├── model ├── action.gen.go ├── aikey.gen.go ├── amount_details.gen.go ├── carmi.gen.go ├── cashback.gen.go ├── config.gen.go ├── dialog.gen.go ├── draw_record.gen.go ├── installed_plugin.gen.go ├── invite_record.gen.go ├── message.gen.go ├── mytables.gen.go ├── notification.gen.go ├── order.gen.go ├── payment.gen.go ├── persona.gen.go ├── plugin.gen.go ├── product.gen.go ├── reward.gen.go ├── signin.gen.go ├── sql │ └── chatgpt.sql ├── turnover.gen.go ├── upload_record.gen.go ├── user.gen.go ├── user.go └── withdrawal_record.gen.go ├── router ├── admin.go ├── admin │ ├── amountHandlers │ │ └── handler.go │ ├── carmiHandlers │ │ └── handler.go │ ├── cashbackHandlers │ │ └── handler.go │ ├── configHandlers │ │ └── handler.go │ ├── dialogHandlers │ │ └── handler.go │ ├── drawHandlers │ │ └── handler.go │ ├── inviteHandlers │ │ └── handler.go │ ├── messageHandlers │ │ └── handler.go │ ├── notificationHandlers │ │ └── handler.go │ ├── orderHandlers │ │ └── handler.go │ ├── payHandlers │ │ └── handler.go │ ├── personaHandlers │ │ └── handler.go │ ├── pluginHandlers │ │ └── handler.go │ ├── productHandlers │ │ └── handler.go │ ├── signinHandlers │ │ └── handler.go │ ├── tokenHandlers │ │ └── handler.go │ ├── turnoverHandlers │ │ └── handler.go │ ├── userHandlers │ │ └── handler.go │ └── withdrawalHandlers │ │ └── handler.go ├── base │ ├── base.go │ ├── request.go │ └── response.go ├── front │ ├── authHandlers │ │ ├── handlers.go │ │ ├── request.go │ │ └── vo.go │ ├── carmiHandlers │ │ ├── handler.go │ │ └── request.go │ ├── chatHandlers │ │ └── handler.go │ ├── configHandlers │ │ └── handler.go │ ├── imagesHandlers │ │ ├── handler.go │ │ └── request.go │ ├── messageHandlers │ │ └── handler.go │ ├── payHandlers │ │ └── handler.go │ ├── personaHandlers │ │ └── handler.go │ ├── pluginHandlers │ │ └── handler.go │ ├── productHandlers │ │ ├── handler.go │ │ └── response.go │ ├── signInHandlers │ │ └── signin.go │ ├── turnoverHandlers │ │ ├── handler.go │ │ └── response.go │ └── userHandlers │ │ ├── handler.go │ │ └── response.go ├── middlewares │ ├── cors.go │ ├── jwt.go │ └── u_info.go └── root.go └── service ├── amount └── amount.go ├── auth ├── login.go └── password.go ├── carmi ├── admin.go ├── carmi.go ├── carmi_type.go └── request.go ├── cashback └── cashback.go ├── config ├── admin.go ├── config.go └── models.go ├── dialog └── dialog.go ├── draw ├── admin.go ├── draw_model.go ├── draw_openai.go ├── draw_sd.go ├── draw_strategy.go ├── proccess.go ├── request.go └── service.go ├── gpt ├── gpt_test.go ├── process.go └── requst.go ├── invite └── invite.go ├── message ├── dto.go ├── message_service.go └── response.go ├── notification └── notification.go ├── order └── order.go ├── pay ├── admin.go └── pay.go ├── persona ├── admin.go └── persona.go ├── plugin ├── admin.go └── plugin.go ├── product └── product.go ├── signin ├── admin.go └── sign.go ├── sns └── sns_codee.go ├── token └── admin.go ├── turnover ├── admin.go └── service3.go ├── user ├── admin.go └── user.go └── withdrawal └── withdrawal.go /.github/workflows/go.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a golang project 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go 3 | 4 | name: Go 5 | 6 | on: 7 | push: 8 | branches: [ "master" ] 9 | pull_request: 10 | branches: [ "master" ] 11 | 12 | jobs: 13 | 14 | build: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v3 18 | 19 | - name: Set up Go 20 | uses: actions/setup-go@v4 21 | with: 22 | go-version: '1.20' 23 | 24 | - name: Build 25 | run: | 26 | go mod tidy 27 | go build -v ./... 28 | 29 | # - name: Test 30 | # run: go test -v ./... 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | .idea/ 8 | .vscode/ 9 | wechatbot 10 | storage.json 11 | 12 | # Test binary, built with `go test -c` 13 | *.test 14 | 15 | # Output of the go coverage tool, specifically when used with LiteIDE 16 | *.out 17 | 18 | # Dependency directories (remove the comment below to include it) 19 | # vendor/ 20 | /config.json 21 | /config/dev.yml 22 | 23 | go.sum 24 | 25 | # log 26 | log/ 27 | *.log 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 79E 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | icon 3 | 4 |

ChatGPT Web Go

5 | 6 | A commercially-viable ChatGpt web application built with Go. 7 | 8 | 可部署商业化的 ChatGpt 网页应用。 9 | 10 | 💡 本项目是后端服务,前端对应的项目是:[79E/ChatGPT-Web](https://github.com/79E/ChatGPT-Web/) 11 | 12 | 13 | [提交问题 Issues](https://github.com/heimeropen/chatgpt-web-go/issues) 14 | 15 | 16 |
17 | 18 | ## 交流群 19 | 20 | 21 | chatgpt-web-go 22 | 23 | 24 | 25 | ## 主要功能 26 | #### 包括但不限于: 27 | - 后台管理系统,可对用户,Token,商品,卡密等进行管理 28 | - 精心设计的 UI,响应式设计 29 | - 极快的首屏加载速度(~100kb) 30 | - 支持Midjourney绘画和DALL·E模型绘画,GPT4等应用 31 | - 海量的内置 prompt 列表,来自[中文](https://github.com/PlexPt/awesome-chatgpt-prompts-zh)和[英文](https://github.com/f/awesome-chatgpt-prompts) 32 | - 一键导出聊天记录,完整的 Markdown 支持 33 | - 支持自定义API地址(如:[openAI](https://api.openai.com) / [API2D](https://api2d.com/r/192767)) 34 | 35 | 36 | #### TODO: 37 | - [x] API Key 功能实现 38 | - [x] API Proxy 代理 39 | - [ ] 绘画功能 40 | - [ ] 思维导图功能 41 | - [ ] 支付功能完善 42 | - [ ] server端渲染模式支持 43 | - [ ] Docker 支持 44 | 45 | 46 | ## 本地启动 47 | **0.环境要求准备** 48 | - golang1.18 49 | - mysql 5.7+ 50 | - redis 51 | - goland 52 | 53 | **1.先 `Fork` 本项目,然后克隆到本地。** 54 | ``` 55 | 建议目录 ~/go/src/github.com/heimeropen/ 56 | git clone https://github.com/heimeropen/chatgpt-web-go.git 57 | ``` 58 | 59 | **2.导入sql** 60 | ``` 61 | # sql文件 62 | ./model/sql/chatgpt.sql 63 | ``` 64 | 65 | **3.配置文件** 66 | 在 ./config 目录下新建文件 dev.yml 内容如下: 67 | (配置内容需要更具自己环境更改) 68 | ``` 69 | port: 8899 70 | 71 | db: 72 | type: mysql 73 | host: 127.0.0.1:3306 74 | user: root 75 | password: 123456 76 | name: chatgpt_web_go 77 | 78 | redis: 79 | addr: 127.0.0.1:6379 80 | 81 | gpt: 82 | proxy: # 代理支持 socks5h://x.x.x.x 或者 http://x.x.x.x 83 | 84 | emailServer: 85 | host: 86 | port: 87 | senderName: 88 | user: 89 | password: 90 | ``` 91 | 92 | **4.运行** 93 | ``` 94 | 用goland打开项目 95 | 启动main函数: 96 | ./cmd/server/main.go 97 | ``` 98 | 99 | **前端服务** 100 | ``` 101 | 前端服务安装参考: 102 | https://github.com/79E/ChatGpt-Web/blob/master/README.md 103 | 104 | 前端项目需要修改配置文件 .env.development, 指向本地服务端: 105 | VITE_APP_REQUEST_HOST=http://127.0.0.1:8899 106 | ``` 107 | 108 | 109 | 110 | ### 页面截图 111 | 112 | ![cover](https://files.catbox.moe/tp963e.png) 113 | ![cover](https://files.catbox.moe/y5avbx.png) 114 | ![cover](https://files.catbox.moe/k16jsz.png) 115 | ![cover](https://files.catbox.moe/8o5oja.png) 116 | 117 | 118 | ## 📋 开源协议 119 | 120 | [![License MIT](https://img.shields.io/badge/License-MIT-brightgreen.svg)](https://github.com/79E/ChatGpt-Web/blob/master/license) 121 | -------------------------------------------------------------------------------- /cmd/gen/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/config" 5 | "chatgpt-web-new-go/common/db" 6 | "chatgpt-web-new-go/common/logs" 7 | ) 8 | 9 | func main() { 10 | // config init 11 | config.InitConfig() 12 | 13 | // log init 14 | logs.LogInit() 15 | 16 | // db init 17 | db.Init() 18 | 19 | // gen 20 | db.InitGen() 21 | } 22 | -------------------------------------------------------------------------------- /cmd/server/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/aiClient" 5 | "chatgpt-web-new-go/common/config" 6 | "chatgpt-web-new-go/common/db" 7 | "chatgpt-web-new-go/common/email" 8 | "chatgpt-web-new-go/common/logs" 9 | "chatgpt-web-new-go/common/redis" 10 | "chatgpt-web-new-go/router" 11 | "fmt" 12 | "github.com/gin-gonic/gin" 13 | ) 14 | 15 | func main() { 16 | // config init 17 | config.InitConfig() 18 | 19 | // log init 20 | logs.LogInit() 21 | 22 | // db init 23 | db.Init() 24 | 25 | // redis init 26 | redis.Init() 27 | 28 | // email service 29 | email.InitEmailDialer() 30 | 31 | // aiClient init 32 | aiClient.Init() 33 | 34 | // gin init 35 | engine := gin.Default() 36 | 37 | // route init 38 | router.Init(engine) 39 | 40 | // listen init 41 | port := fmt.Sprintf("%v", config.Config.Port) 42 | err := engine.Run("127.0.0.1:" + port) 43 | if err != nil { 44 | logs.Error("run webserver error %v", err) 45 | panic(err) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /common/aiClient/getter.go: -------------------------------------------------------------------------------- 1 | package aiClient 2 | 3 | import ( 4 | "math/rand" 5 | ) 6 | 7 | func GetGptClient() *GptClient { 8 | if len(GptClients) < 1 { 9 | return nil 10 | } 11 | 12 | keyCount := len(GptClients) 13 | 14 | index := rand.Intn(keyCount) 15 | 16 | return GptClients[index] 17 | } 18 | -------------------------------------------------------------------------------- /common/aiClient/init.go: -------------------------------------------------------------------------------- 1 | package aiClient 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/config" 5 | "chatgpt-web-new-go/common/logs" 6 | "chatgpt-web-new-go/dao" 7 | "context" 8 | "github.com/robfig/cron/v3" 9 | gogpt "github.com/sashabaranov/go-openai" 10 | "golang.org/x/net/proxy" 11 | "net" 12 | "net/http" 13 | "net/url" 14 | "strings" 15 | "time" 16 | ) 17 | 18 | func Init() { 19 | 20 | // init first 21 | DoInitClient() 22 | 23 | // cron job 24 | c := cron.New() 25 | _, err := c.AddFunc("30 * * * *", DoInitClient) 26 | if err != nil { 27 | logs.Error("cron add func error: %v", err) 28 | panic(err) 29 | } 30 | c.Start() 31 | } 32 | 33 | func DoInitClient() { 34 | logs.Debug("doInitClient start len: %v", len(GptClients)) 35 | 36 | dk := dao.Q.Aikey 37 | aiKeys, err := dk.Where(dk.IsDelete.Eq(0), dk.Status.Eq(1)).Find() 38 | if err != nil { 39 | logs.Error("ai keys get error: %v", err) 40 | panic(err) 41 | } 42 | 43 | var clientList []*GptClient 44 | for _, ak := range aiKeys { 45 | ak := ak 46 | 47 | gptConfig := gogpt.DefaultConfig(ak.Key) 48 | 49 | // proxy 50 | cnf := config.Config.Gpt 51 | if cnf != nil { 52 | addProxy(cnf.Proxy, gptConfig) 53 | } 54 | 55 | newClient := gogpt.NewClientWithConfig(gptConfig) 56 | 57 | gptClient := &GptClient{ 58 | OpenAIClient: newClient, 59 | Model: ak, 60 | } 61 | clientList = append(clientList, gptClient) 62 | } 63 | 64 | GptClients = clientList 65 | 66 | logs.Debug("doInitClient start len: %v", len(GptClients)) 67 | } 68 | 69 | func addProxy(proxy string, gptConfig gogpt.ClientConfig) { 70 | if proxy == "" { 71 | return 72 | } 73 | 74 | transport := &http.Transport{} 75 | 76 | if strings.HasPrefix(proxy, "socks5h://") { 77 | // 创建一个 DialContext 对象,并设置代理服务器 78 | dialContext, err := newDialContext(proxy[10:]) 79 | if err != nil { 80 | panic(err) 81 | } 82 | transport.DialContext = dialContext 83 | } else { 84 | // 创建一个 HTTP Transport 对象,并设置代理服务器 85 | proxyUrl, err := url.Parse(proxy) 86 | if err != nil { 87 | panic(err) 88 | } 89 | transport.Proxy = http.ProxyURL(proxyUrl) 90 | } 91 | // 创建一个 HTTP 客户端,并将 Transport 对象设置为其 Transport 字段 92 | gptConfig.HTTPClient = &http.Client{ 93 | Transport: transport, 94 | } 95 | } 96 | 97 | type dialContextFunc func(ctx context.Context, network, address string) (net.Conn, error) 98 | 99 | func newDialContext(socks5 string) (dialContextFunc, error) { 100 | baseDialer := &net.Dialer{ 101 | Timeout: 60 * time.Second, 102 | KeepAlive: 60 * time.Second, 103 | } 104 | 105 | if socks5 != "" { 106 | // split socks5 proxy string [username:password@]host:port 107 | var auth *proxy.Auth = nil 108 | 109 | if strings.Contains(socks5, "@") { 110 | proxyInfo := strings.SplitN(socks5, "@", 2) 111 | proxyUser := strings.Split(proxyInfo[0], ":") 112 | if len(proxyUser) == 2 { 113 | auth = &proxy.Auth{ 114 | User: proxyUser[0], 115 | Password: proxyUser[1], 116 | } 117 | } 118 | socks5 = proxyInfo[1] 119 | } 120 | 121 | dialSocksProxy, err := proxy.SOCKS5("tcp", socks5, auth, baseDialer) 122 | if err != nil { 123 | return nil, err 124 | } 125 | 126 | contextDialer, ok := dialSocksProxy.(proxy.ContextDialer) 127 | if !ok { 128 | return nil, err 129 | } 130 | 131 | return contextDialer.DialContext, nil 132 | } else { 133 | return baseDialer.DialContext, nil 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /common/aiClient/types.go: -------------------------------------------------------------------------------- 1 | package aiClient 2 | 3 | import ( 4 | "chatgpt-web-new-go/model" 5 | sd "github.com/SpenserCai/sd-webui-go" 6 | "github.com/sashabaranov/go-openai" 7 | ) 8 | 9 | var ( 10 | GptClients []*GptClient 11 | DallE2Clients []*DallE2Client 12 | SDClients []*SDClient 13 | ) 14 | 15 | type GptClient struct { 16 | OpenAIClient *openai.Client 17 | Model *model.Aikey 18 | } 19 | 20 | type DallE2Client struct { 21 | OpenAIClient *openai.Client 22 | Model *model.Aikey 23 | } 24 | 25 | type SDClient struct { 26 | SdClient sd.StableDiffInterface 27 | Model *model.Aikey 28 | } 29 | -------------------------------------------------------------------------------- /common/auth/auth.go: -------------------------------------------------------------------------------- 1 | package auth 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "chatgpt-web-new-go/model" 6 | "errors" 7 | "github.com/gin-gonic/gin" 8 | "github.com/golang-jwt/jwt" 9 | "strings" 10 | "time" 11 | ) 12 | 13 | var ( 14 | GinCtxKey = "authUser" 15 | key = []byte("jansdfjizxuqhawiwehjioas7812738_asdf+787") 16 | ) 17 | 18 | type CustomClaims struct { 19 | User *model.User 20 | jwt.StandardClaims 21 | } 22 | 23 | // Decode a token string into a token object 24 | func Decode(tokenString string) (*CustomClaims, error) { 25 | // Parse the token 26 | token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) { 27 | return key, nil 28 | }) 29 | 30 | if err != nil { 31 | logs.Error("Decode jwt.ParseWithClaims errorL %v", err) 32 | return nil, err 33 | } 34 | 35 | // Validate the token and return the custom claims 36 | if claims, ok := token.Claims.(*CustomClaims); ok && token.Valid { 37 | return claims, nil 38 | } else { 39 | logs.Error("Decode token.Claims errorL %v", err) 40 | return nil, err 41 | } 42 | } 43 | 44 | // Encode a claim into a JWT 45 | func Encode(user *model.User) (string, error) { 46 | expireToken := time.Now().Add(time.Hour * 7200).Unix() 47 | 48 | // Create the Claims 49 | claims := CustomClaims{ 50 | user, 51 | jwt.StandardClaims{ 52 | ExpiresAt: expireToken, 53 | Issuer: "chatgpt-web-new-go", 54 | }, 55 | } 56 | 57 | // Create token 58 | token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) 59 | 60 | // Sign token and return 61 | return token.SignedString(key) 62 | } 63 | 64 | // EncodeByCtx 从ctx中的token获取登录用户信息 65 | func EncodeByCtx(c *gin.Context) (*CustomClaims, error) { 66 | //1.获取token 67 | token := c.GetHeader("Token") 68 | if token != "" { 69 | tokenS := strings.Split(token, " ") 70 | token = tokenS[0] 71 | } else { 72 | token = c.Request.FormValue("token") 73 | } 74 | if token == "" || token == "undefined" { 75 | return nil, errors.New("not found token") 76 | } 77 | 78 | return Decode(token) 79 | } 80 | -------------------------------------------------------------------------------- /common/auth/password/password.go: -------------------------------------------------------------------------------- 1 | package password 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "golang.org/x/crypto/bcrypt" 6 | ) 7 | 8 | // Hash 进行加密 9 | func Hash(password string) string { 10 | bytes, err := bcrypt.GenerateFromPassword([]byte(password), 14) 11 | if err != nil { 12 | logs.Error("hash password bizError: %v", err) 13 | } 14 | 15 | return string(bytes) 16 | } 17 | 18 | //CheckHash 检查密码和hash是否匹配 19 | func CheckHash(password string, hash string) bool { 20 | err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) 21 | return err == nil 22 | } 23 | 24 | // IsHashed 检查密码和hash是否已经加密 25 | func IsHashed(str string) bool { 26 | return len(str) == 60 27 | } 28 | -------------------------------------------------------------------------------- /common/auth/password/password_test.go: -------------------------------------------------------------------------------- 1 | package password 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestHash(t *testing.T) { 9 | pwd := "admin123" 10 | hash := Hash(pwd) 11 | fmt.Println(hash) 12 | } 13 | -------------------------------------------------------------------------------- /common/auth/u_info.go: -------------------------------------------------------------------------------- 1 | package auth 2 | 3 | import "github.com/gin-gonic/gin" 4 | 5 | func GetClientIP(c *gin.Context) string { 6 | clientIP := c.ClientIP() 7 | if clientIP == "" { 8 | clientIP = c.RemoteIP() 9 | } 10 | 11 | return clientIP 12 | } 13 | 14 | func GetUA(c *gin.Context) string { 15 | return c.GetHeader("User-Agent") 16 | } 17 | -------------------------------------------------------------------------------- /common/bizError/biz_error.go: -------------------------------------------------------------------------------- 1 | package bizError 2 | 3 | import "fmt" 4 | 5 | type BizError struct { 6 | Code int `json:"code"` 7 | Message string `json:"messageHandlers"` 8 | } 9 | 10 | func (e *BizError) Error() string { 11 | return fmt.Sprintf("[%v]%v", e.Code, e.Message) 12 | } 13 | 14 | func NewBizError(code int, message string) *BizError { 15 | return &BizError{ 16 | Code: code, 17 | Message: message, 18 | } 19 | } 20 | 21 | var ( 22 | UnknowError = NewBizError(-1, "未知错误!") 23 | 24 | CommonUpdateError = NewBizError(-100, "更新异常!") 25 | CommonDeleteError = NewBizError(-200, "删除异常!") 26 | 27 | LoginCodeNoneError = NewBizError(100000, "验证码不能为空!") 28 | LoginPassCodeNoneError = NewBizError(100001, "密码或验证码不能为空!") 29 | LoginCodeErrorError = NewBizError(100002, "验证码错误!") 30 | LoginPasswordError = NewBizError(100003, "密码错误!") 31 | 32 | SigninedAlreadyError = NewBizError(110000, "已经签到过啦!") 33 | 34 | IntegralNoneError = NewBizError(120000, "积分用光啦!") 35 | 36 | CarmiStatusError = NewBizError(130000, "卡密状态异常!") 37 | CarmiUseError = NewBizError(130001, "卡密使用异常!") 38 | CarmiDelError = NewBizError(130003, "卡密删除异常!") 39 | 40 | UserDelError = NewBizError(140000, "用户删除失败!") 41 | UserUpdateError = NewBizError(140001, "用户更新失败!") 42 | 43 | ProductUpdateError = NewBizError(150000, "商品更新异常!") 44 | ProductDeleteError = NewBizError(150001, "商品删除异常!") 45 | 46 | TurnoverDeleteError = NewBizError(160000, "消费记录删除异常!") 47 | TurnoverUpdateError = NewBizError(160001, "消费记录更新异常!") 48 | 49 | AiKeyTokenDeleteError = NewBizError(170000, "Token删除异常!") 50 | AiKeyTokenUpdateError = NewBizError(170001, "Token更新异常!") 51 | AiKeyNoneUsefullError = NewBizError(170002, "无可用Token!") 52 | 53 | PaymentDeleteError = NewBizError(180000, "支付配置删除异常!") 54 | PaymentUpdateError = NewBizError(180001, "支付配置更新异常!") 55 | 56 | NotificationDeleteError = NewBizError(190000, "同志更新异常!") 57 | NotificationUpdateError = NewBizError(190001, "同志更新异常!") 58 | ) 59 | -------------------------------------------------------------------------------- /common/config/config.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | type Configuration struct { 4 | Port int `json:"port"` 5 | Db *dbConfig `json:"db"` 6 | Redis *redisConfig `json:"redis"` 7 | Gpt *gptConfig `json:"aiClient"` 8 | EmailServer *emailServerConfig `json:"emailServer"` 9 | } 10 | 11 | type dbConfig struct { 12 | Type string `json:"type"` 13 | Name string `json:"name"` 14 | Host string `json:"host"` // and port 15 | HostR1 string `json:"host_r_1"` 16 | User string `json:"user"` 17 | Password string `json:"password"` 18 | } 19 | 20 | type redisConfig struct { 21 | Addr string `json:"addr"` // host and port 22 | Password string `json:"password"` 23 | DB int `json:"db"` 24 | } 25 | 26 | type gptConfig struct { 27 | ApiKey string `json:"api_key"` 28 | Proxy string `json:"proxy"` 29 | ApiURL string `json:"api_url"` 30 | BotDesc string `json:"bot_desc"` 31 | Model string `json:"model"` 32 | MaxTokens int `json:"max_tokens"` 33 | TopP float32 `json:"top_p"` 34 | FrequencyPenalty float32 `json:"frequency_penalty"` 35 | PresencePenalty float32 `json:"presence_penalty"` 36 | } 37 | 38 | type emailServerConfig struct { 39 | Host string `json:"host"` 40 | Port int `json:"port"` 41 | SenderName string `json:"sender_name"` 42 | User string `json:"user"` 43 | Password string `json:"password"` 44 | } 45 | -------------------------------------------------------------------------------- /common/config/global.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "github.com/go-redis/redis" 5 | "github.com/robfig/cron/v3" 6 | "gopkg.in/gomail.v2" 7 | "gorm.io/gorm" 8 | ) 9 | 10 | var ( 11 | Config *Configuration 12 | DB *gorm.DB // DB instance 13 | Redis *redis.Client 14 | Gcron *cron.Cron // cron 15 | EmailDialer *gomail.Dialer 16 | ) 17 | -------------------------------------------------------------------------------- /common/config/init.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/env" 5 | "context" 6 | "flag" 7 | "github.com/fsnotify/fsnotify" 8 | "github.com/spf13/pflag" 9 | "github.com/spf13/viper" 10 | "log" 11 | ) 12 | 13 | func InitConfig() { 14 | v := viper.New() 15 | 16 | // env initializer 17 | e := env.GetEnv() 18 | 19 | //设置配置文件的名字 20 | v.SetConfigName(e) 21 | 22 | //添加配置文件所在的路径,注意在Linux环境下%GOPATH要替换为$GOPATH 23 | v.AddConfigPath("%GOPATH/src/") 24 | v.AddConfigPath("./") 25 | v.AddConfigPath("./config") 26 | v.AddConfigPath("./../config") 27 | v.AddConfigPath("./../../config") 28 | v.AddConfigPath("./../../../config") 29 | 30 | //设置配置文件类型 31 | v.SetConfigType("yml") 32 | 33 | if err := v.ReadInConfig(); err != nil { 34 | panic(err) 35 | } 36 | 37 | // command line args 38 | commandLineConfig(v) 39 | 40 | Config = &Configuration{} 41 | err := v.Unmarshal(Config) 42 | if err != nil { 43 | panic(err) 44 | } 45 | 46 | log.Printf("global config: %v \n", Config) 47 | go watchConfigChange(v) 48 | } 49 | 50 | // 监听配置文件的修改和变动 51 | func watchConfigChange(v *viper.Viper) { 52 | defer func() { 53 | if err := recover(); err != nil { 54 | log.Printf("watchConfigChange panic recover: %v", err) 55 | } 56 | }() 57 | 58 | ctx, cancel := context.WithCancel(context.Background()) 59 | v.WatchConfig() 60 | //监听回调函数 61 | watch := func(e fsnotify.Event) { 62 | log.Printf("Config file is changed: %s \n", e.String()) 63 | cancel() 64 | } 65 | v.OnConfigChange(watch) 66 | <-ctx.Done() 67 | } 68 | 69 | func commandLineConfig(v *viper.Viper) { 70 | pflag.String("token", "", "please input the token") 71 | pflag.Int("adminUserId", 0, "please input the admin user id") 72 | pflag.Bool("debug", false, "please input the debug flag") 73 | //获取标准包的flag 74 | pflag.CommandLine.AddGoFlagSet(flag.CommandLine) 75 | pflag.Parse() 76 | 77 | //BindFlag 78 | err := v.BindPFlags(pflag.CommandLine) 79 | if err != nil { 80 | panic(err) 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /common/constant/constant.go: -------------------------------------------------------------------------------- 1 | package constant 2 | 3 | var ( 4 | WhiteListPhone = map[string]struct{}{ 5 | "18888888888": {}, 6 | "17777777777": {}, 7 | } 8 | ) 9 | -------------------------------------------------------------------------------- /common/db/db.go: -------------------------------------------------------------------------------- 1 | package db 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/config" 5 | "chatgpt-web-new-go/dao" 6 | "database/sql" 7 | "fmt" 8 | "github.com/mattn/go-sqlite3" 9 | "gorm.io/driver/mysql" 10 | "gorm.io/driver/sqlite" 11 | "gorm.io/gorm" 12 | "gorm.io/gorm/logger" 13 | "log" 14 | "os" 15 | "time" 16 | ) 17 | 18 | var dbTypeInitializer = map[string]func(){ 19 | "mysql": initMysql, 20 | "sqlite": initSqlite, 21 | } 22 | 23 | func Init() { 24 | dbType := config.Config.Db.Type 25 | dbInitializer := dbTypeInitializer[dbType] 26 | dbInitializer() 27 | 28 | // gorm gen init 29 | dao.SetDefault(config.DB) 30 | } 31 | 32 | func initMysql() { 33 | dbConfig := config.Config.Db 34 | // refer https://github.com/go-sql-driver/mysql#dsn-data-source-name for details 35 | dsn := fmt.Sprintf("%v:%v@tcp(%v)/%v?charset=utf8mb4&parseTime=True&loc=Local", 36 | dbConfig.User, dbConfig.Password, dbConfig.Host, dbConfig.Name) 37 | 38 | var err error 39 | config.DB, err = gorm.Open( 40 | mysql.New(mysql.Config{ 41 | DSN: dsn, // data source name 42 | DefaultStringSize: 256, // default size for string fields 43 | DisableDatetimePrecision: true, // disable datetime precision, which not supported before MySQL 5.6 44 | DontSupportRenameIndex: true, // drop & create when rename messageDao, rename messageDao not supported before MySQL 5.7, MariaDB 45 | DontSupportRenameColumn: true, // `change` when rename column, rename column not supported before MySQL 8, MariaDB 46 | SkipInitializeWithVersion: false, // autoconfigure based on currently MySQL version 47 | }), 48 | &gorm.Config{ 49 | Logger: logger.New( 50 | log.New(os.Stdout, "\r\n", log.LstdFlags), 51 | logger.Config{ 52 | SlowThreshold: time.Second, 53 | LogLevel: logger.Info, 54 | Colorful: true, 55 | }, 56 | ), 57 | }) 58 | if err != nil { 59 | panic(err) 60 | } 61 | sqlDB, err := config.DB.DB() 62 | sqlDB.SetMaxIdleConns(5) 63 | sqlDB.SetMaxOpenConns(100) 64 | sqlDB.SetConnMaxLifetime(time.Hour) 65 | 66 | // migrate 67 | //err = config.DB.AutoMigrate(&user.User{}) 68 | //if err != nil { 69 | // panic(err) 70 | //} 71 | } 72 | 73 | // initSqlite 数据库初始化,包括新建数据库(如果还没有建立),基本数据的读写 74 | func initSqlite() { 75 | sql.Register("sqlite3_simple", 76 | &sqlite3.SQLiteDriver{ 77 | Extensions: []string{ 78 | "libsimple-osx-x64/libsimple", 79 | }, 80 | }, 81 | ) 82 | 83 | var err error 84 | config.DB, err = gorm.Open(sqlite.Open("data.db"), &gorm.Config{}) 85 | if err != nil { 86 | panic("failed to connect database") 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /common/db/gen.go: -------------------------------------------------------------------------------- 1 | package db 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/config" 5 | "gorm.io/gen" 6 | ) 7 | 8 | // Querier Dynamic SQL 9 | type Querier interface { 10 | // FilterWithNameAndRole SELECT * FROM @@table WHERE name = @name{{if role !=""}} AND role = @role{{end}} 11 | FilterWithNameAndRole(name, role string) ([]gen.T, error) 12 | } 13 | 14 | func InitGen() { 15 | g := gen.NewGenerator(gen.Config{ 16 | OutPath: "./dao", 17 | ModelPkgPath: "./model", 18 | Mode: gen.WithoutContext | gen.WithDefaultQuery | gen.WithQueryInterface, // generate mode 19 | WithUnitTest: false, 20 | }) 21 | 22 | // db, _ := gorm.Open(mysql.Open("root:@(127.0.0.1:3306)/demo?charset=utf8mb4&parseTime=True&loc=Local")) 23 | g.UseDB(config.DB) // reuse your gorm db 24 | 25 | // Generate basic type-safe DAO API for struct `model.User` following conventions 26 | g.ApplyBasic(g.GenerateAllTable()...) 27 | 28 | // Generate Type Safe API with Dynamic SQL defined on Querier interface for `model.User` and `model.Company` 29 | g.ApplyInterface(func(Querier) {}, g.GenerateAllTable()...) 30 | 31 | // Generate the code 32 | g.Execute() 33 | } 34 | -------------------------------------------------------------------------------- /common/email/email.go: -------------------------------------------------------------------------------- 1 | package email 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/config" 5 | "gopkg.in/gomail.v2" 6 | ) 7 | 8 | func InitEmailDialer() { 9 | server := config.Config.EmailServer 10 | 11 | config.EmailDialer = gomail.NewDialer(server.Host, server.Port, server.User, server.Password) 12 | } 13 | 14 | func SendMail(subject, toAddress, content string) error { 15 | server := config.Config.EmailServer 16 | 17 | m := gomail.NewMessage() 18 | m.SetHeader("From", m.FormatAddress(server.User, server.SenderName)) 19 | m.SetHeader("To", toAddress) 20 | m.SetHeader("Subject", subject) 21 | m.SetBody("text/html", content) 22 | err := config.EmailDialer.DialAndSend(m) 23 | return err 24 | } 25 | -------------------------------------------------------------------------------- /common/email/template.go: -------------------------------------------------------------------------------- 1 | package email 2 | 3 | const ( 4 | SendCodeTemplate = ` 5 | 6 | 7 | 8 | 46 | 47 | 48 |
49 |
OurAI 验证码
50 |

以下是您本次请求的验证码,验证码有效期为10分钟,请勿透露给他人:

51 |
%s
52 |
53 | 返回OurAI官网 54 |
55 |
56 | 57 | 58 | ` 59 | ) 60 | -------------------------------------------------------------------------------- /common/env/env.go: -------------------------------------------------------------------------------- 1 | package env 2 | 3 | import "os" 4 | 5 | const ( 6 | KEY = "env" 7 | 8 | KeyDev = "dev" 9 | KeyTest = "test" 10 | KeyProd = "prod" 11 | ) 12 | 13 | func GetEnv() string { 14 | e := os.Getenv(KEY) 15 | if e == "" { 16 | return KeyDev 17 | } 18 | return e 19 | } 20 | 21 | func IsDevelop() bool { 22 | return GetEnv() == KeyDev || GetEnv() == "" 23 | } 24 | 25 | func IsTest() bool { 26 | return GetEnv() == KeyTest 27 | } 28 | 29 | func IsProduction() bool { 30 | return GetEnv() == KeyProd 31 | } 32 | -------------------------------------------------------------------------------- /common/goUtil/recover.go: -------------------------------------------------------------------------------- 1 | package goUtil 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "runtime" 6 | ) 7 | 8 | func Recover(source string) func() { 9 | return func() { 10 | if err := recover(); err != nil { 11 | logs.Error("%v panic: %v", source, err) 12 | var buf [4096]byte 13 | n := runtime.Stack(buf[:], false) 14 | logs.Error("%v panic %s\n", source, string(buf[:n])) 15 | } 16 | } 17 | } 18 | 19 | func New(f func()) { 20 | go func() { 21 | // recover 22 | defer func() { 23 | if err := recover(); err != nil { 24 | var buf [4096]byte 25 | n := runtime.Stack(buf[:], false) 26 | logs.Error("goUtil routiune panic %s\n", string(buf[:n])) 27 | } 28 | }() 29 | 30 | // do function 31 | f() 32 | }() 33 | } 34 | -------------------------------------------------------------------------------- /common/inviteCodeGen/invite_code.go: -------------------------------------------------------------------------------- 1 | package inviteCodeGen 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "math/rand" 7 | "strings" 8 | "time" 9 | ) 10 | 11 | var InviteCodeGen = code{ 12 | base: "HVE8S2DZX9C7P5IK3MJUAR4WYLTN6BGQ", 13 | decimal: 32, 14 | pad: "F", 15 | len: 6, 16 | } 17 | 18 | func init() { 19 | // 初始化检查 20 | if res, err := InviteCodeGen.InitCheck(); !res { 21 | fmt.Println(err) 22 | panic(err) 23 | } 24 | } 25 | 26 | type code struct { 27 | base string // 进制的包含字符, string类型 28 | decimal int64 // 进制长度 29 | pad string // 补位字符,若生成的code小于最小长度,则补位+随机字符, 补位字符不能在进制字符中 30 | len int // code最小长度 31 | } 32 | 33 | // IdToCode id转code 34 | func (c *code) IdToCode(id int64) string { 35 | mod := int64(0) 36 | res := "" 37 | for id != 0 { 38 | mod = id % c.decimal 39 | id = id / c.decimal 40 | res += string(c.base[mod]) 41 | } 42 | resLen := len(res) 43 | if resLen < c.len { 44 | res += c.pad 45 | for i := 0; i < c.len-resLen-1; i++ { 46 | rand.Seed(time.Now().UnixNano()) 47 | res += string(c.base[rand.Intn(int(c.decimal))]) 48 | } 49 | } 50 | return res 51 | } 52 | 53 | // CodeToId code转id 54 | func (c *code) CodeToId(code string) int64 { 55 | res := int64(0) 56 | lenCode := len(code) 57 | 58 | //var baseArr [] byte = []byte(c.base) 59 | baseArr := []byte(c.base) // 字符串进制转换为byte数组 60 | baseRev := make(map[byte]int) // 进制数据键值转换为map 61 | for k, v := range baseArr { 62 | baseRev[v] = k 63 | } 64 | 65 | // 查找补位字符的位置 66 | isPad := strings.Index(code, c.pad) 67 | if isPad != -1 { 68 | lenCode = isPad 69 | } 70 | 71 | r := 0 72 | for i := 0; i < lenCode; i++ { 73 | // 补充字符直接跳过 74 | if string(code[i]) == c.pad { 75 | continue 76 | } 77 | index := baseRev[code[i]] 78 | b := int64(1) 79 | for j := 0; j < r; j++ { 80 | b *= c.decimal 81 | } 82 | // pow 类型为 float64 , 类型转换太麻烦, 所以自己循环实现pow的功能 83 | //res += float64(index) * math.Pow(float64(32), float64(2)) 84 | res += int64(index) * b 85 | r++ 86 | } 87 | return res 88 | } 89 | 90 | // InitCheck 初始化检查 91 | func (c *code) InitCheck() (bool, error) { 92 | lenBase := len(c.base) 93 | // 检查进制字符 94 | if c.base == "" { 95 | return false, errors.New("base string is nil or empty") 96 | } 97 | // 检查长度是否符合 98 | if int64(lenBase) != c.decimal { 99 | return false, errors.New("base length and len not match") 100 | } 101 | return true, errors.New("") 102 | } 103 | -------------------------------------------------------------------------------- /common/inviteCodeGen/invite_code2.go: -------------------------------------------------------------------------------- 1 | package inviteCodeGen 2 | 3 | import ( 4 | "container/list" 5 | "errors" 6 | "fmt" 7 | ) 8 | 9 | var ( 10 | baseStr = "HVE8S2DZX9C7P5IK3MJUAR4WYLTN6BGQ" 11 | base = []byte(baseStr) 12 | ) 13 | 14 | var baseMap map[byte]int 15 | 16 | func InitBaseMap() { 17 | baseMap = make(map[byte]int) 18 | 19 | for i, v := range base { 20 | baseMap[v] = i 21 | } 22 | } 23 | 24 | func Base34(n uint64) []byte { 25 | quotient := n 26 | mod := uint64(0) 27 | l := list.New() 28 | 29 | for quotient != 0 { 30 | mod = quotient % 32 31 | quotient = quotient / 32 32 | l.PushFront(base[int(mod)]) 33 | } 34 | 35 | listLen := l.Len() 36 | 37 | if listLen >= 6 { 38 | res := make([]byte, 0, listLen) 39 | for i := l.Front(); i != nil; i = i.Next() { 40 | res = append(res, i.Value.(byte)) 41 | } 42 | return res 43 | } else { 44 | res := make([]byte, 0, 6) 45 | for i := 0; i < 6; i++ { 46 | if i < 6-listLen { 47 | res = append(res, base[0]) 48 | } else { 49 | res = append(res, l.Front().Value.(byte)) 50 | l.Remove(l.Front()) 51 | } 52 | 53 | } 54 | return res 55 | } 56 | } 57 | 58 | func Base34ToNum(str []byte) (uint64, error) { 59 | if baseMap == nil { 60 | return 0, errors.New("no init base map") 61 | } 62 | 63 | if str == nil || len(str) == 0 { 64 | return 0, errors.New("parameter is nil or empty") 65 | } 66 | 67 | var res uint64 = 0 68 | var r uint64 = 0 69 | 70 | for i := len(str) - 1; i >= 0; i-- { 71 | v, ok := baseMap[str[i]] 72 | if !ok { 73 | fmt.Printf("") 74 | return 0, errors.New("character is not base") 75 | } 76 | 77 | var b uint64 = 1 78 | for j := uint64(0); j < r; j++ { 79 | b *= 32 80 | } 81 | 82 | res += b * uint64(v) 83 | r++ 84 | } 85 | 86 | return res, nil 87 | } 88 | -------------------------------------------------------------------------------- /common/inviteCodeGen/invite_code_test.go: -------------------------------------------------------------------------------- 1 | package inviteCodeGen 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestInviteCode(t *testing.T) { 9 | inviteCode := code{ 10 | base: "HVE8S2DZX9C7P5IK3MJUAR4WYLTN6BGQ", 11 | decimal: 32, 12 | pad: "F", 13 | len: 6, 14 | } 15 | // 初始化检查 16 | if res, err := inviteCode.InitCheck(); !res { 17 | fmt.Println(err) 18 | return 19 | } 20 | id := int64(1) 21 | code := inviteCode.IdToCode(1) 22 | fmt.Printf("id=%v, code=%v\n", id, code) 23 | 24 | code = "VFXXXX" 25 | id = inviteCode.CodeToId(code) 26 | fmt.Printf("code=%v, id=%v\n", code, id) 27 | } 28 | 29 | func TestInviteCode2(t *testing.T) { 30 | InitBaseMap() 31 | 32 | fmt.Printf("len(baseStr):%d, len(base):%d\n", len(baseStr), len(base)) 33 | 34 | res := Base34(1) 35 | 36 | fmt.Printf("=base:1544804416->%s, %d\n", string(res), len(res)) 37 | 38 | str := "VIVZ4EH" 39 | 40 | num, err := Base34ToNum([]byte(str)) 41 | 42 | if err == nil { 43 | fmt.Printf("=base:%s->%d\n", str, num) 44 | } else { 45 | fmt.Printf("===============err:%s\n", err.Error()) 46 | } 47 | } 48 | 49 | func TestByteString(t *testing.T) { 50 | s := "a" 51 | b := []byte(s) 52 | 53 | fmt.Println(b) 54 | } 55 | -------------------------------------------------------------------------------- /common/logs/log.go: -------------------------------------------------------------------------------- 1 | package logs 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/env" 5 | rotateLogs "github.com/lestrrat-go/file-rotatelogs" 6 | "go.uber.org/zap" 7 | "go.uber.org/zap/zapcore" 8 | "io" 9 | "os" 10 | "time" 11 | ) 12 | 13 | var ( 14 | LoggerZap *zap.Logger // log 15 | Logger *zap.SugaredLogger // log 16 | 17 | Debug func(template string, args ...interface{}) 18 | Info func(template string, args ...interface{}) 19 | Warn func(template string, args ...interface{}) 20 | Error func(template string, args ...interface{}) 21 | ) 22 | 23 | func LogSyncLast() { 24 | func() { 25 | _ = Logger.Sync() 26 | _ = LoggerZap.Sync() 27 | }() 28 | } 29 | 30 | func LogInit() { 31 | hook := getWriter("./log/aiClient.log") 32 | encoderConfig := zapcore.EncoderConfig{ 33 | MessageKey: "msg", 34 | LevelKey: "level", 35 | TimeKey: "time", 36 | NameKey: "logger", 37 | CallerKey: "file", 38 | StacktraceKey: "stacktrace", 39 | LineEnding: zapcore.DefaultLineEnding, 40 | EncodeLevel: zapcore.CapitalColorLevelEncoder, 41 | EncodeTime: zapcore.ISO8601TimeEncoder, 42 | EncodeDuration: zapcore.SecondsDurationEncoder, 43 | EncodeCaller: zapcore.ShortCallerEncoder, // 短路径编码器 44 | EncodeName: zapcore.FullNameEncoder, 45 | } 46 | // 设置日志级别 47 | atomicLevel := zap.NewAtomicLevel() 48 | atomicLevel.SetLevel(zap.DebugLevel) 49 | var writes = []zapcore.WriteSyncer{zapcore.AddSync(hook)} 50 | 51 | // 如果是开发环境,同时在控制台上也输出 52 | if !env.IsProduction() { 53 | writes = append(writes, zapcore.AddSync(os.Stdout)) 54 | } 55 | core := zapcore.NewCore( 56 | zapcore.NewConsoleEncoder(encoderConfig), 57 | zapcore.NewMultiWriteSyncer(writes...), 58 | atomicLevel, 59 | ) 60 | 61 | // 开启开发模式,堆栈跟踪 62 | caller := zap.AddCaller() 63 | // 开启文件及行号 64 | development := zap.Development() 65 | 66 | // 设置初始化字段 67 | //field := zap.Fields(zap.String("env", IsProduction())) 68 | 69 | // 构造日志 70 | logger := zap.New(core, caller, development) 71 | LoggerZap = logger 72 | Logger = logger.Sugar() 73 | 74 | { 75 | Debug = Logger.Debugf 76 | Info = Logger.Infof 77 | Warn = Logger.Warnf 78 | Error = Logger.Errorf 79 | } 80 | 81 | Logger.Info("log initializer success") 82 | } 83 | 84 | func getWriter(filename string) io.Writer { 85 | // 生成rotateLogs的Logger 实际生成的文件名 demo.log.YYmmddHH 86 | // 保存90天内的日志,每1天(整点)分割一次日志 87 | hook, err := rotateLogs.New( 88 | filename+".%Y%m%d%H", // 没有使用go风格反人类的format格式 89 | rotateLogs.WithLinkName(filename), 90 | rotateLogs.WithMaxAge(time.Hour*24*365), 91 | rotateLogs.WithRotationTime(time.Hour*24), 92 | ) 93 | 94 | if err != nil { 95 | panic(err) 96 | } 97 | return hook 98 | } 99 | -------------------------------------------------------------------------------- /common/random/rand_number.go: -------------------------------------------------------------------------------- 1 | package random 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "time" 7 | ) 8 | 9 | const ( 10 | randomRound = "0123456789" 11 | 12 | charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" 13 | ) 14 | 15 | var ( 16 | seededRand *rand.Rand = rand.New(rand.NewSource(time.Now().UnixNano())) 17 | ) 18 | 19 | func GenSmsCode() string { 20 | rand.Seed(time.Now().UnixNano()) 21 | var slicePol []byte 22 | for i := 0; i < 4; i++ { 23 | n := rand.Intn(len(randomRound)) 24 | slicePol = append(slicePol, randomRound[n]) 25 | } 26 | return string(slicePol) 27 | } 28 | 29 | func GenCarmiKey() string { 30 | return fmt.Sprintf("CA%v%v", time.Now().Unix(), generateRandomString(6)) 31 | } 32 | 33 | func generateRandomString(length int) string { 34 | b := make([]byte, length) 35 | for i := range b { 36 | b[i] = charset[seededRand.Intn(len(charset))] 37 | } 38 | return string(b) 39 | } 40 | -------------------------------------------------------------------------------- /common/redis/contents.go: -------------------------------------------------------------------------------- 1 | package redis 2 | 3 | const ( 4 | KeySnsCode = "sns_%v" // phone 5 | ) 6 | -------------------------------------------------------------------------------- /common/redis/v6.go: -------------------------------------------------------------------------------- 1 | package redis 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/config" 5 | "github.com/go-redis/redis" 6 | ) 7 | 8 | func Init() { 9 | redisConfig := config.Config.Redis 10 | config.Redis = redis.NewClient(&redis.Options{ 11 | Addr: redisConfig.Addr, 12 | Password: redisConfig.Password, // Redis 服务器没有设置密码 13 | DB: redisConfig.DB, // 使用默认数据库 14 | }) 15 | 16 | _, err := config.Redis.Ping().Result() 17 | if err != nil { 18 | panic(err) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /common/regexp/phone_email_regexp.go: -------------------------------------------------------------------------------- 1 | package regexp 2 | 3 | import "regexp" 4 | 5 | const ( 6 | // 正则表达式匹配中国合法手机号 7 | phoneRegex = "^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(17[6|7|8])|(18[0-9])|166|198|199)\\d{8}$" 8 | 9 | // 正则表达式匹配邮箱 10 | emailRegex = `^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$` 11 | ) 12 | 13 | func IsValidPhone(phone string) bool { 14 | isPhone, _ := regexp.MatchString(phoneRegex, phone) 15 | return isPhone 16 | } 17 | 18 | func isValidEmail(email string) bool { 19 | isEmail, _ := regexp.MatchString(emailRegex, email) 20 | return isEmail 21 | } 22 | 23 | func IsValidPhoneOrEmail(input string) bool { 24 | return IsValidPhone(input) || isValidEmail(input) 25 | } 26 | -------------------------------------------------------------------------------- /common/types/converter.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "strconv" 6 | ) 7 | 8 | func Int64ToString(num int64) string { 9 | return strconv.FormatInt(num, 10) 10 | } 11 | 12 | func UInt64ToString(num uint64) string { 13 | return strconv.FormatUint(num, 10) 14 | } 15 | 16 | func StringToInt(str string) int { 17 | num, err := strconv.Atoi(str) 18 | if err != nil { 19 | logs.Debug("StringToInt Err: %v", err) 20 | } 21 | 22 | return num 23 | } 24 | 25 | func StringToInt64(str string) int64 { 26 | num, err := strconv.ParseInt(str, 10, 64) 27 | if err != nil { 28 | logs.Debug("StringToInt Err: %v", err) 29 | } 30 | 31 | return num 32 | } 33 | 34 | func Booltonumber(b bool) int { 35 | result := 0 36 | if b { 37 | result = 1 38 | } 39 | return result 40 | } 41 | -------------------------------------------------------------------------------- /common/types/dataTrance.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import "strconv" 4 | 5 | func InterfaceToInt(i interface{}) int { 6 | switch i.(type) { 7 | case int: 8 | return i.(int) 9 | case string: 10 | iStr := i.(string) 11 | iInt, _ := strconv.Atoi(iStr) 12 | return iInt 13 | case int64: 14 | return int(i.(int64)) 15 | default: 16 | return 0 17 | } 18 | } 19 | 20 | func InterfaceToInt64(i interface{}) int64 { 21 | switch i.(type) { 22 | case int: 23 | return i.(int64) 24 | case string: 25 | iStr := i.(string) 26 | 27 | iInt, _ := strconv.ParseInt(iStr, 10, 64) 28 | return iInt 29 | case int64: 30 | return i.(int64) 31 | default: 32 | return 0 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /common/types/id.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "math/rand" 5 | "time" 6 | ) 7 | 8 | func GenerateUID() int64 { 9 | rand.Seed(time.Now().UnixNano()) 10 | min := 100000 // 最小值(6位数) 11 | max := 999999 // 最大值(6位数) 12 | return int64(rand.Intn(max-min+1) + min) 13 | } 14 | -------------------------------------------------------------------------------- /common/types/slice.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import "reflect" 4 | 5 | func Contains(arr interface{}, target interface{}) bool { 6 | arrValue := reflect.ValueOf(arr) 7 | if arrValue.Kind() != reflect.Slice { 8 | panic("not a slice") 9 | } 10 | 11 | targetValue := reflect.ValueOf(target) 12 | for i := 0; i < arrValue.Len(); i++ { 13 | if reflect.DeepEqual(arrValue.Index(i).Interface(), targetValue.Interface()) { 14 | return true 15 | } 16 | } 17 | 18 | return false 19 | } 20 | -------------------------------------------------------------------------------- /common/types/time.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import "time" 4 | 5 | const ( 6 | TimeFormatDate = "2006-01-02 15:04:05" 7 | ) 8 | 9 | func GetDayStartEn() (start time.Time, end time.Time) { 10 | now := time.Now() 11 | start = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local) 12 | end = time.Date(now.Year(), now.Month(), now.Day(), 23, 59, 50, 999, time.Local) 13 | return 14 | } 15 | 16 | func GetMonthStartEnd() (start time.Time, end time.Time) { 17 | now := time.Now() 18 | start = now.AddDate(0, 0, -now.Day()+1) 19 | end = now.AddDate(0, 1, -now.Day()) 20 | return 21 | } 22 | -------------------------------------------------------------------------------- /config/prod.yml: -------------------------------------------------------------------------------- 1 | port: 8899 2 | 3 | db: 4 | type: mysql 5 | host: 127.0.0.1:3306 6 | hostR1: 127.0.0.1:3306 7 | user: root 8 | password: 12345 9 | name: chatgpt_web_new_go 10 | 11 | redis: 12 | addr: 127.0.0.1:6379 13 | 14 | gpt: 15 | proxy: # 代理支持 socks5h://x.x.x.x 或者 http://x.x.x.x 16 | -------------------------------------------------------------------------------- /docs/openai.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module chatgpt-web-new-go 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/SpenserCai/sd-webui-go v0.4.3 7 | github.com/fsnotify/fsnotify v1.6.0 8 | github.com/gin-gonic/gin v1.9.1 9 | github.com/go-redis/redis v6.15.9+incompatible 10 | github.com/golang-jwt/jwt v3.2.2+incompatible 11 | github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible 12 | github.com/mattn/go-sqlite3 v1.14.16 13 | github.com/robfig/cron/v3 v3.0.1 14 | github.com/sashabaranov/go-openai v1.9.5 15 | github.com/spf13/pflag v1.0.5 16 | github.com/spf13/viper v1.15.0 17 | go.uber.org/zap v1.24.0 18 | golang.org/x/crypto v0.12.0 19 | golang.org/x/net v0.14.0 20 | gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df 21 | gorm.io/driver/mysql v1.5.1 22 | gorm.io/driver/sqlite v1.5.1 23 | gorm.io/gen v0.3.23 24 | gorm.io/gorm v1.25.4 25 | gorm.io/plugin/dbresolver v1.4.7 26 | ) 27 | 28 | require ( 29 | github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect 30 | github.com/bytedance/sonic v1.9.1 // indirect 31 | github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect 32 | github.com/gabriel-vasile/mimetype v1.4.2 // indirect 33 | github.com/gin-contrib/sse v0.1.0 // indirect 34 | github.com/go-logr/logr v1.2.4 // indirect 35 | github.com/go-logr/stdr v1.2.2 // indirect 36 | github.com/go-openapi/analysis v0.21.4 // indirect 37 | github.com/go-openapi/errors v0.20.4 // indirect 38 | github.com/go-openapi/jsonpointer v0.19.5 // indirect 39 | github.com/go-openapi/jsonreference v0.20.0 // indirect 40 | github.com/go-openapi/loads v0.21.2 // indirect 41 | github.com/go-openapi/runtime v0.26.0 // indirect 42 | github.com/go-openapi/spec v0.20.8 // indirect 43 | github.com/go-openapi/strfmt v0.21.7 // indirect 44 | github.com/go-openapi/swag v0.22.4 // indirect 45 | github.com/go-openapi/validate v0.22.1 // indirect 46 | github.com/go-playground/locales v0.14.1 // indirect 47 | github.com/go-playground/universal-translator v0.18.1 // indirect 48 | github.com/go-playground/validator/v10 v10.14.0 // indirect 49 | github.com/go-sql-driver/mysql v1.7.1 // indirect 50 | github.com/goccy/go-json v0.10.2 // indirect 51 | github.com/hashicorp/hcl v1.0.0 // indirect 52 | github.com/jinzhu/inflection v1.0.0 // indirect 53 | github.com/jinzhu/now v1.1.5 // indirect 54 | github.com/jonboulle/clockwork v0.4.0 // indirect 55 | github.com/josharian/intern v1.0.0 // indirect 56 | github.com/json-iterator/go v1.1.12 // indirect 57 | github.com/klauspost/cpuid/v2 v2.2.4 // indirect 58 | github.com/leodido/go-urn v1.2.4 // indirect 59 | github.com/lestrrat-go/strftime v1.0.6 // indirect 60 | github.com/magiconair/properties v1.8.7 // indirect 61 | github.com/mailru/easyjson v0.7.7 // indirect 62 | github.com/mattn/go-isatty v0.0.19 // indirect 63 | github.com/mitchellh/mapstructure v1.5.0 // indirect 64 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 65 | github.com/modern-go/reflect2 v1.0.2 // indirect 66 | github.com/oklog/ulid v1.3.1 // indirect 67 | github.com/onsi/ginkgo v1.16.5 // indirect 68 | github.com/onsi/gomega v1.27.7 // indirect 69 | github.com/opentracing/opentracing-go v1.2.0 // indirect 70 | github.com/pelletier/go-toml/v2 v2.0.8 // indirect 71 | github.com/pkg/errors v0.9.1 // indirect 72 | github.com/spf13/afero v1.9.3 // indirect 73 | github.com/spf13/cast v1.5.0 // indirect 74 | github.com/spf13/jwalterweatherman v1.1.0 // indirect 75 | github.com/subosito/gotenv v1.4.2 // indirect 76 | github.com/twitchyliquid64/golang-asm v0.15.1 // indirect 77 | github.com/ugorji/go/codec v1.2.11 // indirect 78 | go.mongodb.org/mongo-driver v1.11.3 // indirect 79 | go.opentelemetry.io/otel v1.14.0 // indirect 80 | go.opentelemetry.io/otel/trace v1.14.0 // indirect 81 | go.uber.org/atomic v1.9.0 // indirect 82 | go.uber.org/multierr v1.8.0 // indirect 83 | golang.org/x/arch v0.3.0 // indirect 84 | golang.org/x/mod v0.12.0 // indirect 85 | golang.org/x/sys v0.11.0 // indirect 86 | golang.org/x/text v0.12.0 // indirect 87 | golang.org/x/tools v0.12.0 // indirect 88 | google.golang.org/protobuf v1.30.0 // indirect 89 | gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect 90 | gopkg.in/ini.v1 v1.67.0 // indirect 91 | gopkg.in/yaml.v2 v2.4.0 // indirect 92 | gopkg.in/yaml.v3 v3.0.1 // indirect 93 | gorm.io/datatypes v1.2.0 // indirect 94 | gorm.io/hints v1.1.2 // indirect 95 | ) 96 | -------------------------------------------------------------------------------- /model/action.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | ) 10 | 11 | const TableNameAction = "action" 12 | 13 | // Action mapped from table 14 | type Action struct { 15 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 16 | UserID int64 `gorm:"column:user_id;not null;default:9" json:"user_id"` 17 | Type string `gorm:"column:type" json:"type"` 18 | Describe string `gorm:"column:describe;not null" json:"describe"` 19 | IP string `gorm:"column:ip;not null" json:"ip"` 20 | CreateTime time.Time `gorm:"column:create_time;not null;default:CURRENT_TIMESTAMP" json:"create_time"` 21 | UpdateTime time.Time `gorm:"column:update_time;not null;default:CURRENT_TIMESTAMP" json:"update_time"` 22 | IsDelete int32 `gorm:"column:is_delete;not null" json:"is_delete"` 23 | } 24 | 25 | // TableName Action's table name 26 | func (*Action) TableName() string { 27 | return TableNameAction 28 | } 29 | -------------------------------------------------------------------------------- /model/aikey.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | ) 10 | 11 | const TableNameAikey = "aikey" 12 | 13 | // Aikey mapped from table 14 | type Aikey struct { 15 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 16 | Key string `gorm:"column:key;not null" json:"key"` 17 | Host string `gorm:"column:host;not null" json:"host"` 18 | Remarks string `gorm:"column:remarks;not null" json:"remarks"` 19 | Type string `gorm:"column:type;not null;comment:openai sd" json:"type"` // openai sd 20 | Models string `gorm:"column:models;not null;comment:可用模型" json:"models"` // 可用模型 21 | Check int32 `gorm:"column:check;not null;comment:1 检查token可用性 0不检查" json:"check"` // 1 检查token可用性 0不检查 22 | Limit_ float64 `gorm:"column:limit;not null;comment:总限制" json:"limit"` // 总限制 23 | Usage float64 `gorm:"column:usage;not null;comment:已经使用" json:"usage"` // 已经使用 24 | Status int32 `gorm:"column:status;default:1;comment:1 正常 0异常" json:"status"` // 1 正常 0异常 25 | CreateTime time.Time `gorm:"column:create_time;not null;default:CURRENT_TIMESTAMP" json:"create_time"` 26 | UpdateTime time.Time `gorm:"column:update_time;not null;default:CURRENT_TIMESTAMP" json:"update_time"` 27 | IsDelete int32 `gorm:"column:is_delete;not null" json:"is_delete"` 28 | } 29 | 30 | // TableName Aikey's table name 31 | func (*Aikey) TableName() string { 32 | return TableNameAikey 33 | } 34 | -------------------------------------------------------------------------------- /model/amount_details.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | ) 10 | 11 | const TableNameAmountDetail = "amount_details" 12 | 13 | // AmountDetail mapped from table 14 | type AmountDetail struct { 15 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 16 | UserID int64 `gorm:"column:user_id;not null" json:"user_id"` 17 | Type string `gorm:"column:type;not null;comment:提现 or 提成" json:"type"` // 提现 or 提成 18 | CorrelationID int64 `gorm:"column:correlation_id;not null;comment:关联ID" json:"correlation_id"` // 关联ID 19 | OriginalAmount string `gorm:"column:original_amount;not null;comment:原始金额 分" json:"original_amount"` // 原始金额 分 20 | OperateAmount string `gorm:"column:operate_amount;not null;comment:操作金额" json:"operate_amount"` // 操作金额 21 | CurrentAmount string `gorm:"column:current_amount;not null;comment:当前金额" json:"current_amount"` // 当前金额 22 | Remarks string `gorm:"column:remarks;not null;comment:备注" json:"remarks"` // 备注 23 | Status int32 `gorm:"column:status;not null;default:1;comment:1-正常" json:"status"` // 1-正常 24 | CreateTime time.Time `gorm:"column:create_time;not null;default:CURRENT_TIMESTAMP" json:"create_time"` 25 | UpdateTime time.Time `gorm:"column:update_time;not null;default:CURRENT_TIMESTAMP" json:"update_time"` 26 | IsDelete int32 `gorm:"column:is_delete;not null" json:"is_delete"` 27 | } 28 | 29 | // TableName AmountDetail's table name 30 | func (*AmountDetail) TableName() string { 31 | return TableNameAmountDetail 32 | } 33 | -------------------------------------------------------------------------------- /model/carmi.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | ) 10 | 11 | const TableNameCarmi = "carmi" 12 | 13 | // Carmi mapped from table 14 | type Carmi struct { 15 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 16 | IP string `gorm:"column:ip;not null;comment:使用时候的ip" json:"ip"` // 使用时候的ip 17 | UserID int64 `gorm:"column:user_id;not null;comment:使用者" json:"user_id"` // 使用者 18 | Key string `gorm:"column:key;not null;comment:卡密" json:"key"` // 卡密 19 | Value int32 `gorm:"column:value;not null;comment:积分/天数" json:"value"` // 积分/天数 20 | Status int32 `gorm:"column:status;not null;comment:0有效 1使用 2过期" json:"status"` // 0有效 1使用 2过期 21 | Type string `gorm:"column:type;not null;comment:类型 integral/vip_days/svip_days" json:"type"` // 类型 integral/vip_days/svip_days 22 | EndTime string `gorm:"column:end_time;not null;comment:截止时间" json:"end_time"` // 截止时间 23 | Level int32 `gorm:"column:level;not null;comment:卡密充值等级" json:"level"` // 卡密充值等级 24 | CreateTime time.Time `gorm:"column:create_time;not null;default:CURRENT_TIMESTAMP" json:"create_time"` 25 | UpdateTime time.Time `gorm:"column:update_time;not null;default:CURRENT_TIMESTAMP" json:"update_time"` 26 | IsDelete int32 `gorm:"column:is_delete;not null" json:"is_delete"` 27 | } 28 | 29 | // TableName Carmi's table name 30 | func (*Carmi) TableName() string { 31 | return TableNameCarmi 32 | } 33 | -------------------------------------------------------------------------------- /model/cashback.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | ) 10 | 11 | const TableNameCashback = "cashback" 12 | 13 | // Cashback mapped from table 14 | type Cashback struct { 15 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 16 | UserID int64 `gorm:"column:user_id;not null" json:"user_id"` 17 | BenefitID int64 `gorm:"column:benefit_id;primaryKey;comment:受益者" json:"benefit_id"` // 受益者 18 | PayAmount string `gorm:"column:pay_amount;not null;comment:支付金额(分)" json:"pay_amount"` // 支付金额(分) 19 | CommissionRate string `gorm:"column:commission_rate;not null;comment:提成比例(1 - 10000)" json:"commission_rate"` // 提成比例(1 - 10000) 20 | CommissionAmount string `gorm:"column:commission_amount;not null;comment:提成金额(分)" json:"commission_amount"` // 提成金额(分) 21 | Remarks string `gorm:"column:remarks;comment:评论" json:"remarks"` // 评论 22 | OrderID int64 `gorm:"column:order_id;not null" json:"order_id"` 23 | Status int32 `gorm:"column:status;not null;default:3;comment:0异常 1正常 3审核中 6等待下发" json:"status"` // 0异常 1正常 3审核中 6等待下发 24 | CreateTime time.Time `gorm:"column:create_time;not null;default:CURRENT_TIMESTAMP" json:"create_time"` 25 | UpdateTime time.Time `gorm:"column:update_time;not null;default:CURRENT_TIMESTAMP" json:"update_time"` 26 | IsDelete int32 `gorm:"column:is_delete;not null" json:"is_delete"` 27 | } 28 | 29 | // TableName Cashback's table name 30 | func (*Cashback) TableName() string { 31 | return TableNameCashback 32 | } 33 | -------------------------------------------------------------------------------- /model/config.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | ) 10 | 11 | const TableNameConfig = "config" 12 | 13 | // Config mapped from table 14 | type Config struct { 15 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 16 | Name string `gorm:"column:name;primaryKey" json:"name"` 17 | Value string `gorm:"column:value" json:"value"` 18 | Remarks string `gorm:"column:remarks;not null" json:"remarks"` 19 | CreateTime time.Time `gorm:"column:create_time;not null;default:CURRENT_TIMESTAMP" json:"create_time"` 20 | UpdateTime time.Time `gorm:"column:update_time;not null;default:CURRENT_TIMESTAMP" json:"update_time"` 21 | IsDelete int32 `gorm:"column:is_delete;not null" json:"is_delete"` 22 | } 23 | 24 | // TableName Config's table name 25 | func (*Config) TableName() string { 26 | return TableNameConfig 27 | } 28 | -------------------------------------------------------------------------------- /model/dialog.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | ) 10 | 11 | const TableNameDialog = "dialog" 12 | 13 | // Dialog mapped from table 14 | type Dialog struct { 15 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 16 | Issue string `gorm:"column:issue;not null" json:"issue"` 17 | Answer string `gorm:"column:answer" json:"answer"` 18 | Models string `gorm:"column:models;not null" json:"models"` 19 | Delay int32 `gorm:"column:delay;not null" json:"delay"` 20 | Status int32 `gorm:"column:status;not null" json:"status"` 21 | CreateTime time.Time `gorm:"column:create_time;not null;default:CURRENT_TIMESTAMP" json:"create_time"` 22 | UpdateTime time.Time `gorm:"column:update_time;not null;default:CURRENT_TIMESTAMP" json:"update_time"` 23 | IsDelete int32 `gorm:"column:is_delete;not null" json:"is_delete"` 24 | } 25 | 26 | // TableName Dialog's table name 27 | func (*Dialog) TableName() string { 28 | return TableNameDialog 29 | } 30 | -------------------------------------------------------------------------------- /model/draw_record.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | ) 10 | 11 | const TableNameDrawRecord = "draw_record" 12 | 13 | // DrawRecord mapped from table 14 | type DrawRecord struct { 15 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 16 | UserID int64 `gorm:"column:user_id;not null;comment:用户id" json:"user_id"` // 用户id 17 | InsetImageURL string `gorm:"column:inset_image_url;not null;comment:插入图" json:"inset_image_url"` // 插入图 18 | Images string `gorm:"column:images;comment:生成图" json:"images"` // 生成图 19 | Prompt string `gorm:"column:prompt;not null;comment:生成提示词" json:"prompt"` // 生成提示词 20 | Model string `gorm:"column:model;not null;comment:使用模型" json:"model"` // 使用模型 21 | Params string `gorm:"column:params;not null;comment:附加参数" json:"params"` // 附加参数 22 | TakeTime int32 `gorm:"column:take_time;not null;comment:占用时间" json:"take_time"` // 占用时间 23 | Size string `gorm:"column:size;not null;comment:生成尺寸" json:"size"` // 生成尺寸 24 | Status int32 `gorm:"column:status;not null;default:1;comment:状态 0被删 1公开 4私有" json:"status"` // 状态 0被删 1公开 4私有 25 | CreateTime time.Time `gorm:"column:create_time;not null;default:CURRENT_TIMESTAMP" json:"create_time"` 26 | UpdateTime time.Time `gorm:"column:update_time;not null;default:CURRENT_TIMESTAMP" json:"update_time"` 27 | IsDelete int32 `gorm:"column:is_delete;not null" json:"is_delete"` 28 | } 29 | 30 | // TableName DrawRecord's table name 31 | func (*DrawRecord) TableName() string { 32 | return TableNameDrawRecord 33 | } 34 | -------------------------------------------------------------------------------- /model/installed_plugin.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | ) 10 | 11 | const TableNameInstalledPlugin = "installed_plugin" 12 | 13 | // InstalledPlugin mapped from table 14 | type InstalledPlugin struct { 15 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 16 | UserID int64 `gorm:"column:user_id;not null" json:"user_id"` 17 | PluginID int64 `gorm:"column:plugin_id;not null" json:"plugin_id"` 18 | Status int32 `gorm:"column:status;not null" json:"status"` 19 | CreateTime time.Time `gorm:"column:create_time;default:CURRENT_TIMESTAMP" json:"create_time"` 20 | UpdateTime time.Time `gorm:"column:update_time;default:CURRENT_TIMESTAMP" json:"update_time"` 21 | IsDelete int32 `gorm:"column:is_delete;not null" json:"is_delete"` 22 | } 23 | 24 | // TableName InstalledPlugin's table name 25 | func (*InstalledPlugin) TableName() string { 26 | return TableNameInstalledPlugin 27 | } 28 | -------------------------------------------------------------------------------- /model/invite_record.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | ) 10 | 11 | const TableNameInviteRecord = "invite_record" 12 | 13 | // InviteRecord mapped from table 14 | type InviteRecord struct { 15 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 16 | UserID int64 `gorm:"column:user_id;primaryKey" json:"user_id"` 17 | InviteCode string `gorm:"column:invite_code;not null;comment:邀请码" json:"invite_code"` // 邀请码 18 | SuperiorID int64 `gorm:"column:superior_id;not null;comment:上级ID(一旦确定将不可修改)" json:"superior_id"` // 上级ID(一旦确定将不可修改) 19 | Reward string `gorm:"column:reward;not null;comment:奖励" json:"reward"` // 奖励 20 | RewardType string `gorm:"column:reward_type;not null;comment:奖励类型" json:"reward_type"` // 奖励类型 21 | Status int32 `gorm:"column:status;not null;default:1;comment:1正常" json:"status"` // 1正常 22 | Remarks string `gorm:"column:remarks;not null;comment:评论" json:"remarks"` // 评论 23 | IP string `gorm:"column:ip;not null" json:"ip"` 24 | UserAgent string `gorm:"column:user_agent;comment:ua" json:"user_agent"` // ua 25 | CreateTime time.Time `gorm:"column:create_time;not null;default:CURRENT_TIMESTAMP" json:"create_time"` 26 | UpdateTime time.Time `gorm:"column:update_time;not null;default:CURRENT_TIMESTAMP" json:"update_time"` 27 | IsDelete int32 `gorm:"column:is_delete;not null" json:"is_delete"` 28 | } 29 | 30 | // TableName InviteRecord's table name 31 | func (*InviteRecord) TableName() string { 32 | return TableNameInviteRecord 33 | } 34 | -------------------------------------------------------------------------------- /model/message.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | ) 10 | 11 | const TableNameMessage = "message" 12 | 13 | // Message mapped from table 14 | type Message struct { 15 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 16 | UserID int64 `gorm:"column:user_id;not null" json:"user_id"` 17 | Content string `gorm:"column:content" json:"content"` 18 | PersonaID int64 `gorm:"column:persona_id;not null" json:"persona_id"` 19 | Role string `gorm:"column:role;not null" json:"role"` 20 | FrequencyPenalty int32 `gorm:"column:frequency_penalty;not null" json:"frequency_penalty"` 21 | MaxTokens int32 `gorm:"column:max_tokens;not null" json:"max_tokens"` 22 | Model string `gorm:"column:model;not null" json:"model"` 23 | PresencePenalty int32 `gorm:"column:presence_penalty;not null" json:"presence_penalty"` 24 | Temperature int32 `gorm:"column:temperature;not null" json:"temperature"` 25 | ParentMessageID string `gorm:"column:parent_message_id;not null;default:0" json:"parent_message_id"` 26 | Status int32 `gorm:"column:status;not null;default:1" json:"status"` 27 | PluginID int64 `gorm:"column:plugin_id;not null" json:"plugin_id"` 28 | CreateTime time.Time `gorm:"column:create_time;not null;default:CURRENT_TIMESTAMP" json:"create_time"` 29 | UpdateTime time.Time `gorm:"column:update_time;not null;default:CURRENT_TIMESTAMP" json:"update_time"` 30 | IsDelete int32 `gorm:"column:is_delete;not null" json:"is_delete"` 31 | } 32 | 33 | // TableName Message's table name 34 | func (*Message) TableName() string { 35 | return TableNameMessage 36 | } 37 | -------------------------------------------------------------------------------- /model/mytables.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | const TableNameMytable = "mytables" 8 | 9 | // Mytable mapped from table 10 | type Mytable struct { 11 | ID int32 `gorm:"column:ID;not null" json:"ID"` 12 | Username string `gorm:"column:username" json:"username"` 13 | Age int32 `gorm:"column:age;not null" json:"age"` 14 | Phone string `gorm:"column:phone;not null" json:"phone"` 15 | } 16 | 17 | // TableName Mytable's table name 18 | func (*Mytable) TableName() string { 19 | return TableNameMytable 20 | } 21 | -------------------------------------------------------------------------------- /model/notification.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | ) 10 | 11 | const TableNameNotification = "notification" 12 | 13 | // Notification mapped from table 14 | type Notification struct { 15 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 16 | Title string `gorm:"column:title;not null;comment:标题" json:"title"` // 标题 17 | Content string `gorm:"column:content;not null;comment:内容" json:"content"` // 内容 18 | Sort int32 `gorm:"column:sort;not null;default:1" json:"sort"` 19 | Status int32 `gorm:"column:status;not null;comment:状态" json:"status"` // 状态 20 | CreateTime time.Time `gorm:"column:create_time;default:CURRENT_TIMESTAMP" json:"create_time"` 21 | UpdateTime time.Time `gorm:"column:update_time;default:CURRENT_TIMESTAMP" json:"update_time"` 22 | IsDelete int32 `gorm:"column:is_delete;not null" json:"is_delete"` 23 | } 24 | 25 | // TableName Notification's table name 26 | func (*Notification) TableName() string { 27 | return TableNameNotification 28 | } 29 | -------------------------------------------------------------------------------- /model/order.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | ) 10 | 11 | const TableNameOrder = "order" 12 | 13 | // Order mapped from table 14 | type Order struct { 15 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 16 | TradeNo string `gorm:"column:trade_no;not null;comment:支付方订单ID" json:"trade_no"` // 支付方订单ID 17 | TradeStatus string `gorm:"column:trade_status;not null;comment:支付状态" json:"trade_status"` // 支付状态 18 | UserID string `gorm:"column:user_id;not null;comment:用户ID" json:"user_id"` // 用户ID 19 | ProductID int64 `gorm:"column:product_id;not null;comment:商品产品id" json:"product_id"` // 商品产品id 20 | ProductTitle string `gorm:"column:product_title;not null" json:"product_title"` 21 | ProductInfo string `gorm:"column:product_info;comment:商品信息快照" json:"product_info"` // 商品信息快照 22 | Money float64 `gorm:"column:money;not null;comment:支付金额" json:"money"` // 支付金额 23 | PayType string `gorm:"column:pay_type;not null;comment:支付方式 wxpay alipay" json:"pay_type"` // 支付方式 wxpay alipay 24 | PayURL string `gorm:"column:pay_url;not null;comment:支付URL" json:"pay_url"` // 支付URL 25 | Channel string `gorm:"column:channel;not null;comment:渠道号" json:"channel"` // 渠道号 26 | PaymentID int64 `gorm:"column:payment_id;not null;comment:支付产品ID" json:"payment_id"` // 支付产品ID 27 | PaymentInfo string `gorm:"column:payment_info;comment:支付产品信息" json:"payment_info"` // 支付产品信息 28 | NotifyInfo string `gorm:"column:notify_info;comment:通知回来的全部信息" json:"notify_info"` // 通知回来的全部信息 29 | Params string `gorm:"column:params;comment:拓展参数" json:"params"` // 拓展参数 30 | IP string `gorm:"column:ip;not null" json:"ip"` 31 | CreateTime time.Time `gorm:"column:create_time;default:CURRENT_TIMESTAMP" json:"create_time"` 32 | UpdateTime time.Time `gorm:"column:update_time;default:CURRENT_TIMESTAMP" json:"update_time"` 33 | IsDelete int32 `gorm:"column:is_delete;not null" json:"is_delete"` 34 | } 35 | 36 | // TableName Order's table name 37 | func (*Order) TableName() string { 38 | return TableNameOrder 39 | } 40 | -------------------------------------------------------------------------------- /model/payment.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | ) 10 | 11 | const TableNamePayment = "payment" 12 | 13 | // Payment mapped from table 14 | type Payment struct { 15 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 16 | Name string `gorm:"column:name;not null;comment:名称" json:"name"` // 名称 17 | Channel string `gorm:"column:channel;not null;comment:标识 支付宝 微信 易支付 码支付" json:"channel"` // 标识 支付宝 微信 易支付 码支付 18 | Types string `gorm:"column:types;not null;comment:['ailipay','wxpay']" json:"types"` // ['ailipay','wxpay'] 19 | Params string `gorm:"column:params;comment:支付所需参数" json:"params"` // 支付所需参数 20 | Status int32 `gorm:"column:status;not null;default:1;comment:1 正常 0异常" json:"status"` // 1 正常 0异常 21 | CreateTime time.Time `gorm:"column:create_time;not null;default:CURRENT_TIMESTAMP" json:"create_time"` 22 | UpdateTime time.Time `gorm:"column:update_time;not null;default:CURRENT_TIMESTAMP" json:"update_time"` 23 | IsDelete int32 `gorm:"column:is_delete;not null" json:"is_delete"` 24 | } 25 | 26 | // TableName Payment's table name 27 | func (*Payment) TableName() string { 28 | return TableNamePayment 29 | } 30 | -------------------------------------------------------------------------------- /model/persona.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | ) 10 | 11 | const TableNamePersona = "persona" 12 | 13 | // Persona mapped from table 14 | type Persona struct { 15 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 16 | UserID int64 `gorm:"column:user_id;not null" json:"user_id"` 17 | Title string `gorm:"column:title;not null" json:"title"` 18 | Avatar string `gorm:"column:avatar;not null" json:"avatar"` 19 | Description string `gorm:"column:description;not null" json:"description"` 20 | Context string `gorm:"column:context;not null" json:"context"` 21 | Status int32 `gorm:"column:status;not null;comment:1 正常 0异常 4审核中" json:"status"` // 1 正常 0异常 4审核中 22 | System int32 `gorm:"column:system;not null;comment:系统级别的角色" json:"system"` // 系统级别的角色 23 | CreateTime time.Time `gorm:"column:create_time;not null;default:CURRENT_TIMESTAMP" json:"create_time"` 24 | UpdateTime time.Time `gorm:"column:update_time;not null;default:CURRENT_TIMESTAMP" json:"update_time"` 25 | IsDelete int32 `gorm:"column:is_delete;not null" json:"is_delete"` 26 | } 27 | 28 | // TableName Persona's table name 29 | func (*Persona) TableName() string { 30 | return TableNamePersona 31 | } 32 | -------------------------------------------------------------------------------- /model/plugin.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | ) 10 | 11 | const TableNamePlugin = "plugin" 12 | 13 | // Plugin mapped from table 14 | type Plugin struct { 15 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 16 | Name string `gorm:"column:name;not null;comment:插件名称" json:"name"` // 插件名称 17 | Description string `gorm:"column:description;not null;comment:插件描述" json:"description"` // 插件描述 18 | Avatar string `gorm:"column:avatar;not null;comment:插件头像" json:"avatar"` // 插件头像 19 | Variables string `gorm:"column:variables;not null;comment:变量" json:"variables"` // 变量 20 | Function string `gorm:"column:function;comment:函数配置文件" json:"function"` // 函数配置文件 21 | Script string `gorm:"column:script;comment:js脚本" json:"script"` // js脚本 22 | UserID int64 `gorm:"column:user_id;not null;comment:提交用户id" json:"user_id"` // 提交用户id 23 | Status int32 `gorm:"column:status;not null;comment:4为审核中1为正常0为异常" json:"status"` // 4为审核中1为正常0为异常 24 | CreateTime time.Time `gorm:"column:create_time;not null;default:CURRENT_TIMESTAMP" json:"create_time"` 25 | UpdateTime time.Time `gorm:"column:update_time;not null;default:CURRENT_TIMESTAMP" json:"update_time"` 26 | IsDelete int32 `gorm:"column:is_delete;not null" json:"is_delete"` 27 | } 28 | 29 | // TableName Plugin's table name 30 | func (*Plugin) TableName() string { 31 | return TableNamePlugin 32 | } 33 | -------------------------------------------------------------------------------- /model/product.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | ) 10 | 11 | const TableNameProduct = "product" 12 | 13 | // Product mapped from table 14 | type Product struct { 15 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 16 | Title string `gorm:"column:title;not null" json:"title"` 17 | Price int32 `gorm:"column:price;not null" json:"price"` 18 | OriginalPrice int32 `gorm:"column:original_price;not null" json:"original_price"` 19 | Value int32 `gorm:"column:value;not null" json:"value"` 20 | Badge string `gorm:"column:badge;not null" json:"badge"` 21 | Status int32 `gorm:"column:status;not null;default:1;comment:1为正常" json:"status"` // 1为正常 22 | Type string `gorm:"column:type;not null;comment:integral 或 day" json:"type"` // integral 或 day 23 | Level int32 `gorm:"column:level;not null;default:1;comment:会员级别 1 普通 2会员 3超级会员" json:"level"` // 会员级别 1 普通 2会员 3超级会员 24 | Describe string `gorm:"column:describe;not null;comment:描述" json:"describe"` // 描述 25 | Sort int32 `gorm:"column:sort;not null;comment:排序" json:"sort"` // 排序 26 | CreateTime time.Time `gorm:"column:create_time;not null;default:CURRENT_TIMESTAMP" json:"create_time"` 27 | UpdateTime time.Time `gorm:"column:update_time;not null;default:CURRENT_TIMESTAMP" json:"update_time"` 28 | IsDelete int32 `gorm:"column:is_delete;not null" json:"is_delete"` 29 | } 30 | 31 | // TableName Product's table name 32 | func (*Product) TableName() string { 33 | return TableNameProduct 34 | } 35 | -------------------------------------------------------------------------------- /model/reward.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | ) 10 | 11 | const TableNameReward = "reward" 12 | 13 | // Reward mapped from table 14 | type Reward struct { 15 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true;comment:奖励表" json:"id"` // 奖励表 16 | Category string `gorm:"column:category;not null;comment:签到 | 邀请" json:"category"` // 签到 | 邀请 17 | Value string `gorm:"column:value;not null" json:"value"` 18 | Type string `gorm:"column:type;not null;comment:天 | 积分" json:"type"` // 天 | 积分 19 | Demand string `gorm:"column:demand;not null;comment:要求 签到是连续 邀请是不连续" json:"demand"` // 要求 签到是连续 邀请是不连续 20 | Status int32 `gorm:"column:status;not null;default:1;comment:1有效" json:"status"` // 1有效 21 | CreateTime time.Time `gorm:"column:create_time;not null;default:CURRENT_TIMESTAMP" json:"create_time"` 22 | UpdateTime time.Time `gorm:"column:update_time;not null;default:CURRENT_TIMESTAMP" json:"update_time"` 23 | IsDelete int32 `gorm:"column:is_delete;not null" json:"is_delete"` 24 | } 25 | 26 | // TableName Reward's table name 27 | func (*Reward) TableName() string { 28 | return TableNameReward 29 | } 30 | -------------------------------------------------------------------------------- /model/signin.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | ) 10 | 11 | const TableNameSignin = "signin" 12 | 13 | // Signin mapped from table 14 | type Signin struct { 15 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 16 | UserID int64 `gorm:"column:user_id;not null" json:"user_id"` 17 | IP string `gorm:"column:ip;not null" json:"ip"` 18 | Status int32 `gorm:"column:status;not null;default:1" json:"status"` 19 | CreateTime time.Time `gorm:"column:create_time;not null;default:CURRENT_TIMESTAMP" json:"create_time"` 20 | UpdateTime time.Time `gorm:"column:update_time;not null;default:CURRENT_TIMESTAMP" json:"update_time"` 21 | IsDelete int32 `gorm:"column:is_delete;not null" json:"is_delete"` 22 | } 23 | 24 | // TableName Signin's table name 25 | func (*Signin) TableName() string { 26 | return TableNameSignin 27 | } 28 | -------------------------------------------------------------------------------- /model/turnover.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | ) 10 | 11 | const TableNameTurnover = "turnover" 12 | 13 | // Turnover mapped from table 14 | type Turnover struct { 15 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 16 | UserID int64 `gorm:"column:user_id;not null;comment:用户" json:"user_id"` // 用户 17 | Describe string `gorm:"column:describe;not null;comment:描述" json:"describe"` // 描述 18 | Value string `gorm:"column:value;not null;comment:值" json:"value"` // 值 19 | CreateTime time.Time `gorm:"column:create_time;not null;default:CURRENT_TIMESTAMP" json:"create_time"` 20 | UpdateTime time.Time `gorm:"column:update_time;not null;default:CURRENT_TIMESTAMP" json:"update_time"` 21 | IsDelete int32 `gorm:"column:is_delete;not null" json:"is_delete"` 22 | } 23 | 24 | // TableName Turnover's table name 25 | func (*Turnover) TableName() string { 26 | return TableNameTurnover 27 | } 28 | -------------------------------------------------------------------------------- /model/upload_record.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | ) 10 | 11 | const TableNameUploadRecord = "upload_record" 12 | 13 | // UploadRecord mapped from table 14 | type UploadRecord struct { 15 | ID int32 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 16 | UserID int64 `gorm:"column:user_id;not null" json:"user_id"` 17 | Mimetype string `gorm:"column:mimetype;not null" json:"mimetype"` 18 | Sha1 string `gorm:"column:sha1;not null" json:"sha1"` 19 | Md5 string `gorm:"column:md5;not null" json:"md5"` 20 | URL string `gorm:"column:url;not null" json:"url"` 21 | Originalname string `gorm:"column:originalname;not null" json:"originalname"` 22 | Name string `gorm:"column:name;not null" json:"name"` 23 | Type string `gorm:"column:type;not null" json:"type"` 24 | Size string `gorm:"column:size;not null" json:"size"` 25 | Status int32 `gorm:"column:status;not null;default:1" json:"status"` 26 | CreateTime time.Time `gorm:"column:create_time;not null;default:CURRENT_TIMESTAMP" json:"create_time"` 27 | UpdateTime time.Time `gorm:"column:update_time;not null;default:CURRENT_TIMESTAMP" json:"update_time"` 28 | IsDelete int32 `gorm:"column:is_delete;not null" json:"is_delete"` 29 | } 30 | 31 | // TableName UploadRecord's table name 32 | func (*UploadRecord) TableName() string { 33 | return TableNameUploadRecord 34 | } 35 | -------------------------------------------------------------------------------- /model/user.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | ) 10 | 11 | const TableNameUser = "user" 12 | 13 | // User mapped from table 14 | type User struct { 15 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 16 | Nickname string `gorm:"column:nickname;not null" json:"nickname"` 17 | Account string `gorm:"column:account;not null" json:"account"` 18 | Password string `gorm:"column:password;not null" json:"password"` 19 | Avatar string `gorm:"column:avatar;not null" json:"avatar"` 20 | Role string `gorm:"column:role;not null" json:"role"` 21 | Integral int32 `gorm:"column:integral;not null" json:"integral"` 22 | VipExpireTime time.Time `gorm:"column:vip_expire_time;not null;default:2000-01-01 00:00:00;comment:会员时间" json:"vip_expire_time"` // 会员时间 23 | SvipExpireTime time.Time `gorm:"column:svip_expire_time;not null;default:2000-01-01 00:00:00;comment:超级会员时间" json:"svip_expire_time"` // 超级会员时间 24 | Status int32 `gorm:"column:status;not null;default:1;comment:1正常" json:"status"` // 1正常 25 | IP string `gorm:"column:ip;not null" json:"ip"` 26 | InviteCode string `gorm:"column:invite_code;not null;comment:邀请码" json:"invite_code"` // 邀请码 27 | SuperiorID int64 `gorm:"column:superior_id;not null;comment:上级ID(一旦确定将不可修改)" json:"superior_id"` // 上级ID(一旦确定将不可修改) 28 | UserAgent string `gorm:"column:user_agent;comment:ua" json:"user_agent"` // ua 29 | CreateTime time.Time `gorm:"column:create_time;not null;default:CURRENT_TIMESTAMP" json:"create_time"` 30 | UpdateTime time.Time `gorm:"column:update_time;not null;default:CURRENT_TIMESTAMP" json:"update_time"` 31 | IsDelete int32 `gorm:"column:is_delete;not null" json:"is_delete"` 32 | } 33 | 34 | // TableName User's table name 35 | func (*User) TableName() string { 36 | return TableNameUser 37 | } 38 | -------------------------------------------------------------------------------- /model/user.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/auth/password" 5 | "gorm.io/gorm" 6 | ) 7 | 8 | // ComparePassword 检查密码是否匹配 9 | func (user *User) ComparePassword(_password string) bool { 10 | return password.CheckHash(_password, user.Password) 11 | } 12 | 13 | // BeforeSave 保存前 14 | func (user *User) BeforeSave(tx *gorm.DB) (err error) { 15 | if !password.IsHashed(user.Password) { 16 | user.Password = password.Hash(user.Password) 17 | } 18 | return 19 | } 20 | -------------------------------------------------------------------------------- /model/withdrawal_record.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | ) 10 | 11 | const TableNameWithdrawalRecord = "withdrawal_record" 12 | 13 | // WithdrawalRecord mapped from table 14 | type WithdrawalRecord struct { 15 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 16 | UserID int64 `gorm:"column:user_id;not null;comment:申请的用户id" json:"user_id"` // 申请的用户id 17 | Amount string `gorm:"column:amount;not null;comment:提现金额 分" json:"amount"` // 提现金额 分 18 | Type string `gorm:"column:type;not null;comment:提现方式" json:"type"` // 提现方式 19 | Name string `gorm:"column:name;not null;comment:收款人姓名" json:"name"` // 收款人姓名 20 | Contact string `gorm:"column:contact;not null;comment:联系方式" json:"contact"` // 联系方式 21 | Account string `gorm:"column:account;not null;comment:收款账号" json:"account"` // 收款账号 22 | Remarks string `gorm:"column:remarks;not null;comment:评论" json:"remarks"` // 评论 23 | Message string `gorm:"column:message;not null;comment:消息" json:"message"` // 消息 24 | Status int32 `gorm:"column:status;not null;default:3;comment:0异常 1正常 3审核中 6等待下发" json:"status"` // 0异常 1正常 3审核中 6等待下发 25 | IP string `gorm:"column:ip;not null" json:"ip"` 26 | UserAgent string `gorm:"column:user_agent;not null;comment:ua" json:"user_agent"` // ua 27 | CreateTime time.Time `gorm:"column:create_time;not null;default:CURRENT_TIMESTAMP" json:"create_time"` 28 | UpdateTime time.Time `gorm:"column:update_time;not null;default:CURRENT_TIMESTAMP" json:"update_time"` 29 | IsDelete int32 `gorm:"column:is_delete;not null" json:"is_delete"` 30 | } 31 | 32 | // TableName WithdrawalRecord's table name 33 | func (*WithdrawalRecord) TableName() string { 34 | return TableNameWithdrawalRecord 35 | } 36 | -------------------------------------------------------------------------------- /router/admin.go: -------------------------------------------------------------------------------- 1 | package router 2 | 3 | import ( 4 | "chatgpt-web-new-go/router/admin/amountHandlers" 5 | "chatgpt-web-new-go/router/admin/carmiHandlers" 6 | "chatgpt-web-new-go/router/admin/cashbackHandlers" 7 | "chatgpt-web-new-go/router/admin/configHandlers" 8 | "chatgpt-web-new-go/router/admin/dialogHandlers" 9 | "chatgpt-web-new-go/router/admin/drawHandlers" 10 | "chatgpt-web-new-go/router/admin/inviteHandlers" 11 | "chatgpt-web-new-go/router/admin/messageHandlers" 12 | "chatgpt-web-new-go/router/admin/notificationHandlers" 13 | "chatgpt-web-new-go/router/admin/orderHandlers" 14 | "chatgpt-web-new-go/router/admin/payHandlers" 15 | "chatgpt-web-new-go/router/admin/personaHandlers" 16 | "chatgpt-web-new-go/router/admin/pluginHandlers" 17 | "chatgpt-web-new-go/router/admin/productHandlers" 18 | "chatgpt-web-new-go/router/admin/signinHandlers" 19 | "chatgpt-web-new-go/router/admin/tokenHandlers" 20 | "chatgpt-web-new-go/router/admin/turnoverHandlers" 21 | "chatgpt-web-new-go/router/admin/userHandlers" 22 | "chatgpt-web-new-go/router/admin/withdrawalHandlers" 23 | "github.com/gin-gonic/gin" 24 | ) 25 | 26 | func adminGroup(group *gin.RouterGroup) { 27 | 28 | // carmi Handlers 29 | adminCarmiGroup(group.Group("/carmi")) 30 | 31 | // user handlers 32 | adminUserGroup(group.Group("/user")) 33 | 34 | // product 35 | adminProductGroup(group.Group("/products")) 36 | 37 | // message 38 | adminMessageGroup(group.Group("/messages")) 39 | 40 | // signin 41 | adminSigninGroup(group.Group("/signin")) 42 | 43 | // turnover 44 | adminTurnoverGroup(group.Group("/turnover")) 45 | 46 | // token 47 | adminTokenGroup(group.Group("/aikey")) 48 | 49 | // config 50 | adminConfigGroup(group.Group("/config")) 51 | 52 | // pay 53 | adminPayGroup(group.Group("/payment")) 54 | 55 | // orders 56 | adminOrderGroup(group.Group("/orders")) 57 | 58 | // notice 59 | adminNotificationGroup(group.Group("/notification")) 60 | 61 | // invite_record 62 | adminInviteGroup(group.Group("/invite_record")) 63 | 64 | // cashback 65 | adminCashbackGroup(group.Group("/cashback")) 66 | 67 | // withdrawal_record 68 | adminWithdrawalGroup(group.Group("/withdrawal_record")) 69 | 70 | // amount_details 71 | adminAmountGroup(group.Group("/amount_details")) 72 | 73 | // dialog 74 | adminDialogGroup(group.Group("/dialog")) 75 | 76 | // persona 77 | adminPersonaGroup(group.Group("/persona")) 78 | 79 | // plugins 80 | adminPluginGroup(group.Group("/plugins")) 81 | 82 | // draw_record 83 | adminDrawGroup(group.Group("/draw_record")) 84 | } 85 | 86 | func adminDrawGroup(group *gin.RouterGroup) { 87 | group.GET("", drawHandlers.List) 88 | group.PUT("", drawHandlers.Update) 89 | group.POST("", drawHandlers.Add) 90 | group.DELETE("/:id", drawHandlers.Delete) 91 | } 92 | 93 | func adminPluginGroup(group *gin.RouterGroup) { 94 | group.GET("", pluginHandlers.List) 95 | group.PUT("", pluginHandlers.Update) 96 | group.POST("", pluginHandlers.Add) 97 | group.DELETE("/:id", pluginHandlers.Delete) 98 | } 99 | 100 | func adminPersonaGroup(group *gin.RouterGroup) { 101 | group.GET("", personaHandlers.List) 102 | group.PUT("", personaHandlers.Update) 103 | group.POST("", personaHandlers.Add) 104 | group.DELETE("/:id", personaHandlers.Delete) 105 | } 106 | 107 | func adminDialogGroup(group *gin.RouterGroup) { 108 | group.GET("", dialogHandlers.List) 109 | group.PUT("", dialogHandlers.Update) 110 | group.POST("", dialogHandlers.Add) 111 | group.DELETE("/:id", dialogHandlers.Delete) 112 | } 113 | 114 | func adminAmountGroup(group *gin.RouterGroup) { 115 | group.GET("", amountHandlers.List) 116 | group.PUT("", amountHandlers.Update) 117 | group.DELETE("/:id", amountHandlers.Delete) 118 | } 119 | 120 | func adminWithdrawalGroup(group *gin.RouterGroup) { 121 | group.GET("", withdrawalHandlers.List) 122 | group.PUT("", withdrawalHandlers.Update) 123 | group.DELETE("/:id", withdrawalHandlers.Delete) 124 | } 125 | 126 | func adminCashbackGroup(group *gin.RouterGroup) { 127 | group.GET("", cashbackHandlers.CashbackList) 128 | group.PUT("", cashbackHandlers.CashbackUpdate) 129 | group.DELETE("/:id", cashbackHandlers.CashbackDelete) 130 | group.PUT("/pass", cashbackHandlers.CashbackPass) 131 | } 132 | 133 | func adminInviteGroup(group *gin.RouterGroup) { 134 | group.GET("", inviteHandlers.InviteRecords) 135 | group.PUT("", inviteHandlers.InviteUpdate) 136 | group.PUT("/pass", inviteHandlers.InvitePass) 137 | group.DELETE("/:id", inviteHandlers.InviteDelete) 138 | } 139 | 140 | func adminNotificationGroup(group *gin.RouterGroup) { 141 | group.GET("", notificationHandlers.List) 142 | group.POST("", notificationHandlers.Add) 143 | group.PUT("", notificationHandlers.Update) 144 | group.DELETE("/:id", notificationHandlers.Delete) 145 | } 146 | 147 | func adminOrderGroup(group *gin.RouterGroup) { 148 | group.GET("", orderHandlers.OrderList) 149 | } 150 | 151 | func adminPayGroup(group *gin.RouterGroup) { 152 | group.GET("", payHandlers.PayConfigList) 153 | group.POST("", payHandlers.PayConfigAdd) 154 | group.PUT("", payHandlers.PayConfigUpdate) 155 | group.DELETE("/:id", payHandlers.PayConfigDelete) 156 | } 157 | 158 | func adminConfigGroup(group *gin.RouterGroup) { 159 | group.GET("", configHandlers.ConfigList) 160 | group.PUT("", configHandlers.ConfigUpdate) 161 | } 162 | 163 | func adminTokenGroup(group *gin.RouterGroup) { 164 | group.GET("", tokenHandlers.TokenList) 165 | group.POST("", tokenHandlers.TokenAdd) 166 | group.PUT("", tokenHandlers.TokenUpdate) 167 | group.DELETE("/:id", tokenHandlers.TokenDelete) 168 | // todo 169 | group.POST("/check", tokenHandlers.TokenCheck) 170 | } 171 | 172 | func adminTurnoverGroup(group *gin.RouterGroup) { 173 | group.GET("", turnoverHandlers.TurnoverList) 174 | group.DELETE("/:id", turnoverHandlers.TurnoverDelete) 175 | group.PUT("", turnoverHandlers.TurnoverUpdate) 176 | } 177 | 178 | func adminSigninGroup(group *gin.RouterGroup) { 179 | group.GET("", signinHandlers.SigninList) 180 | } 181 | 182 | func adminMessageGroup(group *gin.RouterGroup) { 183 | group.GET("", messageHandlers.MessageList) 184 | } 185 | 186 | func adminProductGroup(group *gin.RouterGroup) { 187 | group.GET("", productHandlers.ProductList) 188 | group.POST("", productHandlers.ProductAdd) 189 | group.PUT("", productHandlers.ProductPut) 190 | group.DELETE("/:id", productHandlers.ProductDelete) 191 | } 192 | 193 | func adminUserGroup(group *gin.RouterGroup) { 194 | group.GET("", userHandlers.UserList) 195 | group.DELETE("/:id", userHandlers.UserDelete) 196 | group.PUT("", userHandlers.UserUpdate) 197 | } 198 | 199 | func adminCarmiGroup(group *gin.RouterGroup) { 200 | group.GET("", carmiHandlers.CarmiList) 201 | group.POST("", carmiHandlers.CarmiGen) 202 | group.DELETE("/:id", carmiHandlers.CarmiDel) 203 | // TODO 204 | group.GET("/check", carmiHandlers.CarmiCheck) 205 | } 206 | -------------------------------------------------------------------------------- /router/admin/amountHandlers/handler.go: -------------------------------------------------------------------------------- 1 | package amountHandlers 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "chatgpt-web-new-go/common/types" 6 | "chatgpt-web-new-go/model" 7 | "chatgpt-web-new-go/router/base" 8 | "chatgpt-web-new-go/service/amount" 9 | "github.com/gin-gonic/gin" 10 | ) 11 | 12 | func List(c *gin.Context) { 13 | request := &base.Page{} 14 | if err := c.Bind(request); err != nil { 15 | logs.Error("json bind error: %v", err) 16 | base.Fail(c, "参数异常!"+err.Error()) 17 | return 18 | } 19 | 20 | notifications, count, err := amount.List(c, request.Page, request.PageSize) 21 | if err != nil { 22 | logs.Error("amount list error: %v", err) 23 | base.Fail(c, "查询异常:"+err.Error()) 24 | return 25 | } 26 | 27 | base.Success(c, base.PageResponse{ 28 | Count: count, 29 | Rows: notifications, 30 | }) 31 | } 32 | 33 | func Update(c *gin.Context) { 34 | request := &model.AmountDetail{} 35 | if err := c.BindJSON(request); err != nil { 36 | logs.Error("json bind error: %v", err) 37 | base.Fail(c, "参数异常:"+err.Error()) 38 | return 39 | } 40 | 41 | err := amount.Update(c, request) 42 | if err != nil { 43 | logs.Error("amount update error: %v", err) 44 | base.Fail(c, "更新失败:"+err.Error()) 45 | return 46 | } 47 | 48 | base.SuccessMsg(c, "更新成功", nil) 49 | } 50 | 51 | func Delete(c *gin.Context) { 52 | idStr := c.Param("id") 53 | if idStr == "" || idStr == "undefined" { 54 | logs.Error("id is empty: %v", idStr) 55 | base.Fail(c, "参数id为空!"+idStr) 56 | return 57 | } 58 | 59 | id := types.StringToInt64(idStr) 60 | err := amount.Delete(c, id) 61 | if err != nil { 62 | logs.Error("amount delete error: %v", err) 63 | base.Fail(c, "删除失败!"+err.Error()) 64 | return 65 | } 66 | 67 | base.SuccessMsg(c, "删除成功!", nil) 68 | } 69 | -------------------------------------------------------------------------------- /router/admin/carmiHandlers/handler.go: -------------------------------------------------------------------------------- 1 | package carmiHandlers 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "chatgpt-web-new-go/common/types" 6 | "chatgpt-web-new-go/router/base" 7 | "chatgpt-web-new-go/service/carmi" 8 | "github.com/gin-gonic/gin" 9 | ) 10 | 11 | func CarmiList(c *gin.Context) { 12 | request := &base.Page{} 13 | 14 | if err := c.Bind(request); err != nil { 15 | logs.Error("request bind json error: %v", err) 16 | base.Fail(c, "参数异常:"+err.Error()) 17 | return 18 | } 19 | 20 | carmiList, count, err := carmi.CarmiList(c, request.Page, request.PageSize) 21 | if err != nil { 22 | logs.Error("carmi list error: %v", err) 23 | base.Fail(c, "查询异常:"+err.Error()) 24 | return 25 | } 26 | 27 | base.Success(c, &base.PageResponse{ 28 | Count: count, Rows: carmiList, 29 | }) 30 | } 31 | 32 | func CarmiDel(c *gin.Context) { 33 | idStr := c.Param("id") 34 | if idStr == "" || idStr == "undefined" { 35 | logs.Error("param id not found: %v", idStr) 36 | base.Fail(c, "缺少参数id") 37 | return 38 | } 39 | 40 | id := types.StringToInt64(idStr) 41 | err := carmi.CarmiDel(c, id) 42 | if err != nil { 43 | logs.Error("delete carmi error: %v", err) 44 | base.Fail(c, "删除失败:"+err.Error()) 45 | return 46 | } 47 | 48 | base.SuccessMsg(c, "删除成功", nil) 49 | } 50 | 51 | func CarmiGen(c *gin.Context) { 52 | request := &carmi.CarmiGenRequest{} 53 | 54 | if err := c.BindJSON(request); err != nil { 55 | logs.Error("request bind error: %v", err) 56 | base.Fail(c, "参数异常:"+err.Error()) 57 | return 58 | } 59 | 60 | result, err := carmi.CarmiGen(c, request) 61 | if err != nil { 62 | logs.Error("carmi gen service error: %v", err) 63 | base.Fail(c, "卡密生成异常:"+err.Error()) 64 | return 65 | } 66 | 67 | base.Success(c, result) 68 | } 69 | 70 | func CarmiCheck(c *gin.Context) { 71 | 72 | } 73 | -------------------------------------------------------------------------------- /router/admin/cashbackHandlers/handler.go: -------------------------------------------------------------------------------- 1 | package cashbackHandlers 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "chatgpt-web-new-go/common/types" 6 | "chatgpt-web-new-go/model" 7 | "chatgpt-web-new-go/router/base" 8 | "chatgpt-web-new-go/service/cashback" 9 | "github.com/gin-gonic/gin" 10 | ) 11 | 12 | func CashbackList(c *gin.Context) { 13 | request := &base.Page{} 14 | if err := c.Bind(request); err != nil { 15 | logs.Error("json bind error: %v", err) 16 | base.Fail(c, "参数异常:"+err.Error()) 17 | return 18 | } 19 | 20 | cashbackList, count, err := cashback.CashbackList(c, request.Page, request.PageSize) 21 | if err != nil { 22 | logs.Error("cashback list error: %v", err) 23 | base.Fail(c, "查询异常!"+err.Error()) 24 | return 25 | } 26 | 27 | base.Success(c, base.PageResponse{ 28 | Count: count, 29 | Rows: cashbackList, 30 | }) 31 | } 32 | 33 | func CashbackUpdate(c *gin.Context) { 34 | request := &model.Cashback{} 35 | if err := c.BindJSON(request); err != nil { 36 | logs.Error("json bind error: %v", err) 37 | base.Fail(c, "参数异常!"+err.Error()) 38 | return 39 | } 40 | 41 | err := cashback.CashbackUpdate(c, request) 42 | if err != nil { 43 | logs.Error("cashback update error: %v", err) 44 | base.Fail(c, "更新异常:"+err.Error()) 45 | return 46 | } 47 | 48 | base.SuccessMsg(c, "更新成功!", nil) 49 | } 50 | 51 | func CashbackDelete(c *gin.Context) { 52 | idStr := c.Param("id") 53 | if idStr == "" || idStr == "undefined" { 54 | logs.Error("param id not found: %v", idStr) 55 | base.Fail(c, "缺少参数id") 56 | return 57 | } 58 | 59 | id := types.StringToInt64(idStr) 60 | err := cashback.CashbackDelete(c, id) 61 | if err != nil { 62 | logs.Error("delete cashback error: %v", err) 63 | base.Fail(c, "删除失败:"+err.Error()) 64 | return 65 | } 66 | 67 | base.SuccessMsg(c, "删除成功", nil) 68 | } 69 | 70 | func CashbackPass(c *gin.Context) { 71 | request := &model.Cashback{} 72 | if err := c.BindJSON(request); err != nil { 73 | logs.Error("json bind error: %v", err) 74 | base.Fail(c, "参数异常!"+err.Error()) 75 | return 76 | } 77 | 78 | err := cashback.CashbackPass(c, request.ID) 79 | if err != nil { 80 | logs.Error("cashback pass error: %v", err) 81 | base.Fail(c, "更新异常:"+err.Error()) 82 | return 83 | } 84 | 85 | base.SuccessMsg(c, "更新成功!", nil) 86 | } 87 | -------------------------------------------------------------------------------- /router/admin/configHandlers/handler.go: -------------------------------------------------------------------------------- 1 | package configHandlers 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "chatgpt-web-new-go/router/base" 6 | "chatgpt-web-new-go/service/config" 7 | "github.com/gin-gonic/gin" 8 | ) 9 | 10 | func ConfigList(c *gin.Context) { 11 | configList, err := config.AdminConfigList(c) 12 | if err != nil { 13 | logs.Error("config list error: %v", err) 14 | base.Fail(c, "配置列表查询异常:"+err.Error()) 15 | return 16 | } 17 | 18 | base.Success(c, configList) 19 | } 20 | 21 | func ConfigUpdate(c *gin.Context) { 22 | request := map[string]string{} 23 | if err := c.BindJSON(&request); err != nil { 24 | logs.Error("param bind json error: %v", err) 25 | base.Fail(c, "参数异常!"+err.Error()) 26 | return 27 | } 28 | 29 | err := config.ConfigUpdate(c, request) 30 | if err != nil { 31 | logs.Error("config update error: %v", err) 32 | base.Fail(c, "配置更新异常!"+err.Error()) 33 | return 34 | } 35 | 36 | base.SuccessMsg(c, "更新成功!", nil) 37 | } 38 | -------------------------------------------------------------------------------- /router/admin/dialogHandlers/handler.go: -------------------------------------------------------------------------------- 1 | package dialogHandlers 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "chatgpt-web-new-go/common/types" 6 | "chatgpt-web-new-go/model" 7 | "chatgpt-web-new-go/router/base" 8 | "chatgpt-web-new-go/service/dialog" 9 | "github.com/gin-gonic/gin" 10 | ) 11 | 12 | func List(c *gin.Context) { 13 | request := &base.Page{} 14 | if err := c.Bind(request); err != nil { 15 | logs.Error("json bind error: %v", err) 16 | base.Fail(c, "参数异常!"+err.Error()) 17 | return 18 | } 19 | 20 | list, count, err := dialog.List(c, request.Page, request.PageSize) 21 | if err != nil { 22 | logs.Error("list error: %v", err) 23 | base.Fail(c, "查询异常:"+err.Error()) 24 | return 25 | } 26 | 27 | base.Success(c, base.PageResponse{ 28 | Count: count, 29 | Rows: list, 30 | }) 31 | } 32 | 33 | func Add(c *gin.Context) { 34 | request := &model.Dialog{} 35 | if err := c.BindJSON(request); err != nil { 36 | logs.Error("json bind error: %v", err) 37 | base.Fail(c, "参数异常:"+err.Error()) 38 | return 39 | } 40 | 41 | err := dialog.Add(c, request) 42 | if err != nil { 43 | logs.Error("dialog create error: %v", err) 44 | base.Fail(c, "创建失败:"+err.Error()) 45 | return 46 | } 47 | 48 | base.SuccessMsg(c, "创建成功", nil) 49 | } 50 | 51 | func Update(c *gin.Context) { 52 | request := &model.Dialog{} 53 | if err := c.BindJSON(request); err != nil { 54 | logs.Error("json bind error: %v", err) 55 | base.Fail(c, "参数异常:"+err.Error()) 56 | return 57 | } 58 | 59 | err := dialog.Update(c, request) 60 | if err != nil { 61 | logs.Error("dialog update error: %v", err) 62 | base.Fail(c, "更新失败:"+err.Error()) 63 | return 64 | } 65 | 66 | base.SuccessMsg(c, "更新成功", nil) 67 | } 68 | 69 | func Delete(c *gin.Context) { 70 | idStr := c.Param("id") 71 | if idStr == "" || idStr == "undefined" { 72 | logs.Error("id is empty: %v", idStr) 73 | base.Fail(c, "参数id为空!"+idStr) 74 | return 75 | } 76 | 77 | id := types.StringToInt64(idStr) 78 | err := dialog.Delete(c, id) 79 | if err != nil { 80 | logs.Error("dialog delete error: %v", err) 81 | base.Fail(c, "删除失败!"+err.Error()) 82 | return 83 | } 84 | 85 | base.SuccessMsg(c, "删除成功!", nil) 86 | } 87 | -------------------------------------------------------------------------------- /router/admin/drawHandlers/handler.go: -------------------------------------------------------------------------------- 1 | package drawHandlers 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "chatgpt-web-new-go/common/types" 6 | "chatgpt-web-new-go/model" 7 | "chatgpt-web-new-go/router/base" 8 | "chatgpt-web-new-go/service/draw" 9 | "github.com/gin-gonic/gin" 10 | ) 11 | 12 | func List(c *gin.Context) { 13 | request := &base.Page{} 14 | if err := c.Bind(request); err != nil { 15 | logs.Error("json bind error: %v", err) 16 | base.Fail(c, "参数异常!"+err.Error()) 17 | return 18 | } 19 | 20 | list, count, err := draw.List(c, request.Page, request.PageSize) 21 | if err != nil { 22 | logs.Error("list error: %v", err) 23 | base.Fail(c, "查询异常:"+err.Error()) 24 | return 25 | } 26 | 27 | base.Success(c, base.PageResponse{ 28 | Count: count, 29 | Rows: list, 30 | }) 31 | } 32 | 33 | func Add(c *gin.Context) { 34 | request := &model.DrawRecord{} 35 | if err := c.BindJSON(request); err != nil { 36 | logs.Error("json bind error: %v", err) 37 | base.Fail(c, "参数异常:"+err.Error()) 38 | return 39 | } 40 | 41 | err := draw.Add(c, request) 42 | if err != nil { 43 | logs.Error("draw create error: %v", err) 44 | base.Fail(c, "创建失败:"+err.Error()) 45 | return 46 | } 47 | 48 | base.SuccessMsg(c, "创建成功", nil) 49 | } 50 | 51 | func Update(c *gin.Context) { 52 | request := &model.DrawRecord{} 53 | if err := c.BindJSON(request); err != nil { 54 | logs.Error("json bind error: %v", err) 55 | base.Fail(c, "参数异常:"+err.Error()) 56 | return 57 | } 58 | 59 | err := draw.Update(c, request) 60 | if err != nil { 61 | logs.Error("draw update error: %v", err) 62 | base.Fail(c, "更新失败:"+err.Error()) 63 | return 64 | } 65 | 66 | base.SuccessMsg(c, "更新成功", nil) 67 | } 68 | 69 | func Delete(c *gin.Context) { 70 | idStr := c.Param("id") 71 | if idStr == "" || idStr == "undefined" { 72 | logs.Error("id is empty: %v", idStr) 73 | base.Fail(c, "参数id为空!"+idStr) 74 | return 75 | } 76 | 77 | id := types.StringToInt64(idStr) 78 | err := draw.Delete(c, id) 79 | if err != nil { 80 | logs.Error("draw delete error: %v", err) 81 | base.Fail(c, "删除失败!"+err.Error()) 82 | return 83 | } 84 | 85 | base.SuccessMsg(c, "删除成功!", nil) 86 | } 87 | -------------------------------------------------------------------------------- /router/admin/inviteHandlers/handler.go: -------------------------------------------------------------------------------- 1 | package inviteHandlers 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "chatgpt-web-new-go/common/types" 6 | "chatgpt-web-new-go/model" 7 | "chatgpt-web-new-go/router/base" 8 | "chatgpt-web-new-go/service/invite" 9 | "github.com/gin-gonic/gin" 10 | ) 11 | 12 | func InviteRecords(c *gin.Context) { 13 | request := &base.Page{} 14 | if err := c.Bind(request); err != nil { 15 | logs.Error("bind json error: %v", err) 16 | base.Fail(c, "参数异常:"+err.Error()) 17 | return 18 | } 19 | 20 | inviteRecords, count, err := invite.InviteRecords(c, request.Page, request.PageSize) 21 | if err != nil { 22 | logs.Error("invite records error: %v", err) 23 | base.Fail(c, "邀请记录查询异常!"+err.Error()) 24 | return 25 | } 26 | 27 | base.Success(c, base.PageResponse{ 28 | Count: count, 29 | Rows: inviteRecords, 30 | }) 31 | } 32 | 33 | func InviteUpdate(c *gin.Context) { 34 | request := &model.InviteRecord{} 35 | 36 | if err := c.BindJSON(request); err != nil { 37 | logs.Error("json bind error: %v", err) 38 | base.Fail(c, "参数异常:"+err.Error()) 39 | return 40 | } 41 | 42 | err := invite.InviteUpdate(c, request) 43 | if err != nil { 44 | logs.Error("invite update error: %v", err) 45 | base.Fail(c, "邀请记录更新异常:"+err.Error()) 46 | return 47 | } 48 | 49 | base.SuccessMsg(c, "更新成功!", nil) 50 | } 51 | 52 | func InviteDelete(c *gin.Context) { 53 | idStr := c.Param("id") 54 | if idStr == "" || idStr == "undefined" { 55 | logs.Error("param id not found: %v", idStr) 56 | base.Fail(c, "缺少参数id") 57 | return 58 | } 59 | 60 | id := types.StringToInt64(idStr) 61 | err := invite.InviteDelete(c, id) 62 | if err != nil { 63 | logs.Error("delete invite error: %v", err) 64 | base.Fail(c, "删除失败:"+err.Error()) 65 | return 66 | } 67 | 68 | base.SuccessMsg(c, "删除成功", nil) 69 | } 70 | 71 | func InvitePass(c *gin.Context) { 72 | err := invite.InvitePass(c) 73 | if err != nil { 74 | logs.Error("invite pass error: %v", err) 75 | base.Fail(c, "邀请记录通过异常!"+err.Error()) 76 | return 77 | } 78 | 79 | base.SuccessMsg(c, "全部通过成功!", nil) 80 | } 81 | -------------------------------------------------------------------------------- /router/admin/messageHandlers/handler.go: -------------------------------------------------------------------------------- 1 | package messageHandlers 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "chatgpt-web-new-go/router/base" 6 | "chatgpt-web-new-go/service/message" 7 | "github.com/gin-gonic/gin" 8 | ) 9 | 10 | func MessageList(c *gin.Context) { 11 | request := &base.Page{} 12 | if err := c.Bind(request); err != nil { 13 | logs.Error("json bind error: %v", err) 14 | base.Fail(c, "参数异常!"+err.Error()) 15 | return 16 | } 17 | 18 | result, err := message.AdminMessageList(c) 19 | if err != nil { 20 | logs.Error("message list error: %v", err) 21 | base.Fail(c, "回话列表异常:"+err.Error()) 22 | return 23 | } 24 | 25 | base.Success(c, result) 26 | } 27 | -------------------------------------------------------------------------------- /router/admin/notificationHandlers/handler.go: -------------------------------------------------------------------------------- 1 | package notificationHandlers 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "chatgpt-web-new-go/common/types" 6 | "chatgpt-web-new-go/model" 7 | "chatgpt-web-new-go/router/base" 8 | "chatgpt-web-new-go/service/notification" 9 | "github.com/gin-gonic/gin" 10 | ) 11 | 12 | func List(c *gin.Context) { 13 | request := &base.Page{} 14 | if err := c.Bind(request); err != nil { 15 | logs.Error("json bind error: %v", err) 16 | base.Fail(c, "参数异常!"+err.Error()) 17 | return 18 | } 19 | 20 | notifications, count, err := notification.GetList(c, request.Page, request.PageSize) 21 | if err != nil { 22 | logs.Error("notification list error: %v", err) 23 | base.Fail(c, "查询异常:"+err.Error()) 24 | return 25 | } 26 | 27 | base.Success(c, base.PageResponse{ 28 | Count: count, 29 | Rows: notifications, 30 | }) 31 | } 32 | 33 | func Add(c *gin.Context) { 34 | request := &model.Notification{} 35 | if err := c.BindJSON(request); err != nil { 36 | logs.Error("json bind error: %v", err) 37 | base.Fail(c, "参数异常:"+err.Error()) 38 | return 39 | } 40 | 41 | err := notification.Add(c, request) 42 | if err != nil { 43 | logs.Error("notification create error: %v", err) 44 | base.Fail(c, "创建失败:"+err.Error()) 45 | return 46 | } 47 | 48 | base.SuccessMsg(c, "创建成功", nil) 49 | } 50 | 51 | func Update(c *gin.Context) { 52 | request := &model.Notification{} 53 | if err := c.BindJSON(request); err != nil { 54 | logs.Error("json bind error: %v", err) 55 | base.Fail(c, "参数异常:"+err.Error()) 56 | return 57 | } 58 | 59 | err := notification.Update(c, request) 60 | if err != nil { 61 | logs.Error("notification update error: %v", err) 62 | base.Fail(c, "更新失败:"+err.Error()) 63 | return 64 | } 65 | 66 | base.SuccessMsg(c, "更新成功", nil) 67 | } 68 | 69 | func Delete(c *gin.Context) { 70 | idStr := c.Param("id") 71 | if idStr == "" || idStr == "undefined" { 72 | logs.Error("id is empty: %v", idStr) 73 | base.Fail(c, "参数id为空!"+idStr) 74 | return 75 | } 76 | 77 | id := types.StringToInt64(idStr) 78 | err := notification.Delete(c, id) 79 | if err != nil { 80 | logs.Error("notification delete error: %v", err) 81 | base.Fail(c, "删除失败!"+err.Error()) 82 | return 83 | } 84 | 85 | base.SuccessMsg(c, "删除成功!", nil) 86 | } 87 | -------------------------------------------------------------------------------- /router/admin/orderHandlers/handler.go: -------------------------------------------------------------------------------- 1 | package orderHandlers 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "chatgpt-web-new-go/router/base" 6 | "chatgpt-web-new-go/service/order" 7 | "github.com/gin-gonic/gin" 8 | ) 9 | 10 | func OrderList(c *gin.Context) { 11 | request := &base.Page{} 12 | if err := c.Bind(request); err != nil { 13 | logs.Error("json bind error: %v", err) 14 | base.Fail(c, "参数异常: "+err.Error()) 15 | return 16 | } 17 | 18 | orderList, count, err := order.OrderList(c, request.Page, request.PageSize) 19 | if err != nil { 20 | logs.Error("order list error: %v", err) 21 | base.Fail(c, "订单查询失败:"+err.Error()) 22 | return 23 | } 24 | 25 | base.Success(c, base.PageResponse{ 26 | Count: count, 27 | Rows: orderList, 28 | }) 29 | } 30 | -------------------------------------------------------------------------------- /router/admin/payHandlers/handler.go: -------------------------------------------------------------------------------- 1 | package payHandlers 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "chatgpt-web-new-go/common/types" 6 | "chatgpt-web-new-go/model" 7 | "chatgpt-web-new-go/router/base" 8 | "chatgpt-web-new-go/service/pay" 9 | "github.com/gin-gonic/gin" 10 | ) 11 | 12 | func PayConfigList(c *gin.Context) { 13 | payments, err := pay.PayConfigList(c) 14 | if err != nil { 15 | logs.Error("pay config list error: %v", err) 16 | base.Fail(c, "支付配置查询异常!"+err.Error()) 17 | return 18 | } 19 | base.Success(c, base.PageResponse{ 20 | Count: int64(len(payments)), 21 | Rows: payments, 22 | }) 23 | } 24 | 25 | func PayConfigAdd(c *gin.Context) { 26 | request := &model.Payment{} 27 | if err := c.BindJSON(request); err != nil { 28 | logs.Error("bind json error: %v", err) 29 | base.Fail(c, "参数异常:"+err.Error()) 30 | return 31 | } 32 | 33 | err := pay.PayConfigAdd(c, request) 34 | if err != nil { 35 | logs.Error("pay config create error: %v", err) 36 | base.Fail(c, "支付配置新增异常:"+err.Error()) 37 | return 38 | } 39 | 40 | base.SuccessMsg(c, "支付配置新增成功!", nil) 41 | } 42 | 43 | func PayConfigUpdate(c *gin.Context) { 44 | request := &model.Payment{} 45 | if err := c.BindJSON(request); err != nil { 46 | logs.Error("json bind error: %v", err) 47 | base.Fail(c, "参数异常!"+err.Error()) 48 | return 49 | } 50 | 51 | err := pay.PayConfigUpdate(c, request) 52 | if err != nil { 53 | logs.Error("pay config update error: %v", err) 54 | base.Fail(c, "支付配置更新异常:"+err.Error()) 55 | return 56 | } 57 | 58 | base.SuccessMsg(c, "更新成功!", nil) 59 | } 60 | 61 | func PayConfigDelete(c *gin.Context) { 62 | idStr := c.Param("id") 63 | if idStr == "" || idStr == "undefined" { 64 | logs.Error("id is empty: %v", idStr) 65 | base.Fail(c, "参数id为空!"+idStr) 66 | return 67 | } 68 | 69 | id := types.StringToInt64(idStr) 70 | err := pay.PayConfigDelete(c, id) 71 | if err != nil { 72 | logs.Error("pay config delete error: %v", err) 73 | base.Fail(c, "支付配置删除失败!"+err.Error()) 74 | return 75 | } 76 | 77 | base.SuccessMsg(c, "删除成功!", nil) 78 | } 79 | -------------------------------------------------------------------------------- /router/admin/personaHandlers/handler.go: -------------------------------------------------------------------------------- 1 | package personaHandlers 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "chatgpt-web-new-go/common/types" 6 | "chatgpt-web-new-go/model" 7 | "chatgpt-web-new-go/router/base" 8 | "chatgpt-web-new-go/service/persona" 9 | "github.com/gin-gonic/gin" 10 | ) 11 | 12 | func List(c *gin.Context) { 13 | request := &base.Page{} 14 | if err := c.Bind(request); err != nil { 15 | logs.Error("json bind error: %v", err) 16 | base.Fail(c, "参数异常!"+err.Error()) 17 | return 18 | } 19 | 20 | list, count, err := persona.List(c, request.Page, request.PageSize) 21 | if err != nil { 22 | logs.Error("list error: %v", err) 23 | base.Fail(c, "查询异常:"+err.Error()) 24 | return 25 | } 26 | 27 | base.Success(c, base.PageResponse{ 28 | Count: count, 29 | Rows: list, 30 | }) 31 | } 32 | 33 | func Add(c *gin.Context) { 34 | request := &model.Persona{} 35 | if err := c.BindJSON(request); err != nil { 36 | logs.Error("json bind error: %v", err) 37 | base.Fail(c, "参数异常:"+err.Error()) 38 | return 39 | } 40 | 41 | err := persona.Add(c, request) 42 | if err != nil { 43 | logs.Error("persona create error: %v", err) 44 | base.Fail(c, "创建失败:"+err.Error()) 45 | return 46 | } 47 | 48 | base.SuccessMsg(c, "创建成功", nil) 49 | } 50 | 51 | func Update(c *gin.Context) { 52 | request := &model.Persona{} 53 | if err := c.BindJSON(request); err != nil { 54 | logs.Error("json bind error: %v", err) 55 | base.Fail(c, "参数异常:"+err.Error()) 56 | return 57 | } 58 | 59 | err := persona.Update(c, request) 60 | if err != nil { 61 | logs.Error("persona update error: %v", err) 62 | base.Fail(c, "更新失败:"+err.Error()) 63 | return 64 | } 65 | 66 | base.SuccessMsg(c, "更新成功", nil) 67 | } 68 | 69 | func Delete(c *gin.Context) { 70 | idStr := c.Param("id") 71 | if idStr == "" || idStr == "undefined" { 72 | logs.Error("id is empty: %v", idStr) 73 | base.Fail(c, "参数id为空!"+idStr) 74 | return 75 | } 76 | 77 | id := types.StringToInt64(idStr) 78 | err := persona.Delete(c, id) 79 | if err != nil { 80 | logs.Error("persona delete error: %v", err) 81 | base.Fail(c, "删除失败!"+err.Error()) 82 | return 83 | } 84 | 85 | base.SuccessMsg(c, "删除成功!", nil) 86 | } 87 | -------------------------------------------------------------------------------- /router/admin/pluginHandlers/handler.go: -------------------------------------------------------------------------------- 1 | package pluginHandlers 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "chatgpt-web-new-go/common/types" 6 | "chatgpt-web-new-go/model" 7 | "chatgpt-web-new-go/router/base" 8 | "chatgpt-web-new-go/service/plugin" 9 | "github.com/gin-gonic/gin" 10 | ) 11 | 12 | func List(c *gin.Context) { 13 | request := &base.Page{} 14 | if err := c.Bind(request); err != nil { 15 | logs.Error("json bind error: %v", err) 16 | base.Fail(c, "参数异常!"+err.Error()) 17 | return 18 | } 19 | 20 | list, count, err := plugin.List(c, request.Page, request.PageSize) 21 | if err != nil { 22 | logs.Error("list error: %v", err) 23 | base.Fail(c, "查询异常:"+err.Error()) 24 | return 25 | } 26 | 27 | base.Success(c, base.PageResponse{ 28 | Count: count, 29 | Rows: list, 30 | }) 31 | } 32 | 33 | func Add(c *gin.Context) { 34 | request := &model.Plugin{} 35 | if err := c.BindJSON(request); err != nil { 36 | logs.Error("json bind error: %v", err) 37 | base.Fail(c, "参数异常:"+err.Error()) 38 | return 39 | } 40 | 41 | err := plugin.Add(c, request) 42 | if err != nil { 43 | logs.Error("plugin create error: %v", err) 44 | base.Fail(c, "创建失败:"+err.Error()) 45 | return 46 | } 47 | 48 | base.SuccessMsg(c, "创建成功", nil) 49 | } 50 | 51 | func Update(c *gin.Context) { 52 | request := &model.Plugin{} 53 | if err := c.BindJSON(request); err != nil { 54 | logs.Error("json bind error: %v", err) 55 | base.Fail(c, "参数异常:"+err.Error()) 56 | return 57 | } 58 | 59 | err := plugin.Update(c, request) 60 | if err != nil { 61 | logs.Error("plugin update error: %v", err) 62 | base.Fail(c, "更新失败:"+err.Error()) 63 | return 64 | } 65 | 66 | base.SuccessMsg(c, "更新成功", nil) 67 | } 68 | 69 | func Delete(c *gin.Context) { 70 | idStr := c.Param("id") 71 | if idStr == "" || idStr == "undefined" { 72 | logs.Error("id is empty: %v", idStr) 73 | base.Fail(c, "参数id为空!"+idStr) 74 | return 75 | } 76 | 77 | id := types.StringToInt64(idStr) 78 | err := plugin.Delete(c, id) 79 | if err != nil { 80 | logs.Error("plugin delete error: %v", err) 81 | base.Fail(c, "删除失败!"+err.Error()) 82 | return 83 | } 84 | 85 | base.SuccessMsg(c, "删除成功!", nil) 86 | } 87 | -------------------------------------------------------------------------------- /router/admin/productHandlers/handler.go: -------------------------------------------------------------------------------- 1 | package productHandlers 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "chatgpt-web-new-go/common/types" 6 | "chatgpt-web-new-go/model" 7 | "chatgpt-web-new-go/router/base" 8 | "chatgpt-web-new-go/service/product" 9 | "github.com/gin-gonic/gin" 10 | ) 11 | 12 | func ProductList(c *gin.Context) { 13 | request := &base.Page{} 14 | 15 | if err := c.Bind(request); err != nil { 16 | logs.Error("json bind error: %v", err) 17 | base.Fail(c, "参数异常:"+err.Error()) 18 | return 19 | } 20 | 21 | productList, count, err := product.ProductList(c, request.Page, request.PageSize) 22 | if err != nil { 23 | logs.Error("product lsit error: %v", err) 24 | base.Fail(c, "商品列表查询异常: "+err.Error()) 25 | return 26 | } 27 | 28 | base.Success(c, base.PageResponse{ 29 | Count: count, 30 | Rows: productList, 31 | }) 32 | } 33 | 34 | func ProductAdd(c *gin.Context) { 35 | request := &model.Product{} 36 | if err := c.BindJSON(request); err != nil { 37 | logs.Error("json bind error: %v", err) 38 | base.Fail(c, "参数异常:"+err.Error()) 39 | return 40 | } 41 | 42 | productAdd, err := product.ProductAdd(c, request) 43 | if err != nil { 44 | logs.Error("product add error: %v", err) 45 | base.Fail(c, "创建商品异常!"+err.Error()) 46 | return 47 | } 48 | 49 | base.Success(c, productAdd) 50 | } 51 | 52 | func ProductPut(c *gin.Context) { 53 | request := &model.Product{} 54 | if err := c.BindJSON(request); err != nil { 55 | logs.Error("json bind error: %v", err) 56 | base.Fail(c, "参数异常:"+err.Error()) 57 | return 58 | } 59 | 60 | err := product.ProductUpdate(c, request) 61 | if err != nil { 62 | logs.Error("product udpate error: %v", err) 63 | base.Fail(c, "商品更新异常:"+err.Error()) 64 | return 65 | } 66 | 67 | base.SuccessMsg(c, "更新成功", nil) 68 | } 69 | 70 | func ProductDelete(c *gin.Context) { 71 | idStr := c.Param("id") 72 | 73 | if idStr == "" || idStr == "undefined" { 74 | logs.Error("param id empty: %v", idStr) 75 | base.Fail(c, "参数id为空:"+idStr) 76 | return 77 | } 78 | 79 | id := types.StringToInt64(idStr) 80 | 81 | err := product.ProductDelete(c, id) 82 | if err != nil { 83 | logs.Error("product delete error: %v", err) 84 | base.Fail(c, "商品删除异常:"+err.Error()) 85 | return 86 | } 87 | 88 | base.SuccessMsg(c, "删除成功!", nil) 89 | } 90 | -------------------------------------------------------------------------------- /router/admin/signinHandlers/handler.go: -------------------------------------------------------------------------------- 1 | package signinHandlers 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "chatgpt-web-new-go/router/base" 6 | "chatgpt-web-new-go/service/signin" 7 | "github.com/gin-gonic/gin" 8 | ) 9 | 10 | func SigninList(c *gin.Context) { 11 | request := &base.Page{} 12 | 13 | if err := c.Bind(request); err != nil { 14 | logs.Error("json bind error: %v", err) 15 | base.Fail(c, "参数异常:"+err.Error()) 16 | return 17 | } 18 | 19 | signinList, count, err := signin.AdminSigninList(c, request.Page, request.PageSize) 20 | if err != nil { 21 | logs.Error("signin list error: %v", err) 22 | base.Fail(c, "签到列表查询异常:"+err.Error()) 23 | return 24 | } 25 | base.Success(c, base.PageResponse{ 26 | Count: count, 27 | Rows: signinList, 28 | }) 29 | } 30 | -------------------------------------------------------------------------------- /router/admin/tokenHandlers/handler.go: -------------------------------------------------------------------------------- 1 | package tokenHandlers 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "chatgpt-web-new-go/common/types" 6 | "chatgpt-web-new-go/model" 7 | "chatgpt-web-new-go/router/base" 8 | "chatgpt-web-new-go/service/token" 9 | "github.com/gin-gonic/gin" 10 | ) 11 | 12 | func TokenList(c *gin.Context) { 13 | request := &base.Page{} 14 | if err := c.Bind(request); err != nil { 15 | logs.Error("param bind error: %v", err) 16 | base.Fail(c, "参数异常!"+err.Error()) 17 | return 18 | } 19 | 20 | tokenList, count, err := token.TokenList(c, request.Page, request.PageSize) 21 | if err != nil { 22 | logs.Error("token list error: %v", err) 23 | base.Fail(c, "token列表查询异常!"+err.Error()) 24 | return 25 | } 26 | 27 | base.Success(c, base.PageResponse{ 28 | Count: count, 29 | Rows: tokenList, 30 | }) 31 | } 32 | 33 | func TokenAdd(c *gin.Context) { 34 | request := &model.Aikey{} 35 | if err := c.BindJSON(request); err != nil { 36 | logs.Error("param bind json error: %v", err) 37 | base.Fail(c, "参数异常:"+err.Error()) 38 | return 39 | } 40 | 41 | tokenAdd, err := token.TokenAdd(c, request) 42 | if err != nil { 43 | logs.Error("token add error: %v", err) 44 | base.Fail(c, "新增Token失败:"+err.Error()) 45 | return 46 | } 47 | 48 | base.Success(c, tokenAdd) 49 | } 50 | 51 | func TokenUpdate(c *gin.Context) { 52 | request := &model.Aikey{} 53 | if err := c.BindJSON(request); err != nil { 54 | logs.Error("param bind json error: %v", err) 55 | base.Fail(c, "参数异常:"+err.Error()) 56 | return 57 | } 58 | 59 | update, err := token.TokenUpdate(c, request) 60 | if err != nil { 61 | logs.Error("token update error: %v", err) 62 | base.Fail(c, "token更新失败:"+err.Error()) 63 | return 64 | } 65 | 66 | base.Success(c, base.UpdateResponse{update, true}) 67 | } 68 | 69 | func TokenDelete(c *gin.Context) { 70 | idStr := c.Param("id") 71 | 72 | if idStr == "" || idStr == "undefined" { 73 | logs.Error("param id is empty: %v", idStr) 74 | base.Fail(c, "参数id为空!") 75 | return 76 | } 77 | 78 | id := types.StringToInt64(idStr) 79 | 80 | err := token.TokenDelete(c, id) 81 | if err != nil { 82 | logs.Error("token delete error: %v", err) 83 | base.Fail(c, "删除异常:"+err.Error()) 84 | return 85 | } 86 | 87 | base.SuccessMsg(c, "删除成功!", nil) 88 | } 89 | 90 | func TokenCheck(c *gin.Context) { 91 | 92 | } 93 | -------------------------------------------------------------------------------- /router/admin/turnoverHandlers/handler.go: -------------------------------------------------------------------------------- 1 | package turnoverHandlers 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "chatgpt-web-new-go/common/types" 6 | "chatgpt-web-new-go/model" 7 | "chatgpt-web-new-go/router/base" 8 | "chatgpt-web-new-go/service/turnover" 9 | "github.com/gin-gonic/gin" 10 | ) 11 | 12 | func TurnoverList(c *gin.Context) { 13 | request := &base.Page{} 14 | if err := c.Bind(request); err != nil { 15 | logs.Error("request bind error: %v", err) 16 | base.Fail(c, "参数异常:"+err.Error()) 17 | return 18 | } 19 | 20 | turnoverList, count, err := turnover.AdminTurnoverList(c, request.Page, request.PageSize) 21 | if err != nil { 22 | logs.Error("turnover list error: %v", err) 23 | base.Fail(c, "消费列表查询异常:"+err.Error()) 24 | return 25 | } 26 | 27 | base.Success(c, base.PageResponse{ 28 | Count: count, 29 | Rows: turnoverList, 30 | }) 31 | } 32 | 33 | func TurnoverDelete(c *gin.Context) { 34 | idStr := c.Param("id") 35 | if idStr == "" || idStr == "undefined" { 36 | logs.Error("id is empty: %v", idStr) 37 | base.Fail(c, "参数id不能为空:"+idStr) 38 | return 39 | } 40 | 41 | id := types.StringToInt64(idStr) 42 | err := turnover.AdminTurnoverDelete(c, id) 43 | if err != nil { 44 | logs.Error("tuanover delete error: %v", err) 45 | base.Fail(c, "消费记录删除异常!") 46 | return 47 | } 48 | 49 | base.SuccessMsg(c, "消费记录删除成功!", nil) 50 | } 51 | 52 | func TurnoverUpdate(c *gin.Context) { 53 | request := &model.Turnover{} 54 | 55 | if err := c.BindJSON(request); err != nil { 56 | logs.Error("json bind error: %v", err) 57 | base.Fail(c, "参数异常: "+err.Error()) 58 | return 59 | } 60 | 61 | turnoverUpdate, err := turnover.AdminTurnoverUpdate(c, request) 62 | if err != nil { 63 | logs.Error("tuanover update error: %v", err) 64 | base.Fail(c, "消费记录更新失败:"+err.Error()) 65 | return 66 | } 67 | 68 | base.Success(c, base.UpdateResponse{turnoverUpdate, true}) 69 | } 70 | -------------------------------------------------------------------------------- /router/admin/userHandlers/handler.go: -------------------------------------------------------------------------------- 1 | package userHandlers 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "chatgpt-web-new-go/common/types" 6 | "chatgpt-web-new-go/model" 7 | "chatgpt-web-new-go/router/base" 8 | "chatgpt-web-new-go/service/user" 9 | "github.com/gin-gonic/gin" 10 | ) 11 | 12 | func UserList(c *gin.Context) { 13 | request := &base.Page{} 14 | if err := c.Bind(request); err != nil { 15 | logs.Error("user list bind error: %v", err) 16 | base.Fail(c, "参数异常:"+err.Error()) 17 | return 18 | } 19 | 20 | userList, count, err := user.UserList(c, request.Page, request.PageSize) 21 | if err != nil { 22 | logs.Error("user list error: %v", err) 23 | base.Fail(c, "用户列表查询异常:"+err.Error()) 24 | return 25 | } 26 | 27 | base.Success(c, &base.PageResponse{ 28 | Count: count, Rows: userList, 29 | }) 30 | } 31 | 32 | func UserDelete(c *gin.Context) { 33 | idStr := c.Param("id") 34 | if idStr == "" || idStr == "undefined" { 35 | logs.Error("param empty id: %v", idStr) 36 | base.Fail(c, "id参数不能为空!") 37 | return 38 | } 39 | 40 | id := types.StringToInt64(idStr) 41 | 42 | err := user.UserDelete(c, id) 43 | if err != nil { 44 | logs.Error("user delete error: %v", err) 45 | base.Fail(c, "用户删除失败:"+err.Error()) 46 | return 47 | } 48 | 49 | base.SuccessMsg(c, "删除成功!", nil) 50 | } 51 | 52 | func UserUpdate(c *gin.Context) { 53 | request := &model.User{} 54 | 55 | if err := c.BindJSON(request); err != nil { 56 | logs.Error("json bind error: %v", err) 57 | base.Fail(c, "参数异常:"+err.Error()) 58 | return 59 | } 60 | 61 | err := user.UserUpdate(c, request) 62 | if err != nil { 63 | logs.Error("user update error: %v", err) 64 | base.Fail(c, "用户更新失败:"+err.Error()) 65 | return 66 | } 67 | 68 | base.SuccessMsg(c, "更新成功!", nil) 69 | } 70 | -------------------------------------------------------------------------------- /router/admin/withdrawalHandlers/handler.go: -------------------------------------------------------------------------------- 1 | package withdrawalHandlers 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "chatgpt-web-new-go/common/types" 6 | "chatgpt-web-new-go/model" 7 | "chatgpt-web-new-go/router/base" 8 | "chatgpt-web-new-go/service/withdrawal" 9 | "github.com/gin-gonic/gin" 10 | ) 11 | 12 | func List(c *gin.Context) { 13 | request := &base.Page{} 14 | if err := c.Bind(request); err != nil { 15 | logs.Error("json bind error: %v", err) 16 | base.Fail(c, "参数异常!"+err.Error()) 17 | return 18 | } 19 | 20 | notifications, count, err := withdrawal.List(c, request.Page, request.PageSize) 21 | if err != nil { 22 | logs.Error("notification list error: %v", err) 23 | base.Fail(c, "查询异常:"+err.Error()) 24 | return 25 | } 26 | 27 | base.Success(c, base.PageResponse{ 28 | Count: count, 29 | Rows: notifications, 30 | }) 31 | } 32 | 33 | func Update(c *gin.Context) { 34 | request := &model.WithdrawalRecord{} 35 | if err := c.BindJSON(request); err != nil { 36 | logs.Error("json bind error: %v", err) 37 | base.Fail(c, "参数异常:"+err.Error()) 38 | return 39 | } 40 | 41 | err := withdrawal.Update(c, request) 42 | if err != nil { 43 | logs.Error("notification update error: %v", err) 44 | base.Fail(c, "更新失败:"+err.Error()) 45 | return 46 | } 47 | 48 | base.SuccessMsg(c, "更新成功", nil) 49 | } 50 | 51 | func Delete(c *gin.Context) { 52 | idStr := c.Param("id") 53 | if idStr == "" || idStr == "undefined" { 54 | logs.Error("id is empty: %v", idStr) 55 | base.Fail(c, "参数id为空!"+idStr) 56 | return 57 | } 58 | 59 | id := types.StringToInt64(idStr) 60 | err := withdrawal.Delete(c, id) 61 | if err != nil { 62 | logs.Error("notification delete error: %v", err) 63 | base.Fail(c, "删除失败!"+err.Error()) 64 | return 65 | } 66 | 67 | base.SuccessMsg(c, "删除成功!", nil) 68 | } 69 | -------------------------------------------------------------------------------- /router/base/base.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | "net/http" 6 | ) 7 | 8 | const ( 9 | CodeSuccess = 0 10 | CodeFail = -1 11 | CodeUnauthorized = 403 12 | ) 13 | 14 | type Response struct { 15 | Data interface{} `json:"data"` 16 | Code int `json:"code"` 17 | Message string `json:"message"` 18 | } 19 | 20 | func Success(c *gin.Context, data interface{}) { 21 | c.JSON(http.StatusOK, Response{ 22 | Data: data, 23 | Code: CodeSuccess, 24 | Message: "", 25 | }) 26 | return 27 | } 28 | 29 | func SuccessMsg(c *gin.Context, message string, data interface{}) { 30 | c.JSON(http.StatusOK, Response{ 31 | Data: data, 32 | Code: CodeSuccess, 33 | Message: message, 34 | }) 35 | return 36 | } 37 | 38 | func ReturnDataDirect(c *gin.Context, data interface{}) { 39 | c.PureJSON(http.StatusOK, data) 40 | return 41 | } 42 | 43 | func Fail(c *gin.Context, err string) { 44 | c.JSON(http.StatusOK, Response{ 45 | Code: -1, 46 | Message: err, 47 | }) 48 | return 49 | } 50 | -------------------------------------------------------------------------------- /router/base/request.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | type Page struct { 4 | Page int `json:"page" form:"page"` 5 | PageSize int `json:"size" form:"page_size"` 6 | } 7 | -------------------------------------------------------------------------------- /router/base/response.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | type PageResponse struct { 4 | Count int64 `json:"count"` 5 | Rows interface{} `json:"rows"` // slice 6 | } 7 | 8 | type UpdateResponse []interface{} 9 | -------------------------------------------------------------------------------- /router/front/authHandlers/handlers.go: -------------------------------------------------------------------------------- 1 | package authHandlers 2 | 3 | import ( 4 | authGlobal "chatgpt-web-new-go/common/auth" 5 | "chatgpt-web-new-go/common/logs" 6 | "chatgpt-web-new-go/common/types" 7 | "chatgpt-web-new-go/model" 8 | "chatgpt-web-new-go/router/base" 9 | "chatgpt-web-new-go/service/auth" 10 | "chatgpt-web-new-go/service/signin" 11 | "chatgpt-web-new-go/service/sns" 12 | "github.com/gin-gonic/gin" 13 | ) 14 | 15 | func CodeSendHandler(c *gin.Context) { 16 | source := c.Query("source") 17 | if source == "" { 18 | base.Fail(c, "账号不能为空!") 19 | return 20 | } 21 | 22 | err := sns.SendCode(source) 23 | if err != nil { 24 | base.Fail(c, "发送失败!"+err.Error()) 25 | return 26 | } 27 | 28 | base.SuccessMsg(c, "发送成功,请注意查收!", nil) 29 | } 30 | 31 | func LoginHandler(c *gin.Context) { 32 | request := &CodeSendRequest{} 33 | if err := c.BindJSON(request); err != nil { 34 | base.Fail(c, "账号参数异常:"+err.Error()) 35 | return 36 | } 37 | if request.Account == "" || (request.Code == "" && request.Password == "") { 38 | base.Fail(c, "登陆参数不能为空!") 39 | return 40 | } 41 | 42 | u, token, err := auth.Login(c, request.Account, request.Password, request.Code, request.InviteCode) 43 | if err != nil { 44 | base.Fail(c, "登陆失败!"+err.Error()) 45 | return 46 | } 47 | 48 | isSignIn := signin.IsSignInToday(u.ID) 49 | response := &LoginResponse{ 50 | UserInfo: UserInfo{ 51 | User: u, 52 | IsSignIn: types.Booltonumber(isSignIn), 53 | }, 54 | Token: token, 55 | } 56 | base.SuccessMsg(c, "登陆成功", response) 57 | } 58 | 59 | func SessionHandler(c *gin.Context) { 60 | response := &SessionResponse{ 61 | Auth: true, 62 | Model: ModelOfficial, 63 | } 64 | base.Success(c, response) 65 | } 66 | 67 | func UserPasswordResetHandler(c *gin.Context) { 68 | uFromCtx, found := c.Get(authGlobal.GinCtxKey) 69 | if !found { 70 | logs.Error("cannot get auth user key:%v", authGlobal.GinCtxKey) 71 | base.Fail(c, "cannot get auth user key:"+authGlobal.GinCtxKey) 72 | return 73 | } 74 | 75 | u := uFromCtx.(*model.User) 76 | 77 | request := &CodeSendRequest{} 78 | if err := c.BindJSON(request); err != nil { 79 | base.Fail(c, "账号参数异常:"+err.Error()) 80 | return 81 | } 82 | if request.Account == "" || (request.Code == "" && request.Password == "") { 83 | base.Fail(c, "参数不能为空!") 84 | return 85 | } 86 | 87 | if request.Account != u.Account { 88 | base.Fail(c, "非法修改操作!") 89 | return 90 | } 91 | 92 | err := auth.UserPasswordReset(c, request.Account, request.Code, request.Password) 93 | if err != nil { 94 | base.Fail(c, "密码修改失败!"+err.Error()) 95 | return 96 | } 97 | 98 | base.SuccessMsg(c, "密码修改成功!", nil) 99 | } 100 | -------------------------------------------------------------------------------- /router/front/authHandlers/request.go: -------------------------------------------------------------------------------- 1 | package authHandlers 2 | 3 | type CodeSendRequest struct { 4 | Account string `json:"account"` 5 | Code string `json:"code"` 6 | InviteCode string `json:"invite_code"` 7 | Password string `json:"password"` 8 | } 9 | -------------------------------------------------------------------------------- /router/front/authHandlers/vo.go: -------------------------------------------------------------------------------- 1 | package authHandlers 2 | 3 | import ( 4 | "chatgpt-web-new-go/model" 5 | ) 6 | 7 | const ( 8 | ModelOfficial = "ChatGPTAPI" 9 | ModelUnofficial = "ChatGPTUnofficialProxyAPI" 10 | ) 11 | 12 | type UserInfo struct { 13 | *model.User 14 | IsSignIn int `json:"is_signin"` 15 | } 16 | 17 | type LoginResponse struct { 18 | UserInfo UserInfo `json:"user_info"` 19 | Token string `json:"token"` 20 | } 21 | 22 | type SessionResponse struct { 23 | Auth bool `json:"auth"` 24 | Model string `json:"model"` 25 | } 26 | -------------------------------------------------------------------------------- /router/front/carmiHandlers/handler.go: -------------------------------------------------------------------------------- 1 | package carmiHandlers 2 | 3 | import ( 4 | authGlobal "chatgpt-web-new-go/common/auth" 5 | "chatgpt-web-new-go/common/logs" 6 | "chatgpt-web-new-go/model" 7 | "chatgpt-web-new-go/router/base" 8 | "chatgpt-web-new-go/service/carmi" 9 | "github.com/gin-gonic/gin" 10 | ) 11 | 12 | func UseCarmiHandler(c *gin.Context) { 13 | request := &UseCarmiRequest{} 14 | 15 | if err := c.BindJSON(request); err != nil { 16 | logs.Error("gin bind json error: %v", err) 17 | base.Fail(c, "参数异常!"+err.Error()) 18 | return 19 | } 20 | 21 | uFromCtx, found := c.Get(authGlobal.GinCtxKey) 22 | if !found { 23 | logs.Error("cannot get auth user key:%v", authGlobal.GinCtxKey) 24 | base.Fail(c, "cannot get auth user key:"+authGlobal.GinCtxKey) 25 | return 26 | } 27 | 28 | u := uFromCtx.(*model.User) 29 | 30 | ip := authGlobal.GetClientIP(c) 31 | 32 | err := carmi.UseCarmi(c, u.ID, request.Carmi, ip) 33 | if err != nil { 34 | logs.Error("carmiHandlers use error: %v", err) 35 | base.Fail(c, "卡密使用异常:"+err.Error()) 36 | return 37 | } 38 | 39 | base.SuccessMsg(c, "充值成功", nil) 40 | } 41 | -------------------------------------------------------------------------------- /router/front/carmiHandlers/request.go: -------------------------------------------------------------------------------- 1 | package carmiHandlers 2 | 3 | type UseCarmiRequest struct { 4 | Carmi string `json:"carmiHandlers"` 5 | } 6 | -------------------------------------------------------------------------------- /router/front/chatHandlers/handler.go: -------------------------------------------------------------------------------- 1 | package chatHandlers 2 | 3 | import ( 4 | authGlobal "chatgpt-web-new-go/common/auth" 5 | "chatgpt-web-new-go/common/goUtil" 6 | "chatgpt-web-new-go/common/logs" 7 | "chatgpt-web-new-go/common/types" 8 | "chatgpt-web-new-go/model" 9 | "chatgpt-web-new-go/router/base" 10 | "chatgpt-web-new-go/service/gpt" 11 | "chatgpt-web-new-go/service/message" 12 | "encoding/json" 13 | "errors" 14 | "github.com/gin-gonic/gin" 15 | "io" 16 | "time" 17 | ) 18 | 19 | func ChatListHandler(c *gin.Context) { 20 | 21 | } 22 | 23 | func ChatCompletionsHandler(c *gin.Context) { 24 | var request gpt.Request 25 | err := c.BindJSON(&request) 26 | if err != nil { 27 | base.Fail(c, err.Error()) 28 | return 29 | } 30 | logs.Info("chat process request: %v", request) 31 | 32 | if len(request.Prompt) == 0 { 33 | base.Fail(c, "request messages required") 34 | return 35 | } 36 | 37 | uFromCtx, found := c.Get(authGlobal.GinCtxKey) 38 | if !found { 39 | logs.Error("cannot get auth user key:%v", authGlobal.GinCtxKey) 40 | base.Fail(c, "cannot get auth user key:"+authGlobal.GinCtxKey) 41 | return 42 | } 43 | 44 | u := uFromCtx.(*model.User) 45 | 46 | stream, err := gpt.Process(c, &request, u.ID) 47 | if err != nil { 48 | logs.Error("aiClient Process bizError: %v", err) 49 | base.Fail(c, "错误:"+err.Error()) 50 | return 51 | } 52 | 53 | defer stream.Close() 54 | 55 | chanStream := make(chan *message.ChatProcessResponse, 100) 56 | go func() { 57 | defer stream.Close() 58 | defer close(chanStream) 59 | for i := 0; ; i++ { 60 | response, err := stream.Recv() 61 | if errors.Is(err, io.EOF) { 62 | logs.Debug("Stream finished") 63 | chanStream <- message.StopResponse 64 | return 65 | } 66 | 67 | if err != nil { 68 | logs.Error("Stream error: %v\n", err) 69 | chanStream <- message.ErrorResponse 70 | return 71 | } 72 | if len(response.Choices) == 0 { 73 | logs.Debug("Stream finished") 74 | chanStream <- message.StopResponse 75 | return 76 | } 77 | 78 | choice := response.Choices[0] 79 | data := &message.ChatProcessResponse{ 80 | ID: response.ID, 81 | Role: choice.Delta.Role, 82 | Segment: message.SegmentText, 83 | DateTime: time.Now().Format(types.TimeFormatDate), 84 | Content: choice.Delta.Content, 85 | ParentMessageID: message.AssistantMessageId, 86 | } 87 | 88 | if i == 0 { 89 | data.Segment = message.SegmentStart 90 | } 91 | 92 | if choice.FinishReason == message.SegmentStop { 93 | data.Segment = message.SegmentStop 94 | } 95 | 96 | chanStream <- data 97 | 98 | if choice.FinishReason == message.SegmentStop { 99 | return 100 | } 101 | } 102 | }() 103 | 104 | var msgList []*message.ChatProcessResponse 105 | c.Stream(func(w io.Writer) bool { 106 | if msg, ok := <-chanStream; ok { 107 | if msg == message.ErrorResponse { 108 | return false 109 | } 110 | 111 | msgList = append(msgList, msg) 112 | 113 | marshal, _ := json.Marshal(msg) 114 | write, err := w.Write(marshal) 115 | if err != nil { 116 | logs.Error("w write error: %v, write: %v", err, write) 117 | return false 118 | } 119 | if msg == message.StopResponse { 120 | return false 121 | } 122 | 123 | _, _ = w.Write([]byte("\n\n")) 124 | return true 125 | } 126 | return false 127 | }) 128 | 129 | goUtil.New(func() { 130 | message.MessageAdd(c, u.ID, &request, msgList) 131 | }) 132 | } 133 | -------------------------------------------------------------------------------- /router/front/configHandlers/handler.go: -------------------------------------------------------------------------------- 1 | package configHandlers 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "chatgpt-web-new-go/router/base" 6 | "chatgpt-web-new-go/service/config" 7 | "github.com/gin-gonic/gin" 8 | ) 9 | 10 | func ConfigList(c *gin.Context) { 11 | configList, err := config.ConfigList(c) 12 | if err != nil { 13 | logs.Error("config list error: %v", err) 14 | base.Fail(c, "获取配置信息异常:"+err.Error()) 15 | return 16 | } 17 | 18 | base.Success(c, configList) 19 | } 20 | -------------------------------------------------------------------------------- /router/front/imagesHandlers/handler.go: -------------------------------------------------------------------------------- 1 | package imagesHandlers 2 | 3 | import ( 4 | authGlobal "chatgpt-web-new-go/common/auth" 5 | "chatgpt-web-new-go/common/logs" 6 | "chatgpt-web-new-go/model" 7 | "chatgpt-web-new-go/router/base" 8 | "chatgpt-web-new-go/service/draw" 9 | "github.com/gin-gonic/gin" 10 | ) 11 | 12 | func ImageList(c *gin.Context) { 13 | request := &ImagesRequest{} 14 | 15 | if err := c.Bind(request); err != nil { 16 | logs.Error("request bind error: %v", err) 17 | base.Fail(c, "参数异常:"+err.Error()) 18 | return 19 | } 20 | 21 | uFromCtx, found := c.Get(authGlobal.GinCtxKey) 22 | if !found { 23 | logs.Error("cannot get auth user key:%v", authGlobal.GinCtxKey) 24 | base.Fail(c, "cannot get auth user key:"+authGlobal.GinCtxKey) 25 | return 26 | } 27 | 28 | u := uFromCtx.(*model.User) 29 | 30 | drawRecords, count, err := draw.DrawList(c, u.ID, request.Type, request.Page, request.PageSize) 31 | if err != nil { 32 | logs.Error("draw list error: %v", err) 33 | base.Fail(c, "查询异常:"+err.Error()) 34 | return 35 | } 36 | 37 | base.Success(c, base.PageResponse{ 38 | Count: count, 39 | Rows: drawRecords, 40 | }) 41 | } 42 | 43 | func ImagesGenerationsHandler(c *gin.Context) { 44 | request := &draw.Request{} 45 | 46 | if err := c.Bind(request); err != nil { 47 | logs.Error("draw bind error: %v", err) 48 | base.Fail(c, "参数异常"+err.Error()) 49 | return 50 | } 51 | 52 | uFromCtx, found := c.Get(authGlobal.GinCtxKey) 53 | if !found { 54 | logs.Error("cannot get auth user key:%v", authGlobal.GinCtxKey) 55 | base.Fail(c, "cannot get auth user key:"+authGlobal.GinCtxKey) 56 | return 57 | } 58 | 59 | u := uFromCtx.(*model.User) 60 | 61 | response, err := draw.Process(c, request, u.ID) 62 | if err != nil { 63 | logs.Error("draw process error: %v", err) 64 | base.Fail(c, "绘画服务异常:"+err.Error()) 65 | return 66 | } 67 | 68 | base.Success(c, response) 69 | } 70 | -------------------------------------------------------------------------------- /router/front/imagesHandlers/request.go: -------------------------------------------------------------------------------- 1 | package imagesHandlers 2 | 3 | type ImagesRequest struct { 4 | IsAll bool `json:"isAll"` 5 | Loading bool `json:"loading"` 6 | Type string `json:"type"` 7 | Page int `json:"page"` 8 | PageSize int `json:"page_size"` 9 | } 10 | -------------------------------------------------------------------------------- /router/front/messageHandlers/handler.go: -------------------------------------------------------------------------------- 1 | package messageHandlers 2 | 3 | import ( 4 | authGlobal "chatgpt-web-new-go/common/auth" 5 | "chatgpt-web-new-go/common/logs" 6 | "chatgpt-web-new-go/model" 7 | "chatgpt-web-new-go/router/base" 8 | "chatgpt-web-new-go/service/message" 9 | "github.com/gin-gonic/gin" 10 | ) 11 | 12 | func MessageList(c *gin.Context) { 13 | uFromCtx, found := c.Get(authGlobal.GinCtxKey) 14 | if !found { 15 | logs.Error("cannot get auth user key:%v", authGlobal.GinCtxKey) 16 | base.Fail(c, "cannot get auth user key:"+authGlobal.GinCtxKey) 17 | return 18 | } 19 | 20 | u := uFromCtx.(*model.User) 21 | 22 | messageList, err := message.MessageList(c, u.ID) 23 | if err != nil { 24 | logs.Error("message list error:%v", err) 25 | base.Fail(c, "查询异常:"+err.Error()) 26 | return 27 | } 28 | 29 | if len(messageList) == 0 { 30 | messageList = make([]*message.Message, 0) 31 | } 32 | 33 | base.Success(c, messageList) 34 | } 35 | -------------------------------------------------------------------------------- /router/front/payHandlers/handler.go: -------------------------------------------------------------------------------- 1 | package payHandlers 2 | 3 | import "github.com/gin-gonic/gin" 4 | 5 | func PayPreCreateHandler(c *gin.Context) { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /router/front/personaHandlers/handler.go: -------------------------------------------------------------------------------- 1 | package personaHandlers 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "chatgpt-web-new-go/router/base" 6 | "chatgpt-web-new-go/service/persona" 7 | "github.com/gin-gonic/gin" 8 | ) 9 | 10 | func PersonaHandler(c *gin.Context) { 11 | 12 | personaList, err := persona.PersonaList(c) 13 | if err != nil { 14 | logs.Error("persona list error: %v", err) 15 | base.Fail(c, "查询异常:"+err.Error()) 16 | return 17 | } 18 | 19 | base.Success(c, personaList) 20 | } 21 | -------------------------------------------------------------------------------- /router/front/pluginHandlers/handler.go: -------------------------------------------------------------------------------- 1 | package pluginHandlers 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "chatgpt-web-new-go/router/base" 6 | "chatgpt-web-new-go/service/plugin" 7 | "github.com/gin-gonic/gin" 8 | ) 9 | 10 | func PluginHandler(c *gin.Context) { 11 | pluginList, err := plugin.PluginList(c) 12 | if err != nil { 13 | logs.Error("plugin list error: %v", err) 14 | base.Fail(c, "查询异常:"+err.Error()) 15 | return 16 | } 17 | 18 | base.Success(c, pluginList) 19 | } 20 | -------------------------------------------------------------------------------- /router/front/productHandlers/handler.go: -------------------------------------------------------------------------------- 1 | package productHandlers 2 | 3 | import ( 4 | "chatgpt-web-new-go/router/base" 5 | "chatgpt-web-new-go/service/pay" 6 | "chatgpt-web-new-go/service/product" 7 | "github.com/gin-gonic/gin" 8 | ) 9 | 10 | // ProductListHandler product list 11 | func ProductListHandler(c *gin.Context) { 12 | request := &base.Page{} 13 | if err := c.Bind(request); err != nil { 14 | base.Fail(c, "参数异常:"+err.Error()) 15 | return 16 | } 17 | 18 | if request.PageSize == 0 { 19 | request.PageSize = 10 20 | } 21 | 22 | productList, _, err := product.ProductList(c, request.Page, request.PageSize) 23 | if err != nil { 24 | base.Fail(c, "商品查询异常:"+err.Error()) 25 | return 26 | } 27 | 28 | payTypeList, err := pay.PayTypeList(c) 29 | if err != nil { 30 | base.Fail(c, "支付信息查询异常:"+err.Error()) 31 | return 32 | } 33 | 34 | response := &ProductListData{ 35 | Products: productList, 36 | PayTypes: payTypeList, 37 | } 38 | 39 | base.Success(c, response) 40 | } 41 | -------------------------------------------------------------------------------- /router/front/productHandlers/response.go: -------------------------------------------------------------------------------- 1 | package productHandlers 2 | 3 | import "chatgpt-web-new-go/model" 4 | 5 | type ProductListData struct { 6 | Products []*model.Product `json:"products"` 7 | PayTypes []string `json:"pay_types"` 8 | } 9 | -------------------------------------------------------------------------------- /router/front/signInHandlers/signin.go: -------------------------------------------------------------------------------- 1 | package signInHandlers 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/auth" 5 | "chatgpt-web-new-go/common/logs" 6 | "chatgpt-web-new-go/model" 7 | "chatgpt-web-new-go/router/base" 8 | "chatgpt-web-new-go/service/signin" 9 | "fmt" 10 | "github.com/gin-gonic/gin" 11 | ) 12 | 13 | func SignIn(c *gin.Context) { 14 | uFromCtx, found := c.Get(auth.GinCtxKey) 15 | if !found { 16 | logs.Error("cannot get auth user key:%v", auth.GinCtxKey) 17 | base.Fail(c, "请先登陆") 18 | return 19 | } 20 | 21 | u := uFromCtx.(*model.User) 22 | ip := auth.GetClientIP(c) 23 | 24 | err := signin.SignIn(c, u.ID, ip) 25 | if err != nil { 26 | logs.Error("signin error: %v", err) 27 | base.Fail(c, "签到异常: "+err.Error()) 28 | return 29 | } 30 | 31 | base.SuccessMsg(c, fmt.Sprintf("签到成功 +%v积分", signin.SigninCoin), nil) 32 | } 33 | 34 | func SignInList(c *gin.Context) { 35 | uFromCtx, found := c.Get(auth.GinCtxKey) 36 | if !found { 37 | logs.Error("cannot get auth user key:%v", auth.GinCtxKey) 38 | base.Fail(c, "请先登陆") 39 | return 40 | } 41 | 42 | u := uFromCtx.(*model.User) 43 | 44 | signinList, err := signin.GetSignListMonth(u.ID) 45 | if err != nil { 46 | logs.Error("signin.GetSignListMonth error: %v", err) 47 | base.Fail(c, "获取签到记录异常!"+err.Error()) 48 | return 49 | } 50 | 51 | base.Success(c, signinList) 52 | } 53 | -------------------------------------------------------------------------------- /router/front/turnoverHandlers/handler.go: -------------------------------------------------------------------------------- 1 | package turnoverHandlers 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/auth" 5 | "chatgpt-web-new-go/common/logs" 6 | "chatgpt-web-new-go/model" 7 | "chatgpt-web-new-go/router/base" 8 | "chatgpt-web-new-go/service/turnover" 9 | "github.com/gin-gonic/gin" 10 | ) 11 | 12 | func TurnoverListHandler(c *gin.Context) { 13 | request := &base.Page{} 14 | if err := c.Bind(request); err != nil { 15 | base.Fail(c, "参数异常:"+err.Error()) 16 | return 17 | } 18 | if request.PageSize == 0 { 19 | request.PageSize = 10 20 | } 21 | if request.Page == 0 { 22 | request.Page = 1 23 | } 24 | 25 | uFromCtx, found := c.Get(auth.GinCtxKey) 26 | if !found { 27 | logs.Error("cannot get auth user key:%v", auth.GinCtxKey) 28 | base.Fail(c, "cannot get auth user key:"+auth.GinCtxKey) 29 | return 30 | } 31 | u := uFromCtx.(*model.User) 32 | 33 | turnoverList, count, err := turnover.TurnoverList(c, u.ID, request.Page, request.PageSize) 34 | if err != nil { 35 | logs.Error("turnover list error: %v", err) 36 | base.Fail(c, "获取记录异常:%v"+err.Error()) 37 | return 38 | } 39 | 40 | response := &TurnoverListData{ 41 | Count: count, 42 | Rows: turnoverList, 43 | } 44 | base.Success(c, response) 45 | } 46 | -------------------------------------------------------------------------------- /router/front/turnoverHandlers/response.go: -------------------------------------------------------------------------------- 1 | package turnoverHandlers 2 | 3 | import "chatgpt-web-new-go/model" 4 | 5 | type TurnoverListData struct { 6 | Count int64 `json:"count"` 7 | Rows []*model.Turnover `json:"rows"` 8 | } 9 | -------------------------------------------------------------------------------- /router/front/userHandlers/handler.go: -------------------------------------------------------------------------------- 1 | package userHandlers 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/auth" 5 | "chatgpt-web-new-go/common/logs" 6 | "chatgpt-web-new-go/model" 7 | "chatgpt-web-new-go/router/base" 8 | "chatgpt-web-new-go/service/user" 9 | "github.com/gin-gonic/gin" 10 | ) 11 | 12 | func UserInfoHandler(c *gin.Context) { 13 | uFromCtx, found := c.Get(auth.GinCtxKey) 14 | if !found { 15 | logs.Error("cannot get auth user key:%v", auth.GinCtxKey) 16 | base.Fail(c, "cannot get auth user key:"+auth.GinCtxKey) 17 | return 18 | } 19 | 20 | u := uFromCtx.(*model.User) 21 | 22 | userModel, err := user.GetUserInfo(c, u.Account) 23 | if err != nil { 24 | logs.Error("user GetUserInfo bizError: %v", err) 25 | base.Fail(c, "user GetUserInfo bizError") 26 | return 27 | } 28 | base.Success(c, userModel) 29 | } 30 | 31 | func UserRecordHandler(c *gin.Context) { 32 | 33 | } 34 | -------------------------------------------------------------------------------- /router/front/userHandlers/response.go: -------------------------------------------------------------------------------- 1 | package userHandlers 2 | 3 | type UserResponse struct { 4 | Avatar string `json:"avatar"` 5 | Name string `json:"name"` 6 | Description string `json:"description"` 7 | Id int64 `json:"id"` 8 | Type int `json:"type"` 9 | ReferNumber int64 `json:"refer_number"` 10 | } 11 | -------------------------------------------------------------------------------- /router/middlewares/cors.go: -------------------------------------------------------------------------------- 1 | package middlewares 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | "net/http" 6 | ) 7 | 8 | func Cors() gin.HandlerFunc { 9 | return func(c *gin.Context) { 10 | method := c.Request.Method 11 | origin := c.Request.Header.Get("Origin") 12 | if origin != "" { 13 | c.Header("Access-Control-Allow-Origin", "*") // 可将将 * 替换为指定的域名 14 | c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE") 15 | c.Header("Access-Control-Allow-Headers", "content-type,token") 16 | c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Cache-Control, Content-Language, Content-Type") 17 | c.Header("Access-Control-Allow-Credentials", "true") 18 | } 19 | if method == "OPTIONS" { 20 | c.AbortWithStatus(http.StatusNoContent) 21 | return 22 | } 23 | c.Next() 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /router/middlewares/jwt.go: -------------------------------------------------------------------------------- 1 | package middlewares 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/auth" 5 | "chatgpt-web-new-go/router/base" 6 | "github.com/gin-gonic/gin" 7 | ) 8 | 9 | // Jwt jwt认证 10 | func Jwt() gin.HandlerFunc { 11 | return func(c *gin.Context) { 12 | claims, err := auth.EncodeByCtx(c) 13 | if err != nil { 14 | base.Fail(c, "用户信息错误: "+err.Error()) 15 | c.Abort() 16 | return 17 | } 18 | 19 | if claims.User.ID == 0 { 20 | base.Fail(c, "用户信息错误,未知的token") 21 | c.Abort() 22 | return 23 | } 24 | c.Set(auth.GinCtxKey, claims.User) 25 | c.Next() 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /router/middlewares/u_info.go: -------------------------------------------------------------------------------- 1 | package middlewares 2 | 3 | import "github.com/gin-gonic/gin" 4 | 5 | func UInfo() gin.HandlerFunc { 6 | return func(c *gin.Context) { 7 | 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /router/root.go: -------------------------------------------------------------------------------- 1 | package router 2 | 3 | import ( 4 | "chatgpt-web-new-go/router/front/authHandlers" 5 | "chatgpt-web-new-go/router/front/carmiHandlers" 6 | "chatgpt-web-new-go/router/front/chatHandlers" 7 | "chatgpt-web-new-go/router/front/configHandlers" 8 | "chatgpt-web-new-go/router/front/imagesHandlers" 9 | "chatgpt-web-new-go/router/front/messageHandlers" 10 | "chatgpt-web-new-go/router/front/payHandlers" 11 | "chatgpt-web-new-go/router/front/personaHandlers" 12 | "chatgpt-web-new-go/router/front/pluginHandlers" 13 | "chatgpt-web-new-go/router/front/productHandlers" 14 | "chatgpt-web-new-go/router/front/signInHandlers" 15 | "chatgpt-web-new-go/router/front/turnoverHandlers" 16 | "chatgpt-web-new-go/router/front/userHandlers" 17 | "chatgpt-web-new-go/router/middlewares" 18 | "github.com/gin-gonic/gin" 19 | ) 20 | 21 | func Init(r *gin.Engine) { 22 | // cors 23 | r.Use(middlewares.Cors()) 24 | 25 | // api root 26 | apiRoot := r.Group("/api") 27 | 28 | adminGroup(apiRoot.Group("/admin")) 29 | 30 | // root group 31 | authGroup(apiRoot.Group("")) 32 | 33 | // config 34 | configGroup(apiRoot.Group("/config")) 35 | 36 | // persona 37 | personaGroup(apiRoot.Group("/persona")) 38 | 39 | // ============== ⬇ need auth ⬇ ============== 40 | // add jwt 41 | apiRoot.Use(middlewares.Jwt()) 42 | 43 | // user group 44 | userGroup(apiRoot.Group("/user")) 45 | 46 | // product 47 | productGroup(apiRoot.Group("/product")) 48 | 49 | // turnover 50 | turnoverGroup(apiRoot.Group("/turnover")) 51 | 52 | // pay TODO 53 | payGroup(apiRoot.Group("/pay")) 54 | 55 | // carmiHandlers 56 | carmiGroup(apiRoot.Group("/use_carmi")) 57 | 58 | // signIn 59 | signInGroup(apiRoot.Group("/signin")) 60 | 61 | // plugin 62 | pluginGroup(apiRoot.Group("/plugin")) 63 | 64 | // chat group 65 | chatGroup(apiRoot.Group("/chat")) 66 | 67 | // images group 68 | imagesGroup(apiRoot.Group("/images")) 69 | 70 | // promotion group 71 | promotionGroup(apiRoot.Group("/promotion")) 72 | } 73 | 74 | func pluginGroup(group *gin.RouterGroup) { 75 | group.GET("", pluginHandlers.PluginHandler) 76 | } 77 | 78 | func carmiGroup(group *gin.RouterGroup) { 79 | group.POST("", carmiHandlers.UseCarmiHandler) 80 | } 81 | 82 | func personaGroup(group *gin.RouterGroup) { 83 | group.GET("", personaHandlers.PersonaHandler) 84 | } 85 | 86 | func payGroup(group *gin.RouterGroup) { 87 | group.POST("/precreate", payHandlers.PayPreCreateHandler) 88 | } 89 | 90 | func imagesGroup(group *gin.RouterGroup) { 91 | group.GET("", imagesHandlers.ImageList) 92 | group.POST("/generations", imagesHandlers.ImagesGenerationsHandler) 93 | } 94 | 95 | func configGroup(group *gin.RouterGroup) { 96 | group.GET("", configHandlers.ConfigList) 97 | } 98 | 99 | func signInGroup(group *gin.RouterGroup) { 100 | group.POST("", signInHandlers.SignIn) 101 | group.GET("/list", signInHandlers.SignInList) // 获取用户当月签到记录 102 | } 103 | 104 | func turnoverGroup(group *gin.RouterGroup) { 105 | group.GET("", turnoverHandlers.TurnoverListHandler) 106 | } 107 | 108 | func productGroup(group *gin.RouterGroup) { 109 | group.GET("", productHandlers.ProductListHandler) 110 | } 111 | 112 | func authGroup(group *gin.RouterGroup) { 113 | group.GET("/send_sms", authHandlers.CodeSendHandler) 114 | group.POST("/login", authHandlers.LoginHandler) 115 | } 116 | 117 | func userGroup(group *gin.RouterGroup) { 118 | group.GET("/info", userHandlers.UserInfoHandler) 119 | group.GET("/records", userHandlers.UserRecordHandler) 120 | group.PUT("/password", authHandlers.UserPasswordResetHandler) 121 | 122 | group.GET("/messages", messageHandlers.MessageList) 123 | } 124 | 125 | func chatGroup(group *gin.RouterGroup) { 126 | group.POST("/completions", chatHandlers.ChatCompletionsHandler) 127 | group.POST("/completion", chatHandlers.ChatCompletionsHandler) 128 | } 129 | 130 | func promotionGroup(group *gin.RouterGroup) { 131 | group.GET("/get_") 132 | } 133 | -------------------------------------------------------------------------------- /service/amount/amount.go: -------------------------------------------------------------------------------- 1 | package amount 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/bizError" 5 | "chatgpt-web-new-go/common/logs" 6 | "chatgpt-web-new-go/dao" 7 | "chatgpt-web-new-go/model" 8 | "context" 9 | ) 10 | 11 | func List(ctx context.Context, page, size int) (list []*model.AmountDetail, count int64, err error) { 12 | du := dao.Q.AmountDetail 13 | 14 | list, count, err = du.WithContext(ctx).Where(du.IsDelete.Eq(0)).FindByPage((page-1)*size, size) 15 | if err != nil { 16 | logs.Error("AmountDetail list error: %v", err) 17 | return nil, 0, err 18 | } 19 | return 20 | } 21 | 22 | func Delete(ctx context.Context, id int64) error { 23 | du := dao.Q.AmountDetail 24 | 25 | resultInfo, err := du.WithContext(ctx).Where(du.ID.Eq(id)).Update(du.IsDelete, 1) 26 | if err != nil { 27 | logs.Error("AmountDetail delete error: %v", err) 28 | return err 29 | } 30 | if resultInfo.RowsAffected < 1 { 31 | logs.Error("AmountDetail delete fail: RowsAffected < 1") 32 | return bizError.CommonDeleteError 33 | } 34 | 35 | return nil 36 | } 37 | 38 | func Update(ctx context.Context, u *model.AmountDetail) error { 39 | du := dao.Q.AmountDetail 40 | resultInfo, err := du.WithContext(ctx).Where(du.ID.Eq(u.ID)).Updates(u) 41 | if err != nil { 42 | logs.Error("AmountDetail update error: %v", err) 43 | return err 44 | } 45 | if resultInfo.RowsAffected < 1 { 46 | logs.Error("AmountDetail update fail: RowsAffected < 1") 47 | return bizError.CommonUpdateError 48 | } 49 | 50 | return nil 51 | } 52 | -------------------------------------------------------------------------------- /service/auth/login.go: -------------------------------------------------------------------------------- 1 | package auth 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/auth" 5 | "chatgpt-web-new-go/common/bizError" 6 | "chatgpt-web-new-go/common/config" 7 | "chatgpt-web-new-go/common/constant" 8 | "chatgpt-web-new-go/common/inviteCodeGen" 9 | "chatgpt-web-new-go/common/logs" 10 | "chatgpt-web-new-go/common/redis" 11 | "chatgpt-web-new-go/dao" 12 | "chatgpt-web-new-go/model" 13 | "errors" 14 | "fmt" 15 | "github.com/gin-gonic/gin" 16 | "gorm.io/gorm" 17 | ) 18 | 19 | func Login(ctx *gin.Context, account, password, code, inviteCode string) (*model.User, string, error) { 20 | // 0. valid 21 | if password == "" && code == "" { 22 | return nil, "", bizError.LoginPassCodeNoneError 23 | } 24 | 25 | // 1. login or register 26 | du := dao.Q.User 27 | userDao := du.WithContext(ctx) 28 | 29 | u, err := userDao.Where(du.Account.Eq(account)).First() 30 | if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { 31 | logs.Error("user FirstOrCreate by account:%v bizError:%v", account, err) 32 | return nil, "", err 33 | } 34 | 35 | // register or login 36 | if u == nil { 37 | return doRegister(ctx, account, password, code, inviteCode) 38 | } else { 39 | return doLogin(u, account, password, code) 40 | } 41 | } 42 | 43 | func doLogin(u *model.User, account, password, code string) (*model.User, string, error) { 44 | // password valid 45 | if password != "" && !u.ComparePassword(password) { 46 | return nil, "", bizError.LoginPasswordError 47 | } 48 | if code != "" && !loginCodeValid(account, code) { 49 | return nil, "", bizError.LoginCodeErrorError 50 | } 51 | 52 | // session key token 53 | token, err := auth.Encode(u) 54 | if err != nil { 55 | logs.Error("user auth encode phone:%v bizError:%v", account, err) 56 | return nil, "", err 57 | } 58 | return u, token, nil 59 | } 60 | 61 | func doRegister(ctx *gin.Context, account, password, code, inviteCode string) (*model.User, string, error) { 62 | // 0. valid 63 | if password == "" { 64 | return nil, "", bizError.LoginPassCodeNoneError 65 | } 66 | 67 | pass := loginCodeValid(account, code) 68 | if !pass { 69 | return nil, "", bizError.LoginCodeErrorError 70 | } 71 | 72 | // 1. user model 73 | u := &model.User{ 74 | Account: account, 75 | Password: password, 76 | IP: auth.GetClientIP(ctx), 77 | UserAgent: auth.GetUA(ctx), 78 | } 79 | 80 | // 2. get super id 81 | du := dao.Q.User 82 | su, err := du.WithContext(ctx).Where(du.InviteCode.Eq(inviteCode)).First() 83 | if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { 84 | logs.Error("user get by inviteCode error: %v", err) 85 | return nil, "", err 86 | } 87 | if su != nil { 88 | u.SuperiorID = su.ID 89 | } 90 | 91 | err = du.WithContext(ctx).Create(u) 92 | if err != nil { 93 | logs.Error("user Create by account:%v bizError:%v", account, err) 94 | return nil, "", err 95 | } 96 | 97 | // update invite code 98 | ic := inviteCodeGen.InviteCodeGen.IdToCode(u.ID) 99 | updateColumn, err := du.WithContext(ctx).Where(du.ID.Eq(u.ID)).UpdateColumn(du.InviteCode, ic) 100 | if err != nil { 101 | logs.Error("user update by account:%v bizError:%v", account, err) 102 | return nil, "", err 103 | } 104 | logs.Info("user invite code update result: %v", updateColumn) 105 | 106 | // 3. session key token 107 | token, err := auth.Encode(u) 108 | if err != nil { 109 | logs.Error("user auth encode phone:%v bizError:%v", account, err) 110 | return nil, "", err 111 | } 112 | 113 | return u, token, nil 114 | } 115 | 116 | // only one time 117 | func loginCodeValid(phone string, code string) bool { 118 | if _, found := constant.WhiteListPhone[phone]; found { 119 | return true 120 | } 121 | 122 | key := fmt.Sprintf(redis.KeySnsCode, phone) 123 | codeFromRedis, err := config.Redis.Get(key).Result() 124 | if err != nil { 125 | logs.Warn("redis get: %v bizError: %v", key, err) 126 | return false 127 | } 128 | 129 | if code != codeFromRedis { 130 | logs.Info("code:%v != codeFromRedis:%v", code, codeFromRedis) 131 | return false 132 | } 133 | 134 | // expire code 135 | _ = config.Redis.Del(key) 136 | 137 | return true 138 | } 139 | -------------------------------------------------------------------------------- /service/auth/password.go: -------------------------------------------------------------------------------- 1 | package auth 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/bizError" 5 | "chatgpt-web-new-go/common/logs" 6 | "chatgpt-web-new-go/dao" 7 | "context" 8 | ) 9 | 10 | func UserPasswordReset(ctx context.Context, account, code, password string) error { 11 | // 0. valid 12 | if password == "" && code == "" { 13 | return bizError.LoginPassCodeNoneError 14 | } 15 | 16 | // 1. valid code 17 | pass := loginCodeValid(account, code) 18 | if !pass { 19 | return bizError.LoginCodeErrorError 20 | } 21 | 22 | // 2. update 23 | du := dao.Q.User 24 | _, err := du.WithContext(ctx).Where(du.Account.Eq(account)).Update(du.Password, pass) 25 | if err != nil { 26 | logs.Error("user password update error: %v", err) 27 | return err 28 | } 29 | 30 | return nil 31 | } 32 | -------------------------------------------------------------------------------- /service/carmi/admin.go: -------------------------------------------------------------------------------- 1 | package carmi 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/bizError" 5 | "chatgpt-web-new-go/common/logs" 6 | "chatgpt-web-new-go/common/random" 7 | "chatgpt-web-new-go/dao" 8 | "chatgpt-web-new-go/model" 9 | "context" 10 | ) 11 | 12 | func CarmiList(ctx context.Context, page, size int) (carmiList []*model.Carmi, count int64, err error) { 13 | dc := dao.Q.Carmi 14 | 15 | carmiList, count, err = dc.WithContext(ctx).Where(dc.IsDelete.Eq(0)).FindByPage((page-1)*size, size) 16 | if err != nil { 17 | logs.Error("carmi list error: %v", err) 18 | return nil, 0, err 19 | } 20 | 21 | return 22 | } 23 | 24 | func CarmiDel(ctx context.Context, id int64) error { 25 | dc := dao.Q.Carmi 26 | 27 | resultInfo, err := dc.WithContext(ctx).Where(dc.ID.Eq(id)).UpdateSimple(dc.IsDelete.Value(1)) 28 | if err != nil { 29 | logs.Error("carmi update is_delete error: %v", err) 30 | return err 31 | } 32 | if resultInfo.RowsAffected < 1 { 33 | logs.Error("carmi update is_delete error: RowsAffected < 1") 34 | return bizError.CarmiDelError 35 | } 36 | 37 | return nil 38 | } 39 | 40 | func CarmiGen(ctx context.Context, r *CarmiGenRequest) (carmiList []*model.Carmi, err error) { 41 | for i := 0; i < r.Quantity; i++ { 42 | c := &model.Carmi{ 43 | Key: random.GenCarmiKey(), 44 | Value: r.Reward, 45 | Type: r.Type, 46 | EndTime: r.EndTime, 47 | Level: r.Level, 48 | } 49 | carmiList = append(carmiList, c) 50 | } 51 | 52 | dc := dao.Q.Carmi 53 | err = dc.WithContext(ctx).CreateInBatches(carmiList, 50) 54 | if err != nil { 55 | logs.Error("carmi batch insert error: %v", err) 56 | return nil, err 57 | } 58 | return 59 | } 60 | -------------------------------------------------------------------------------- /service/carmi/carmi.go: -------------------------------------------------------------------------------- 1 | package carmi 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/bizError" 5 | "chatgpt-web-new-go/common/logs" 6 | "chatgpt-web-new-go/dao" 7 | "chatgpt-web-new-go/model" 8 | "context" 9 | ) 10 | 11 | const ( 12 | CarmiStatusCanuse = 0 13 | CarmiStatusUsed = 1 14 | CarmiStatusExpired = 2 15 | ) 16 | 17 | func UseCarmi(ctx context.Context, uid int64, carmi, ip string) error { 18 | dc := dao.Q.Carmi 19 | 20 | c, err := dc.WithContext(ctx).Where(dc.Key.Eq(carmi)).First() 21 | if err != nil { 22 | logs.Error("carmiHandlers find carmiHandlers: %v error: %v", carmi, err) 23 | return err 24 | } 25 | 26 | if c.Status != CarmiStatusCanuse { 27 | return bizError.CarmiStatusError 28 | } 29 | 30 | // update user 31 | nu := CarmiToUser(uid, c) 32 | du := dao.Q.User 33 | updateUserInfo, err := du.WithContext(ctx).Where(du.ID.Eq(uid)).Updates(nu) 34 | if err != nil { 35 | logs.Error("user update error: %v", err) 36 | return err 37 | } 38 | if updateUserInfo.RowsAffected < 1 { 39 | logs.Error("user update fail RowsAffected < 1: %v", updateUserInfo) 40 | return err 41 | } 42 | 43 | // update carmiHandlers 44 | nc := model.Carmi{ 45 | IP: ip, 46 | UserID: uid, 47 | Status: CarmiStatusUsed, 48 | } 49 | updates, err := dc.WithContext(ctx).Where(dc.ID.Eq(c.ID)).Updates(nc) 50 | if err != nil { 51 | logs.Error("carmiHandlers use error: %v", err) 52 | return err 53 | } 54 | if updates.RowsAffected < 1 { 55 | logs.Error("carmiHandlers use fail updates.RowsAffected < 1 : %v", updates) 56 | return bizError.CarmiUseError 57 | } 58 | 59 | return nil 60 | } 61 | -------------------------------------------------------------------------------- /service/carmi/carmi_type.go: -------------------------------------------------------------------------------- 1 | package carmi 2 | 3 | import ( 4 | "chatgpt-web-new-go/model" 5 | "time" 6 | ) 7 | 8 | const ( 9 | CarmiTypeIntegral = "integral" 10 | CarmiTypeVipDays = "day" 11 | 12 | CarmiLevelVip = 1 13 | CarmiLevelSVip = 2 14 | ) 15 | 16 | func CarmiToUser(uid int64, carmi *model.Carmi) (u *model.User) { 17 | u = &model.User{ 18 | ID: uid, 19 | } 20 | 21 | if carmi.Type == CarmiTypeIntegral { 22 | u.Integral = carmi.Value 23 | } 24 | 25 | if carmi.Type == CarmiTypeVipDays { 26 | et := time.Now().AddDate(0, 0, int(carmi.Value)) 27 | if carmi.Level == CarmiLevelVip { 28 | u.VipExpireTime = et 29 | } 30 | if carmi.Level == CarmiLevelSVip { 31 | u.SvipExpireTime = et 32 | } 33 | } 34 | 35 | return u 36 | } 37 | -------------------------------------------------------------------------------- /service/carmi/request.go: -------------------------------------------------------------------------------- 1 | package carmi 2 | 3 | type CarmiGenRequest struct { 4 | Type string `json:"type"` 5 | EndTime string `json:"end_time"` 6 | Quantity int `json:"quantity"` 7 | Reward int32 `json:"reward"` 8 | Level int32 `json:"level"` 9 | } 10 | -------------------------------------------------------------------------------- /service/cashback/cashback.go: -------------------------------------------------------------------------------- 1 | package cashback 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/bizError" 5 | "chatgpt-web-new-go/common/logs" 6 | "chatgpt-web-new-go/dao" 7 | "chatgpt-web-new-go/model" 8 | "context" 9 | ) 10 | 11 | const ( 12 | CashbackStatusFail = 0 13 | CashbackStatusPass = 1 14 | CashbackStatusPending = 3 15 | ) 16 | 17 | func CashbackList(ctx context.Context, page, size int) (cashbackList []*model.Cashback, count int64, err error) { 18 | dc := dao.Q.Cashback 19 | 20 | cashbackList, count, err = dc.WithContext(ctx).Where(dc.IsDelete.Eq(0)).FindByPage((page-1)*size, size) 21 | if err != nil { 22 | logs.Error("cashback list error: %v", err) 23 | return nil, 0, err 24 | } 25 | return 26 | } 27 | 28 | func CashbackUpdate(ctx context.Context, c *model.Cashback) error { 29 | dc := dao.Q.Cashback 30 | 31 | resultInfo, err := dc.WithContext(ctx).Updates(c) 32 | if err != nil { 33 | logs.Error("cashback update error: %v", err) 34 | return err 35 | } 36 | if resultInfo.RowsAffected < 1 { 37 | logs.Error("cashback update fail: RowsAffected < 1") 38 | return bizError.CommonUpdateError 39 | } 40 | return nil 41 | } 42 | 43 | func CashbackDelete(ctx context.Context, id int64) error { 44 | dc := dao.Q.Cashback 45 | 46 | resultInfo, err := dc.WithContext(ctx).Where(dc.ID.Eq(id)).Update(dc.IsDelete, 1) 47 | if err != nil { 48 | logs.Error("cashback delete error: %v", err) 49 | return err 50 | } 51 | if resultInfo.RowsAffected < 1 { 52 | logs.Error("cashback delete fail: RowsAffected < 1") 53 | return bizError.CommonDeleteError 54 | } 55 | return nil 56 | } 57 | 58 | func CashbackPass(ctx context.Context, id int64) error { 59 | dc := dao.Q.Cashback 60 | 61 | resultInfo, err := dc.WithContext(ctx).Where(dc.ID.Eq(id)).Update(dc.Status, CashbackStatusPass) 62 | if err != nil { 63 | logs.Error("cashback pass error: %v", err) 64 | return err 65 | } 66 | if resultInfo.RowsAffected < 1 { 67 | logs.Error("cashback pass fail: RowsAffected < 1") 68 | return bizError.CommonDeleteError 69 | } 70 | return nil 71 | } 72 | -------------------------------------------------------------------------------- /service/config/admin.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "chatgpt-web-new-go/dao" 6 | "chatgpt-web-new-go/model" 7 | "context" 8 | ) 9 | 10 | func AdminConfigList(ctx context.Context) (configList []*model.Config, err error) { 11 | dc := dao.Q.Config 12 | configList, err = dc.WithContext(ctx).Find() 13 | if err != nil { 14 | logs.Error("config list error: %v", err) 15 | return nil, err 16 | } 17 | 18 | return 19 | } 20 | 21 | func ConfigUpdate(ctx context.Context, configMap map[string]string) error { 22 | dc := dao.Q.Config 23 | for cName, cValue := range configMap { 24 | find, err := dc.WithContext(ctx).Where(dc.Name).Find() 25 | if err != nil { 26 | logs.Error("config find name:%v error: %v", cName, err) 27 | return err 28 | } 29 | 30 | if len(find) == 0 { 31 | logs.Error("config find none, name: %v", cName) 32 | continue 33 | } 34 | 35 | resultInfo, err := dc.WithContext(ctx).Where(dc.Name.Eq(cName)).Update(dc.Value, cValue) 36 | if err != nil { 37 | logs.Error("config update error: %v", err) 38 | return err 39 | } 40 | if resultInfo.RowsAffected < 1 { 41 | logs.Error("config update fail: RowsAffected < 1") 42 | continue 43 | } 44 | } 45 | 46 | return nil 47 | } 48 | -------------------------------------------------------------------------------- /service/config/config.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "chatgpt-web-new-go/dao" 6 | "context" 7 | "encoding/json" 8 | ) 9 | 10 | var ( 11 | indexConfigs = []string{ 12 | "shop_introduce", 13 | "user_introduce", 14 | "notifications", 15 | "website_title", 16 | "website_description", 17 | "website_keywords", 18 | "website_logo", 19 | "website_footer", 20 | "invite_introduce", 21 | "random_personas", 22 | "chat_models", 23 | "draw_models", 24 | } 25 | ) 26 | 27 | func ConfigList(ctx context.Context) (result map[string]interface{}, err error) { 28 | dc := dao.Q.Config 29 | 30 | configs, err := dc.WithContext(ctx).Where(dc.Name.In(indexConfigs...)).Find() 31 | if err != nil { 32 | logs.Error("config get error: %v", err) 33 | return nil, err 34 | } 35 | 36 | // trans 37 | result = make(map[string]interface{}) 38 | for _, c := range configs { 39 | result[c.Name] = c.Value 40 | } 41 | 42 | // notificationHandlers 43 | dn := dao.Q.Notification 44 | notifications, err := dn.WithContext(ctx).Where(dn.Status.Eq(1)).Find() 45 | if err != nil { 46 | logs.Error("Notification get error: %v", err) 47 | } else { 48 | result["notifications"] = notifications 49 | } 50 | 51 | // personas 52 | dp := dao.Q.Persona 53 | personas, err := dp.WithContext(ctx).Where(dp.Status.Eq(1)).Find() 54 | if err != nil { 55 | logs.Error("Persona get error: %v", err) 56 | } else { 57 | result["random_personas"] = personas 58 | } 59 | 60 | // chat_models 61 | if _, found := result["chat_models"]; found { 62 | chatModels := result["chat_models"].(string) 63 | var chatModelsMap []map[string]string 64 | err := json.Unmarshal([]byte(chatModels), &chatModelsMap) 65 | if err != nil { 66 | logs.Error("chatModels json error: %v", err) 67 | } else { 68 | result["chat_models"] = chatModelsMap 69 | } 70 | } 71 | 72 | // draw models 73 | if _, found := result["draw_models"]; found { 74 | drawModels := result["draw_models"].(string) 75 | var drawModelsMap []map[string]string 76 | err := json.Unmarshal([]byte(drawModels), &drawModelsMap) 77 | if err != nil { 78 | logs.Error("drawModels json error: %v", err) 79 | } else { 80 | result["draw_models"] = drawModelsMap 81 | } 82 | } 83 | 84 | return 85 | } 86 | -------------------------------------------------------------------------------- /service/config/models.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | var () 4 | -------------------------------------------------------------------------------- /service/dialog/dialog.go: -------------------------------------------------------------------------------- 1 | package dialog 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/bizError" 5 | "chatgpt-web-new-go/common/logs" 6 | "chatgpt-web-new-go/dao" 7 | "chatgpt-web-new-go/model" 8 | "context" 9 | ) 10 | 11 | func List(ctx context.Context, page, size int) (list []*model.Dialog, count int64, err error) { 12 | du := dao.Q.Dialog 13 | 14 | list, count, err = du.WithContext(ctx).Where(du.IsDelete.Eq(0)).FindByPage((page-1)*size, size) 15 | if err != nil { 16 | logs.Error("Dialog list error: %v", err) 17 | return nil, 0, err 18 | } 19 | return 20 | } 21 | 22 | func Delete(ctx context.Context, id int64) error { 23 | du := dao.Q.Dialog 24 | 25 | resultInfo, err := du.WithContext(ctx).Where(du.ID.Eq(id)).Update(du.IsDelete, 1) 26 | if err != nil { 27 | logs.Error("Dialog delete error: %v", err) 28 | return err 29 | } 30 | if resultInfo.RowsAffected < 1 { 31 | logs.Error("Dialog delete fail: RowsAffected < 1") 32 | return bizError.CommonDeleteError 33 | } 34 | 35 | return nil 36 | } 37 | 38 | func Add(ctx context.Context, n *model.Dialog) error { 39 | dn := dao.Q.Dialog 40 | 41 | err := dn.WithContext(ctx).Create(n) 42 | if err != nil { 43 | logs.Error("Dialog create error: %v", err) 44 | return err 45 | } 46 | 47 | return nil 48 | } 49 | func Update(ctx context.Context, u *model.Dialog) error { 50 | du := dao.Q.Dialog 51 | resultInfo, err := du.WithContext(ctx).Where(du.ID.Eq(u.ID)).Updates(u) 52 | if err != nil { 53 | logs.Error("Dialog update error: %v", err) 54 | return err 55 | } 56 | if resultInfo.RowsAffected < 1 { 57 | logs.Error("Dialog update fail: RowsAffected < 1") 58 | return bizError.CommonUpdateError 59 | } 60 | 61 | return nil 62 | } 63 | -------------------------------------------------------------------------------- /service/draw/admin.go: -------------------------------------------------------------------------------- 1 | package draw 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/bizError" 5 | "chatgpt-web-new-go/common/logs" 6 | "chatgpt-web-new-go/dao" 7 | "chatgpt-web-new-go/model" 8 | "context" 9 | ) 10 | 11 | func List(ctx context.Context, page, size int) (list []*model.DrawRecord, count int64, err error) { 12 | du := dao.Q.DrawRecord 13 | 14 | list, count, err = du.WithContext(ctx).Where(du.IsDelete.Eq(0)).FindByPage((page-1)*size, size) 15 | if err != nil { 16 | logs.Error("DrawRecord list error: %v", err) 17 | return nil, 0, err 18 | } 19 | return 20 | } 21 | 22 | func Delete(ctx context.Context, id int64) error { 23 | du := dao.Q.DrawRecord 24 | 25 | resultInfo, err := du.WithContext(ctx).Where(du.ID.Eq(id)).Update(du.IsDelete, 1) 26 | if err != nil { 27 | logs.Error("DrawRecord delete error: %v", err) 28 | return err 29 | } 30 | if resultInfo.RowsAffected < 1 { 31 | logs.Error("DrawRecord delete fail: RowsAffected < 1") 32 | return bizError.CommonDeleteError 33 | } 34 | 35 | return nil 36 | } 37 | 38 | func Add(ctx context.Context, n *model.DrawRecord) error { 39 | dn := dao.Q.DrawRecord 40 | 41 | err := dn.WithContext(ctx).Create(n) 42 | if err != nil { 43 | logs.Error("DrawRecord create error: %v", err) 44 | return err 45 | } 46 | 47 | return nil 48 | } 49 | 50 | func Update(ctx context.Context, u *model.DrawRecord) error { 51 | du := dao.Q.DrawRecord 52 | resultInfo, err := du.WithContext(ctx).Where(du.ID.Eq(u.ID)).Updates(u) 53 | if err != nil { 54 | logs.Error("DrawRecord update error: %v", err) 55 | return err 56 | } 57 | if resultInfo.RowsAffected < 1 { 58 | logs.Error("DrawRecord update fail: RowsAffected < 1") 59 | return bizError.CommonUpdateError 60 | } 61 | 62 | return nil 63 | } 64 | -------------------------------------------------------------------------------- /service/draw/draw_model.go: -------------------------------------------------------------------------------- 1 | package draw 2 | 3 | import "context" 4 | 5 | type DrawModel interface { 6 | // Draw from platform 7 | Draw(ctx context.Context, r *Request) (response *Response, err error) 8 | } 9 | -------------------------------------------------------------------------------- /service/draw/draw_openai.go: -------------------------------------------------------------------------------- 1 | package draw 2 | 3 | import "context" 4 | 5 | type OpenAI struct { 6 | } 7 | 8 | func (o *OpenAI) Draw(ctx context.Context, r *Request) (response *Response, err error) { 9 | 10 | return 11 | } 12 | -------------------------------------------------------------------------------- /service/draw/draw_sd.go: -------------------------------------------------------------------------------- 1 | package draw 2 | 3 | import "context" 4 | 5 | type SD struct { 6 | } 7 | 8 | func (S *SD) Draw(ctx context.Context, r *Request) (response *Response, err error) { 9 | 10 | return 11 | } 12 | -------------------------------------------------------------------------------- /service/draw/draw_strategy.go: -------------------------------------------------------------------------------- 1 | package draw 2 | 3 | import "context" 4 | 5 | func Draw(ctx context.Context, r *Request) (response *Response, err error) { 6 | 7 | return 8 | } 9 | -------------------------------------------------------------------------------- /service/draw/proccess.go: -------------------------------------------------------------------------------- 1 | package draw 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | gogpt "github.com/sashabaranov/go-openai" 6 | ) 7 | 8 | func Process(ctx *gin.Context, r *Request, uid int64) (stream *gogpt.ChatCompletionStream, err error) { 9 | 10 | return 11 | } 12 | -------------------------------------------------------------------------------- /service/draw/request.go: -------------------------------------------------------------------------------- 1 | package draw 2 | 3 | const ( 4 | DrawTypeOpenAI = "openai" 5 | DrawTypeSD = "sd" 6 | ) 7 | 8 | type Request struct { 9 | Prompt string `json:"prompt"` 10 | Quantity int64 `json:"quantity"` 11 | Width int64 `json:"width"` 12 | Height int64 `json:"height"` 13 | Quality int64 `json:"quality"` 14 | Steps int64 `json:"steps"` 15 | Style string `json:"style"` 16 | Image string `json:"image"` 17 | DrawType string `json:"draw_type"` 18 | } 19 | 20 | type Response struct { 21 | } 22 | -------------------------------------------------------------------------------- /service/draw/service.go: -------------------------------------------------------------------------------- 1 | package draw 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "chatgpt-web-new-go/dao" 6 | "chatgpt-web-new-go/model" 7 | "context" 8 | ) 9 | 10 | const ( 11 | drawListTypeMe = "me" 12 | drawListTypeGallery = "gallery" 13 | ) 14 | 15 | func DrawList(ctx context.Context, uid int64, _type string, page, size int) (drawRecords []*model.DrawRecord, count int64, err error) { 16 | do := dao.Q.DrawRecord 17 | 18 | if _type == drawListTypeMe { 19 | drawRecords, count, err = do.WithContext(ctx).Where(do.IsDelete.Eq(0), do.UserID.Eq(uid)).FindByPage((page-1)*size, size) 20 | } else { 21 | drawRecords, count, err = do.WithContext(ctx).Where(do.IsDelete.Eq(0)).FindByPage((page-1)*size, size) 22 | } 23 | if err != nil { 24 | logs.Error("draw list error: %v", err) 25 | return nil, 0, err 26 | } 27 | return 28 | } 29 | -------------------------------------------------------------------------------- /service/gpt/gpt_test.go: -------------------------------------------------------------------------------- 1 | package gpt 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/aiClient" 5 | "chatgpt-web-new-go/common/config" 6 | "chatgpt-web-new-go/common/logs" 7 | "context" 8 | "fmt" 9 | "os" 10 | "testing" 11 | ) 12 | 13 | func TestMain(m *testing.M) { 14 | // config init 15 | config.InitConfig() 16 | 17 | // log init 18 | logs.LogInit() 19 | 20 | // aiClient init 21 | aiClient.Init() 22 | 23 | code := m.Run() 24 | os.Exit(code) 25 | } 26 | 27 | func TestListModels(t *testing.T) { 28 | models, err := aiClient.GetGptClient().OpenAIClient.ListModels(context.Background()) 29 | fmt.Println(err) 30 | fmt.Println(models) 31 | 32 | for _, m := range models.Models { 33 | fmt.Println(m) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /service/gpt/process.go: -------------------------------------------------------------------------------- 1 | package gpt 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/aiClient" 5 | "chatgpt-web-new-go/common/bizError" 6 | "chatgpt-web-new-go/common/goUtil" 7 | "chatgpt-web-new-go/common/logs" 8 | "chatgpt-web-new-go/common/types" 9 | "chatgpt-web-new-go/dao" 10 | "chatgpt-web-new-go/model" 11 | "fmt" 12 | "github.com/gin-gonic/gin" 13 | gogpt "github.com/sashabaranov/go-openai" 14 | ) 15 | 16 | const ( 17 | coinPerMessage = -1 18 | ) 19 | 20 | func Process(ctx *gin.Context, r *Request, uid int64) (stream *gogpt.ChatCompletionStream, err error) { 21 | // Deduction of points 22 | du := dao.Q.User 23 | updateInfo, err := du.WithContext(ctx).Where(du.ID.Eq(uid)).UpdateSimple(du.Integral.Add(coinPerMessage)) 24 | if err != nil { 25 | logs.Error("user integral update error: %v", err) 26 | return 27 | } 28 | if updateInfo.RowsAffected < 1 { 29 | logs.Error("user integral update error: updateInfo.RowsAffected <= 0") 30 | err = bizError.IntegralNoneError 31 | return 32 | } 33 | 34 | request := gogpt.ChatCompletionRequest{ 35 | Model: r.Options.Model, 36 | MaxTokens: r.Options.MaxTokens, 37 | Temperature: r.Options.Temperature, 38 | PresencePenalty: r.Options.PresencePenalty, 39 | FrequencyPenalty: r.Options.FrequencyPenalty, 40 | Messages: []gogpt.ChatCompletionMessage{ 41 | { 42 | Role: gogpt.ChatMessageRoleAssistant, 43 | Content: r.Prompt, 44 | }, 45 | }, 46 | Stream: true, 47 | } 48 | 49 | // cnf.Model 是否在 chatModels 中 50 | gptClient := aiClient.GetGptClient() 51 | if gptClient == nil { 52 | logs.Error("gptClient is nil!") 53 | return nil, bizError.AiKeyNoneUsefullError 54 | } 55 | 56 | stream, err = gptClient.OpenAIClient.CreateChatCompletionStream(ctx, request) 57 | if err != nil { 58 | logs.Error("aiClient client.CreateChatCompletion bizError:%v", err) 59 | goUtil.New(func() { 60 | refreshKey(gptClient) 61 | }) 62 | return nil, err 63 | } 64 | 65 | // insert message 66 | goUtil.New(func() { 67 | addMessage(ctx, r, uid) 68 | }) 69 | 70 | // insert record 71 | goUtil.New(func() { 72 | insertTurnOverRecord(ctx, r, uid) 73 | }) 74 | 75 | return 76 | } 77 | 78 | func refreshKey(client *aiClient.GptClient) { 79 | aiKey := client.Model 80 | 81 | aiKey.Status = 0 82 | 83 | da := dao.Q.Aikey 84 | resultInfo, err := da.Where(da.ID.Eq(aiKey.ID)).Update(da.Status, 0) 85 | if err != nil { 86 | logs.Error("aiKey update error: %v", err) 87 | return 88 | } 89 | if resultInfo.RowsAffected < 1 { 90 | logs.Error("aiKey update fail: RowsAffected < 1") 91 | return 92 | } 93 | 94 | // refresh 95 | aiClient.DoInitClient() 96 | } 97 | 98 | func insertTurnOverRecord(ctx *gin.Context, r *Request, uid int64) { 99 | t := &model.Turnover{ 100 | UserID: uid, 101 | Describe: "对话(" + r.Options.Model + ")", 102 | Value: fmt.Sprintf("%v积分", coinPerMessage), 103 | } 104 | 105 | dr := dao.Q.Turnover 106 | err := dr.WithContext(ctx).Create(t) 107 | if err != nil { 108 | logs.Error("turnover create error: %v", err) 109 | } 110 | } 111 | 112 | func addMessage(ctx *gin.Context, r *Request, uid int64) { 113 | msg := &model.Message{ 114 | UserID: uid, 115 | Content: r.Prompt, 116 | PersonaID: types.InterfaceToInt64(r.PersonaId), 117 | Role: gogpt.ChatMessageRoleUser, 118 | FrequencyPenalty: int32(r.Options.FrequencyPenalty), 119 | MaxTokens: int32(r.Options.MaxTokens), 120 | Model: r.Options.Model, 121 | PresencePenalty: int32(r.Options.PresencePenalty), 122 | Temperature: int32(r.Options.Temperature), 123 | ParentMessageID: r.ParentMessageId, 124 | } 125 | 126 | dm := dao.Q.Message 127 | err := dm.WithContext(ctx).Create(msg) 128 | if err != nil { 129 | logs.Error("message create error: %v", err) 130 | } 131 | return 132 | } 133 | -------------------------------------------------------------------------------- /service/gpt/requst.go: -------------------------------------------------------------------------------- 1 | package gpt 2 | 3 | type Request struct { 4 | ParentMessageId string `json:"parentMessageId"` 5 | PersonaId interface{} `json:"persona_id"` 6 | Prompt string `json:"prompt"` 7 | Options Options `json:"options"` 8 | } 9 | 10 | type Options struct { 11 | FrequencyPenalty float32 `json:"frequencyPenalty"` 12 | MaxTokens int `json:"max_tokens"` 13 | Model string `json:"model"` 14 | PresencePenalty float32 `json:"presence_penalty"` 15 | Temperature float32 `json:"temperature"` 16 | } 17 | -------------------------------------------------------------------------------- /service/invite/invite.go: -------------------------------------------------------------------------------- 1 | package invite 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/bizError" 5 | "chatgpt-web-new-go/common/logs" 6 | "chatgpt-web-new-go/dao" 7 | "chatgpt-web-new-go/model" 8 | "context" 9 | ) 10 | 11 | const ( 12 | InviteStatusFail = 0 13 | InviteStatusPass = 1 14 | InviteStatusPending = 3 15 | ) 16 | 17 | func InviteRecords(ctx context.Context, page, size int) (inviteRecords []*model.InviteRecord, count int64, err error) { 18 | di := dao.Q.InviteRecord 19 | 20 | inviteRecords, count, err = di.WithContext(ctx).Where(di.IsDelete.Eq(0)).FindByPage((page-1)*size, size) 21 | if err != nil { 22 | logs.Error("invite records error: %v", err) 23 | return nil, 0, err 24 | } 25 | return 26 | } 27 | 28 | func InviteUpdate(ctx context.Context, invite *model.InviteRecord) error { 29 | di := dao.Q.InviteRecord 30 | resultInfo, err := di.WithContext(ctx).Updates(invite) 31 | if err != nil { 32 | logs.Error("invite update error: %v", err) 33 | return err 34 | } 35 | if resultInfo.RowsAffected < 1 { 36 | logs.Error("invite update fail: RowsAffected < 1") 37 | return bizError.CommonUpdateError 38 | } 39 | 40 | return nil 41 | } 42 | 43 | func InviteDelete(ctx context.Context, id int64) error { 44 | di := dao.Q.InviteRecord 45 | resultInfo, err := di.WithContext(ctx).Where(di.ID.Eq(id)).Update(di.IsDelete, 1) 46 | if err != nil { 47 | logs.Error("invite delete error: %v", err) 48 | return err 49 | } 50 | if resultInfo.RowsAffected < 1 { 51 | logs.Error("invite delete fail: RowsAffected < 1") 52 | return bizError.CommonUpdateError 53 | } 54 | 55 | return nil 56 | } 57 | 58 | func InvitePass(ctx context.Context) error { 59 | di := dao.Q.InviteRecord 60 | 61 | _, err := di.WithContext(ctx).Where(di.Status.Eq(InviteStatusPending)).Update(di.Status, InviteStatusPass) 62 | if err != nil { 63 | logs.Error("invite pass error: %v", err) 64 | return err 65 | } 66 | return nil 67 | } 68 | -------------------------------------------------------------------------------- /service/message/dto.go: -------------------------------------------------------------------------------- 1 | package message 2 | 3 | type Options struct { 4 | FrequencyPenalty int32 `json:"frequency_penalty"` 5 | MaxTokens int32 `json:"max_tokens"` 6 | Model string `json:"model"` 7 | PresencePenalty int32 `json:"presence_penalty"` 8 | Temperature int32 `json:"temperature"` 9 | } 10 | 11 | type RequestOptions struct { 12 | ParentMessageID string `json:"parentMessageId"` 13 | Prompt string `json:"prompt"` 14 | Options *Options `json:"options"` 15 | } 16 | 17 | type MessageData struct { 18 | UserID int64 `json:"user_id"` 19 | DateTime string `json:"dateTime"` 20 | Role string `json:"role"` 21 | Status string `json:"status"` 22 | Text string `json:"text"` 23 | PersonaID int64 `json:"persona_id"` 24 | PluginID int64 `json:"plugin_id"` 25 | PluginInfo interface{} `json:"plugin_info"` 26 | RequestOptions *RequestOptions `json:"requestOptions"` 27 | } 28 | 29 | type Message struct { 30 | Data []*MessageData `json:"data"` 31 | ID string `json:"id"` 32 | Path string `json:"path"` 33 | Name string `json:"name"` 34 | PersonaID int64 `json:"persona_id"` 35 | } 36 | -------------------------------------------------------------------------------- /service/message/message_service.go: -------------------------------------------------------------------------------- 1 | package message 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "chatgpt-web-new-go/common/types" 6 | "chatgpt-web-new-go/dao" 7 | "chatgpt-web-new-go/model" 8 | "chatgpt-web-new-go/service/gpt" 9 | "context" 10 | ) 11 | 12 | func MessageList(ctx context.Context, uid int64) (result []*Message, err error) { 13 | dm := dao.Q.Message 14 | 15 | messages, err := dm.WithContext(ctx).Where(dm.UserID.Eq(uid)).Find() 16 | if err != nil { 17 | logs.Error("message find error: %v", err) 18 | return 19 | } 20 | 21 | pMsgMap := make(map[string][]*model.Message) 22 | for _, m := range messages { 23 | m := m 24 | pID := m.ParentMessageID 25 | 26 | pList, found := pMsgMap[pID] 27 | if !found { 28 | pList = []*model.Message{} 29 | } 30 | pList = append(pList, m) 31 | pMsgMap[pID] = pList 32 | } 33 | 34 | for pID, pList := range pMsgMap { 35 | head := pList[0] 36 | 37 | msgItem := &Message{ 38 | ID: pID, 39 | Path: pID, 40 | Name: head.Content, 41 | PersonaID: head.PersonaID, 42 | } 43 | 44 | var msgDatas []*MessageData 45 | for _, msgItem := range pList { 46 | msgDataItem := &MessageData{ 47 | UserID: msgItem.UserID, 48 | DateTime: msgItem.CreateTime.Format(types.TimeFormatDate), 49 | Role: msgItem.Role, 50 | Status: "pass", 51 | Text: msgItem.Content, 52 | PersonaID: msgItem.PersonaID, 53 | PluginID: msgItem.PluginID, 54 | PluginInfo: nil, 55 | RequestOptions: &RequestOptions{ 56 | ParentMessageID: msgItem.ParentMessageID, 57 | Prompt: msgItem.Content, 58 | Options: &Options{ 59 | FrequencyPenalty: msgItem.FrequencyPenalty, 60 | MaxTokens: msgItem.MaxTokens, 61 | Model: msgItem.Model, 62 | PresencePenalty: msgItem.PresencePenalty, 63 | Temperature: msgItem.Temperature, 64 | }, 65 | }, 66 | } 67 | 68 | msgDatas = append(msgDatas, msgDataItem) 69 | } 70 | 71 | msgItem.Data = msgDatas 72 | 73 | result = append(result, msgItem) 74 | } 75 | 76 | return 77 | } 78 | 79 | func AdminMessageList(ctx context.Context) (result []*model.Message, err error) { 80 | dm := dao.Q.Message 81 | 82 | result, err = dm.WithContext(ctx).Where(dm.IsDelete.Eq(0)).Find() 83 | if err != nil { 84 | logs.Error("admin message find error: %v", err) 85 | return 86 | } 87 | 88 | return 89 | } 90 | 91 | func MessageAdd(ctx context.Context, uid int64, r *gpt.Request, msgList []*ChatProcessResponse) { 92 | if len(msgList) == 0 { 93 | return 94 | } 95 | msgHead := msgList[0] 96 | 97 | content := "" 98 | for _, m := range msgList { 99 | content += m.Content 100 | } 101 | 102 | // insert message 103 | msg := &model.Message{ 104 | UserID: uid, 105 | Content: content, 106 | PersonaID: types.InterfaceToInt64(r.PersonaId), 107 | Role: msgHead.Role, 108 | FrequencyPenalty: int32(r.Options.FrequencyPenalty), 109 | MaxTokens: int32(r.Options.MaxTokens), 110 | Model: r.Options.Model, 111 | PresencePenalty: int32(r.Options.PresencePenalty), 112 | Temperature: int32(r.Options.Temperature), 113 | ParentMessageID: r.ParentMessageId, 114 | } 115 | 116 | dm := dao.Q.Message 117 | err := dm.WithContext(ctx).Create(msg) 118 | if err != nil { 119 | logs.Error("message create error: %v", err) 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /service/message/response.go: -------------------------------------------------------------------------------- 1 | package message 2 | 3 | import gogpt "github.com/sashabaranov/go-openai" 4 | 5 | const ( 6 | SegmentText = "text" 7 | SegmentStart = "start" 8 | SegmentStop = "stop" 9 | SegmentError = "error" 10 | 11 | AssistantMessageId = "assistantMessageId" 12 | ) 13 | 14 | var ( 15 | StartResponse = &ChatProcessResponse{ 16 | Role: gogpt.ChatMessageRoleAssistant, 17 | Segment: SegmentStart, 18 | ParentMessageID: AssistantMessageId, 19 | } 20 | 21 | StopResponse = &ChatProcessResponse{ 22 | Role: gogpt.ChatMessageRoleAssistant, 23 | Segment: SegmentStop, 24 | ParentMessageID: AssistantMessageId, 25 | } 26 | 27 | ErrorResponse = &ChatProcessResponse{ 28 | Role: gogpt.ChatMessageRoleAssistant, 29 | Segment: SegmentError, 30 | ParentMessageID: AssistantMessageId, 31 | } 32 | ) 33 | 34 | type ChatProcessResponse struct { 35 | ID string `json:"id"` 36 | Role string `json:"role"` 37 | Segment string `json:"segment"` 38 | DateTime string `json:"dateTime"` 39 | Content string `json:"content"` 40 | ParentMessageID string `json:"parentMessageId"` 41 | } 42 | -------------------------------------------------------------------------------- /service/notification/notification.go: -------------------------------------------------------------------------------- 1 | package notification 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/bizError" 5 | "chatgpt-web-new-go/common/logs" 6 | "chatgpt-web-new-go/dao" 7 | "chatgpt-web-new-go/model" 8 | "context" 9 | ) 10 | 11 | func GetList(ctx context.Context, page, size int) (notifications []*model.Notification, count int64, err error) { 12 | dn := dao.Q.Notification 13 | notifications, count, err = dn.WithContext(ctx).Where(dn.IsDelete.Eq(0)).FindByPage((page-1)*size, size) 14 | if err != nil { 15 | logs.Error("notifications list error: %v", err) 16 | return nil, 0, err 17 | } 18 | return 19 | } 20 | 21 | func Add(ctx context.Context, n *model.Notification) error { 22 | dn := dao.Q.Notification 23 | 24 | err := dn.WithContext(ctx).Create(n) 25 | if err != nil { 26 | logs.Error("notifications create error: %v", err) 27 | return err 28 | } 29 | 30 | return nil 31 | } 32 | 33 | func Update(ctx context.Context, n *model.Notification) error { 34 | dn := dao.Q.Notification 35 | 36 | resultInfo, err := dn.WithContext(ctx).Where(dn.ID.Eq(n.ID)).Updates(n) 37 | if err != nil { 38 | logs.Error("notifications update error: %v", err) 39 | return err 40 | } 41 | 42 | if resultInfo.RowsAffected < 1 { 43 | logs.Error("notification update fail: RowsAffected < 1") 44 | return bizError.NotificationUpdateError 45 | } 46 | 47 | return nil 48 | } 49 | 50 | func Delete(ctx context.Context, id int64) error { 51 | dn := dao.Q.Notification 52 | 53 | resultInfo, err := dn.WithContext(ctx).Where(dn.ID.Eq(id)).Update(dn.IsDelete, 1) 54 | if err != nil { 55 | logs.Error("notifications delete error: %v", err) 56 | return err 57 | } 58 | 59 | if resultInfo.RowsAffected < 1 { 60 | logs.Error("notification delete fail: RowsAffected < 1") 61 | return bizError.NotificationDeleteError 62 | } 63 | 64 | return nil 65 | } 66 | -------------------------------------------------------------------------------- /service/order/order.go: -------------------------------------------------------------------------------- 1 | package order 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "chatgpt-web-new-go/dao" 6 | "chatgpt-web-new-go/model" 7 | "context" 8 | ) 9 | 10 | func OrderList(ctx context.Context, page, size int) (orderList []*model.Order, count int64, err error) { 11 | do := dao.Q.Order 12 | orderList, count, err = do.WithContext(ctx).Where(do.IsDelete.Eq(0)).FindByPage((page-1)*size, size) 13 | if err != nil { 14 | logs.Error("order list error: %v", err) 15 | return nil, 0, err 16 | } 17 | return 18 | } 19 | -------------------------------------------------------------------------------- /service/pay/admin.go: -------------------------------------------------------------------------------- 1 | package pay 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/bizError" 5 | "chatgpt-web-new-go/common/logs" 6 | "chatgpt-web-new-go/dao" 7 | "chatgpt-web-new-go/model" 8 | "context" 9 | ) 10 | 11 | func PayConfigList(ctx context.Context) (payments []*model.Payment, err error) { 12 | dp := dao.Q.Payment 13 | payments, err = dp.WithContext(ctx).Find() 14 | if err != nil { 15 | logs.Error("pay config list error: %v", err) 16 | return nil, err 17 | } 18 | return 19 | } 20 | 21 | func PayConfigAdd(ctx context.Context, pay *model.Payment) error { 22 | dp := dao.Q.Payment 23 | 24 | err := dp.WithContext(ctx).Create(pay) 25 | if err != nil { 26 | logs.Error("payment create error: %v", err) 27 | return err 28 | } 29 | 30 | return nil 31 | } 32 | 33 | func PayConfigUpdate(ctx context.Context, pay *model.Payment) error { 34 | dp := dao.Q.Payment 35 | resultInfo, err := dp.WithContext(ctx).Where(dp.ID.Eq(pay.ID)).Updates(pay) 36 | if err != nil { 37 | logs.Error("payment update error: %v", err) 38 | return err 39 | } 40 | if resultInfo.RowsAffected < 1 { 41 | logs.Error("payment update fail: RowsAffected < 1") 42 | return bizError.PaymentUpdateError 43 | } 44 | return nil 45 | } 46 | 47 | func PayConfigDelete(ctx context.Context, id int64) error { 48 | dp := dao.Q.Payment 49 | 50 | resultInfo, err := dp.WithContext(ctx).Where(dp.ID.Eq(id)).Update(dp.IsDelete, 1) 51 | if err != nil { 52 | logs.Error("payment delete error: %v", err) 53 | return err 54 | } 55 | if resultInfo.RowsAffected < 1 { 56 | logs.Error("payment delete fail: RowsAffected < 1") 57 | return bizError.PaymentDeleteError 58 | } 59 | return nil 60 | } 61 | -------------------------------------------------------------------------------- /service/pay/pay.go: -------------------------------------------------------------------------------- 1 | package pay 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "chatgpt-web-new-go/dao" 6 | "context" 7 | ) 8 | 9 | func PayTypeList(ctx context.Context) (payTypeList []string, err error) { 10 | dp := dao.Q.Payment 11 | payDao := dp.WithContext(ctx) 12 | 13 | paymentList, err := payDao.Where(dp.Status.Eq(1)).Find() 14 | if err != nil { 15 | logs.Error("pay dao find error: %v", err) 16 | return nil, err 17 | } 18 | 19 | for _, p := range paymentList { 20 | payTypeList = append(payTypeList, p.Types) 21 | } 22 | 23 | return 24 | } 25 | -------------------------------------------------------------------------------- /service/persona/admin.go: -------------------------------------------------------------------------------- 1 | package persona 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/bizError" 5 | "chatgpt-web-new-go/common/logs" 6 | "chatgpt-web-new-go/dao" 7 | "chatgpt-web-new-go/model" 8 | "context" 9 | ) 10 | 11 | func List(ctx context.Context, page, size int) (list []*model.Persona, count int64, err error) { 12 | du := dao.Q.Persona 13 | 14 | list, count, err = du.WithContext(ctx).Where(du.IsDelete.Eq(0)).FindByPage((page-1)*size, size) 15 | if err != nil { 16 | logs.Error("Persona list error: %v", err) 17 | return nil, 0, err 18 | } 19 | return 20 | } 21 | 22 | func Delete(ctx context.Context, id int64) error { 23 | du := dao.Q.Persona 24 | 25 | resultInfo, err := du.WithContext(ctx).Where(du.ID.Eq(id)).Update(du.IsDelete, 1) 26 | if err != nil { 27 | logs.Error("Persona delete error: %v", err) 28 | return err 29 | } 30 | if resultInfo.RowsAffected < 1 { 31 | logs.Error("Persona delete fail: RowsAffected < 1") 32 | return bizError.CommonDeleteError 33 | } 34 | 35 | return nil 36 | } 37 | 38 | func Add(ctx context.Context, n *model.Persona) error { 39 | dn := dao.Q.Persona 40 | 41 | err := dn.WithContext(ctx).Create(n) 42 | if err != nil { 43 | logs.Error("Persona create error: %v", err) 44 | return err 45 | } 46 | 47 | return nil 48 | } 49 | func Update(ctx context.Context, u *model.Persona) error { 50 | du := dao.Q.Persona 51 | resultInfo, err := du.WithContext(ctx).Where(du.ID.Eq(u.ID)).Updates(u) 52 | if err != nil { 53 | logs.Error("Persona update error: %v", err) 54 | return err 55 | } 56 | if resultInfo.RowsAffected < 1 { 57 | logs.Error("Persona update fail: RowsAffected < 1") 58 | return bizError.CommonUpdateError 59 | } 60 | 61 | return nil 62 | } 63 | -------------------------------------------------------------------------------- /service/persona/persona.go: -------------------------------------------------------------------------------- 1 | package persona 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "chatgpt-web-new-go/dao" 6 | "chatgpt-web-new-go/model" 7 | "context" 8 | ) 9 | 10 | func PersonaList(ctx context.Context) (personaList []*model.Persona, err error) { 11 | dp := dao.Q.Persona 12 | 13 | personaList, err = dp.WithContext(ctx).Find() 14 | if err != nil { 15 | logs.Error("persona find error: %v", err) 16 | return 17 | } 18 | 19 | return 20 | } 21 | -------------------------------------------------------------------------------- /service/plugin/admin.go: -------------------------------------------------------------------------------- 1 | package plugin 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/bizError" 5 | "chatgpt-web-new-go/common/logs" 6 | "chatgpt-web-new-go/dao" 7 | "chatgpt-web-new-go/model" 8 | "context" 9 | ) 10 | 11 | func List(ctx context.Context, page, size int) (list []*model.Plugin, count int64, err error) { 12 | du := dao.Q.Plugin 13 | 14 | list, count, err = du.WithContext(ctx).Where(du.IsDelete.Eq(0)).FindByPage((page-1)*size, size) 15 | if err != nil { 16 | logs.Error("Plugin list error: %v", err) 17 | return nil, 0, err 18 | } 19 | return 20 | } 21 | 22 | func Delete(ctx context.Context, id int64) error { 23 | du := dao.Q.Plugin 24 | 25 | resultInfo, err := du.WithContext(ctx).Where(du.ID.Eq(id)).Update(du.IsDelete, 1) 26 | if err != nil { 27 | logs.Error("Plugin delete error: %v", err) 28 | return err 29 | } 30 | if resultInfo.RowsAffected < 1 { 31 | logs.Error("Plugin delete fail: RowsAffected < 1") 32 | return bizError.CommonDeleteError 33 | } 34 | 35 | return nil 36 | } 37 | 38 | func Add(ctx context.Context, n *model.Plugin) error { 39 | dn := dao.Q.Plugin 40 | 41 | err := dn.WithContext(ctx).Create(n) 42 | if err != nil { 43 | logs.Error("Plugin create error: %v", err) 44 | return err 45 | } 46 | 47 | return nil 48 | } 49 | 50 | func Update(ctx context.Context, u *model.Plugin) error { 51 | du := dao.Q.Plugin 52 | resultInfo, err := du.WithContext(ctx).Where(du.ID.Eq(u.ID)).Updates(u) 53 | if err != nil { 54 | logs.Error("Plugin update error: %v", err) 55 | return err 56 | } 57 | if resultInfo.RowsAffected < 1 { 58 | logs.Error("Plugin update fail: RowsAffected < 1") 59 | return bizError.CommonUpdateError 60 | } 61 | 62 | return nil 63 | } 64 | -------------------------------------------------------------------------------- /service/plugin/plugin.go: -------------------------------------------------------------------------------- 1 | package plugin 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "chatgpt-web-new-go/dao" 6 | "chatgpt-web-new-go/model" 7 | "context" 8 | ) 9 | 10 | func PluginList(ctx context.Context) (pluginList []*model.Plugin, err error) { 11 | dp := dao.Q.Plugin 12 | 13 | pluginList, err = dp.WithContext(ctx).Find() 14 | if err != nil { 15 | logs.Error("plugin list error: %v", err) 16 | return nil, err 17 | } 18 | return 19 | } 20 | -------------------------------------------------------------------------------- /service/product/product.go: -------------------------------------------------------------------------------- 1 | package product 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/bizError" 5 | "chatgpt-web-new-go/common/logs" 6 | "chatgpt-web-new-go/dao" 7 | "chatgpt-web-new-go/model" 8 | "context" 9 | ) 10 | 11 | func ProductList(ctx context.Context, page, size int) (productList []*model.Product, count int64, err error) { 12 | dp := dao.Q.Product 13 | 14 | productList, count, err = dp.WithContext(ctx).Where(dp.IsDelete.Eq(0)).FindByPage((page-1)*size, size) 15 | if err != nil { 16 | logs.Error("product find by page error: %v", err) 17 | return nil, 0, err 18 | } 19 | 20 | return 21 | } 22 | 23 | func ProductAdd(ctx context.Context, p *model.Product) (result *model.Product, err error) { 24 | dp := dao.Q.Product 25 | err = dp.WithContext(ctx).Create(p) 26 | if err != nil { 27 | logs.Error("product create error: %v", err) 28 | return nil, err 29 | } 30 | return 31 | } 32 | 33 | func ProductUpdate(ctx context.Context, p *model.Product) error { 34 | dp := dao.Q.Product 35 | resultInfo, err := dp.WithContext(ctx).Where(dp.ID.Eq(p.ID)).Updates(p) 36 | if err != nil { 37 | logs.Error("product update error: %v", err) 38 | return err 39 | } 40 | if resultInfo.RowsAffected < 1 { 41 | logs.Error("product update fail: RowsAffected < 1") 42 | return bizError.ProductUpdateError 43 | } 44 | 45 | return nil 46 | } 47 | 48 | func ProductDelete(ctx context.Context, id int64) error { 49 | dp := dao.Q.Product 50 | 51 | resultInfo, err := dp.WithContext(ctx).Where(dp.ID.Eq(id)).Update(dp.ID, 1) 52 | if err != nil { 53 | logs.Error("product delete error: %v", err) 54 | return err 55 | } 56 | if resultInfo.RowsAffected < 1 { 57 | logs.Error("product delete fail: RowsAffected < 1") 58 | return bizError.ProductDeleteError 59 | } 60 | 61 | return nil 62 | } 63 | -------------------------------------------------------------------------------- /service/signin/admin.go: -------------------------------------------------------------------------------- 1 | package signin 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "chatgpt-web-new-go/dao" 6 | "chatgpt-web-new-go/model" 7 | "context" 8 | ) 9 | 10 | func AdminSigninList(ctx context.Context, page, size int) (signinList []*model.Signin, count int64, err error) { 11 | ds := dao.Q.Signin 12 | signinList, count, err = ds.WithContext(ctx).Where(ds.IsDelete.Eq(0)).FindByPage((page-1)*size, size) 13 | if err != nil { 14 | logs.Error("signin list error: %v", err) 15 | return nil, 0, err 16 | } 17 | 18 | return 19 | } 20 | -------------------------------------------------------------------------------- /service/signin/sign.go: -------------------------------------------------------------------------------- 1 | package signin 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/bizError" 5 | "chatgpt-web-new-go/common/logs" 6 | "chatgpt-web-new-go/common/types" 7 | "chatgpt-web-new-go/dao" 8 | "chatgpt-web-new-go/model" 9 | "context" 10 | "fmt" 11 | ) 12 | 13 | const ( 14 | SigninCoin = 10 15 | ) 16 | 17 | func SignIn(ctx context.Context, uid int64, ip string) error { 18 | if IsSignInToday(uid) { 19 | return bizError.SigninedAlreadyError 20 | } 21 | 22 | sign := &model.Signin{ 23 | UserID: uid, 24 | IP: ip, 25 | } 26 | 27 | err := dao.Q.Signin.WithContext(ctx).Create(sign) 28 | if err != nil { 29 | logs.Error("signin create error: %v", err) 30 | return err 31 | } 32 | 33 | // add integral 34 | du := dao.Q.User 35 | result, err := du.WithContext(ctx).Where(du.ID.Eq(uid)).UpdateSimple(du.Integral.Add(SigninCoin)) 36 | if err != nil { 37 | logs.Error("user integral update error: %v", err) 38 | return err 39 | } 40 | if result.RowsAffected < 1 { 41 | err := fmt.Errorf("user integral update RowsAffected < 1, uid: %v", uid) 42 | logs.Error("user integral update error: %v", err) 43 | return err 44 | } 45 | 46 | return nil 47 | } 48 | 49 | func IsSignInToday(uid int64) bool { 50 | startTime, endTime := types.GetDayStartEn() 51 | 52 | sign := dao.Q.Signin 53 | signInToday, err := sign. 54 | Where(sign.UserID.Eq(uid), 55 | sign.CreateTime.Between(startTime, endTime)). 56 | Find() 57 | if err != nil { 58 | logs.Error("signIn today get error: %v", err) 59 | return false 60 | } 61 | return len(signInToday) > 0 62 | } 63 | 64 | func GetSignListMonth(uid int64) (result []*model.Signin, err error) { 65 | start, end := types.GetMonthStartEnd() 66 | 67 | sign := dao.Q.Signin 68 | result, err = sign.Where(sign.UserID.Eq(uid), sign.CreateTime.Between(start, end)).Find() 69 | 70 | return 71 | } 72 | -------------------------------------------------------------------------------- /service/sns/sns_codee.go: -------------------------------------------------------------------------------- 1 | package sns 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/config" 5 | "chatgpt-web-new-go/common/constant" 6 | "chatgpt-web-new-go/common/email" 7 | "chatgpt-web-new-go/common/env" 8 | "chatgpt-web-new-go/common/logs" 9 | "chatgpt-web-new-go/common/random" 10 | "chatgpt-web-new-go/common/redis" 11 | "chatgpt-web-new-go/common/regexp" 12 | "encoding/json" 13 | "fmt" 14 | "io/ioutil" 15 | "net/http" 16 | "net/url" 17 | "time" 18 | ) 19 | 20 | const ( 21 | whiteListPhoneCode = "0000" 22 | ) 23 | 24 | func SendCode(source string) error { 25 | // 0. valid first 26 | if !regexp.IsValidPhoneOrEmail(source) { 27 | return fmt.Errorf("只支持手机号或者邮箱!") 28 | } 29 | 30 | // 1. generate sns code, eg:1234 31 | snsCode := random.GenSmsCode() 32 | 33 | // 2. store code 34 | key := fmt.Sprintf(redis.KeySnsCode, source) 35 | if err := config.Redis.Set(key, snsCode, 20*time.Minute).Err(); err != nil { 36 | return err 37 | } 38 | 39 | // 3. type based 40 | if regexp.IsValidPhone(source) { 41 | return apiSendSnsCode(source, snsCode) 42 | } else { 43 | return SendEmailCode(source, snsCode) 44 | } 45 | } 46 | 47 | func SendEmailCode(emailAddress string, code string) error { 48 | emailContent := fmt.Sprintf(email.SendCodeTemplate, code) 49 | err := email.SendMail("OurAI", emailAddress, emailContent) 50 | if err != nil { 51 | logs.Error("mail.SendMail emailAddress:%v, bizError: %v", emailAddress, err) 52 | } 53 | return err 54 | } 55 | 56 | type apiResponse struct { 57 | Code string `json:"code"` 58 | Msg string `json:"msg"` 59 | SmUuid string `json:"sm_uuid"` 60 | } 61 | 62 | func apiSendSnsCode(phone, code string) error { 63 | if _, found := constant.WhiteListPhone[phone]; found || env.IsDevelop() { 64 | return nil 65 | } 66 | 67 | data := url.Values{} 68 | 69 | data.Set("accesskey", "1QQRVwDIBvQ3nSnd") 70 | data.Set("secret", "Ib87ISCYEfYbsF51WGkXAdt61HhrmW7V") 71 | data.Set("signin", "【云上AI】") 72 | data.Set("templateId", "182578") 73 | data.Set("mobile", phone) 74 | data.Set("content", code) 75 | 76 | resp, err := http.PostForm("https://api.1cloudsp.com/api/v2/single_send", data) 77 | if err != nil { 78 | logs.Error("http.PostForm erorr: %v", err) 79 | return err 80 | } 81 | defer resp.Body.Close() 82 | content, err := ioutil.ReadAll(resp.Body) 83 | if err != nil { 84 | logs.Error("ioutil.ReadAll erorr: %v", err) 85 | return err 86 | } 87 | 88 | logs.Info("sns send api response: %v", string(content)) 89 | 90 | result := &apiResponse{} 91 | err = json.Unmarshal(content, result) 92 | if err != nil || result == nil { 93 | logs.Error("json.Unmarshal erorr: %v, content:%v", err, string(content)) 94 | return err 95 | } 96 | 97 | if result.Code != "0" { 98 | logs.Error("result code not 0: %v, msg: %v", result.Code, result.Msg) 99 | return fmt.Errorf("result code not 0: %v, msg: %v", result.Code, result.Msg) 100 | } 101 | return nil 102 | } 103 | -------------------------------------------------------------------------------- /service/token/admin.go: -------------------------------------------------------------------------------- 1 | package token 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/aiClient" 5 | "chatgpt-web-new-go/common/bizError" 6 | "chatgpt-web-new-go/common/goUtil" 7 | "chatgpt-web-new-go/common/logs" 8 | "chatgpt-web-new-go/dao" 9 | "chatgpt-web-new-go/model" 10 | "context" 11 | ) 12 | 13 | func TokenList(ctx context.Context, page, size int) (tokenList []*model.Aikey, count int64, err error) { 14 | dt := dao.Q.Aikey 15 | 16 | tokenList, count, err = dt.WithContext(ctx).Where(dt.IsDelete.Eq(0)).FindByPage((page-1)*size, size) 17 | if err != nil { 18 | logs.Error("token list error: %v", err) 19 | return 20 | } 21 | return 22 | } 23 | 24 | func TokenAdd(ctx context.Context, token *model.Aikey) (result *model.Aikey, err error) { 25 | dt := dao.Q.Aikey 26 | err = dt.WithContext(ctx).Create(token) 27 | if err != nil { 28 | logs.Error("token create error: %v", err) 29 | return nil, err 30 | } 31 | 32 | goUtil.New(func() { 33 | aiClient.DoInitClient() 34 | }) 35 | 36 | return 37 | } 38 | 39 | func TokenUpdate(ctx context.Context, token *model.Aikey) (result *model.Aikey, err error) { 40 | dt := dao.Q.Aikey 41 | 42 | resultInfo, err := dt.WithContext(ctx).Where(dt.ID.Eq(token.ID)).Updates(token) 43 | if err != nil { 44 | logs.Error("token update error: %v", err) 45 | return nil, err 46 | } 47 | if resultInfo.RowsAffected < 1 { 48 | logs.Error("token update fail: RowsAffected < 1") 49 | return nil, bizError.AiKeyTokenUpdateError 50 | } 51 | 52 | goUtil.New(func() { 53 | aiClient.DoInitClient() 54 | }) 55 | 56 | return 57 | } 58 | 59 | func TokenDelete(ctx context.Context, id int64) error { 60 | dt := dao.Q.Aikey 61 | 62 | resultInfo, err := dt.WithContext(ctx).Where(dt.ID.Eq(id)).Update(dt.IsDelete, 1) 63 | if err != nil { 64 | logs.Error("token delete error: %v", err) 65 | return err 66 | } 67 | if resultInfo.RowsAffected < 1 { 68 | logs.Error("token delete fail: RowsAffected < 1") 69 | return bizError.AiKeyTokenDeleteError 70 | } 71 | 72 | goUtil.New(func() { 73 | aiClient.DoInitClient() 74 | }) 75 | 76 | return nil 77 | } 78 | -------------------------------------------------------------------------------- /service/turnover/admin.go: -------------------------------------------------------------------------------- 1 | package turnover 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/bizError" 5 | "chatgpt-web-new-go/common/logs" 6 | "chatgpt-web-new-go/dao" 7 | "chatgpt-web-new-go/model" 8 | "context" 9 | ) 10 | 11 | func AdminTurnoverList(ctx context.Context, page, size int) (turnoverList []*model.Turnover, count int64, err error) { 12 | dt := dao.Q.Turnover 13 | turnoverList, count, err = dt.WithContext(ctx).Where(dt.IsDelete.Eq(0)).FindByPage((page-1)*size, size) 14 | if err != nil { 15 | logs.Error("turnover list error: %v", err) 16 | return nil, 0, err 17 | } 18 | 19 | return 20 | } 21 | 22 | func AdminTurnoverDelete(ctx context.Context, id int64) error { 23 | dt := dao.Q.Turnover 24 | resultInfo, err := dt.WithContext(ctx).Where(dt.ID.Eq(id)).Update(dt.IsDelete, 1) 25 | if err != nil { 26 | logs.Error("turnover delete error: %v", err) 27 | return err 28 | } 29 | if resultInfo.RowsAffected < 1 { 30 | logs.Error("turnover delete fail: RowsAffected < 1") 31 | return bizError.TurnoverDeleteError 32 | } 33 | 34 | return nil 35 | } 36 | 37 | func AdminTurnoverUpdate(ctx context.Context, t *model.Turnover) (result *model.Turnover, err error) { 38 | dt := dao.Q.Turnover 39 | resultInfo, err := dt.WithContext(ctx).Where(dt.ID.Eq(t.ID)).Updates(t) 40 | if err != nil { 41 | logs.Error("turnover update error: %v", err) 42 | return nil, err 43 | } 44 | if resultInfo.RowsAffected < 1 { 45 | logs.Error("turnover update fail: RowsAffected < 1 : %v", resultInfo) 46 | return nil, bizError.TurnoverUpdateError 47 | } 48 | 49 | return 50 | } 51 | -------------------------------------------------------------------------------- /service/turnover/service3.go: -------------------------------------------------------------------------------- 1 | package turnover 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "chatgpt-web-new-go/dao" 6 | "chatgpt-web-new-go/model" 7 | "context" 8 | ) 9 | 10 | func TurnoverList(ctx context.Context, uid int64, page, size int) (turnovers []*model.Turnover, count int64, err error) { 11 | dt := dao.Q.Turnover 12 | tDao := dt.WithContext(ctx) 13 | 14 | offset := (page - 1) * size 15 | turnovers, count, err = tDao.Where(dt.UserID.Eq(uid)).FindByPage(offset, size) 16 | if err != nil { 17 | logs.Error("turnover find by page error: %v, uid: %v", err, uid) 18 | return nil, 0, err 19 | } 20 | 21 | return 22 | } 23 | -------------------------------------------------------------------------------- /service/user/admin.go: -------------------------------------------------------------------------------- 1 | package user 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/bizError" 5 | "chatgpt-web-new-go/common/logs" 6 | "chatgpt-web-new-go/dao" 7 | "chatgpt-web-new-go/model" 8 | "context" 9 | ) 10 | 11 | func UserList(ctx context.Context, page, size int) (userList []*model.User, count int64, err error) { 12 | du := dao.Q.User 13 | 14 | userList, count, err = du.WithContext(ctx).Where(du.IsDelete.Eq(0)).FindByPage((page-1)*size, size) 15 | if err != nil { 16 | logs.Error("user list error: %v", err) 17 | return nil, 0, err 18 | } 19 | return 20 | } 21 | 22 | func UserDelete(ctx context.Context, uid int64) error { 23 | du := dao.Q.User 24 | 25 | resultInfo, err := du.WithContext(ctx).Where(du.ID.Eq(uid)).Update(du.IsDelete, 1) 26 | if err != nil { 27 | logs.Error("user delete error: %v", err) 28 | return err 29 | } 30 | if resultInfo.RowsAffected < 1 { 31 | logs.Error("user delete fail: RowsAffected < 1") 32 | return bizError.UserDelError 33 | } 34 | 35 | return nil 36 | } 37 | 38 | func UserUpdate(ctx context.Context, u *model.User) error { 39 | du := dao.Q.User 40 | resultInfo, err := du.WithContext(ctx).Where(du.ID.Eq(u.ID)).Updates(u) 41 | if err != nil { 42 | logs.Error("user update error: %v", err) 43 | return err 44 | } 45 | if resultInfo.RowsAffected < 1 { 46 | logs.Error("user update fail: RowsAffected < 1") 47 | return bizError.UserUpdateError 48 | } 49 | 50 | return nil 51 | } 52 | -------------------------------------------------------------------------------- /service/user/user.go: -------------------------------------------------------------------------------- 1 | package user 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/logs" 5 | "chatgpt-web-new-go/dao" 6 | "chatgpt-web-new-go/model" 7 | "github.com/gin-gonic/gin" 8 | ) 9 | 10 | func GetUserInfo(ctx *gin.Context, account string) (*model.User, error) { 11 | du := dao.Q.User 12 | userDao := du.WithContext(ctx) 13 | 14 | u, err := userDao.Where(du.Account.Eq(account)).First() 15 | if err != nil { 16 | logs.Error("userDao get error: %v", err) 17 | return nil, err 18 | } 19 | 20 | return u, err 21 | } 22 | -------------------------------------------------------------------------------- /service/withdrawal/withdrawal.go: -------------------------------------------------------------------------------- 1 | package withdrawal 2 | 3 | import ( 4 | "chatgpt-web-new-go/common/bizError" 5 | "chatgpt-web-new-go/common/logs" 6 | "chatgpt-web-new-go/dao" 7 | "chatgpt-web-new-go/model" 8 | "context" 9 | ) 10 | 11 | func List(ctx context.Context, page, size int) (list []*model.WithdrawalRecord, count int64, err error) { 12 | du := dao.Q.WithdrawalRecord 13 | 14 | list, count, err = du.WithContext(ctx).Where(du.IsDelete.Eq(0)).FindByPage((page-1)*size, size) 15 | if err != nil { 16 | logs.Error("WithdrawalRecord list error: %v", err) 17 | return nil, 0, err 18 | } 19 | return 20 | } 21 | 22 | func Delete(ctx context.Context, id int64) error { 23 | du := dao.Q.WithdrawalRecord 24 | 25 | resultInfo, err := du.WithContext(ctx).Where(du.ID.Eq(id)).Update(du.IsDelete, 1) 26 | if err != nil { 27 | logs.Error("WithdrawalRecord delete error: %v", err) 28 | return err 29 | } 30 | if resultInfo.RowsAffected < 1 { 31 | logs.Error("WithdrawalRecord delete fail: RowsAffected < 1") 32 | return bizError.CommonDeleteError 33 | } 34 | 35 | return nil 36 | } 37 | 38 | func Update(ctx context.Context, u *model.WithdrawalRecord) error { 39 | du := dao.Q.WithdrawalRecord 40 | resultInfo, err := du.WithContext(ctx).Where(du.ID.Eq(u.ID)).Updates(u) 41 | if err != nil { 42 | logs.Error("WithdrawalRecord update error: %v", err) 43 | return err 44 | } 45 | if resultInfo.RowsAffected < 1 { 46 | logs.Error("WithdrawalRecord update fail: RowsAffected < 1") 47 | return bizError.CommonUpdateError 48 | } 49 | 50 | return nil 51 | } 52 | --------------------------------------------------------------------------------