mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-31 14:08:06 +08:00
feat: Add support for multiple host license (#7296)
This commit is contained in:
parent
e5660a0d91
commit
a8170a499a
@ -9,7 +9,7 @@ import (
|
||||
)
|
||||
|
||||
func (b *BaseApi) CheckHealth(c *gin.Context) {
|
||||
_, err := xpack.RequestToMaster("/api/v2/agent/health", http.MethodGet, nil)
|
||||
_, err := xpack.RequestToMaster("/api/v2/agent/xpack/health", http.MethodGet, nil)
|
||||
if err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
|
@ -293,7 +293,7 @@ func NewBackupClientWithID(id uint) (*model.BackupAccount, cloud_storage.CloudSt
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
data, err := xpack.RequestToMaster("/api/v2/agent/backup", http.MethodPost, bytes.NewReader(bodyItem))
|
||||
data, err := xpack.RequestToMaster("/api/v2/agent/xpack/backup", http.MethodPost, bytes.NewReader(bodyItem))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@ -358,7 +358,7 @@ func NewBackupClientMap(ids []string) (map[string]backupClientHelper, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data, err := xpack.RequestToMaster("/api/v2/agent/backup/list", http.MethodPost, bytes.NewReader(bodyItem))
|
||||
data, err := xpack.RequestToMaster("/api/v2/agent/xpack/backup/list", http.MethodPost, bytes.NewReader(bodyItem))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ type System struct {
|
||||
|
||||
Version string `mapstructure:"version"`
|
||||
BaseDir string `mapstructure:"base_dir"`
|
||||
CurrentNode string `mapstructure:"base_dir"`
|
||||
MasterAddr string `mapstructure:"master_addr"`
|
||||
EncryptKey string `mapstructure:"encrypt_key"`
|
||||
|
||||
|
@ -30,7 +30,7 @@ var (
|
||||
ErrDemoEnvironment = "ErrDemoEnvironment"
|
||||
ErrCmdIllegal = "ErrCmdIllegal"
|
||||
ErrXpackNotFound = "ErrXpackNotFound"
|
||||
ErrXpackNotActive = "ErrXpackNotActive"
|
||||
ErrXpackExceptional = "ErrXpackExceptional"
|
||||
ErrXpackOutOfDate = "ErrXpackOutOfDate"
|
||||
)
|
||||
|
||||
@ -134,11 +134,3 @@ var (
|
||||
var (
|
||||
ErrNotExistUser = "ErrNotExistUser"
|
||||
)
|
||||
|
||||
// license
|
||||
var (
|
||||
ErrLicense = "ErrLicense"
|
||||
ErrLicenseCheck = "ErrLicenseCheck"
|
||||
ErrLicenseSave = "ErrLicenseSave"
|
||||
ErrLicenseSync = "ErrLicenseSync"
|
||||
)
|
||||
|
@ -240,16 +240,6 @@ cc: 'Access Frequency Limit'
|
||||
defaultUrlBlack: 'URL Rules'
|
||||
sqlInject: 'SQL Injection'
|
||||
|
||||
|
||||
#license
|
||||
ErrLicense: "License format error, please check and try again!"
|
||||
ErrLicenseCheck: "License verification failed, please check and try again!"
|
||||
ErrLicenseSave: "Failed to save license information, error {{ .err }}, please try again!"
|
||||
ErrLicenseSync: "Failed to sync license information, no license information detected in the database!"
|
||||
ErrXpackNotFound: "This section is a professional edition feature, please import the license first in Panel Settings-License interface"
|
||||
ErrXpackNotActive: "This section is a professional edition feature, please synchronize the license status first in Panel Settings-License interface"
|
||||
ErrXpackOutOfDate: "The current license has expired, please re-import the license in Panel Settings-License interface"
|
||||
|
||||
#task
|
||||
TaskStart: "{{.name}} Start [START]"
|
||||
TaskEnd: "{{.name}} End [COMPLETED]"
|
||||
|
@ -241,16 +241,6 @@ cc: '訪問頻率限制'
|
||||
defaultUrlBlack: 'URL 規則'
|
||||
sqlInject: 'SQL 注入'
|
||||
|
||||
|
||||
#license
|
||||
ErrLicense: "許可證格式錯誤,請檢查後重試!"
|
||||
ErrLicenseCheck: "許可證校驗失敗,請檢查後重試!"
|
||||
ErrLicenseSave: "許可證信息保存失敗,錯誤 {{ .err }}, 請重試!"
|
||||
ErrLicenseSync: "許可證信息同步失敗,資料庫中未檢測到許可證信息!"
|
||||
ErrXpackNotFound: "該部分為專業版功能,請先在 面板設置-許可證 界面導入許可證"
|
||||
ErrXpackNotActive: "該部分為專業版功能,請先在 面板設置-許可證 界面同步許可證狀態"
|
||||
ErrXpackOutOfDate: "當前許可證已過期,請重新在 面板設置-許可證 界面導入許可證"
|
||||
|
||||
#task
|
||||
TaskStart: "{{.name}} 開始 [START]"
|
||||
TaskEnd: "{{.name}} 結束 [COMPLETED]"
|
||||
|
@ -239,16 +239,6 @@ cc: '访问频率限制'
|
||||
defaultUrlBlack: 'URL 规则'
|
||||
sqlInject: 'SQL 注入'
|
||||
|
||||
|
||||
#license
|
||||
ErrLicense: "许可证格式错误,请检查后重试!"
|
||||
ErrLicenseCheck: "许可证校验失败,请检查后重试!"
|
||||
ErrLicenseSave: "许可证信息保存失败,错误 {{ .err }},请重试!"
|
||||
ErrLicenseSync: "许可证信息同步失败,数据库中未检测到许可证信息!"
|
||||
ErrXpackNotFound: "该部分为专业版功能,请先在 面板设置-许可证 界面导入许可证"
|
||||
ErrXpackNotActive: "该部分为专业版功能,请先在 面板设置-许可证 界面同步许可证状态"
|
||||
ErrXpackOutOfDate: "当前许可证已过期,请重新在 面板设置-许可证 界面导入许可证"
|
||||
|
||||
#task
|
||||
TaskStart: "{{.name}} 任务开始 [START]"
|
||||
TaskEnd: "{{.name}} 任务结束 [COMPLETED]"
|
||||
|
@ -33,9 +33,9 @@ func initGlobalData() {
|
||||
global.CONF.System.BaseDir, _ = settingRepo.GetValueByKey("BaseDir")
|
||||
global.CONF.System.Version, _ = settingRepo.GetValueByKey("SystemVersion")
|
||||
global.CONF.System.EncryptKey, _ = settingRepo.GetValueByKey("EncryptKey")
|
||||
currentNode, _ := settingRepo.GetValueByKey("CurrentNode")
|
||||
global.CONF.System.CurrentNode, _ = settingRepo.GetValueByKey("CurrentNode")
|
||||
|
||||
global.IsMaster = currentNode == "127.0.0.1" || len(currentNode) == 0
|
||||
global.IsMaster = global.CONF.System.CurrentNode == "127.0.0.1" || len(global.CONF.System.CurrentNode) == 0
|
||||
if global.IsMaster {
|
||||
global.CoreDB = common.LoadDBConnByPath(path.Join(global.CONF.System.DbPath, "core.db"), "core")
|
||||
} else {
|
||||
|
@ -3,6 +3,10 @@ package server
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/app/repo"
|
||||
"github.com/1Panel-dev/1Panel/agent/cron"
|
||||
"github.com/1Panel-dev/1Panel/agent/global"
|
||||
@ -18,12 +22,10 @@ import (
|
||||
"github.com/1Panel-dev/1Panel/agent/init/validator"
|
||||
"github.com/1Panel-dev/1Panel/agent/init/viper"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/encrypt"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
_ "net/http/pprof"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
_ "net/http/pprof"
|
||||
)
|
||||
|
||||
func Start() {
|
||||
@ -47,12 +49,13 @@ func Start() {
|
||||
}
|
||||
|
||||
go func() {
|
||||
http.ListenAndServe("0.0.0.0:6060", nil)
|
||||
_ = http.ListenAndServe("0.0.0.0:6060", nil)
|
||||
}()
|
||||
|
||||
if global.IsMaster {
|
||||
_ = os.Remove("/tmp/agent.sock")
|
||||
listener, err := net.Listen("unix", "/tmp/agent.sock")
|
||||
_ = os.Remove("/etc/1panel/agent.sock")
|
||||
_ = os.Mkdir("/etc/1panel", 0755)
|
||||
listener, err := net.Listen("unix", "/etc/1panel/agent.sock")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -49,7 +49,6 @@ func LoadNodeInfo() (bool, model.NodeInfo, error) {
|
||||
var info model.NodeInfo
|
||||
info.BaseDir = loadParams("BASE_DIR")
|
||||
info.Version = loadParams("ORIGINAL_VERSION")
|
||||
info.CurrentNode = "127.0.0.1"
|
||||
info.EncryptKey = common.RandStr(16)
|
||||
return false, info, nil
|
||||
}
|
||||
|
@ -8,78 +8,66 @@ import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type ICommonRepo interface {
|
||||
WithByID(id uint) global.DBOption
|
||||
WithByGroupID(id uint) global.DBOption
|
||||
|
||||
WithByName(name string) global.DBOption
|
||||
WithByType(ty string) global.DBOption
|
||||
WithByKey(key string) global.DBOption
|
||||
WithOrderBy(orderStr string) global.DBOption
|
||||
WithByStatus(status string) global.DBOption
|
||||
WithByGroupBelong(group string) global.DBOption
|
||||
|
||||
WithByIDs(ids []uint) global.DBOption
|
||||
|
||||
WithOrderRuleBy(orderBy, order string) global.DBOption
|
||||
}
|
||||
|
||||
type CommonRepo struct{}
|
||||
|
||||
func NewICommonRepo() ICommonRepo {
|
||||
return &CommonRepo{}
|
||||
}
|
||||
|
||||
func (c *CommonRepo) WithByID(id uint) global.DBOption {
|
||||
func WithByID(id uint) global.DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("id = ?", id)
|
||||
}
|
||||
}
|
||||
func (c *CommonRepo) WithByGroupID(id uint) global.DBOption {
|
||||
func WithByGroupID(id uint) global.DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("group_id = ?", id)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CommonRepo) WithByIDs(ids []uint) global.DBOption {
|
||||
func WithByIDs(ids []uint) global.DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("id in (?)", ids)
|
||||
}
|
||||
}
|
||||
func (c *CommonRepo) WithByName(name string) global.DBOption {
|
||||
func WithByName(name string) global.DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("`name` = ?", name)
|
||||
}
|
||||
}
|
||||
func WithoutByName(name string) global.DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("`name` != ?", name)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CommonRepo) WithByType(ty string) global.DBOption {
|
||||
func WithByType(ty string) global.DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("`type` = ?", ty)
|
||||
}
|
||||
}
|
||||
func (c *CommonRepo) WithByKey(key string) global.DBOption {
|
||||
func WithByAddr(addr string) global.DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("addr = ?", addr)
|
||||
}
|
||||
}
|
||||
func WithByKey(key string) global.DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("key = ?", key)
|
||||
}
|
||||
}
|
||||
func (c *CommonRepo) WithByStatus(status string) global.DBOption {
|
||||
func WithByStatus(status string) global.DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("status = ?", status)
|
||||
}
|
||||
}
|
||||
func (c *CommonRepo) WithByGroupBelong(group string) global.DBOption {
|
||||
func WithByGroupBelong(group string) global.DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("group_belong = ?", group)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CommonRepo) WithOrderBy(orderStr string) global.DBOption {
|
||||
func WithOrderBy(orderStr string) global.DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Order(orderStr)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CommonRepo) WithOrderRuleBy(orderBy, order string) global.DBOption {
|
||||
func WithOrderRuleBy(orderBy, order string) global.DBOption {
|
||||
switch order {
|
||||
case constant.OrderDesc:
|
||||
order = "desc"
|
||||
|
@ -2,6 +2,7 @@ package service
|
||||
|
||||
import (
|
||||
"github.com/1Panel-dev/1Panel/core/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/core/app/repo"
|
||||
"github.com/1Panel-dev/1Panel/core/constant"
|
||||
)
|
||||
|
||||
@ -17,7 +18,7 @@ func NewIAppLauncher() IAppLauncher {
|
||||
}
|
||||
|
||||
func (u *LauncherService) Search() ([]string, error) {
|
||||
launchers, err := launcherRepo.List(commonRepo.WithOrderBy("created_at"))
|
||||
launchers, err := launcherRepo.List(repo.WithOrderBy("created_at"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -29,7 +30,7 @@ func (u *LauncherService) Search() ([]string, error) {
|
||||
}
|
||||
|
||||
func (u *LauncherService) ChangeShow(req dto.SettingUpdate) error {
|
||||
launcher, _ := launcherRepo.Get(commonRepo.WithByKey(req.Key))
|
||||
launcher, _ := launcherRepo.Get(repo.WithByKey(req.Key))
|
||||
if req.Value == constant.StatusEnable {
|
||||
if launcher.ID != 0 {
|
||||
return nil
|
||||
@ -41,5 +42,5 @@ func (u *LauncherService) ChangeShow(req dto.SettingUpdate) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
return launcherRepo.Delete(commonRepo.WithByKey(req.Key))
|
||||
return launcherRepo.Delete(repo.WithByKey(req.Key))
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"strconv"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/core/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/core/app/repo"
|
||||
"github.com/1Panel-dev/1Panel/core/buserr"
|
||||
"github.com/1Panel-dev/1Panel/core/constant"
|
||||
"github.com/1Panel-dev/1Panel/core/global"
|
||||
@ -31,11 +32,11 @@ func NewIAuthService() IAuthService {
|
||||
}
|
||||
|
||||
func (u *AuthService) Login(c *gin.Context, info dto.Login, entrance string) (*dto.UserLoginInfo, error) {
|
||||
nameSetting, err := settingRepo.Get(commonRepo.WithByKey("UserName"))
|
||||
nameSetting, err := settingRepo.Get(repo.WithByKey("UserName"))
|
||||
if err != nil {
|
||||
return nil, errors.WithMessage(constant.ErrRecordNotFound, err.Error())
|
||||
}
|
||||
passwordSetting, err := settingRepo.Get(commonRepo.WithByKey("Password"))
|
||||
passwordSetting, err := settingRepo.Get(repo.WithByKey("Password"))
|
||||
if err != nil {
|
||||
return nil, errors.WithMessage(constant.ErrRecordNotFound, err.Error())
|
||||
}
|
||||
@ -46,14 +47,14 @@ func (u *AuthService) Login(c *gin.Context, info dto.Login, entrance string) (*d
|
||||
if !hmac.Equal([]byte(info.Password), []byte(pass)) || nameSetting.Value != info.Name {
|
||||
return nil, constant.ErrAuth
|
||||
}
|
||||
entranceSetting, err := settingRepo.Get(commonRepo.WithByKey("SecurityEntrance"))
|
||||
entranceSetting, err := settingRepo.Get(repo.WithByKey("SecurityEntrance"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(entranceSetting.Value) != 0 && entranceSetting.Value != entrance {
|
||||
return nil, buserr.New(constant.ErrEntrance)
|
||||
}
|
||||
mfa, err := settingRepo.Get(commonRepo.WithByKey("MFAStatus"))
|
||||
mfa, err := settingRepo.Get(repo.WithByKey("MFAStatus"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -67,11 +68,11 @@ func (u *AuthService) Login(c *gin.Context, info dto.Login, entrance string) (*d
|
||||
}
|
||||
|
||||
func (u *AuthService) MFALogin(c *gin.Context, info dto.MFALogin, entrance string) (*dto.UserLoginInfo, error) {
|
||||
nameSetting, err := settingRepo.Get(commonRepo.WithByKey("UserName"))
|
||||
nameSetting, err := settingRepo.Get(repo.WithByKey("UserName"))
|
||||
if err != nil {
|
||||
return nil, errors.WithMessage(constant.ErrRecordNotFound, err.Error())
|
||||
}
|
||||
passwordSetting, err := settingRepo.Get(commonRepo.WithByKey("Password"))
|
||||
passwordSetting, err := settingRepo.Get(repo.WithByKey("Password"))
|
||||
if err != nil {
|
||||
return nil, errors.WithMessage(constant.ErrRecordNotFound, err.Error())
|
||||
}
|
||||
@ -82,18 +83,18 @@ func (u *AuthService) MFALogin(c *gin.Context, info dto.MFALogin, entrance strin
|
||||
if !hmac.Equal([]byte(info.Password), []byte(pass)) || nameSetting.Value != info.Name {
|
||||
return nil, constant.ErrAuth
|
||||
}
|
||||
entranceSetting, err := settingRepo.Get(commonRepo.WithByKey("SecurityEntrance"))
|
||||
entranceSetting, err := settingRepo.Get(repo.WithByKey("SecurityEntrance"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(entranceSetting.Value) != 0 && entranceSetting.Value != entrance {
|
||||
return nil, buserr.New(constant.ErrEntrance)
|
||||
}
|
||||
mfaSecret, err := settingRepo.Get(commonRepo.WithByKey("MFASecret"))
|
||||
mfaSecret, err := settingRepo.Get(repo.WithByKey("MFASecret"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mfaInterval, err := settingRepo.Get(commonRepo.WithByKey("MFAInterval"))
|
||||
mfaInterval, err := settingRepo.Get(repo.WithByKey("MFAInterval"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -106,11 +107,11 @@ func (u *AuthService) MFALogin(c *gin.Context, info dto.MFALogin, entrance strin
|
||||
}
|
||||
|
||||
func (u *AuthService) generateSession(c *gin.Context, name, authMethod string) (*dto.UserLoginInfo, error) {
|
||||
setting, err := settingRepo.Get(commonRepo.WithByKey("SessionTimeout"))
|
||||
setting, err := settingRepo.Get(repo.WithByKey("SessionTimeout"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
httpsSetting, err := settingRepo.Get(commonRepo.WithByKey("SSL"))
|
||||
httpsSetting, err := settingRepo.Get(repo.WithByKey("SSL"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -147,7 +148,7 @@ func (u *AuthService) generateSession(c *gin.Context, name, authMethod string) (
|
||||
}
|
||||
|
||||
func (u *AuthService) LogOut(c *gin.Context) error {
|
||||
httpsSetting, err := settingRepo.Get(commonRepo.WithByKey("SSL"))
|
||||
httpsSetting, err := settingRepo.Get(repo.WithByKey("SSL"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -163,7 +164,7 @@ func (u *AuthService) LogOut(c *gin.Context) error {
|
||||
}
|
||||
|
||||
func (u *AuthService) VerifyCode(code string) (bool, error) {
|
||||
setting, err := settingRepo.Get(commonRepo.WithByKey("SecurityEntrance"))
|
||||
setting, err := settingRepo.Get(repo.WithByKey("SecurityEntrance"))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@ -171,7 +172,7 @@ func (u *AuthService) VerifyCode(code string) (bool, error) {
|
||||
}
|
||||
|
||||
func (u *AuthService) CheckIsSafety(code string) (string, error) {
|
||||
status, err := settingRepo.Get(commonRepo.WithByKey("SecurityEntrance"))
|
||||
status, err := settingRepo.Get(repo.WithByKey("SecurityEntrance"))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@ -185,7 +186,7 @@ func (u *AuthService) CheckIsSafety(code string) (string, error) {
|
||||
}
|
||||
|
||||
func (u *AuthService) GetResponsePage() (string, error) {
|
||||
pageCode, err := settingRepo.Get(commonRepo.WithByKey("NoAuthSetting"))
|
||||
pageCode, err := settingRepo.Get(repo.WithByKey("NoAuthSetting"))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
|
||||
"github.com/1Panel-dev/1Panel/core/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/core/app/model"
|
||||
"github.com/1Panel-dev/1Panel/core/app/repo"
|
||||
"github.com/1Panel-dev/1Panel/core/buserr"
|
||||
"github.com/1Panel-dev/1Panel/core/constant"
|
||||
"github.com/1Panel-dev/1Panel/core/global"
|
||||
@ -51,7 +52,7 @@ func NewIBackupService() IBackupService {
|
||||
|
||||
func (u *BackupService) Get(req dto.OperateByID) (dto.BackupInfo, error) {
|
||||
var data dto.BackupInfo
|
||||
account, err := backupRepo.Get(commonRepo.WithByID(req.ID))
|
||||
account, err := backupRepo.Get(repo.WithByID(req.ID))
|
||||
if err != nil {
|
||||
return data, err
|
||||
}
|
||||
@ -70,7 +71,7 @@ func (u *BackupService) Get(req dto.OperateByID) (dto.BackupInfo, error) {
|
||||
}
|
||||
|
||||
func (u *BackupService) List(req dto.OperateByIDs) ([]dto.BackupInfo, error) {
|
||||
accounts, err := backupRepo.List(commonRepo.WithByIDs(req.IDs), commonRepo.WithOrderBy("created_at desc"))
|
||||
accounts, err := backupRepo.List(repo.WithByIDs(req.IDs), repo.WithOrderBy("created_at desc"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -94,7 +95,7 @@ func (u *BackupService) List(req dto.OperateByIDs) ([]dto.BackupInfo, error) {
|
||||
}
|
||||
|
||||
func (u *BackupService) GetLocalDir() (string, error) {
|
||||
account, err := backupRepo.Get(commonRepo.WithByType(constant.Local))
|
||||
account, err := backupRepo.Get(repo.WithByType(constant.Local))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@ -106,7 +107,7 @@ func (u *BackupService) GetLocalDir() (string, error) {
|
||||
}
|
||||
|
||||
func (u *BackupService) LoadBackupOptions() ([]dto.BackupOption, error) {
|
||||
accounts, err := backupRepo.List(commonRepo.WithOrderBy("created_at desc"))
|
||||
accounts, err := backupRepo.List(repo.WithOrderBy("created_at desc"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -125,9 +126,9 @@ func (u *BackupService) SearchWithPage(req dto.SearchPageWithType) (int64, inter
|
||||
count, accounts, err := backupRepo.Page(
|
||||
req.Page,
|
||||
req.PageSize,
|
||||
commonRepo.WithByType(req.Type),
|
||||
commonRepo.WithByName(req.Info),
|
||||
commonRepo.WithOrderBy("created_at desc"),
|
||||
repo.WithByType(req.Type),
|
||||
repo.WithByName(req.Info),
|
||||
repo.WithOrderBy("created_at desc"),
|
||||
)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
@ -181,7 +182,7 @@ func (u *BackupService) LoadBackupClientInfo(clientType string) (dto.BackupClien
|
||||
} else {
|
||||
data.RedirectUri = constant.OneDriveRedirectURI
|
||||
}
|
||||
clientID, err := settingRepo.Get(commonRepo.WithByKey(clientIDKey))
|
||||
clientID, err := settingRepo.Get(repo.WithByKey(clientIDKey))
|
||||
if err != nil {
|
||||
return data, err
|
||||
}
|
||||
@ -190,7 +191,7 @@ func (u *BackupService) LoadBackupClientInfo(clientType string) (dto.BackupClien
|
||||
return data, err
|
||||
}
|
||||
data.ClientID = string(idItem)
|
||||
clientSecret, err := settingRepo.Get(commonRepo.WithByKey(clientIDSc))
|
||||
clientSecret, err := settingRepo.Get(repo.WithByKey(clientIDSc))
|
||||
if err != nil {
|
||||
return data, err
|
||||
}
|
||||
@ -204,7 +205,7 @@ func (u *BackupService) LoadBackupClientInfo(clientType string) (dto.BackupClien
|
||||
}
|
||||
|
||||
func (u *BackupService) Create(req dto.BackupOperate) error {
|
||||
backup, _ := backupRepo.Get(commonRepo.WithByName(req.Name))
|
||||
backup, _ := backupRepo.Get(repo.WithByName(req.Name))
|
||||
if backup.ID != 0 {
|
||||
return constant.ErrRecordExist
|
||||
}
|
||||
@ -279,7 +280,7 @@ func (u *BackupService) GetBuckets(req dto.ForBuckets) ([]interface{}, error) {
|
||||
}
|
||||
|
||||
func (u *BackupService) Delete(id uint) error {
|
||||
backup, _ := backupRepo.Get(commonRepo.WithByID(id))
|
||||
backup, _ := backupRepo.Get(repo.WithByID(id))
|
||||
if backup.ID == 0 {
|
||||
return constant.ErrRecordNotFound
|
||||
}
|
||||
@ -295,11 +296,11 @@ func (u *BackupService) Delete(id uint) error {
|
||||
return buserr.New(constant.ErrBackupInUsed)
|
||||
}
|
||||
|
||||
return backupRepo.Delete(commonRepo.WithByID(id))
|
||||
return backupRepo.Delete(repo.WithByID(id))
|
||||
}
|
||||
|
||||
func (u *BackupService) Update(req dto.BackupOperate) error {
|
||||
backup, _ := backupRepo.Get(commonRepo.WithByID(req.ID))
|
||||
backup, _ := backupRepo.Get(repo.WithByID(req.ID))
|
||||
if backup.ID == 0 {
|
||||
return constant.ErrRecordNotFound
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package service
|
||||
|
||||
import (
|
||||
"github.com/1Panel-dev/1Panel/core/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/core/app/repo"
|
||||
"github.com/1Panel-dev/1Panel/core/constant"
|
||||
"github.com/1Panel-dev/1Panel/core/global"
|
||||
"github.com/jinzhu/copier"
|
||||
@ -24,7 +25,7 @@ func NewICommandService() ICommandService {
|
||||
}
|
||||
|
||||
func (u *CommandService) List(req dto.OperateByType) ([]dto.CommandInfo, error) {
|
||||
commands, err := commandRepo.List(commonRepo.WithOrderBy("name"), commonRepo.WithByType(req.Type))
|
||||
commands, err := commandRepo.List(repo.WithOrderBy("name"), repo.WithByType(req.Type))
|
||||
if err != nil {
|
||||
return nil, constant.ErrRecordNotFound
|
||||
}
|
||||
@ -40,11 +41,11 @@ func (u *CommandService) List(req dto.OperateByType) ([]dto.CommandInfo, error)
|
||||
}
|
||||
|
||||
func (u *CommandService) SearchForTree(req dto.OperateByType) ([]dto.CommandTree, error) {
|
||||
cmdList, err := commandRepo.List(commonRepo.WithOrderBy("name"), commonRepo.WithByType(req.Type))
|
||||
cmdList, err := commandRepo.List(repo.WithOrderBy("name"), repo.WithByType(req.Type))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
groups, err := groupRepo.GetList(commonRepo.WithByType(req.Type))
|
||||
groups, err := groupRepo.GetList(repo.WithByType(req.Type))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -67,20 +68,20 @@ func (u *CommandService) SearchForTree(req dto.OperateByType) ([]dto.CommandTree
|
||||
|
||||
func (u *CommandService) SearchWithPage(req dto.SearchCommandWithPage) (int64, interface{}, error) {
|
||||
options := []global.DBOption{
|
||||
commonRepo.WithOrderRuleBy(req.OrderBy, req.Order),
|
||||
commonRepo.WithByType(req.Type),
|
||||
repo.WithOrderRuleBy(req.OrderBy, req.Order),
|
||||
repo.WithByType(req.Type),
|
||||
}
|
||||
if len(req.Info) != 0 {
|
||||
options = append(options, commandRepo.WithByInfo(req.Info))
|
||||
}
|
||||
if req.GroupID != 0 {
|
||||
options = append(options, commonRepo.WithByGroupID(req.GroupID))
|
||||
options = append(options, repo.WithByGroupID(req.GroupID))
|
||||
}
|
||||
total, commands, err := commandRepo.Page(req.Page, req.PageSize, options...)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
groups, _ := groupRepo.GetList(commonRepo.WithByType(req.Type))
|
||||
groups, _ := groupRepo.GetList(repo.WithByType(req.Type))
|
||||
var dtoCommands []dto.CommandInfo
|
||||
for _, command := range commands {
|
||||
var item dto.CommandInfo
|
||||
@ -99,7 +100,7 @@ func (u *CommandService) SearchWithPage(req dto.SearchCommandWithPage) (int64, i
|
||||
}
|
||||
|
||||
func (u *CommandService) Create(commandDto dto.CommandOperate) error {
|
||||
command, _ := commandRepo.Get(commonRepo.WithByName(commandDto.Name))
|
||||
command, _ := commandRepo.Get(repo.WithByName(commandDto.Name))
|
||||
if command.ID != 0 {
|
||||
return constant.ErrRecordExist
|
||||
}
|
||||
@ -114,13 +115,13 @@ func (u *CommandService) Create(commandDto dto.CommandOperate) error {
|
||||
|
||||
func (u *CommandService) Delete(ids []uint) error {
|
||||
if len(ids) == 1 {
|
||||
command, _ := commandRepo.Get(commonRepo.WithByID(ids[0]))
|
||||
command, _ := commandRepo.Get(repo.WithByID(ids[0]))
|
||||
if command.ID == 0 {
|
||||
return constant.ErrRecordNotFound
|
||||
}
|
||||
return commandRepo.Delete(commonRepo.WithByID(ids[0]))
|
||||
return commandRepo.Delete(repo.WithByID(ids[0]))
|
||||
}
|
||||
return commandRepo.Delete(commonRepo.WithByIDs(ids))
|
||||
return commandRepo.Delete(repo.WithByIDs(ids))
|
||||
}
|
||||
|
||||
func (u *CommandService) Update(id uint, upMap map[string]interface{}) error {
|
||||
|
@ -5,7 +5,6 @@ import "github.com/1Panel-dev/1Panel/core/app/repo"
|
||||
var (
|
||||
hostRepo = repo.NewIHostRepo()
|
||||
commandRepo = repo.NewICommandRepo()
|
||||
commonRepo = repo.NewICommonRepo()
|
||||
settingRepo = repo.NewISettingRepo()
|
||||
backupRepo = repo.NewIBackupRepo()
|
||||
logRepo = repo.NewILogRepo()
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/1Panel-dev/1Panel/core/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/core/app/model"
|
||||
"github.com/1Panel-dev/1Panel/core/app/repo"
|
||||
"github.com/1Panel-dev/1Panel/core/buserr"
|
||||
"github.com/1Panel-dev/1Panel/core/constant"
|
||||
"github.com/1Panel-dev/1Panel/core/global"
|
||||
@ -31,11 +32,11 @@ func NewIGroupService() IGroupService {
|
||||
|
||||
func (u *GroupService) List(req dto.OperateByType) ([]dto.GroupInfo, error) {
|
||||
options := []global.DBOption{
|
||||
commonRepo.WithOrderBy("is_default desc"),
|
||||
commonRepo.WithOrderBy("created_at desc"),
|
||||
repo.WithOrderBy("is_default desc"),
|
||||
repo.WithOrderBy("created_at desc"),
|
||||
}
|
||||
if len(req.Type) != 0 {
|
||||
options = append(options, commonRepo.WithByType(req.Type))
|
||||
options = append(options, repo.WithByType(req.Type))
|
||||
}
|
||||
var (
|
||||
groups []model.Group
|
||||
@ -57,7 +58,7 @@ func (u *GroupService) List(req dto.OperateByType) ([]dto.GroupInfo, error) {
|
||||
}
|
||||
|
||||
func (u *GroupService) Create(req dto.GroupCreate) error {
|
||||
group, _ := groupRepo.Get(commonRepo.WithByName(req.Name), commonRepo.WithByType(req.Type))
|
||||
group, _ := groupRepo.Get(repo.WithByName(req.Name), repo.WithByType(req.Type))
|
||||
if group.ID != 0 {
|
||||
return constant.ErrRecordExist
|
||||
}
|
||||
@ -71,14 +72,14 @@ func (u *GroupService) Create(req dto.GroupCreate) error {
|
||||
}
|
||||
|
||||
func (u *GroupService) Delete(id uint) error {
|
||||
group, _ := groupRepo.Get(commonRepo.WithByID(id))
|
||||
group, _ := groupRepo.Get(repo.WithByID(id))
|
||||
if group.ID == 0 {
|
||||
return constant.ErrRecordNotFound
|
||||
}
|
||||
if group.IsDefault {
|
||||
return buserr.New(constant.ErrGroupIsDefault)
|
||||
}
|
||||
defaultGroup, err := groupRepo.Get(commonRepo.WithByType(group.Type), groupRepo.WithByDefault(true))
|
||||
defaultGroup, err := groupRepo.Get(repo.WithByType(group.Type), groupRepo.WithByDefault(true))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -103,7 +104,7 @@ func (u *GroupService) Delete(id uint) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return groupRepo.Delete(commonRepo.WithByID(id))
|
||||
return groupRepo.Delete(repo.WithByID(id))
|
||||
}
|
||||
|
||||
func (u *GroupService) Update(req dto.GroupUpdate) error {
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
|
||||
"github.com/1Panel-dev/1Panel/core/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/core/app/model"
|
||||
"github.com/1Panel-dev/1Panel/core/app/repo"
|
||||
"github.com/1Panel-dev/1Panel/core/constant"
|
||||
"github.com/1Panel-dev/1Panel/core/global"
|
||||
"github.com/1Panel-dev/1Panel/core/utils/encrypt"
|
||||
@ -84,7 +85,7 @@ func (u *HostService) TestLocalConn(id uint) bool {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
host, err = hostRepo.Get(commonRepo.WithByID(id))
|
||||
host, err = hostRepo.Get(repo.WithByID(id))
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
@ -124,7 +125,7 @@ func (u *HostService) TestLocalConn(id uint) bool {
|
||||
}
|
||||
|
||||
func (u *HostService) GetHostInfo(id uint) (*model.Host, error) {
|
||||
host, err := hostRepo.Get(commonRepo.WithByID(id))
|
||||
host, err := hostRepo.Get(repo.WithByID(id))
|
||||
if err != nil {
|
||||
return nil, constant.ErrRecordNotFound
|
||||
}
|
||||
@ -156,7 +157,7 @@ func (u *HostService) SearchWithPage(req dto.SearchHostWithPage) (int64, interfa
|
||||
options = append(options, hostRepo.WithByInfo(req.Info))
|
||||
}
|
||||
if req.GroupID != 0 {
|
||||
options = append(options, commonRepo.WithByGroupID(req.GroupID))
|
||||
options = append(options, repo.WithByGroupID(req.GroupID))
|
||||
}
|
||||
total, hosts, err := hostRepo.Page(req.Page, req.PageSize, options...)
|
||||
if err != nil {
|
||||
@ -168,7 +169,7 @@ func (u *HostService) SearchWithPage(req dto.SearchHostWithPage) (int64, interfa
|
||||
if err := copier.Copy(&item, &host); err != nil {
|
||||
return 0, nil, errors.WithMessage(constant.ErrStructTransform, err.Error())
|
||||
}
|
||||
group, _ := groupRepo.Get(commonRepo.WithByID(host.GroupID))
|
||||
group, _ := groupRepo.Get(repo.WithByID(host.GroupID))
|
||||
item.GroupBelong = group.Name
|
||||
if !item.RememberPassword {
|
||||
item.Password = ""
|
||||
@ -204,7 +205,7 @@ func (u *HostService) SearchForTree(search dto.SearchForTree) ([]dto.HostTree, e
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
groups, err := groupRepo.GetList(commonRepo.WithByType("host"))
|
||||
groups, err := groupRepo.GetList(repo.WithByType("host"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -257,7 +258,7 @@ func (u *HostService) Create(req dto.HostOperate) (*dto.HostInfo, error) {
|
||||
return nil, errors.WithMessage(constant.ErrStructTransform, err.Error())
|
||||
}
|
||||
if req.GroupID == 0 {
|
||||
group, err := groupRepo.Get(commonRepo.WithByType("host"), groupRepo.WithByDefault(true))
|
||||
group, err := groupRepo.Get(repo.WithByType("host"), groupRepo.WithByDefault(true))
|
||||
if err != nil {
|
||||
return nil, errors.New("get default group failed")
|
||||
}
|
||||
@ -307,7 +308,7 @@ func (u *HostService) Create(req dto.HostOperate) (*dto.HostInfo, error) {
|
||||
}
|
||||
|
||||
func (u *HostService) Delete(ids []uint) error {
|
||||
hosts, _ := hostRepo.GetList(commonRepo.WithByIDs(ids))
|
||||
hosts, _ := hostRepo.GetList(repo.WithByIDs(ids))
|
||||
for _, host := range hosts {
|
||||
if host.ID == 0 {
|
||||
return constant.ErrRecordNotFound
|
||||
@ -316,7 +317,7 @@ func (u *HostService) Delete(ids []uint) error {
|
||||
return errors.New("the local connection information cannot be deleted!")
|
||||
}
|
||||
}
|
||||
return hostRepo.Delete(commonRepo.WithByIDs(ids))
|
||||
return hostRepo.Delete(repo.WithByIDs(ids))
|
||||
}
|
||||
|
||||
func (u *HostService) Update(id uint, upMap map[string]interface{}) error {
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
|
||||
"github.com/1Panel-dev/1Panel/core/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/core/app/model"
|
||||
"github.com/1Panel-dev/1Panel/core/app/repo"
|
||||
"github.com/1Panel-dev/1Panel/core/constant"
|
||||
"github.com/1Panel-dev/1Panel/core/global"
|
||||
"github.com/1Panel-dev/1Panel/core/utils/cmd"
|
||||
@ -75,13 +76,13 @@ func (u *LogService) ListSystemLogFile() ([]string, error) {
|
||||
|
||||
func (u *LogService) PageLoginLog(req dto.SearchLgLogWithPage) (int64, interface{}, error) {
|
||||
options := []global.DBOption{
|
||||
commonRepo.WithOrderBy("created_at desc"),
|
||||
repo.WithOrderBy("created_at desc"),
|
||||
}
|
||||
if len(req.IP) != 0 {
|
||||
options = append(options, logRepo.WithByIP(req.IP))
|
||||
}
|
||||
if len(req.Status) != 0 {
|
||||
options = append(options, commonRepo.WithByStatus(req.Status))
|
||||
options = append(options, repo.WithByStatus(req.Status))
|
||||
}
|
||||
total, ops, err := logRepo.PageLoginLog(
|
||||
req.Page,
|
||||
@ -105,14 +106,14 @@ func (u *LogService) CreateOperationLog(operation *model.OperationLog) error {
|
||||
|
||||
func (u *LogService) PageOperationLog(req dto.SearchOpLogWithPage) (int64, interface{}, error) {
|
||||
options := []global.DBOption{
|
||||
commonRepo.WithOrderBy("created_at desc"),
|
||||
repo.WithOrderBy("created_at desc"),
|
||||
logRepo.WithByLikeOperation(req.Operation),
|
||||
}
|
||||
if len(req.Source) != 0 {
|
||||
options = append(options, logRepo.WithBySource(req.Source))
|
||||
}
|
||||
if len(req.Status) != 0 {
|
||||
options = append(options, commonRepo.WithByStatus(req.Status))
|
||||
options = append(options, repo.WithByStatus(req.Status))
|
||||
}
|
||||
|
||||
total, ops, err := logRepo.PageOperationLog(
|
||||
|
@ -14,6 +14,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/core/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/core/app/repo"
|
||||
"github.com/1Panel-dev/1Panel/core/buserr"
|
||||
"github.com/1Panel-dev/1Panel/core/constant"
|
||||
"github.com/1Panel-dev/1Panel/core/global"
|
||||
@ -74,7 +75,7 @@ func (u *SettingService) GetSettingInfo() (*dto.SettingInfo, error) {
|
||||
func (u *SettingService) Update(key, value string) error {
|
||||
switch key {
|
||||
case "AppStoreLastModified":
|
||||
exist, _ := settingRepo.Get(commonRepo.WithByKey("AppStoreLastModified"))
|
||||
exist, _ := settingRepo.Get(repo.WithByKey("AppStoreLastModified"))
|
||||
if exist.ID == 0 {
|
||||
_ = settingRepo.Create("AppStoreLastModified", value)
|
||||
return nil
|
||||
@ -270,14 +271,14 @@ func (u *SettingService) UpdateSSL(c *gin.Context, req dto.SSLUpdate) error {
|
||||
}
|
||||
|
||||
func (u *SettingService) LoadFromCert() (*dto.SSLInfo, error) {
|
||||
ssl, err := settingRepo.Get(commonRepo.WithByKey("SSL"))
|
||||
ssl, err := settingRepo.Get(repo.WithByKey("SSL"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if ssl.Value == "disable" {
|
||||
return &dto.SSLInfo{}, nil
|
||||
}
|
||||
sslType, err := settingRepo.Get(commonRepo.WithByKey("SSLType"))
|
||||
sslType, err := settingRepo.Get(repo.WithByKey("SSLType"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -311,7 +312,7 @@ func (u *SettingService) LoadFromCert() (*dto.SSLInfo, error) {
|
||||
}
|
||||
|
||||
func (u *SettingService) HandlePasswordExpired(c *gin.Context, old, new string) error {
|
||||
setting, err := settingRepo.Get(commonRepo.WithByKey("Password"))
|
||||
setting, err := settingRepo.Get(repo.WithByKey("Password"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -328,7 +329,7 @@ func (u *SettingService) HandlePasswordExpired(c *gin.Context, old, new string)
|
||||
return err
|
||||
}
|
||||
|
||||
expiredSetting, err := settingRepo.Get(commonRepo.WithByKey("ExpirationDays"))
|
||||
expiredSetting, err := settingRepo.Get(repo.WithByKey("ExpirationDays"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package service
|
||||
|
||||
import (
|
||||
"github.com/1Panel-dev/1Panel/core/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/core/app/repo"
|
||||
"github.com/1Panel-dev/1Panel/core/global"
|
||||
)
|
||||
|
||||
@ -17,13 +18,13 @@ func NewITaskService() ITaskLogService {
|
||||
|
||||
func (u *TaskLogService) Page(req dto.SearchTaskLogReq) (int64, []dto.TaskDTO, error) {
|
||||
opts := []global.DBOption{
|
||||
commonRepo.WithOrderBy("created_at desc"),
|
||||
repo.WithOrderBy("created_at desc"),
|
||||
}
|
||||
if req.Status != "" {
|
||||
opts = append(opts, commonRepo.WithByStatus(req.Status))
|
||||
opts = append(opts, repo.WithByStatus(req.Status))
|
||||
}
|
||||
if req.Type != "" {
|
||||
opts = append(opts, commonRepo.WithByType(req.Type))
|
||||
opts = append(opts, repo.WithByType(req.Type))
|
||||
}
|
||||
|
||||
total, tasks, err := taskRepo.Page(
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
|
||||
"github.com/1Panel-dev/1Panel/core/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/core/app/model"
|
||||
"github.com/1Panel-dev/1Panel/core/app/repo"
|
||||
"github.com/1Panel-dev/1Panel/core/constant"
|
||||
"github.com/1Panel-dev/1Panel/core/global"
|
||||
"github.com/1Panel-dev/1Panel/core/utils/cmd"
|
||||
@ -35,11 +36,11 @@ func NewIUpgradeService() IUpgradeService {
|
||||
|
||||
func (u *UpgradeService) SearchUpgrade() (*dto.UpgradeInfo, error) {
|
||||
var upgrade dto.UpgradeInfo
|
||||
currentVersion, err := settingRepo.Get(commonRepo.WithByKey("SystemVersion"))
|
||||
currentVersion, err := settingRepo.Get(repo.WithByKey("SystemVersion"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
DeveloperMode, err := settingRepo.Get(commonRepo.WithByKey("DeveloperMode"))
|
||||
DeveloperMode, err := settingRepo.Get(repo.WithByKey("DeveloperMode"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -167,7 +168,7 @@ func (u *UpgradeService) Upgrade(req dto.Upgrade) error {
|
||||
}
|
||||
|
||||
func (u *UpgradeService) Rollback(req dto.OperateByID) error {
|
||||
log, _ := upgradeLogRepo.Get(commonRepo.WithByID(req.ID))
|
||||
log, _ := upgradeLogRepo.Get(repo.WithByID(req.ID))
|
||||
if log.ID == 0 {
|
||||
return constant.ErrRecordNotFound
|
||||
}
|
||||
|
@ -38,6 +38,18 @@ func New(Key string) BusinessError {
|
||||
}
|
||||
}
|
||||
|
||||
func WithErr(Key string, err error) BusinessError {
|
||||
paramMap := map[string]interface{}{}
|
||||
if err != nil {
|
||||
paramMap["err"] = err
|
||||
}
|
||||
return BusinessError{
|
||||
Msg: Key,
|
||||
Map: paramMap,
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
|
||||
func WithDetail(Key string, detail interface{}, err error) BusinessError {
|
||||
return BusinessError{
|
||||
Msg: Key,
|
||||
|
@ -50,6 +50,14 @@ var (
|
||||
ErrEntrance = "ErrEntrance"
|
||||
ErrProxy = "ErrProxy"
|
||||
ErrLocalDelete = "ErrLocalDelete"
|
||||
|
||||
ErrXpackNotFound = "ErrXpackNotFound"
|
||||
ErrXpackExceptional = "ErrXpackExceptional"
|
||||
ErrXpackLost = "ErrXpackLost"
|
||||
ErrXpackTimeout = "ErrXpackTimeout"
|
||||
ErrXpackOutOfDate = "ErrXpackOutOfDate"
|
||||
ErrNoSuchNode = "ErrNoSuchNode"
|
||||
ErrNodeUnbind = "ErrNodeUnbind"
|
||||
)
|
||||
|
||||
// backup
|
||||
@ -58,3 +66,14 @@ var (
|
||||
ErrBackupLocalDelete = "ErrBackupLocalDelete"
|
||||
ErrMasterAddr = "ErrMasterAddr"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrLicense = "ErrLicense"
|
||||
ErrLicenseCheck = "ErrLicenseCheck"
|
||||
ErrLicenseSave = "ErrLicenseSave"
|
||||
ErrLicenseSync = "ErrLicenseSync"
|
||||
ErrUnbindMaster = "ErrUnbindMaster"
|
||||
ErrFreeNodeLimit = "ErrFreeNodeLimit"
|
||||
ErrNodeBound = "ErrNodeBound"
|
||||
ErrNodeBind = "ErrNodeBind"
|
||||
)
|
||||
|
@ -14,4 +14,9 @@ const (
|
||||
StatusUnhealthy = "unhealthy"
|
||||
StatusUpgrading = "upgrading"
|
||||
StatusRunning = "running"
|
||||
StatusFree = "free"
|
||||
StatusBound = "bound"
|
||||
StatusExceptional = "exceptional"
|
||||
StatusRetrying = "retrying"
|
||||
StatusLost = "lost"
|
||||
)
|
||||
|
@ -30,6 +30,23 @@ ErrBackupInUsed: "The backup account is currently in use in a scheduled task and
|
||||
ErrBackupCheck: "Backup account test connection failed {{.err}}"
|
||||
ErrBackupLocalDelete: "Deleting local server backup accounts is not currently supported."
|
||||
|
||||
#license
|
||||
ErrLicense: "License format error, please check and try again!"
|
||||
ErrLicenseCheck: "License verification failed, please check and try again!"
|
||||
ErrLicenseSave: "Failed to save license information, error {{ .err }}, please try again!"
|
||||
ErrLicenseSync: "Failed to sync license information, no license information detected in the database!"
|
||||
ErrXpackNotFound: "This section is a professional edition feature, please import the license first in Panel Settings-License interface"
|
||||
ErrXpackExceptional: "This section is a professional edition feature, please synchronize the license status first in Panel Settings-License interface"
|
||||
ErrXpackOutOfDate: "The current license has expired, please re-import the license in Panel Settings-License interface"
|
||||
ErrXpackLost: "The license has reached the maximum number of retry attempts. Please go to the [Settings] [License] page and manually click the sync button to ensure that the professional version features are functioning properly."
|
||||
ErrXpackTimeout: "Request timed out, the network connection may be unstable, please try again later!"
|
||||
ErrUnbindMaster: "Detected that there are nodes in the node management, unable to unbind the current license. Please remove them first and try again!"
|
||||
ErrFreeNodeLimit: "The number of nodes for the community edition has reached the free limit. Please visit www.lxware.cn/1panel to purchase and try again!"
|
||||
ErrNodeBound: "This license is already bound to another node. Please check and try again!"
|
||||
ErrNoSuchNode: "Failed to find the node information. Please check and try again!"
|
||||
ErrNodeUnbind: "Detected that this node is no longer within the license binding range. Please check and try again!"
|
||||
ErrNodeBind: "The node is already bound to a license. Please check and try again!"
|
||||
|
||||
#task
|
||||
TaskStart: "{{.name}} Task Start [START]"
|
||||
TaskEnd: "{{.name}} Task End [COMPLETED]"
|
||||
|
@ -30,6 +30,23 @@ ErrBackupInUsed: "該備份帳號已在計劃任務中使用,無法刪除"
|
||||
ErrBackupCheck: "備份帳號測試連接失敗 {{.err}}"
|
||||
ErrBackupLocalDelete: "暫不支持刪除本地伺服器備份帳號"
|
||||
|
||||
#license
|
||||
ErrLicense: "許可證格式錯誤,請檢查後重試!"
|
||||
ErrLicenseCheck: "許可證校驗失敗,請檢查後重試!"
|
||||
ErrLicenseSave: "許可證信息保存失敗,錯誤 {{ .err }}, 請重試!"
|
||||
ErrLicenseSync: "許可證信息同步失敗,資料庫中未檢測到許可證信息!"
|
||||
ErrXpackNotFound: "該部分為專業版功能,請先在 面板設置-許可證 界面導入許可證"
|
||||
ErrXpackExceptional: "該部分為專業版功能,請先在 面板設置-許可證 界面同步許可證狀態"
|
||||
ErrXpackOutOfDate: "當前許可證已過期,請重新在 面板設置-許可證 界面導入許可證"
|
||||
ErrXpackLost: "許可證已達到最大重試次數,請進入【面板設定】【許可證】頁面手動點擊同步按鈕,以確保專業版功能正常使用"
|
||||
ErrXpackTimeout: "請求超時,網絡連接可能不穩定,請稍後再試!"
|
||||
ErrUnbindMaster: "檢測到節點管理內存在節點,無法解綁當前許可證,請先移除後重試!"
|
||||
ErrFreeNodeLimit: "社區版節點數量已達到免費上限,請前往 www.lxware.cn/1panel 購買後重試!"
|
||||
ErrNodeBound: "該許可證已綁定到其他節點,請檢查後重試!"
|
||||
ErrNoSuchNode: "未能找到該節點信息,請檢查後重試!"
|
||||
ErrNodeUnbind: "檢測到該節點未在許可證綁定範圍內,請檢查後重試!"
|
||||
ErrNodeBind: "檢測到該節點已綁定許可證,請檢查後重試!"
|
||||
|
||||
#task
|
||||
TaskStart: "{{.name}} 任務開始 [START]"
|
||||
TaskEnd: "{{.name}} 任務結束 [COMPLETED]"
|
||||
|
@ -32,7 +32,23 @@ ErrBackupInUsed: "该备份账号已在计划任务中使用,无法删除"
|
||||
ErrBackupCheck: "备份账号测试连接失败 {{ .err}}"
|
||||
ErrBackupLocalDelete: "暂不支持删除本地服务器备份账号"
|
||||
|
||||
#task
|
||||
#license
|
||||
ErrLicense: "许可证格式错误,请检查后重试!"
|
||||
ErrLicenseCheck: "许可证校验失败,请检查后重试!"
|
||||
ErrLicenseSave: "许可证信息保存失败,错误 {{ .err }},请重试!"
|
||||
ErrLicenseSync: "许可证信息同步失败,数据库中未检测到许可证信息!"
|
||||
ErrXpackNotFound: "该部分为专业版功能,请先在 面板设置-许可证 界面导入许可证"
|
||||
ErrXpackExceptional: "该部分为专业版功能,请先在 面板设置-许可证 界面同步许可证状态"
|
||||
ErrXpackOutOfDate: "当前许可证已过期,请重新在 面板设置-许可证 界面导入许可证"
|
||||
ErrXpackLost: "许可证已达到最大重试次数,请进入【面板设置】【许可证】页面手动点击同步按钮,以确保专业版功能正常使用"
|
||||
ErrXpackTimeout: "请求超时,网络连接可能不稳定,请稍后再试!"
|
||||
ErrUnbindMaster: "检测到节点管理内存在节点,无法解绑当前许可证,请先移除后重试!"
|
||||
ErrFreeNodeLimit: "社区版节点数量已达到免费上限,请前往 www.lxware.cn/1panel 购买后重试!"
|
||||
ErrNodeBound: "该许可证已绑定到其他节点,请检查后重试!"
|
||||
ErrNoSuchNode: "未能找到该节点信息,请检查后重试!"
|
||||
ErrNodeUnbind: "检测到该节点未在许可证绑定范围内,请检查后重试!"
|
||||
ErrNodeBind: "检测到该节点已绑定许可证,请检查后重试!"
|
||||
|
||||
#task
|
||||
TaskStart: "{{.name}} 任务开始 [START]"
|
||||
TaskEnd: "{{.name}} 任务结束 [COMPLETED]"
|
||||
|
@ -1,89 +1,13 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"time"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/core/global"
|
||||
"github.com/glebarez/sqlite"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
"github.com/1Panel-dev/1Panel/core/utils/common"
|
||||
)
|
||||
|
||||
func Init() {
|
||||
initDB()
|
||||
initTaskDB()
|
||||
}
|
||||
|
||||
func initDB() {
|
||||
dbPath := path.Join(global.CONF.System.BaseDir, "1panel/db")
|
||||
if _, err := os.Stat(dbPath); err != nil {
|
||||
if err := os.MkdirAll(dbPath, os.ModePerm); err != nil {
|
||||
panic(fmt.Errorf("init db dir failed, err: %v", err))
|
||||
}
|
||||
}
|
||||
fullPath := path.Join(dbPath, global.CONF.System.DbCoreFile)
|
||||
if _, err := os.Stat(fullPath); err != nil {
|
||||
f, err := os.Create(fullPath)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("init db file failed, err: %v", err))
|
||||
}
|
||||
_ = f.Close()
|
||||
}
|
||||
|
||||
db, err := NewDBWithPath(fullPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
global.DB = db
|
||||
global.LOG.Info("init db successfully")
|
||||
}
|
||||
|
||||
func initTaskDB() {
|
||||
fullPath := path.Join(global.CONF.System.BaseDir, "1panel/db/task.db")
|
||||
if _, err := os.Stat(fullPath); err != nil {
|
||||
f, err := os.Create(fullPath)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("init task db file failed, err: %v", err))
|
||||
}
|
||||
_ = f.Close()
|
||||
}
|
||||
|
||||
db, err := NewDBWithPath(fullPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
global.TaskDB = db
|
||||
global.LOG.Info("init task db successfully")
|
||||
}
|
||||
|
||||
func NewDBWithPath(dbPath string) (*gorm.DB, error) {
|
||||
db, _ := gorm.Open(sqlite.Open(dbPath), &gorm.Config{
|
||||
DisableForeignKeyConstraintWhenMigrating: true,
|
||||
Logger: getLogger(),
|
||||
})
|
||||
sqlDB, dbError := db.DB()
|
||||
if dbError != nil {
|
||||
return nil, dbError
|
||||
}
|
||||
sqlDB.SetConnMaxIdleTime(10)
|
||||
sqlDB.SetMaxOpenConns(100)
|
||||
sqlDB.SetConnMaxLifetime(time.Hour)
|
||||
return db, nil
|
||||
}
|
||||
func getLogger() logger.Interface {
|
||||
return logger.New(
|
||||
log.New(os.Stdout, "\r\n", log.LstdFlags),
|
||||
logger.Config{
|
||||
SlowThreshold: time.Second,
|
||||
LogLevel: logger.Silent,
|
||||
IgnoreRecordNotFoundError: true,
|
||||
Colorful: false,
|
||||
},
|
||||
)
|
||||
global.DB = common.LoadDBConnByPath(path.Join(global.CONF.System.BaseDir, "1panel/db/core.db"), "core")
|
||||
global.TaskDB = common.LoadDBConnByPath(path.Join(global.CONF.System.BaseDir, "1panel/db/task.db"), "task")
|
||||
}
|
||||
|
@ -14,39 +14,38 @@ import (
|
||||
|
||||
func Init() {
|
||||
settingRepo := repo.NewISettingRepo()
|
||||
commonRepo := repo.NewICommonRepo()
|
||||
masterSetting, err := settingRepo.Get(commonRepo.WithByKey("MasterAddr"))
|
||||
masterSetting, err := settingRepo.Get(repo.WithByKey("MasterAddr"))
|
||||
if err != nil {
|
||||
global.LOG.Errorf("load master addr from setting failed, err: %v", err)
|
||||
}
|
||||
global.CONF.System.MasterAddr = masterSetting.Value
|
||||
portSetting, err := settingRepo.Get(commonRepo.WithByKey("ServerPort"))
|
||||
portSetting, err := settingRepo.Get(repo.WithByKey("ServerPort"))
|
||||
if err != nil {
|
||||
global.LOG.Errorf("load service port from setting failed, err: %v", err)
|
||||
}
|
||||
global.CONF.System.Port = portSetting.Value
|
||||
ipv6Setting, err := settingRepo.Get(commonRepo.WithByKey("Ipv6"))
|
||||
ipv6Setting, err := settingRepo.Get(repo.WithByKey("Ipv6"))
|
||||
if err != nil {
|
||||
global.LOG.Errorf("load ipv6 status from setting failed, err: %v", err)
|
||||
}
|
||||
global.CONF.System.Ipv6 = ipv6Setting.Value
|
||||
bindAddressSetting, err := settingRepo.Get(commonRepo.WithByKey("BindAddress"))
|
||||
bindAddressSetting, err := settingRepo.Get(repo.WithByKey("BindAddress"))
|
||||
if err != nil {
|
||||
global.LOG.Errorf("load bind address from setting failed, err: %v", err)
|
||||
}
|
||||
global.CONF.System.BindAddress = bindAddressSetting.Value
|
||||
sslSetting, err := settingRepo.Get(commonRepo.WithByKey("SSL"))
|
||||
sslSetting, err := settingRepo.Get(repo.WithByKey("SSL"))
|
||||
if err != nil {
|
||||
global.LOG.Errorf("load service ssl from setting failed, err: %v", err)
|
||||
}
|
||||
global.CONF.System.SSL = sslSetting.Value
|
||||
versionSetting, err := settingRepo.Get(commonRepo.WithByKey("SystemVersion"))
|
||||
versionSetting, err := settingRepo.Get(repo.WithByKey("SystemVersion"))
|
||||
if err != nil {
|
||||
global.LOG.Errorf("load version from setting failed, err: %v", err)
|
||||
}
|
||||
global.CONF.System.Version = versionSetting.Value
|
||||
|
||||
if _, err := settingRepo.Get(commonRepo.WithByKey("SystemStatus")); err != nil {
|
||||
if _, err := settingRepo.Get(repo.WithByKey("SystemStatus")); err != nil {
|
||||
_ = settingRepo.Create("SystemStatus", "Free")
|
||||
}
|
||||
if err := settingRepo.Update("SystemStatus", "Free"); err != nil {
|
||||
|
@ -13,8 +13,7 @@ import (
|
||||
func BindDomain() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
settingRepo := repo.NewISettingRepo()
|
||||
commonRepo := repo.NewICommonRepo()
|
||||
status, err := settingRepo.Get(commonRepo.WithByKey("BindDomain"))
|
||||
status, err := settingRepo.Get(repo.WithByKey("BindDomain"))
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
|
@ -8,8 +8,7 @@ import (
|
||||
|
||||
func LoadErrCode(errInfo string) int {
|
||||
settingRepo := repo.NewISettingRepo()
|
||||
commonRepo := repo.NewICommonRepo()
|
||||
codeVal, err := settingRepo.Get(commonRepo.WithByKey("NoAuthSetting"))
|
||||
codeVal, err := settingRepo.Get(repo.WithByKey("NoAuthSetting"))
|
||||
if err != nil {
|
||||
return 500
|
||||
}
|
||||
|
@ -15,8 +15,7 @@ import (
|
||||
func WhiteAllow() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
settingRepo := repo.NewISettingRepo()
|
||||
commonRepo := repo.NewICommonRepo()
|
||||
status, err := settingRepo.Get(commonRepo.WithByKey("AllowIPs"))
|
||||
status, err := settingRepo.Get(repo.WithByKey("AllowIPs"))
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
|
@ -10,8 +10,7 @@ import (
|
||||
func GlobalLoading() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
settingRepo := repo.NewISettingRepo()
|
||||
commonRepo := repo.NewICommonRepo()
|
||||
status, err := settingRepo.Get(commonRepo.WithByKey("SystemStatus"))
|
||||
status, err := settingRepo.Get(repo.WithByKey("SystemStatus"))
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
|
@ -21,8 +21,7 @@ func PasswordExpired() gin.HandlerFunc {
|
||||
return
|
||||
}
|
||||
settingRepo := repo.NewISettingRepo()
|
||||
commonRepo := repo.NewICommonRepo()
|
||||
setting, err := settingRepo.Get(commonRepo.WithByKey("ExpirationDays"))
|
||||
setting, err := settingRepo.Get(repo.WithByKey("ExpirationDays"))
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypePasswordExpired, err)
|
||||
return
|
||||
@ -33,7 +32,7 @@ func PasswordExpired() gin.HandlerFunc {
|
||||
return
|
||||
}
|
||||
|
||||
extime, err := settingRepo.Get(commonRepo.WithByKey("ExpirationTime"))
|
||||
extime, err := settingRepo.Get(repo.WithByKey("ExpirationTime"))
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypePasswordExpired, err)
|
||||
return
|
||||
|
@ -16,24 +16,18 @@ import (
|
||||
|
||||
func Proxy() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
if strings.HasPrefix(c.Request.URL.Path, "/api/v2/core") || strings.HasPrefix(c.Request.URL.Path, "/1panel/swagger") {
|
||||
if strings.HasPrefix(c.Request.URL.Path, "/1panel/swagger") || !strings.HasPrefix(c.Request.URL.Path, "/api/v2") {
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
if !strings.HasPrefix(c.Request.URL.Path, "/api/v2") {
|
||||
if strings.HasPrefix(c.Request.URL.Path, "/api/v2/core") && !strings.HasPrefix(c.Request.URL.Path, "/api/v2/core/xpack") {
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
|
||||
currentNode := c.Request.Header.Get("CurrentNode")
|
||||
if len(currentNode) != 0 && currentNode != "127.0.0.1" {
|
||||
if err := xpack.Proxy(c, currentNode); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrProxy, err)
|
||||
return
|
||||
}
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
sockPath := "/tmp/agent.sock"
|
||||
if !strings.HasPrefix(c.Request.URL.Path, "/api/v2/core") && (currentNode == "local" || len(currentNode) == 0) {
|
||||
sockPath := "/etc/1panel/agent.sock"
|
||||
if _, err := os.Stat(sockPath); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrProxy, err)
|
||||
return
|
||||
@ -55,5 +49,10 @@ func Proxy() gin.HandlerFunc {
|
||||
}
|
||||
proxy.ServeHTTP(c.Writer, c.Request)
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
xpack.Proxy(c, currentNode)
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -27,14 +27,13 @@ func SessionAuth() gin.HandlerFunc {
|
||||
return
|
||||
}
|
||||
settingRepo := repo.NewISettingRepo()
|
||||
commonRepo := repo.NewICommonRepo()
|
||||
setting, err := settingRepo.Get(commonRepo.WithByKey("SessionTimeout"))
|
||||
setting, err := settingRepo.Get(repo.WithByKey("SessionTimeout"))
|
||||
if err != nil {
|
||||
global.LOG.Errorf("create operation record failed, err: %v", err)
|
||||
return
|
||||
}
|
||||
lifeTime, _ := strconv.Atoi(setting.Value)
|
||||
httpsSetting, err := settingRepo.Get(commonRepo.WithByKey("SSL"))
|
||||
httpsSetting, err := settingRepo.Get(repo.WithByKey("SSL"))
|
||||
if err != nil {
|
||||
global.LOG.Errorf("create operation record failed, err: %v", err)
|
||||
return
|
||||
|
@ -4,10 +4,13 @@ import (
|
||||
"fmt"
|
||||
mathRand "math/rand"
|
||||
"net"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/core/global"
|
||||
"github.com/1Panel-dev/1Panel/core/utils/cmd"
|
||||
)
|
||||
|
||||
@ -120,3 +123,23 @@ func LoadArch() (string, error) {
|
||||
}
|
||||
return "", fmt.Errorf("unsupported such arch: %s", std)
|
||||
}
|
||||
|
||||
func Clean(str []byte) {
|
||||
for i := 0; i < len(str); i++ {
|
||||
str[i] = 0
|
||||
}
|
||||
}
|
||||
|
||||
func CreateDirWhenNotExist(isDir bool, pathItem string) (string, error) {
|
||||
checkPath := pathItem
|
||||
if !isDir {
|
||||
checkPath = path.Dir(pathItem)
|
||||
}
|
||||
if _, err := os.Stat(checkPath); err != nil && os.IsNotExist(err) {
|
||||
if err = os.MkdirAll(checkPath, os.ModePerm); err != nil {
|
||||
global.LOG.Errorf("mkdir %s failed, err: %v", checkPath, err)
|
||||
return pathItem, err
|
||||
}
|
||||
}
|
||||
return pathItem, nil
|
||||
}
|
||||
|
86
core/utils/common/sqlite.go
Normal file
86
core/utils/common/sqlite.go
Normal file
@ -0,0 +1,86 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"time"
|
||||
|
||||
"github.com/glebarez/sqlite"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
)
|
||||
|
||||
func LoadDBConnByPath(fullPath, dbName string) *gorm.DB {
|
||||
if _, err := CreateDirWhenNotExist(true, path.Dir(fullPath)); err != nil {
|
||||
panic(fmt.Errorf("init db dir failed, err: %v", err))
|
||||
}
|
||||
if _, err := os.Stat(fullPath); err != nil {
|
||||
f, err := os.Create(fullPath)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("init %s db file failed, err: %v", dbName, err))
|
||||
}
|
||||
_ = f.Close()
|
||||
}
|
||||
|
||||
db, err := GetDBWithPath(fullPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return db
|
||||
}
|
||||
|
||||
func LoadDBConnByPathWithErr(fullPath, dbName string) (*gorm.DB, error) {
|
||||
if _, err := CreateDirWhenNotExist(true, path.Dir(fullPath)); err != nil {
|
||||
return nil, fmt.Errorf("init db dir failed, err: %v", err)
|
||||
}
|
||||
if _, err := os.Stat(fullPath); err != nil {
|
||||
f, err := os.Create(fullPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("init %s db file failed, err: %v", dbName, err)
|
||||
}
|
||||
_ = f.Close()
|
||||
}
|
||||
|
||||
db, err := GetDBWithPath(fullPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("init %s db failed, err: %v", dbName, err)
|
||||
}
|
||||
return db, nil
|
||||
}
|
||||
|
||||
func CloseDB(db *gorm.DB) {
|
||||
sqlDB, err := db.DB()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
_ = sqlDB.Close()
|
||||
}
|
||||
|
||||
func GetDBWithPath(dbPath string) (*gorm.DB, error) {
|
||||
db, _ := gorm.Open(sqlite.Open(dbPath), &gorm.Config{
|
||||
DisableForeignKeyConstraintWhenMigrating: true,
|
||||
Logger: newLogger(),
|
||||
})
|
||||
sqlDB, dbError := db.DB()
|
||||
if dbError != nil {
|
||||
return nil, dbError
|
||||
}
|
||||
sqlDB.SetConnMaxIdleTime(10)
|
||||
sqlDB.SetMaxOpenConns(100)
|
||||
sqlDB.SetConnMaxLifetime(time.Hour)
|
||||
return db, nil
|
||||
}
|
||||
|
||||
func newLogger() logger.Interface {
|
||||
return logger.New(
|
||||
log.New(os.Stdout, "\r\n", log.LstdFlags),
|
||||
logger.Config{
|
||||
SlowThreshold: time.Second,
|
||||
LogLevel: logger.Silent,
|
||||
IgnoreRecordNotFoundError: true,
|
||||
Colorful: false,
|
||||
},
|
||||
)
|
||||
}
|
@ -14,7 +14,7 @@ import (
|
||||
)
|
||||
|
||||
func NewLocalClient(reqUrl, reqMethod string, body io.Reader) (interface{}, error) {
|
||||
sockPath := "/tmp/agent.sock"
|
||||
sockPath := "/etc/1panel/agent.sock"
|
||||
if _, err := os.Stat(sockPath); err != nil {
|
||||
return nil, fmt.Errorf("no such agent.sock find in localhost, err: %v", err)
|
||||
}
|
||||
|
@ -27,8 +27,7 @@ type BaseClaims struct {
|
||||
|
||||
func NewJWT() *JWT {
|
||||
settingRepo := repo.NewISettingRepo()
|
||||
commonRepo := repo.NewICommonRepo()
|
||||
jwtSign, _ := settingRepo.Get(commonRepo.WithByKey("JWTSigningKey"))
|
||||
jwtSign, _ := settingRepo.Get(repo.WithByKey("JWTSigningKey"))
|
||||
return &JWT{
|
||||
[]byte(jwtSign.Value),
|
||||
}
|
||||
|
@ -6,8 +6,8 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func Proxy(c *gin.Context, currentNode string) error {
|
||||
return nil
|
||||
func Proxy(c *gin.Context, currentNode string) {
|
||||
return
|
||||
}
|
||||
|
||||
func UpdateGroup(name string, group, newGroup uint) error {
|
||||
|
@ -224,4 +224,9 @@ export namespace Setting {
|
||||
productPro: string;
|
||||
status: string;
|
||||
}
|
||||
export interface NodeItem {
|
||||
id: number;
|
||||
addr: string;
|
||||
status: string;
|
||||
}
|
||||
}
|
||||
|
@ -1,24 +1,39 @@
|
||||
import http from '@/api';
|
||||
import { deepCopy } from '@/utils/util';
|
||||
import { Base64 } from 'js-base64';
|
||||
import { ResPage, SearchWithPage, DescriptionUpdate } from '../interface';
|
||||
import { ResPage, SearchWithPage, DescriptionUpdate, ReqPage } from '../interface';
|
||||
import { Setting } from '../interface/setting';
|
||||
|
||||
// license
|
||||
export const UploadFileData = (params: FormData) => {
|
||||
return http.upload('/xpack/licenses/upload', params);
|
||||
return http.upload('/core/licenses/upload', params);
|
||||
};
|
||||
export const getLicense = () => {
|
||||
return http.get<Setting.License>(`/xpack/licenses/get`);
|
||||
export const SearchLicense = (params: ReqPage) => {
|
||||
return http.post<ResPage<Setting.License>>('/core/licenses/search', params);
|
||||
};
|
||||
export const DeleteLicense = (id: number, force: boolean) => {
|
||||
return http.post('/core/licenses/del', { id: id, force: force });
|
||||
};
|
||||
export const getLicenseStatus = () => {
|
||||
return http.get<Setting.LicenseStatus>(`/xpack/licenses/get/status`);
|
||||
return http.get<Setting.LicenseStatus>(`/core/licenses/status`);
|
||||
};
|
||||
export const syncLicense = () => {
|
||||
return http.post(`/xpack/licenses/sync`);
|
||||
export const getMasterLicenseStatus = () => {
|
||||
return http.get<Setting.LicenseStatus>(`/core/licenses/master/status`);
|
||||
};
|
||||
export const unbindLicense = () => {
|
||||
return http.post(`/xpack/licenses/unbind`);
|
||||
export const syncLicense = (id: number) => {
|
||||
return http.post(`/core/licenses/sync`, { id: id });
|
||||
};
|
||||
export const bindLicense = (id: number, nodeID: number) => {
|
||||
return http.post(`/core/licenses/bind`, { nodeID: nodeID, licenseID: id });
|
||||
};
|
||||
export const unbindLicense = (id: number) => {
|
||||
return http.post(`/core/licenses/unbind`, { id: id });
|
||||
};
|
||||
export const loadLicenseOptions = () => {
|
||||
return http.get(`/core/licenses/options`);
|
||||
};
|
||||
export const listNodeOptions = () => {
|
||||
return http.get<Array<Setting.NodeItem>>(`/core/nodes/list`);
|
||||
};
|
||||
|
||||
// agent
|
||||
|
@ -15,7 +15,7 @@
|
||||
<el-divider direction="vertical" />
|
||||
</span>
|
||||
<el-button type="primary" link @click="toHalo">
|
||||
<span class="font-normal">{{ isProductPro ? $t('license.pro') : $t('license.community') }}</span>
|
||||
<span class="font-normal">{{ isMasterProductPro ? $t('license.pro') : $t('license.community') }}</span>
|
||||
</el-button>
|
||||
<span class="version">{{ version }}</span>
|
||||
<el-badge is-dot style="margin-top: -3px" v-if="version !== 'Waiting' && globalStore.hasNewVersion">
|
||||
@ -49,7 +49,7 @@ const globalStore = GlobalStore();
|
||||
const upgradeRef = ref();
|
||||
|
||||
const version = ref<string>('');
|
||||
const isProductPro = ref();
|
||||
const isMasterProductPro = ref();
|
||||
const loading = ref(false);
|
||||
const upgradeInfo = ref();
|
||||
const upgradeVersion = ref();
|
||||
@ -112,7 +112,7 @@ const onLoadUpgradeInfo = async () => {
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
isProductPro.value = globalStore.isProductPro;
|
||||
isMasterProductPro.value = globalStore.isMasterProductPro;
|
||||
search();
|
||||
});
|
||||
</script>
|
||||
|
@ -3,7 +3,7 @@ import { GlobalStore } from '@/store';
|
||||
export const useTheme = () => {
|
||||
const globalStore = GlobalStore();
|
||||
const switchTheme = () => {
|
||||
if (globalStore.themeConfig.isGold && globalStore.isProductPro) {
|
||||
if (globalStore.themeConfig.isGold && globalStore.isMasterProductPro) {
|
||||
const body = document.documentElement as HTMLElement;
|
||||
body.setAttribute('class', 'dark-gold');
|
||||
return;
|
||||
|
@ -72,6 +72,8 @@ const message = {
|
||||
createNewFolder: 'Create new folder',
|
||||
createNewFile: 'Create new file',
|
||||
helpDoc: 'Help Document',
|
||||
bind: 'Bind',
|
||||
unbind: 'Unbind',
|
||||
},
|
||||
search: {
|
||||
timeStart: 'Time start',
|
||||
@ -1731,30 +1733,34 @@ const message = {
|
||||
community: 'Community Edition: ',
|
||||
community2: 'Community Edition',
|
||||
pro: 'Professional Edition: ',
|
||||
trial: 'Trial Edition',
|
||||
office: 'Official Edition',
|
||||
xpack: 'Professional Edition',
|
||||
trial: 'Trial Version',
|
||||
forceDelete: 'Force delete, will ignore errors during the deletion process and eventually remove metadata',
|
||||
deleteHelper: 'Deleting the license may cause child nodes to be unable to switch, please proceed with caution!',
|
||||
office: 'Official Version',
|
||||
trialInfo: 'Version',
|
||||
authorizationId: 'Subscription Authorization ID',
|
||||
authorizedUser: 'Authorized User',
|
||||
expiresAt: 'Expiry Date',
|
||||
expiresAt: 'Expiration Date',
|
||||
productName: 'Product Name',
|
||||
productStatus: 'Product Status',
|
||||
Lost01: 'Lost * 1',
|
||||
Lost02: 'Lost * 2',
|
||||
Lost03: 'Lost',
|
||||
Enable: 'Enabled',
|
||||
Disable: 'Disabled',
|
||||
lost: 'Lost Contact',
|
||||
bound: 'Bound',
|
||||
exceptional: 'Exceptional',
|
||||
free: 'Free',
|
||||
lostHelper:
|
||||
'The License needs to be periodically synchronized for availability. Please ensure normal external network access. After three losses of connection, the License binding will be released.',
|
||||
'The license has reached the maximum number of retry attempts. Please manually click the sync button to ensure the professional version functions properly.',
|
||||
exceptionalHelper:
|
||||
'License synchronization verification is abnormal. Please manually click the sync button to ensure the professional version functions properly.',
|
||||
quickUpdate: 'Quick Update',
|
||||
import: 'Import',
|
||||
power: 'Authorize',
|
||||
unbind: 'Unbind License',
|
||||
unbindHelper: 'All Pro related Settings will be cleared after unbinding. Do you want to continue? ',
|
||||
power: 'Authorization',
|
||||
unbind: 'Unbind',
|
||||
unbindHelper: 'Unbinding will clear all professional edition settings for this node. Do you wish to continue?',
|
||||
unbindMasterHelper:
|
||||
'There are currently other nodes besides the master node. The {0} operation is not supported. Please delete the nodes in the node management and try again.',
|
||||
importLicense: 'Import License',
|
||||
importHelper: 'Please click or drag the license file here',
|
||||
technicalAdvice: 'Technical Advice',
|
||||
advice: 'Consultation',
|
||||
indefinitePeriod: 'Indefinite Period',
|
||||
levelUpPro: 'Upgrade to Professional Edition',
|
||||
licenseSync: 'License Sync',
|
||||
|
@ -71,6 +71,8 @@ const message = {
|
||||
createNewFolder: '新建資料夾',
|
||||
createNewFile: '新建檔案',
|
||||
helpDoc: '幫助文档',
|
||||
bind: '綁定',
|
||||
unbind: '解除綁定',
|
||||
},
|
||||
search: {
|
||||
timeStart: '開始時間',
|
||||
@ -1612,7 +1614,10 @@ const message = {
|
||||
community: '社區版:',
|
||||
community2: '社區版',
|
||||
pro: '專業版:',
|
||||
xpack: '專業版',
|
||||
trial: '試用版',
|
||||
forceDelete: '強制刪除,會忽略刪除過程中產生的錯誤並最終刪除元數據',
|
||||
deleteHelper: '刪除許可證可能導致子節點無法切換,請謹慎操作!',
|
||||
office: '正式版',
|
||||
trialInfo: '版本',
|
||||
authorizationId: '訂閱授權 ID',
|
||||
@ -1620,22 +1625,21 @@ const message = {
|
||||
expiresAt: '到期時間',
|
||||
productName: '產品名稱',
|
||||
productStatus: '產品狀態',
|
||||
Lost01: '失聯 * 1',
|
||||
Lost02: '失聯 * 2',
|
||||
Lost03: '已失聯',
|
||||
Enable: '已啟用',
|
||||
Disable: '未啟用',
|
||||
lostHelper: '許可證需要定時同步是否可用,請保證正常外網訪問,失聯三次後將解除許可證綁定',
|
||||
lost: '已失聯',
|
||||
bound: '已綁定',
|
||||
exceptional: '異常',
|
||||
free: '空閒',
|
||||
lostHelper: '許可證已達到最大重試次數,請手動點擊同步按鈕,以確保專業版功能正常使用。',
|
||||
exceptionalHelper: '許可證同步驗證異常,請手動點擊同步按鈕,以確保專業版功能正常使用。',
|
||||
quickUpdate: '快速更新',
|
||||
import: '導入',
|
||||
power: '授 權',
|
||||
power: '授權',
|
||||
unbind: '解除綁定',
|
||||
unbindHelper: '解除綁定後將清除所有專業版相關設置,是否繼續?',
|
||||
unbindHelper: '解除綁定後將清除該節點所有專業版相關設置,是否繼續?',
|
||||
unbindMasterHelper: '當前已存在除主節點外其他節點,不支持 {0} 操作,請在節點管理中刪除節點後重試',
|
||||
importLicense: '導入許可證',
|
||||
importHelper: '請點擊或拖動許可文件到此處',
|
||||
technicalAdvice: '技術諮詢',
|
||||
advice: '諮詢',
|
||||
indefinitePeriod: '無限期',
|
||||
indefinitePeriod: '無期限',
|
||||
levelUpPro: '升級專業版',
|
||||
licenseSync: '許可證同步',
|
||||
knowMorePro: '了解更多',
|
||||
|
@ -71,6 +71,8 @@ const message = {
|
||||
createNewFolder: '新建文件夹',
|
||||
createNewFile: '新建文件',
|
||||
helpDoc: '帮助文档',
|
||||
bind: '绑定',
|
||||
unbind: '解绑',
|
||||
},
|
||||
search: {
|
||||
timeStart: '开始时间',
|
||||
@ -1597,6 +1599,8 @@ const message = {
|
||||
currentVersion: '当前运行版本:',
|
||||
|
||||
license: '许可证',
|
||||
bind: '绑定',
|
||||
bindNode: '绑定节点',
|
||||
advancedMenuHide: '高级功能菜单隐藏',
|
||||
showMainAdvancedMenu: '如果只保留 1 个菜单,则侧边栏只会显示高级功能主菜单',
|
||||
showAll: '全部显示',
|
||||
@ -1611,7 +1615,10 @@ const message = {
|
||||
community: '社区版:',
|
||||
community2: '社区版',
|
||||
pro: '专业版:',
|
||||
xpack: '专业版',
|
||||
trial: '试用版',
|
||||
forceDelete: '强制删除,会忽略删除过程中产生的错误并最终删除元数据',
|
||||
deleteHelper: '删除许可证可能导致子节点无法切换,请谨慎操作!',
|
||||
office: '正式版',
|
||||
trialInfo: '版本',
|
||||
authorizationId: '订阅授权 ID',
|
||||
@ -1619,21 +1626,20 @@ const message = {
|
||||
expiresAt: '到期时间',
|
||||
productName: '产品名称',
|
||||
productStatus: '产品状态',
|
||||
Lost01: '失联 * 1',
|
||||
Lost02: '失联 * 2',
|
||||
Lost03: '已失联',
|
||||
Enable: '已激活',
|
||||
Disable: '未激活',
|
||||
lostHelper: '许可证需要定时同步是否可用,请保证正常外网访问,失联三次后将解除许可证绑定',
|
||||
lost: '已失联',
|
||||
bound: '已绑定',
|
||||
exceptional: '异常',
|
||||
free: '空闲',
|
||||
lostHelper: '许可证已达到最大重试次数,请手动点击同步按钮,以确保专业版功能正常使用。',
|
||||
exceptionalHelper: '许可证同步验证异常,请手动点击同步按钮,以确保专业版功能正常使用。',
|
||||
quickUpdate: '快速更新',
|
||||
import: '导入',
|
||||
power: '授 权',
|
||||
unbind: '解除绑定',
|
||||
unbindHelper: '解除绑定后将清除所有专业版相关设置,是否继续?',
|
||||
unbindHelper: '解除绑定后将清除该节点所有专业版相关设置,是否继续?',
|
||||
unbindMasterHelper: '当前已存在除主节点外其他节点,不支持 {0} 操作,请在节点管理中删除节点后重试',
|
||||
importLicense: '导入许可证',
|
||||
importHelper: '请点击或拖动许可文件到此处',
|
||||
technicalAdvice: '技术咨询',
|
||||
advice: '咨询',
|
||||
indefinitePeriod: '无限期',
|
||||
levelUpPro: '升级专业版',
|
||||
licenseSync: '许可证同步',
|
||||
|
@ -8,13 +8,16 @@
|
||||
>
|
||||
<Logo :isCollapse="isCollapse" />
|
||||
|
||||
<span v-if="nodes.length !== 1" class="el-dropdown-link">
|
||||
{{ globalStore.currentNode || '127.0.0.1' }}
|
||||
<span v-if="nodes.length !== 0" class="el-dropdown-link">
|
||||
{{ loadCurrentName() }}
|
||||
</span>
|
||||
<el-dropdown v-if="nodes.length !== 1" placement="right-start" @command="changeNode">
|
||||
<el-dropdown v-if="nodes.length !== 0" placement="right-start" @command="changeNode">
|
||||
<el-icon class="ico"><Switch /></el-icon>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item command="local">
|
||||
{{ $t('terminal.local') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-for="item in nodes" :key="item.name" :command="item.name">
|
||||
{{ item.name }}
|
||||
</el-dropdown-item>
|
||||
@ -60,7 +63,7 @@ import { ElMessageBox } from 'element-plus';
|
||||
import { GlobalStore, MenuStore } from '@/store';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { isString } from '@vueuse/core';
|
||||
import { getSettingInfo } from '@/api/modules/setting';
|
||||
import { getSettingInfo, listNodeOptions } from '@/api/modules/setting';
|
||||
|
||||
const route = useRoute();
|
||||
const menuStore = MenuStore();
|
||||
@ -83,6 +86,13 @@ let routerMenus = computed((): RouteRecordRaw[] => {
|
||||
return menuStore.menuList.filter((route) => route.meta && !route.meta.hideInSidebar);
|
||||
});
|
||||
|
||||
const loadCurrentName = () => {
|
||||
if (globalStore.currentNode) {
|
||||
return globalStore.currentNode === 'local' ? i18n.global.t('terminal.local') : globalStore.currentNode;
|
||||
}
|
||||
return i18n.global.t('terminal.local');
|
||||
};
|
||||
|
||||
const screenWidth = ref(0);
|
||||
|
||||
interface Node {
|
||||
@ -127,25 +137,23 @@ const systemLogOut = async () => {
|
||||
};
|
||||
|
||||
const loadNodes = async () => {
|
||||
let listXNodes;
|
||||
const xpackModules = import.meta.glob('../../../xpack/api/modules/node.ts', { eager: true });
|
||||
if (xpackModules['../../../xpack/api/modules/node.ts']) {
|
||||
listXNodes = xpackModules['../../../xpack/api/modules/node.ts']['listNodes'] || {};
|
||||
const res = await listXNodes();
|
||||
await listNodeOptions()
|
||||
.then((res) => {
|
||||
if (!res) {
|
||||
nodes.value = [];
|
||||
return;
|
||||
}
|
||||
nodes.value = res.data;
|
||||
if (nodes.value.length === 1) {
|
||||
globalStore.currentNode = nodes.value[0].name;
|
||||
}
|
||||
return;
|
||||
if (nodes.value.length === 0) {
|
||||
globalStore.currentNode = 'local';
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
nodes.value = [];
|
||||
});
|
||||
};
|
||||
const changeNode = (command: string) => {
|
||||
globalStore.currentNode = command || '127.0.0.1';
|
||||
globalStore.currentNode = command || 'local';
|
||||
location.reload();
|
||||
};
|
||||
|
||||
|
@ -22,7 +22,7 @@ import { GlobalStore, MenuStore, TabsStore } from '@/store';
|
||||
import { DeviceType } from '@/enums/app';
|
||||
import { getSystemAvailable } from '@/api/modules/setting';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { loadProductProFromDB } from '@/utils/xpack';
|
||||
import { loadMasterProductProFromDB, loadProductProFromDB } from '@/utils/xpack';
|
||||
import { useTheme } from '@/global/use-theme';
|
||||
const { switchTheme } = useTheme();
|
||||
useResize();
|
||||
@ -100,6 +100,7 @@ onMounted(() => {
|
||||
|
||||
loadStatus();
|
||||
loadProductProFromDB();
|
||||
loadMasterProductProFromDB();
|
||||
|
||||
const mqList = window.matchMedia('(prefers-color-scheme: dark)');
|
||||
if (mqList.addEventListener) {
|
||||
|
@ -35,6 +35,7 @@ export interface GlobalState {
|
||||
|
||||
isProductPro: boolean;
|
||||
productProExpires: number;
|
||||
isMasterProductPro: boolean;
|
||||
|
||||
errStatus: string;
|
||||
|
||||
|
@ -39,17 +39,18 @@ const GlobalStore = defineStore({
|
||||
|
||||
isProductPro: false,
|
||||
productProExpires: 0,
|
||||
isMasterProductPro: false,
|
||||
|
||||
errStatus: '',
|
||||
|
||||
currentNode: '127.0.0.1',
|
||||
currentNode: 'local',
|
||||
}),
|
||||
getters: {
|
||||
isDarkTheme: (state) =>
|
||||
state.themeConfig.theme === 'dark' ||
|
||||
state.themeConfig.isGold ||
|
||||
(state.themeConfig.theme === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches),
|
||||
isDarkGoldTheme: (state) => state.themeConfig.isGold && state.isProductPro,
|
||||
isDarkGoldTheme: (state) => state.themeConfig.isGold && state.isMasterProductPro,
|
||||
},
|
||||
actions: {
|
||||
setOpenMenuTabs(openMenuTabs: boolean) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { getLicenseStatus, getSettingInfo } from '@/api/modules/setting';
|
||||
import { getLicenseStatus, getMasterLicenseStatus, getSettingInfo } from '@/api/modules/setting';
|
||||
import { useTheme } from '@/global/use-theme';
|
||||
import { GlobalStore } from '@/store';
|
||||
const globalStore = GlobalStore();
|
||||
@ -53,36 +53,39 @@ const loadDataFromDB = async () => {
|
||||
export async function loadProductProFromDB() {
|
||||
const res = await getLicenseStatus();
|
||||
if (!res || !res.data) {
|
||||
resetXSetting();
|
||||
globalStore.isProductPro = false;
|
||||
} else {
|
||||
globalStore.isProductPro =
|
||||
res.data.status === 'Enable' || res.data.status === 'Lost01' || res.data.status === 'Lost02';
|
||||
globalStore.isProductPro = res.data.status === 'bound';
|
||||
if (globalStore.isProductPro) {
|
||||
globalStore.productProExpires = Number(res.data.productPro);
|
||||
}
|
||||
}
|
||||
switchTheme();
|
||||
initFavicon();
|
||||
loadDataFromDB();
|
||||
}
|
||||
|
||||
export async function loadMasterProductProFromDB() {
|
||||
const res = await getMasterLicenseStatus();
|
||||
if (!res || !res.data) {
|
||||
globalStore.isMasterProductPro = false;
|
||||
} else {
|
||||
globalStore.isMasterProductPro = res.data.status === 'bound';
|
||||
}
|
||||
switchTheme();
|
||||
initFavicon();
|
||||
}
|
||||
|
||||
export async function getXpackSettingForTheme() {
|
||||
const res = await getLicenseStatus();
|
||||
const res = await getMasterLicenseStatus();
|
||||
if (!res.data) {
|
||||
globalStore.isProductPro = false;
|
||||
globalStore.isMasterProductPro = false;
|
||||
resetXSetting();
|
||||
switchTheme();
|
||||
initFavicon();
|
||||
return;
|
||||
}
|
||||
globalStore.isProductPro =
|
||||
res.data.status === 'Enable' || res.data.status === 'Lost01' || res.data.status === 'Lost02';
|
||||
if (globalStore.isProductPro) {
|
||||
globalStore.productProExpires = Number(res.data.productPro);
|
||||
}
|
||||
if (!globalStore.isProductPro) {
|
||||
globalStore.isProductPro = false;
|
||||
globalStore.isMasterProductPro = res.data.status === 'bound';
|
||||
if (!globalStore.isMasterProductPro) {
|
||||
globalStore.isMasterProductPro = false;
|
||||
resetXSetting();
|
||||
switchTheme();
|
||||
initFavicon();
|
||||
|
97
frontend/src/views/setting/license/bind/index.vue
Normal file
97
frontend/src/views/setting/license/bind/index.vue
Normal file
@ -0,0 +1,97 @@
|
||||
<template>
|
||||
<DrawerPro
|
||||
v-model="drawerVisible"
|
||||
:header="$t('commons.button.bind')"
|
||||
:resource="licenseName"
|
||||
:back="handleClose"
|
||||
size="small"
|
||||
>
|
||||
<el-form ref="formRef" label-position="top" :model="form" @submit.prevent v-loading="loading">
|
||||
<el-form-item :label="$t('setting.bindNode')" prop="nodeID" :rules="Rules.requiredSelect">
|
||||
<el-select filterable v-model="form.nodeID" style="width: 100%">
|
||||
<el-option v-for="item in freeNodes" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button>
|
||||
<el-button :disabled="loading" type="primary" @click="onBind(formRef)">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</DrawerPro>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
import i18n from '@/lang';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { bindLicense, listNodeOptions } from '@/api/modules/setting';
|
||||
import { FormInstance } from 'element-plus';
|
||||
import { GlobalStore } from '@/store';
|
||||
import { Rules } from '@/global/form-rules';
|
||||
const globalStore = GlobalStore();
|
||||
|
||||
interface DialogProps {
|
||||
licenseName: string;
|
||||
licenseID: number;
|
||||
}
|
||||
const drawerVisible = ref();
|
||||
const loading = ref();
|
||||
const licenseName = ref();
|
||||
const freeNodes = ref([]);
|
||||
|
||||
const form = reactive({
|
||||
nodeID: null,
|
||||
licenseID: null,
|
||||
});
|
||||
|
||||
const formRef = ref<FormInstance>();
|
||||
|
||||
const acceptParams = (params: DialogProps): void => {
|
||||
licenseName.value = params.licenseName;
|
||||
form.licenseID = params.licenseID;
|
||||
loadNodes();
|
||||
drawerVisible.value = true;
|
||||
};
|
||||
|
||||
const onBind = async (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return;
|
||||
formEl.validate(async (valid) => {
|
||||
if (!valid) return;
|
||||
loading.value = true;
|
||||
await bindLicense(form.licenseID, form.nodeID)
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
globalStore.isProductPro = false;
|
||||
globalStore.themeConfig.isGold = false;
|
||||
window.location.reload();
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const loadNodes = async () => {
|
||||
if (!globalStore.isMasterProductPro) {
|
||||
freeNodes.value = [{ id: 0, name: i18n.global.t('terminal.local') }];
|
||||
return;
|
||||
}
|
||||
await listNodeOptions()
|
||||
.then((res) => {
|
||||
freeNodes.value = res.data || [];
|
||||
})
|
||||
.catch(() => {
|
||||
freeNodes.value = [];
|
||||
});
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
drawerVisible.value = false;
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
</script>
|
74
frontend/src/views/setting/license/delete/index.vue
Normal file
74
frontend/src/views/setting/license/delete/index.vue
Normal file
@ -0,0 +1,74 @@
|
||||
<template>
|
||||
<el-dialog v-model="dialogVisible" :title="$t('commons.button.delete')" width="30%" :close-on-click-modal="false">
|
||||
<el-form ref="deleteRef" v-loading="loading" @submit.prevent>
|
||||
<el-form-item>
|
||||
<el-alert :title="$t('license.deleteHelper')" :closable="false" type="warning" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-checkbox v-model="form.forceDelete" :label="$t('database.unBindForce')" />
|
||||
<span class="input-help">
|
||||
{{ $t('license.forceDelete') }}
|
||||
</span>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false" :disabled="loading">
|
||||
{{ $t('commons.button.cancel') }}
|
||||
</el-button>
|
||||
<el-button type="primary" @click="submit" :disabled="loading">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { FormInstance } from 'element-plus';
|
||||
import { ref } from 'vue';
|
||||
import i18n from '@/lang';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { DeleteLicense } from '@/api/modules/setting';
|
||||
|
||||
let form = reactive({
|
||||
id: 0,
|
||||
licenseName: '',
|
||||
forceDelete: false,
|
||||
});
|
||||
let dialogVisible = ref(false);
|
||||
let loading = ref(false);
|
||||
|
||||
const deleteRef = ref<FormInstance>();
|
||||
|
||||
interface DialogProps {
|
||||
id: number;
|
||||
name: string;
|
||||
database: string;
|
||||
}
|
||||
const emit = defineEmits<{ (e: 'search'): void }>();
|
||||
|
||||
const acceptParams = async (prop: DialogProps) => {
|
||||
form.id = prop.id;
|
||||
form.licenseName = prop.name;
|
||||
form.forceDelete = false;
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
const submit = async () => {
|
||||
loading.value = true;
|
||||
DeleteLicense(form.id, form.forceDelete)
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
emit('search');
|
||||
MsgSuccess(i18n.global.t('commons.msg.deleteSuccess'));
|
||||
dialogVisible.value = false;
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
</script>
|
@ -1,144 +1,133 @@
|
||||
<template>
|
||||
<div>
|
||||
<LayoutContent v-loading="loading" :title="$t('setting.license')" :divider="true">
|
||||
<LayoutContent v-loading="loading" :title="$t('setting.license')">
|
||||
<template #leftToolBar>
|
||||
<el-button type="primary" @click="toUpload()">
|
||||
{{ $t('commons.button.add') }}
|
||||
</el-button>
|
||||
</template>
|
||||
<template #main>
|
||||
<el-row :gutter="20" class="mt-5; mb-10">
|
||||
<el-col :xs="24" :sm="24" :md="15" :lg="15" :xl="15">
|
||||
<div class="descriptions" v-if="hasLicense">
|
||||
<el-descriptions :column="1" direction="horizontal" size="large" border>
|
||||
<el-descriptions-item :label="$t('license.authorizationId')">
|
||||
{{ license.licenseName || '-' }}
|
||||
<el-button
|
||||
type="primary"
|
||||
class="ml-3"
|
||||
plain
|
||||
@click="onSync"
|
||||
size="small"
|
||||
v-if="showSync()"
|
||||
>
|
||||
{{ $t('commons.button.sync') }}
|
||||
</el-button>
|
||||
<el-button type="primary" class="ml-3" plain @click="onUnBind()" size="small">
|
||||
{{ $t('license.unbind') }}
|
||||
</el-button>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('license.authorizedUser')">
|
||||
{{ license.assigneeName || '-' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('license.productName')">
|
||||
{{ license.productName || '-' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('license.trialInfo')">
|
||||
{{ license.trial ? $t('license.trial') : $t('license.office') }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('license.expiresAt')">
|
||||
{{ license.expiresAt || '-' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('license.productStatus')">
|
||||
<div v-if="license.status">
|
||||
<ComplexTable :pagination-config="paginationConfig" @sort-change="search" @search="search" :data="data">
|
||||
<el-table-column
|
||||
:label="$t('license.authorizationId')"
|
||||
:min-width="80"
|
||||
prop="licenseName"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column :label="$t('license.authorizedUser')" prop="assigneeName" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
{{ row.assigneeName || '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('license.expiresAt')" prop="expiresAt" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
{{ row.expiresAt || '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('commons.table.status')" prop="status" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<div v-if="row.status">
|
||||
<el-tooltip
|
||||
v-if="license.status.indexOf('Lost') !== -1"
|
||||
:content="$t('license.lostHelper')"
|
||||
v-if="row.status === 'exceptional'"
|
||||
:content="$t('license.exceptionalHelper')"
|
||||
>
|
||||
<el-tag type="info">
|
||||
{{ $t('license.' + license.status) }}
|
||||
<el-tag type="danger">
|
||||
{{ $t('license.' + row.status) }}
|
||||
</el-tag>
|
||||
</el-tooltip>
|
||||
<el-tag v-else>{{ $t('license.' + license.status) }}</el-tag>
|
||||
<el-tooltip v-if="row.status === 'lost'" :content="$t('license.lostHelper')">
|
||||
<el-tag type="info">
|
||||
{{ $t('license.' + row.status) }}
|
||||
</el-tag>
|
||||
</el-tooltip>
|
||||
<el-tag v-if="row.status !== 'exceptional' && row.status !== 'lost'">
|
||||
{{ $t('license.' + row.status) }}
|
||||
</el-tag>
|
||||
</div>
|
||||
<span v-else>-</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item class="descriptions" :label="$t('commons.table.message')">
|
||||
{{ license.message }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('setting.bindNode')">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row.freeCount !== 0 && (row.status === 'free' || row.status === 'exceptional')">
|
||||
-
|
||||
</span>
|
||||
<div v-else>
|
||||
<span v-if="row.freeCount === 0">{{ row.bindNode || '-' }}</span>
|
||||
<div v-else>
|
||||
<el-popover
|
||||
placement="bottom"
|
||||
:width="120"
|
||||
trigger="hover"
|
||||
v-if="row.freeNodes && row.freeNodes.length != 0"
|
||||
>
|
||||
<div v-for="(item, index) of row.freeNodes" :key="index">
|
||||
<el-tag>{{ item.name }}</el-tag>
|
||||
</div>
|
||||
<template #reference>
|
||||
<el-button link type="primary">
|
||||
({{ row.bindCount }} / {{ row.freeCount }})
|
||||
</el-button>
|
||||
</template>
|
||||
</el-popover>
|
||||
<span v-else link type="primary">({{ row.bindCount }} / {{ row.freeCount }})</span>
|
||||
</div>
|
||||
|
||||
<CardWithHeader :header="$t('home.overview')" height="160px" v-if="!hasLicense">
|
||||
<template #body>
|
||||
<div class="h-app-card">
|
||||
<el-row>
|
||||
<el-col :span="6">
|
||||
<span>{{ $t('setting.license') }}</span>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<span>{{ $t('license.community2') }}</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
</CardWithHeader>
|
||||
</el-col>
|
||||
|
||||
<el-col :xs="24" :sm="24" :md="9" :lg="9" :xl="9">
|
||||
<CardWithHeader :header="$t('license.quickUpdate')" height="160px">
|
||||
<template #body>
|
||||
<div class="h-app-card">
|
||||
<el-row>
|
||||
<el-col :span="15">
|
||||
<div class="h-app-content">{{ $t('license.importLicense') }}:</div>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<el-button type="primary" plain round size="small" @click="toUpload">
|
||||
{{ $t('license.import') }}
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="h-app-card">
|
||||
<el-row>
|
||||
<el-col :span="15">
|
||||
<div class="h-app-content">{{ $t('license.technicalAdvice') }}:</div>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<el-button type="primary" plain round size="small" @click="toHalo()">
|
||||
{{ $t('license.advice') }}
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
</CardWithHeader>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="createdAt"
|
||||
:label="$t('commons.table.date')"
|
||||
:formatter="dateFormat"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<fu-table-operations
|
||||
width="300px"
|
||||
:buttons="buttons"
|
||||
:ellipsis="10"
|
||||
:label="$t('commons.table.operate')"
|
||||
fix
|
||||
/>
|
||||
</ComplexTable>
|
||||
</template>
|
||||
</LayoutContent>
|
||||
|
||||
<LicenseImport ref="licenseRef" />
|
||||
<LicenseBind ref="bindRef" />
|
||||
<LicenseDelete ref="delRef" @search="search" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import { getLicense, syncLicense, unbindLicense } from '@/api/modules/setting';
|
||||
import CardWithHeader from '@/components/card-with-header/index.vue';
|
||||
import { SearchLicense, syncLicense, unbindLicense } from '@/api/modules/setting';
|
||||
import LicenseImport from '@/components/license-import/index.vue';
|
||||
import LicenseDelete from '@/views/setting/license/delete/index.vue';
|
||||
import LicenseBind from '@/views/setting/license/bind/index.vue';
|
||||
import { dateFormat } from '@/utils/util';
|
||||
import i18n from '@/lang';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { MsgError, MsgSuccess } from '@/utils/message';
|
||||
import { GlobalStore } from '@/store';
|
||||
|
||||
const globalStore = GlobalStore();
|
||||
const loading = ref();
|
||||
const licenseRef = ref();
|
||||
const globalStore = GlobalStore();
|
||||
const hasLicense = ref();
|
||||
const delRef = ref();
|
||||
const bindRef = ref();
|
||||
|
||||
const license = reactive({
|
||||
licenseName: '',
|
||||
trial: true,
|
||||
expiresAt: '',
|
||||
assigneeName: '',
|
||||
productName: '',
|
||||
|
||||
status: '',
|
||||
message: '',
|
||||
const data = ref();
|
||||
const paginationConfig = reactive({
|
||||
cacheSizeKey: 'backup-page-size',
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
type: '',
|
||||
name: '',
|
||||
});
|
||||
|
||||
const toHalo = () => {
|
||||
window.open('https://www.lxware.cn/1panel' + '', '_blank', 'noopener,noreferrer');
|
||||
};
|
||||
|
||||
const onSync = async () => {
|
||||
const onSync = async (row: any) => {
|
||||
loading.value = true;
|
||||
await syncLicense()
|
||||
await syncLicense(row.id)
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
@ -149,20 +138,24 @@ const onSync = async () => {
|
||||
});
|
||||
};
|
||||
|
||||
const onUnBind = async () => {
|
||||
const onUnbind = async (row: any) => {
|
||||
ElMessageBox.confirm(i18n.global.t('license.unbindHelper'), i18n.global.t('license.unbind'), {
|
||||
confirmButtonText: i18n.global.t('commons.button.confirm'),
|
||||
cancelButtonText: i18n.global.t('commons.button.cancel'),
|
||||
type: 'info',
|
||||
}).then(async () => {
|
||||
loading.value = true;
|
||||
await unbindLicense()
|
||||
await unbindLicense(row.id)
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
if (row.freeCount !== 0) {
|
||||
globalStore.isProductPro = false;
|
||||
globalStore.themeConfig.isGold = false;
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
window.location.reload();
|
||||
return;
|
||||
}
|
||||
search();
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
@ -170,6 +163,29 @@ const onUnBind = async () => {
|
||||
});
|
||||
};
|
||||
|
||||
const search = async () => {
|
||||
loading.value = true;
|
||||
let params = {
|
||||
page: paginationConfig.currentPage,
|
||||
pageSize: paginationConfig.pageSize,
|
||||
};
|
||||
await SearchLicense(params)
|
||||
.then((res) => {
|
||||
loading.value = false;
|
||||
data.value = res.data.items || [];
|
||||
for (const item of data.value) {
|
||||
item.productName = 'product-1panel-pro';
|
||||
item.expiresAt =
|
||||
item.productPro === '0'
|
||||
? i18n.global.t('license.indefinitePeriod')
|
||||
: timestampToDate(Number(item.productPro));
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
const timestampToDate = (timestamp: number) => {
|
||||
const date = new Date(timestamp * 1000);
|
||||
const y = date.getFullYear();
|
||||
@ -186,47 +202,64 @@ const timestampToDate = (timestamp: number) => {
|
||||
return `${y}-${m}-${d} ${h}:${minute}:${second}`;
|
||||
};
|
||||
|
||||
const search = async () => {
|
||||
loading.value = true;
|
||||
await getLicense()
|
||||
.then((res) => {
|
||||
loading.value = false;
|
||||
license.status = res.data.status;
|
||||
globalStore.isProductPro =
|
||||
res.data.status === 'Enable' || res.data.status === 'Lost01' || res.data.status === 'Lost02';
|
||||
if (res.data.status === '') {
|
||||
hasLicense.value = false;
|
||||
return;
|
||||
}
|
||||
hasLicense.value = true;
|
||||
if (globalStore.isProductPro) {
|
||||
globalStore.productProExpires = Number(res.data.productPro);
|
||||
}
|
||||
license.licenseName = res.data.licenseName;
|
||||
license.message = res.data.message;
|
||||
license.assigneeName = res.data.assigneeName;
|
||||
license.trial = res.data.trial;
|
||||
if (res.data.productPro) {
|
||||
license.productName = 'product-1panel-pro';
|
||||
license.expiresAt =
|
||||
res.data.productPro === '0'
|
||||
? i18n.global.t('license.indefinitePeriod')
|
||||
: timestampToDate(Number(res.data.productPro));
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
const showSync = () => {
|
||||
return license.status.indexOf('Lost') !== -1 || license.status === 'Disable';
|
||||
};
|
||||
|
||||
const toUpload = () => {
|
||||
licenseRef.value.acceptParams();
|
||||
};
|
||||
|
||||
const buttons = [
|
||||
{
|
||||
label: i18n.global.t('commons.button.bind'),
|
||||
disabled: (row: any) => {
|
||||
return row.status !== 'free';
|
||||
},
|
||||
click: (row: any) => {
|
||||
bindRef.value.acceptParams({ licenseID: row.id, licenseName: row.licenseName });
|
||||
},
|
||||
},
|
||||
{
|
||||
label: i18n.global.t('commons.button.unbind'),
|
||||
disabled: (row: any) => {
|
||||
return row.status === 'free';
|
||||
},
|
||||
click: (row: any) => {
|
||||
if (row.freeCount != 0) {
|
||||
if (row.freeNodes) {
|
||||
MsgError(i18n.global.t('license.unbindMasterHelper', [i18n.global.t('commons.button.unbind')]));
|
||||
return;
|
||||
}
|
||||
for (const item of data.value) {
|
||||
if (item.bindNode && item.freeCount == 0) {
|
||||
MsgError(i18n.global.t('license.unbindMasterHelper', [i18n.global.t('commons.button.unbind')]));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
onUnbind(row);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: i18n.global.t('commons.button.sync'),
|
||||
disabled: (row: any) => {
|
||||
return row.status.indexOf('Lost') !== -1 || row.status === 'Disable';
|
||||
},
|
||||
click: (row: any) => {
|
||||
onSync(row);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: i18n.global.t('commons.button.delete'),
|
||||
click: (row: any) => {
|
||||
for (const item of data.value) {
|
||||
if (item.bindNode && row.freeCount != 0) {
|
||||
MsgError(i18n.global.t('license.unbindMasterHelper', [i18n.global.t('commons.button.delete')]));
|
||||
return;
|
||||
}
|
||||
}
|
||||
delRef.value.acceptParams({ id: row.id, name: row.licenseName });
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
onMounted(() => {
|
||||
search();
|
||||
});
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
<el-form-item :label="$t('setting.theme')" prop="theme">
|
||||
<el-radio-group @change="onSave('Theme', form.theme)" v-model="form.theme">
|
||||
<el-radio-button v-if="isProductPro" value="dark-gold">
|
||||
<el-radio-button v-if="isMasterProductPro" value="dark-gold">
|
||||
<span>{{ $t('setting.darkGold') }}</span>
|
||||
</el-radio-button>
|
||||
<el-radio-button value="light">
|
||||
@ -159,7 +159,7 @@ const loading = ref(false);
|
||||
const i18n = useI18n();
|
||||
const globalStore = GlobalStore();
|
||||
|
||||
const { isProductPro } = storeToRefs(globalStore);
|
||||
const { isMasterProductPro } = storeToRefs(globalStore);
|
||||
|
||||
const { switchTheme } = useTheme();
|
||||
|
||||
@ -230,7 +230,7 @@ const search = async () => {
|
||||
const checkedTitles = getCheckedTitles(json);
|
||||
form.proHideMenus = checkedTitles.toString();
|
||||
|
||||
if (isProductPro.value) {
|
||||
if (isMasterProductPro.value) {
|
||||
const xpackRes = await getXpackSetting();
|
||||
if (xpackRes) {
|
||||
form.theme = xpackRes.data.theme === 'dark-gold' ? 'dark-gold' : res.data.theme;
|
||||
@ -305,7 +305,7 @@ const onSave = async (key: string, val: any) => {
|
||||
globalStore.themeConfig.theme = val;
|
||||
}
|
||||
switchTheme();
|
||||
if (globalStore.isProductPro) {
|
||||
if (globalStore.isMasterProductPro) {
|
||||
updateXpackSettingByKey('Theme', val === 'dark-gold' ? 'dark-gold' : '');
|
||||
if (val === 'dark-gold') {
|
||||
MsgSuccess(i18n.t('commons.msg.operationSuccess'));
|
||||
|
@ -5,8 +5,8 @@
|
||||
<template #default>
|
||||
{{ $t('setting.proxyHelper') }}
|
||||
<ul class="-ml-5">
|
||||
<li v-if="isProductPro">{{ $t('setting.proxyHelper1') }}</li>
|
||||
<li v-if="isProductPro">{{ $t('setting.proxyHelper2') }}</li>
|
||||
<li v-if="isMasterProductPro">{{ $t('setting.proxyHelper1') }}</li>
|
||||
<li v-if="isMasterProductPro">{{ $t('setting.proxyHelper2') }}</li>
|
||||
<li>{{ $t('setting.proxyHelper3') }}</li>
|
||||
</ul>
|
||||
</template>
|
||||
@ -69,7 +69,7 @@ import { storeToRefs } from 'pinia';
|
||||
|
||||
const globalStore = GlobalStore();
|
||||
const emit = defineEmits<{ (e: 'search'): void }>();
|
||||
const { isProductPro } = storeToRefs(globalStore);
|
||||
const { isMasterProductPro } = storeToRefs(globalStore);
|
||||
|
||||
const formRef = ref<FormInstance>();
|
||||
const rules = reactive({
|
||||
|
Loading…
x
Reference in New Issue
Block a user