mirror of
https://github.com/yangjian102621/geekai.git
synced 2025-09-17 16:56:38 +08:00
synchronize license every 10 secs
This commit is contained in:
parent
74b1b07b31
commit
1966e69460
@ -4,6 +4,7 @@ import (
|
|||||||
"chatplus/core"
|
"chatplus/core"
|
||||||
"chatplus/core/types"
|
"chatplus/core/types"
|
||||||
"chatplus/handler"
|
"chatplus/handler"
|
||||||
|
"chatplus/service"
|
||||||
"chatplus/store/model"
|
"chatplus/store/model"
|
||||||
"chatplus/store/vo"
|
"chatplus/store/vo"
|
||||||
"chatplus/utils"
|
"chatplus/utils"
|
||||||
@ -17,10 +18,11 @@ import (
|
|||||||
|
|
||||||
type UserHandler struct {
|
type UserHandler struct {
|
||||||
handler.BaseHandler
|
handler.BaseHandler
|
||||||
|
licenseService *service.LicenseService
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewUserHandler(app *core.AppServer, db *gorm.DB) *UserHandler {
|
func NewUserHandler(app *core.AppServer, db *gorm.DB, licenseService *service.LicenseService) *UserHandler {
|
||||||
return &UserHandler{BaseHandler: handler.BaseHandler{App: app, DB: db}}
|
return &UserHandler{BaseHandler: handler.BaseHandler{App: app, DB: db}, licenseService: licenseService}
|
||||||
}
|
}
|
||||||
|
|
||||||
// List 用户列表
|
// List 用户列表
|
||||||
@ -75,6 +77,13 @@ func (h *UserHandler) Save(c *gin.Context) {
|
|||||||
resp.ERROR(c, types.InvalidArgs)
|
resp.ERROR(c, types.InvalidArgs)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// 检测最大注册人数
|
||||||
|
var totalUser int64
|
||||||
|
h.DB.Model(&model.User{}).Count(&totalUser)
|
||||||
|
if int(totalUser) >= h.licenseService.GetLicense().UserNum {
|
||||||
|
resp.ERROR(c, "当前注册用户数已达上限,请请升级 License")
|
||||||
|
return
|
||||||
|
}
|
||||||
var user = model.User{}
|
var user = model.User{}
|
||||||
var res *gorm.DB
|
var res *gorm.DB
|
||||||
var userVo vo.User
|
var userVo vo.User
|
||||||
|
@ -3,6 +3,7 @@ package handler
|
|||||||
import (
|
import (
|
||||||
"chatplus/core"
|
"chatplus/core"
|
||||||
"chatplus/core/types"
|
"chatplus/core/types"
|
||||||
|
"chatplus/service"
|
||||||
"chatplus/store/model"
|
"chatplus/store/model"
|
||||||
"chatplus/store/vo"
|
"chatplus/store/vo"
|
||||||
"chatplus/utils"
|
"chatplus/utils"
|
||||||
@ -21,16 +22,23 @@ import (
|
|||||||
|
|
||||||
type UserHandler struct {
|
type UserHandler struct {
|
||||||
BaseHandler
|
BaseHandler
|
||||||
searcher *xdb.Searcher
|
searcher *xdb.Searcher
|
||||||
redis *redis.Client
|
redis *redis.Client
|
||||||
|
licenseService *service.LicenseService
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewUserHandler(
|
func NewUserHandler(
|
||||||
app *core.AppServer,
|
app *core.AppServer,
|
||||||
db *gorm.DB,
|
db *gorm.DB,
|
||||||
searcher *xdb.Searcher,
|
searcher *xdb.Searcher,
|
||||||
client *redis.Client) *UserHandler {
|
client *redis.Client,
|
||||||
return &UserHandler{BaseHandler: BaseHandler{DB: db, App: app}, searcher: searcher, redis: client}
|
licenseService *service.LicenseService) *UserHandler {
|
||||||
|
return &UserHandler{
|
||||||
|
BaseHandler: BaseHandler{DB: db, App: app},
|
||||||
|
searcher: searcher,
|
||||||
|
redis: client,
|
||||||
|
licenseService: licenseService,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register user register
|
// Register user register
|
||||||
@ -53,6 +61,14 @@ func (h *UserHandler) Register(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检测最大注册人数
|
||||||
|
var totalUser int64
|
||||||
|
h.DB.Model(&model.User{}).Count(&totalUser)
|
||||||
|
if int(totalUser) >= h.licenseService.GetLicense().UserNum {
|
||||||
|
resp.ERROR(c, "当前注册用户数已达上限,请请升级 License")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// 检查验证码
|
// 检查验证码
|
||||||
var key string
|
var key string
|
||||||
if data.RegWay == "email" || data.RegWay == "mobile" || data.Code != "" {
|
if data.RegWay == "email" || data.RegWay == "mobile" || data.Code != "" {
|
||||||
|
@ -166,6 +166,9 @@ func main() {
|
|||||||
fx.Provide(service.NewSmtpService),
|
fx.Provide(service.NewSmtpService),
|
||||||
// License 服务
|
// License 服务
|
||||||
fx.Provide(service.NewLicenseService),
|
fx.Provide(service.NewLicenseService),
|
||||||
|
fx.Invoke(func(licenseService *service.LicenseService) {
|
||||||
|
licenseService.SyncLicense()
|
||||||
|
}),
|
||||||
|
|
||||||
// 微信机器人服务
|
// 微信机器人服务
|
||||||
fx.Provide(wx.NewWeChatBot),
|
fx.Provide(wx.NewWeChatBot),
|
||||||
|
@ -13,10 +13,11 @@ 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
|
||||||
machineId string
|
urlWhiteList []string
|
||||||
|
machineId string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewLicenseService(server *core.AppServer, levelDB *store.LevelDB) * LicenseService {
|
func NewLicenseService(server *core.AppServer, levelDB *store.LevelDB) * LicenseService {
|
||||||
@ -28,25 +29,27 @@ func NewLicenseService(server *core.AppServer, levelDB *store.LevelDB) * License
|
|||||||
machineId = info.HostID
|
machineId = info.HostID
|
||||||
}
|
}
|
||||||
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 {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Value string `json:"license"`
|
||||||
|
Mid string `json:"mid"`
|
||||||
|
ExpiredAt int64 `json:"expired_at"`
|
||||||
|
UserNum int `json:"user_num"`
|
||||||
|
}
|
||||||
|
|
||||||
// ActiveLicense 激活 License
|
// ActiveLicense 激活 License
|
||||||
func (s *LicenseService) ActiveLicense(license string, machineId string) error {
|
func (s *LicenseService) ActiveLicense(license string, machineId string) 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"`
|
||||||
Name string `json:"name"`
|
|
||||||
License string `json:"license"`
|
|
||||||
Mid string `json:"mid"`
|
|
||||||
ExpiredAt int64 `json:"expired_at"`
|
|
||||||
UserNum int `json:"user_num"`
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
apiURL := fmt.Sprintf("%s/%s", s.config.ApiURL, "api/license/active")
|
apiURL := fmt.Sprintf("%s/%s", s.config.ApiURL, "api/license/active")
|
||||||
response, err := req.C().R().
|
response, err := req.C().R().
|
||||||
@ -75,10 +78,54 @@ func (s *LicenseService) ActiveLicense(license string, machineId string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("保存许可证书失败:%v", err)
|
return fmt.Errorf("保存许可证书失败:%v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SyncLicense 定期同步 License
|
||||||
|
func (s *LicenseService) SyncLicense() {
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
var res struct {
|
||||||
|
Code types.BizCode `json:"code"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
Data struct {
|
||||||
|
License License `json:"license"`
|
||||||
|
Urls []string `json:"urls"`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
apiURL := fmt.Sprintf("%s/%s", s.config.ApiURL, "api/license/check")
|
||||||
|
response, err := req.C().R().
|
||||||
|
SetBody(map[string]string{"license": s.license.Key, "machine_id": s.machineId}).
|
||||||
|
SetSuccessResult(&res).Post(apiURL)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("发送激活请求失败: %v", err)
|
||||||
|
goto next
|
||||||
|
}
|
||||||
|
if response.IsErrorState() {
|
||||||
|
logger.Errorf("激活失败:%v", response.Status)
|
||||||
|
goto next
|
||||||
|
}
|
||||||
|
if res.Code != types.Success {
|
||||||
|
logger.Errorf("激活失败:%v", res.Message)
|
||||||
|
s.license.IsActive = false
|
||||||
|
goto next
|
||||||
|
}
|
||||||
|
|
||||||
|
s.license = types.License{
|
||||||
|
Key: res.Data.License.Value,
|
||||||
|
MachineId: res.Data.License.Mid,
|
||||||
|
UserNum: res.Data.License.UserNum,
|
||||||
|
ExpiredAt: res.Data.License.ExpiredAt,
|
||||||
|
IsActive: true,
|
||||||
|
}
|
||||||
|
s.urlWhiteList = res.Data.Urls
|
||||||
|
logger.Debugf("同步 License 成功:%v\n%v", s.license, s.urlWhiteList)
|
||||||
|
next:
|
||||||
|
time.Sleep(time.Second * 10)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
// GetLicense 获取许可信息
|
// GetLicense 获取许可信息
|
||||||
func (s *LicenseService) GetLicense() types.License {
|
func (s *LicenseService) GetLicense() types.License {
|
||||||
return s.license
|
return s.license
|
||||||
@ -98,12 +145,10 @@ func (s *LicenseService) IsValidApiURL(uri string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if !strings.HasPrefix(uri, "https://gpt.bemore.lol") &&
|
for _, v := range s.urlWhiteList {
|
||||||
!strings.HasPrefix(uri, "https://api.openai.com") &&
|
if strings.HasPrefix(uri, v) {
|
||||||
!strings.HasPrefix(uri, "http://cdn.chat-plus.net") &&
|
return nil
|
||||||
!strings.HasPrefix(uri, "https://api.chat-plus.net") {
|
}
|
||||||
return fmt.Errorf("当前 API 地址 %s 不在白名单列表当中。",uri)
|
|
||||||
}
|
}
|
||||||
|
return fmt.Errorf("当前 API 地址 %s 不在白名单列表当中。", uri)
|
||||||
return nil
|
|
||||||
}
|
}
|
@ -73,7 +73,7 @@
|
|||||||
<el-input v-model="user.username" autocomplete="off"/>
|
<el-input v-model="user.username" autocomplete="off"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item v-if="add" label="密码:" prop="password">
|
<el-form-item v-if="add" label="密码:" prop="password">
|
||||||
<el-input v-model="user.password" autocomplete="off"/>
|
<el-input v-model="user.password" autocomplete="off" placeholder="8-16位"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="剩余算力:" prop="power">
|
<el-form-item label="剩余算力:" prop="power">
|
||||||
<el-input v-model.number="user.power" autocomplete="off" placeholder="0"/>
|
<el-input v-model.number="user.power" autocomplete="off" placeholder="0"/>
|
||||||
@ -186,8 +186,17 @@ const models = ref([])
|
|||||||
const showUserEditDialog = ref(false)
|
const showUserEditDialog = ref(false)
|
||||||
const showResetPassDialog = ref(false)
|
const showResetPassDialog = ref(false)
|
||||||
const rules = reactive({
|
const rules = reactive({
|
||||||
username: [{required: true, message: '请输入账号', trigger: 'change',}],
|
username: [{required: true, message: '请输入账号', trigger: 'blur',}],
|
||||||
password: [{required: true, message: '请输入密码', trigger: 'change',}],
|
password: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
validator: (rule, value) => {
|
||||||
|
return !(value.length > 16 || value.length < 8);
|
||||||
|
|
||||||
|
}, message: '密码必须为8-16',
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
],
|
||||||
calls: [
|
calls: [
|
||||||
{required: true, message: '请输入提问次数'},
|
{required: true, message: '请输入提问次数'},
|
||||||
{type: 'number', message: '请输入有效数字'},
|
{type: 'number', message: '请输入有效数字'},
|
||||||
|
Loading…
Reference in New Issue
Block a user