fix bug for license synchronize

This commit is contained in:
RockYang 2024-05-04 21:30:29 +08:00
parent 8900e72e45
commit c2bf5e845a
5 changed files with 82 additions and 42 deletions

View File

@ -1,5 +1,5 @@
SHELL=/usr/bin/env bash SHELL=/usr/bin/env bash
NAME := chatgpt-plus NAME := geekai
all: amd64 arm64 all: amd64 arm64
amd64: amd64:

View File

@ -200,8 +200,10 @@ func authorizeMiddleware(s *AppServer, client *redis.Client) gin.HandlerFunc {
func needLogin(c *gin.Context) bool { func needLogin(c *gin.Context) bool {
if c.Request.URL.Path == "/api/user/login" || if c.Request.URL.Path == "/api/user/login" ||
c.Request.URL.Path == "/api/user/logout" ||
c.Request.URL.Path == "/api/user/resetPass" || c.Request.URL.Path == "/api/user/resetPass" ||
c.Request.URL.Path == "/api/admin/login" || c.Request.URL.Path == "/api/admin/login" ||
c.Request.URL.Path == "/api/admin/logout" ||
c.Request.URL.Path == "/api/admin/login/captcha" || c.Request.URL.Path == "/api/admin/login/captcha" ||
c.Request.URL.Path == "/api/user/register" || c.Request.URL.Path == "/api/user/register" ||
c.Request.URL.Path == "/api/user/session" || c.Request.URL.Path == "/api/user/session" ||

View File

@ -16,7 +16,7 @@ import (
type LicenseService struct { type LicenseService struct {
config types.ApiConfig config types.ApiConfig
levelDB *store.LevelDB levelDB *store.LevelDB
license types.License license *types.License
urlWhiteList []string urlWhiteList []string
machineId string machineId string
} }
@ -29,18 +29,20 @@ func NewLicenseService(server *core.AppServer, levelDB *store.LevelDB) *LicenseS
if err == nil { if err == nil {
machineId = info.HostID machineId = info.HostID
} }
logger.Infof("License: %+v", license)
return &LicenseService{ return &LicenseService{
config: server.Config.ApiConfig, config: server.Config.ApiConfig,
levelDB: levelDB, levelDB: levelDB,
license: license, license: &license,
machineId: machineId, machineId: machineId,
} }
} }
type License struct { type License struct {
Name string `json:"name"` Name string `json:"name"`
Value string `json:"license"` License string `json:"license"`
Mid string `json:"mid"` Mid string `json:"mid"`
ActiveAt int64 `json:"active_at"`
ExpiredAt int64 `json:"expired_at"` ExpiredAt int64 `json:"expired_at"`
UserNum int `json:"user_num"` UserNum int `json:"user_num"`
} }
@ -68,7 +70,7 @@ func (s *LicenseService) ActiveLicense(license string, machineId string) error {
return fmt.Errorf("激活失败:%v", res.Message) return fmt.Errorf("激活失败:%v", res.Message)
} }
s.license = types.License{ s.license = &types.License{
Key: license, Key: license,
MachineId: machineId, MachineId: machineId,
UserNum: res.Data.UserNum, UserNum: res.Data.UserNum,
@ -85,50 +87,81 @@ func (s *LicenseService) ActiveLicense(license string, machineId string) error {
// SyncLicense 定期同步 License // SyncLicense 定期同步 License
func (s *LicenseService) SyncLicense() { func (s *LicenseService) SyncLicense() {
go func() { go func() {
retryCounter := 0
for { for {
license, err := s.fetchLicense()
if err != nil {
retryCounter++
if retryCounter < 5 {
logger.Error(err)
}
s.license.IsActive = false
} else {
s.license = license
}
urls, err := s.fetchUrlWhiteList()
if err == nil {
s.urlWhiteList = urls
}
time.Sleep(time.Second * 10)
}
}()
}
func (s *LicenseService) fetchLicense() (*types.License, error) {
var res struct { var res struct {
Code types.BizCode `json:"code"` Code types.BizCode `json:"code"`
Message string `json:"message"` Message string `json:"message"`
Data struct { Data License `json:"data"`
License License `json:"license"`
Urls []string `json:"urls"`
}
} }
apiURL := fmt.Sprintf("%s/%s", s.config.ApiURL, "api/license/check") apiURL := fmt.Sprintf("%s/%s", s.config.ApiURL, "api/license/check")
response, err := req.C().R(). response, err := req.C().R().
SetBody(map[string]string{"license": s.license.Key, "machine_id": s.machineId}). SetBody(map[string]string{"license": s.license.Key, "machine_id": s.machineId}).
SetSuccessResult(&res).Post(apiURL) SetSuccessResult(&res).Post(apiURL)
if err != nil { if err != nil {
logger.Errorf("发送激活请求失败: %v", err) return nil, fmt.Errorf("发送激活请求失败: %v", err)
goto next
} }
if response.IsErrorState() { if response.IsErrorState() {
logger.Errorf("激活失败:%v", response.Status) return nil, fmt.Errorf("激活失败:%v", response.Status)
goto next
} }
if res.Code != types.Success { if res.Code != types.Success {
logger.Errorf("激活失败:%v", res.Message) return nil, fmt.Errorf("激活失败:%v", res.Message)
s.license.IsActive = false
goto next
} }
s.license = types.License{ return &types.License{
Key: res.Data.License.Value, Key: res.Data.License,
MachineId: res.Data.License.Mid, MachineId: res.Data.Mid,
UserNum: res.Data.License.UserNum, UserNum: res.Data.UserNum,
ExpiredAt: res.Data.License.ExpiredAt, ExpiredAt: res.Data.ExpiredAt,
IsActive: true, IsActive: true,
}, nil
}
func (s *LicenseService) fetchUrlWhiteList() ([]string, error) {
var res struct {
Code types.BizCode `json:"code"`
Message string `json:"message"`
Data []string `json:"data"`
} }
s.urlWhiteList = res.Data.Urls apiURL := fmt.Sprintf("%s/%s", s.config.ApiURL, "api/license/urls")
//logger.Debugf("同步 License 成功:%v\n%v", s.license, s.urlWhiteList) response, err := req.C().R().SetSuccessResult(&res).Get(apiURL)
next: if err != nil {
time.Sleep(time.Second * 10) return nil, fmt.Errorf("发送请求失败: %v", err)
} }
}() if response.IsErrorState() {
return nil, fmt.Errorf("发送请求失败:%v", response.Status)
}
if res.Code != types.Success {
return nil, fmt.Errorf("获取白名单失败:%v", res.Message)
}
return res.Data, nil
} }
// GetLicense 获取许可信息 // GetLicense 获取许可信息
func (s *LicenseService) GetLicense() types.License { func (s *LicenseService) GetLicense() *types.License {
return s.license return s.license
} }

View File

@ -4,9 +4,9 @@ FROM registry.cn-hangzhou.aliyuncs.com/geekmaster/alpine:3.18.2
MAINTAINER yangjian<yangjian102621@163.com> MAINTAINER yangjian<yangjian102621@163.com>
WORKDIR /var/www/app WORKDIR /var/www/app
COPY ./api/bin/chatgpt-plus-linux /var/www/app COPY ./api/bin/geekai-linux /var/www/app
EXPOSE 5678 EXPOSE 5678
# 容器启动时执行的命令 # 容器启动时执行的命令
CMD ["./chatgpt-plus-linux"] CMD ["./geekai-linux"]

View File

@ -1,5 +1,5 @@
import axios from 'axios' import axios from 'axios'
import {getAdminToken, getSessionId, getUserToken} from "@/store/session"; import {getAdminToken, getSessionId, getUserToken, removeAdminToken, removeUserToken} from "@/store/session";
axios.defaults.timeout = 180000 axios.defaults.timeout = 180000
axios.defaults.baseURL = process.env.VUE_APP_API_HOST axios.defaults.baseURL = process.env.VUE_APP_API_HOST
@ -22,9 +22,14 @@ axios.interceptors.response.use(
let data = response.data; let data = response.data;
if (data.code === 0) { if (data.code === 0) {
return response return response
} else if (data.code === 400) {
if (response.request.responseURL.indexOf("/api/admin") !== -1) {
removeAdminToken()
} else { } else {
return Promise.reject(response.data) removeUserToken()
} }
}
return Promise.reject(response.data)
}, error => { }, error => {
return Promise.reject(error) return Promise.reject(error)
}) })