feat: qqwry 文件嵌入二进制

This commit is contained in:
ssongliu 2022-11-18 16:14:23 +08:00 committed by ssongliu
parent 0a109b594b
commit e6142a403c
46 changed files with 477 additions and 571 deletions

View File

@ -1,12 +1,14 @@
package v1
import (
"errors"
"reflect"
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/gin-gonic/gin"
"reflect"
)
func (b *BaseApi) SearchAppInstalled(c *gin.Context) {
@ -37,6 +39,20 @@ func (b *BaseApi) SearchAppInstalled(c *gin.Context) {
}
}
func (b *BaseApi) CheckAppInstalld(c *gin.Context) {
key, ok := c.Params.Get("key")
if !ok {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, errors.New("error key in path"))
return
}
checkData, err := appInstallService.CheckExist(key)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, checkData)
}
func (b *BaseApi) SyncInstalled(c *gin.Context) {
if err := appInstallService.SyncAll(); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)

View File

@ -95,13 +95,7 @@ func (b *BaseApi) UpdateMysqlVariables(c *gin.Context) {
return
}
mysqlName, ok := c.Params.Get("mysqlName")
if !ok {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, errors.New("error mysqlName in path"))
return
}
if err := mysqlService.UpdateVariables(mysqlName, req); err != nil {
if err := mysqlService.UpdateVariables(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
@ -124,7 +118,7 @@ func (b *BaseApi) UpdateMysqlConfByFile(c *gin.Context) {
}
func (b *BaseApi) SearchMysql(c *gin.Context) {
var req dto.SearchDBWithPage
var req dto.PageInfo
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
@ -142,14 +136,8 @@ func (b *BaseApi) SearchMysql(c *gin.Context) {
})
}
func (b *BaseApi) ListDBNameByVersion(c *gin.Context) {
name, ok := c.Params.Get("name")
if !ok {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, errors.New("error name in path"))
return
}
list, err := mysqlService.ListDBByVersion(name)
func (b *BaseApi) ListDBName(c *gin.Context) {
list, err := mysqlService.ListDBName()
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@ -232,37 +220,16 @@ func (b *BaseApi) DeleteMysql(c *gin.Context) {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
name, ok := c.Params.Get("name")
if !ok {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, errors.New("error name in path"))
return
}
if err := mysqlService.Delete(name, req.Ids); err != nil {
if err := mysqlService.Delete(req.Ids); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
func (b *BaseApi) LoadVersions(c *gin.Context) {
data, err := mysqlService.LoadRunningVersion()
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, data)
}
func (b *BaseApi) LoadBaseinfo(c *gin.Context) {
name, ok := c.Params.Get("name")
if !ok {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, errors.New("error name in path"))
return
}
data, err := mysqlService.LoadBaseInfo(name)
data, err := mysqlService.LoadBaseInfo()
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@ -272,13 +239,7 @@ func (b *BaseApi) LoadBaseinfo(c *gin.Context) {
}
func (b *BaseApi) LoadStatus(c *gin.Context) {
name, ok := c.Params.Get("name")
if !ok {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, errors.New("error name in path"))
return
}
data, err := mysqlService.LoadStatus(name)
data, err := mysqlService.LoadStatus()
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@ -288,12 +249,7 @@ func (b *BaseApi) LoadStatus(c *gin.Context) {
}
func (b *BaseApi) LoadVariables(c *gin.Context) {
name, ok := c.Params.Get("name")
if !ok {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, errors.New("error name in path"))
return
}
data, err := mysqlService.LoadVariables(name)
data, err := mysqlService.LoadVariables()
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return

View File

@ -39,6 +39,12 @@ type AppInstallRequest struct {
Services map[string]string `json:"services"`
}
type CheckInstalled struct {
IsExist bool `json:"isExist"`
Name string `json:"name"`
Version string `json:"version"`
}
type AppInstalled struct {
model.AppInstall
Total int `json:"total"`

View File

@ -14,7 +14,6 @@ type CronjobCreate struct {
Script string `json:"script"`
Website string `json:"website"`
ExclusionRules string `json:"exclusionRules"`
Database string `json:"database"`
DBName string `json:"dbName"`
URL string `json:"url"`
SourceDir string `json:"sourceDir"`
@ -34,7 +33,6 @@ type CronjobUpdate struct {
Script string `json:"script"`
Website string `json:"website"`
ExclusionRules string `json:"exclusionRules"`
Database string `json:"database"`
DBName string `json:"dbName"`
URL string `json:"url"`
SourceDir string `json:"sourceDir"`
@ -66,7 +64,6 @@ type CronjobInfo struct {
Script string `json:"script"`
Website string `json:"website"`
ExclusionRules string `json:"exclusionRules"`
Database string `json:"database"`
DBName string `json:"dbName"`
URL string `json:"url"`
SourceDir string `json:"sourceDir"`

View File

@ -16,7 +16,6 @@ type MysqlDBInfo struct {
type MysqlDBCreate struct {
Name string `json:"name" validate:"required"`
MysqlName string `json:"mysqlName" validate:"required"`
Format string `json:"format" validate:"required,oneof=utf8mb4 utf-8 gbk big5"`
Username string `json:"username" validate:"required"`
Password string `json:"password" validate:"required"`
@ -106,7 +105,6 @@ type DBBaseInfo struct {
Port int64 `json:"port"`
Password string `json:"password"`
RemoteConn bool `json:"remoteConn"`
MysqlKey string `json:"mysqlKey"`
}
type SearchDBWithPage struct {

View File

@ -16,7 +16,6 @@ type Cronjob struct {
Script string `gorm:"longtext" json:"script"`
Website string `gorm:"type:varchar(64)" json:"website"`
Database string `gorm:"type:varchar(64)" json:"database"`
DBName string `gorm:"type:varchar(64)" json:"dbName"`
URL string `gorm:"type:varchar(256)" json:"url"`
SourceDir string `gorm:"type:varchar(256)" json:"sourceDir"`

View File

@ -20,9 +20,7 @@ type IMysqlRepo interface {
Create(ctx context.Context, mysql *model.DatabaseMysql) error
Delete(ctx context.Context, opts ...DBOption) error
Update(id uint, vars map[string]interface{}) error
LoadRunningVersion(keys []string) ([]string, error)
LoadBaseInfoByName(name string) (*RootInfo, error)
LoadRedisBaseInfo() (*RootInfo, error)
LoadBaseInfoByKey(key string) (*RootInfo, error)
UpdateDatabaseInfo(id uint, vars map[string]interface{}) error
}
@ -62,26 +60,6 @@ func (u *MysqlRepo) Page(page, size int, opts ...DBOption) (int64, []model.Datab
return count, users, err
}
func (u *MysqlRepo) LoadRunningVersion(keys []string) ([]string, error) {
var (
apps []model.App
appInstall []model.AppInstall
results []string
)
if err := global.DB.Where("name in (?)", keys).Find(&apps).Error; err != nil {
return nil, err
}
for _, app := range apps {
if err := global.DB.Where("app_id = ?", app.ID).Find(&appInstall).Error; err != nil {
return nil, err
}
for _, item := range appInstall {
results = append(results, item.Name)
}
}
return results, nil
}
type RootInfo struct {
ID uint `json:"id"`
Name string `json:"name"`
@ -91,52 +69,16 @@ type RootInfo struct {
Param string `json:"param"`
Env string `json:"env"`
Key string `json:"key"`
Version string `json:"version"`
}
func (u *MysqlRepo) LoadBaseInfoByName(name string) (*RootInfo, error) {
func (u *MysqlRepo) LoadBaseInfoByKey(key string) (*RootInfo, error) {
var (
app model.App
appInstall model.AppInstall
info RootInfo
)
if err := global.DB.Where("name = ?", name).First(&appInstall).Error; err != nil {
return nil, err
}
if err := global.DB.Where("id = ?", appInstall.AppId).First(&app).Error; err != nil {
return nil, err
}
envMap := make(map[string]interface{})
if err := json.Unmarshal([]byte(appInstall.Env), &envMap); err != nil {
return nil, err
}
password, ok := envMap["PANEL_DB_ROOT_PASSWORD"].(string)
if ok {
info.Password = password
} else {
return nil, errors.New("error password in db")
}
port, ok := envMap["PANEL_APP_PORT_HTTP"].(float64)
if ok {
info.Port = int64(port)
} else {
return nil, errors.New("error port in db")
}
info.ID = appInstall.ID
info.Key = app.Key
info.ContainerName = appInstall.ContainerName
info.Name = appInstall.Name
info.Env = appInstall.Env
info.Param = appInstall.Param
return &info, nil
}
func (u *MysqlRepo) LoadRedisBaseInfo() (*RootInfo, error) {
var (
app model.App
appInstall model.AppInstall
info RootInfo
)
if err := global.DB.Where("key = ?", "redis").First(&app).Error; err != nil {
if err := global.DB.Where("key = ?", key).First(&app).Error; err != nil {
return nil, err
}
if err := global.DB.Where("app_id = ?", app.ID).First(&appInstall).Error; err != nil {
@ -163,6 +105,7 @@ func (u *MysqlRepo) LoadRedisBaseInfo() (*RootInfo, error) {
info.Name = appInstall.Name
info.Env = appInstall.Env
info.Param = appInstall.Param
info.Version = appInstall.Version
return &info, nil
}

View File

@ -3,6 +3,12 @@ package service
import (
"context"
"fmt"
"io/ioutil"
"os"
"path"
"strconv"
"strings"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/app/model"
"github.com/1Panel-dev/1Panel/backend/constant"
@ -12,11 +18,6 @@ import (
"github.com/1Panel-dev/1Panel/backend/utils/docker"
"github.com/1Panel-dev/1Panel/backend/utils/files"
"github.com/pkg/errors"
"io/ioutil"
"os"
"path"
"strconv"
"strings"
)
type AppInstallService struct {
@ -38,6 +39,18 @@ func (a AppInstallService) Page(req dto.AppInstalledRequest) (int64, []dto.AppIn
return total, installDTOs, nil
}
func (a AppInstallService) CheckExist(key string) (*dto.CheckInstalled, error) {
app, err := appRepo.GetFirst(appRepo.WithKey(key))
if err != nil {
return nil, err
}
appInstall, _ := appInstallRepo.GetFirst(appInstallRepo.WithAppId(app.ID))
if appInstall.ID != 0 {
return &dto.CheckInstalled{Name: appInstall.Name, IsExist: true, Version: appInstall.Version}, nil
}
return &dto.CheckInstalled{IsExist: false}, nil
}
func (a AppInstallService) Search(req dto.AppInstalledRequest) ([]dto.AppInstalled, error) {
var installs []model.AppInstall
var err error
@ -221,7 +234,7 @@ func (a AppInstallService) ChangeAppPort(req dto.PortUpdate) error {
files []string
newFiles []string
)
app, err := mysqlRepo.LoadBaseInfoByName(req.Name)
app, err := mysqlRepo.LoadBaseInfoByKey(req.Key)
if err != nil {
return err
}

View File

@ -216,7 +216,6 @@ func (u *CronjobService) Update(id uint, req dto.CronjobUpdate) error {
upMap["minute"] = req.Minute
upMap["website"] = req.Website
upMap["exclusion_rules"] = req.ExclusionRules
upMap["database"] = req.Database
upMap["db_name"] = req.DBName
upMap["url"] = req.URL
upMap["source_dir"] = req.SourceDir

View File

@ -78,7 +78,7 @@ func (u *CronjobService) HandleBackup(cronjob *model.Cronjob, startTime time.Tim
if err != nil {
return "", err
}
app, err := mysqlRepo.LoadBaseInfoByName(cronjob.Database)
app, err := mysqlRepo.LoadBaseInfoByKey("mysql")
if err != nil {
return "", err
}
@ -94,8 +94,8 @@ func (u *CronjobService) HandleBackup(cronjob *model.Cronjob, startTime time.Tim
if cronjob.Type == "database" {
fileName = fmt.Sprintf("db_%s_%s.sql.gz", cronjob.DBName, time.Now().Format("20060102150405"))
backupDir = fmt.Sprintf("database/%s/%s/%s", app.Key, cronjob.Database, cronjob.DBName)
err = backupMysql(backup.Type, baseDir, backupDir, cronjob.Database, cronjob.DBName, fileName)
backupDir = fmt.Sprintf("database/mysql/%s/%s", app.Name, cronjob.DBName)
err = backupMysql(backup.Type, baseDir, backupDir, app.Name, cronjob.DBName, fileName)
if err != nil {
return "", err
}

View File

@ -31,12 +31,12 @@ import (
type MysqlService struct{}
type IMysqlService interface {
SearchWithPage(search dto.SearchDBWithPage) (int64, interface{}, error)
ListDBByVersion(name string) ([]string, error)
SearchWithPage(search dto.PageInfo) (int64, interface{}, error)
ListDBName() ([]string, error)
SearchBackupsWithPage(search dto.SearchBackupsWithPage) (int64, interface{}, error)
Create(mysqlDto dto.MysqlDBCreate) error
ChangeInfo(info dto.ChangeDBInfo) error
UpdateVariables(mysqlName string, updatas []dto.MysqlVariablesUpdate) error
UpdateVariables(updatas []dto.MysqlVariablesUpdate) error
UpdateConfByFile(info dto.MysqlConfUpdateByFile) error
UpFile(mysqlName string, files []*multipart.FileHeader) error
@ -45,19 +45,18 @@ type IMysqlService interface {
Backup(db dto.BackupDB) error
Recover(db dto.RecoverDB) error
Delete(name string, ids []uint) error
LoadStatus(name string) (*dto.MysqlStatus, error)
LoadVariables(vernamesion string) (*dto.MysqlVariables, error)
LoadRunningVersion() ([]string, error)
LoadBaseInfo(name string) (*dto.DBBaseInfo, error)
Delete(ids []uint) error
LoadStatus() (*dto.MysqlStatus, error)
LoadVariables() (*dto.MysqlVariables, error)
LoadBaseInfo() (*dto.DBBaseInfo, error)
}
func NewIMysqlService() IMysqlService {
return &MysqlService{}
}
func (u *MysqlService) SearchWithPage(search dto.SearchDBWithPage) (int64, interface{}, error) {
total, mysqls, err := mysqlRepo.Page(search.Page, search.PageSize, mysqlRepo.WithByMysqlName(search.MysqlName))
func (u *MysqlService) SearchWithPage(search dto.PageInfo) (int64, interface{}, error) {
total, mysqls, err := mysqlRepo.Page(search.Page, search.PageSize)
var dtoMysqls []dto.MysqlDBInfo
for _, mysql := range mysqls {
var item dto.MysqlDBInfo
@ -74,11 +73,11 @@ func (u *MysqlService) SearchUpListWithPage(req dto.SearchDBWithPage) (int64, in
list []dto.DatabaseFileRecords
backDatas []dto.DatabaseFileRecords
)
localDir, appKey, err := loadBackupDirAndKey(req.MysqlName)
localDir, err := loadLocalDir()
if err != nil {
return 0, list, nil
}
uploadDir := fmt.Sprintf("%s/database/%s/%s/upload", localDir, appKey, req.MysqlName)
uploadDir := fmt.Sprintf("%s/database/mysql/%s/upload", localDir, req.MysqlName)
if _, err := os.Stat(uploadDir); err != nil {
return 0, list, nil
}
@ -109,11 +108,11 @@ func (u *MysqlService) SearchUpListWithPage(req dto.SearchDBWithPage) (int64, in
}
func (u *MysqlService) UpFile(mysqlName string, files []*multipart.FileHeader) error {
localDir, appKey, err := loadBackupDirAndKey(mysqlName)
localDir, err := loadLocalDir()
if err != nil {
return err
}
dstDir := fmt.Sprintf("%s/database/%s/%s/upload", localDir, appKey, mysqlName)
dstDir := fmt.Sprintf("%s/database/mysql/%s/upload", localDir, mysqlName)
if _, err := os.Stat(dstDir); err != nil && os.IsNotExist(err) {
if err = os.MkdirAll(dstDir, os.ModePerm); err != nil {
if err != nil {
@ -138,7 +137,7 @@ func (u *MysqlService) UpFile(mysqlName string, files []*multipart.FileHeader) e
}
func (u *MysqlService) RecoverByUpload(req dto.UploadRecover) error {
app, err := mysqlRepo.LoadBaseInfoByName(req.MysqlName)
app, err := mysqlRepo.LoadBaseInfoByKey("mysql")
if err != nil {
return err
}
@ -150,7 +149,7 @@ func (u *MysqlService) RecoverByUpload(req dto.UploadRecover) error {
if !strings.HasSuffix(req.FileName, ".sql") && !strings.HasSuffix(req.FileName, ".gz") {
fileOp := files.NewFileOp()
fileNameItem := time.Now().Format("20060102150405")
dstDir := fmt.Sprintf("%s/database/%s/%s/upload/tmp/%s", localDir, app.Key, req.MysqlName, fileNameItem)
dstDir := fmt.Sprintf("%s/database/mysql/%s/upload/tmp/%s", localDir, req.MysqlName, fileNameItem)
if _, err := os.Stat(dstDir); err != nil && os.IsNotExist(err) {
if err = os.MkdirAll(dstDir, os.ModePerm); err != nil {
if err != nil {
@ -215,8 +214,8 @@ func (u *MysqlService) RecoverByUpload(req dto.UploadRecover) error {
return nil
}
func (u *MysqlService) ListDBByVersion(name string) ([]string, error) {
mysqls, err := mysqlRepo.List(mysqlRepo.WithByMysqlName(name))
func (u *MysqlService) ListDBName() ([]string, error) {
mysqls, err := mysqlRepo.List()
var dbNames []string
for _, mysql := range mysqls {
dbNames = append(dbNames, mysql.Name)
@ -225,7 +224,7 @@ func (u *MysqlService) ListDBByVersion(name string) ([]string, error) {
}
func (u *MysqlService) SearchBackupsWithPage(search dto.SearchBackupsWithPage) (int64, interface{}, error) {
app, err := mysqlRepo.LoadBaseInfoByName(search.MysqlName)
app, err := mysqlRepo.LoadBaseInfoByKey("mysql")
if err != nil {
return 0, nil, err
}
@ -239,19 +238,15 @@ func (u *MysqlService) SearchBackupsWithPage(search dto.SearchBackupsWithPage) (
return NewIBackupService().SearchRecordWithPage(searchDto)
}
func (u *MysqlService) LoadRunningVersion() ([]string, error) {
return mysqlRepo.LoadRunningVersion([]string{"Mysql5.7", "Mysql8.0"})
}
func (u *MysqlService) Create(mysqlDto dto.MysqlDBCreate) error {
if mysqlDto.Username == "root" {
return errors.New("Cannot set root as user name")
}
app, err := mysqlRepo.LoadBaseInfoByName(mysqlDto.MysqlName)
app, err := mysqlRepo.LoadBaseInfoByKey("mysql")
if err != nil {
return err
}
mysql, _ := mysqlRepo.Get(commonRepo.WithByName(mysqlDto.Name), mysqlRepo.WithByMysqlName(app.Key))
mysql, _ := mysqlRepo.Get(commonRepo.WithByName(mysqlDto.Name))
if mysql.ID != 0 {
return constant.ErrRecordExist
}
@ -267,12 +262,13 @@ func (u *MysqlService) Create(mysqlDto dto.MysqlDBCreate) error {
return err
}
grantStr := fmt.Sprintf("grant all privileges on %s.* to '%s'@'%s'", mysqlDto.Name, mysqlDto.Username, tmpPermission)
if app.Key == "mysql5.7" {
if app.Version == "5.7.39" {
grantStr = fmt.Sprintf("%s identified by '%s' with grant option;", grantStr, mysqlDto.Password)
}
if err := excuteSql(app.ContainerName, app.Password, grantStr); err != nil {
return err
}
mysql.MysqlName = app.Name
if err := mysqlRepo.Create(context.TODO(), &mysql); err != nil {
return err
}
@ -280,11 +276,11 @@ func (u *MysqlService) Create(mysqlDto dto.MysqlDBCreate) error {
}
func (u *MysqlService) Backup(db dto.BackupDB) error {
localDir, appKey, err := loadBackupDirAndKey(db.MysqlName)
localDir, err := loadLocalDir()
if err != nil {
return err
}
backupDir := fmt.Sprintf("database/%s/%s/%s", appKey, db.MysqlName, db.DBName)
backupDir := fmt.Sprintf("database/mysql/%s/%s", db.MysqlName, db.DBName)
fileName := fmt.Sprintf("%s_%s.sql.gz", db.DBName, time.Now().Format("20060102150405"))
if err := backupMysql("LOCAL", localDir, backupDir, db.MysqlName, db.DBName, fileName); err != nil {
return err
@ -293,7 +289,7 @@ func (u *MysqlService) Backup(db dto.BackupDB) error {
}
func (u *MysqlService) Recover(db dto.RecoverDB) error {
app, err := mysqlRepo.LoadBaseInfoByName(db.MysqlName)
app, err := mysqlRepo.LoadBaseInfoByKey("mysql")
if err != nil {
return err
}
@ -317,8 +313,8 @@ func (u *MysqlService) Recover(db dto.RecoverDB) error {
return nil
}
func (u *MysqlService) Delete(name string, ids []uint) error {
app, err := mysqlRepo.LoadBaseInfoByName(name)
func (u *MysqlService) Delete(ids []uint) error {
app, err := mysqlRepo.LoadBaseInfoByKey("mysql")
if err != nil {
return err
}
@ -353,7 +349,7 @@ func (u *MysqlService) ChangeInfo(info dto.ChangeDBInfo) error {
return err
}
}
app, err := mysqlRepo.LoadBaseInfoByName(info.MysqlName)
app, err := mysqlRepo.LoadBaseInfoByKey("mysql")
if err != nil {
return err
}
@ -402,7 +398,7 @@ func (u *MysqlService) ChangeInfo(info dto.ChangeDBInfo) error {
return err
}
grantStr := fmt.Sprintf("grant all privileges on %s.* to '%s'@'%s'", mysql.Name, mysql.Username, info.Value)
if app.Key == "mysql5.7" {
if app.Version == "5.7.39" {
grantStr = fmt.Sprintf("%s identified by '%s' with grant option;", grantStr, mysql.Password)
}
if err := excuteSql(app.ContainerName, app.Password, grantStr); err != nil {
@ -421,11 +417,11 @@ func (u *MysqlService) ChangeInfo(info dto.ChangeDBInfo) error {
}
func (u *MysqlService) UpdateConfByFile(info dto.MysqlConfUpdateByFile) error {
app, err := mysqlRepo.LoadBaseInfoByName(info.MysqlName)
app, err := mysqlRepo.LoadBaseInfoByKey("mysql")
if err != nil {
return err
}
path := fmt.Sprintf("%s/%s/%s/conf/my.cnf", constant.AppInstallDir, app.Key, app.Name)
path := fmt.Sprintf("%s/mysql/%s/conf/my.cnf", constant.AppInstallDir, app.Name)
file, err := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0640)
if err != nil {
return err
@ -434,20 +430,20 @@ func (u *MysqlService) UpdateConfByFile(info dto.MysqlConfUpdateByFile) error {
write := bufio.NewWriter(file)
_, _ = write.WriteString(info.File)
write.Flush()
if _, err := compose.Restart(fmt.Sprintf("%s/%s/%s/docker-compose.yml", constant.AppInstallDir, app.Key, app.Name)); err != nil {
if _, err := compose.Restart(fmt.Sprintf("%s/mysql/%s/docker-compose.yml", constant.AppInstallDir, app.Name)); err != nil {
return err
}
return nil
}
func (u *MysqlService) UpdateVariables(mysqlName string, updatas []dto.MysqlVariablesUpdate) error {
app, err := mysqlRepo.LoadBaseInfoByName(mysqlName)
func (u *MysqlService) UpdateVariables(updatas []dto.MysqlVariablesUpdate) error {
app, err := mysqlRepo.LoadBaseInfoByKey("mysql")
if err != nil {
return err
}
var files []string
path := fmt.Sprintf("%s/%s/%s/conf/my.cnf", constant.AppInstallDir, app.Key, app.Name)
path := fmt.Sprintf("%s/mysql/%s/conf/my.cnf", constant.AppInstallDir, app.Name)
lineBytes, err := ioutil.ReadFile(path)
if err != nil {
return err
@ -474,16 +470,16 @@ func (u *MysqlService) UpdateVariables(mysqlName string, updatas []dto.MysqlVari
return err
}
if _, err := compose.Restart(fmt.Sprintf("%s/%s/%s/docker-compose.yml", constant.AppInstallDir, app.Key, app.Name)); err != nil {
if _, err := compose.Restart(fmt.Sprintf("%s/mysql/%s/docker-compose.yml", constant.AppInstallDir, app.Name)); err != nil {
return err
}
return nil
}
func (u *MysqlService) LoadBaseInfo(name string) (*dto.DBBaseInfo, error) {
func (u *MysqlService) LoadBaseInfo() (*dto.DBBaseInfo, error) {
var data dto.DBBaseInfo
app, err := mysqlRepo.LoadBaseInfoByName(name)
app, err := mysqlRepo.LoadBaseInfoByKey("mysql")
if err != nil {
return nil, err
}
@ -491,7 +487,6 @@ func (u *MysqlService) LoadBaseInfo(name string) (*dto.DBBaseInfo, error) {
data.Name = app.Name
data.Port = int64(app.Port)
data.Password = app.Password
data.MysqlKey = app.Key
hosts, err := excuteSqlForRows(app.ContainerName, app.Password, "select host from mysql.user where user='root';")
if err != nil {
@ -506,8 +501,8 @@ func (u *MysqlService) LoadBaseInfo(name string) (*dto.DBBaseInfo, error) {
return &data, nil
}
func (u *MysqlService) LoadVariables(name string) (*dto.MysqlVariables, error) {
app, err := mysqlRepo.LoadBaseInfoByName(name)
func (u *MysqlService) LoadVariables() (*dto.MysqlVariables, error) {
app, err := mysqlRepo.LoadBaseInfoByKey("mysql")
if err != nil {
return nil, err
}
@ -524,8 +519,8 @@ func (u *MysqlService) LoadVariables(name string) (*dto.MysqlVariables, error) {
return &info, nil
}
func (u *MysqlService) LoadStatus(name string) (*dto.MysqlStatus, error) {
app, err := mysqlRepo.LoadBaseInfoByName(name)
func (u *MysqlService) LoadStatus() (*dto.MysqlStatus, error) {
app, err := mysqlRepo.LoadBaseInfoByKey("mysql")
if err != nil {
return nil, err
}
@ -609,7 +604,7 @@ func excuteSql(containerName, password, command string) error {
}
func backupMysql(backupType, baseDir, backupDir, mysqlName, dbName, fileName string) error {
app, err := mysqlRepo.LoadBaseInfoByName(mysqlName)
app, err := mysqlRepo.LoadBaseInfoByKey("mysql")
if err != nil {
return err
}
@ -690,15 +685,3 @@ func updateMyCnf(oldFiles []string, group string, param string, value interface{
}
return newFiles
}
func loadBackupDirAndKey(mysqlName string) (string, string, error) {
app, err := mysqlRepo.LoadBaseInfoByName(mysqlName)
if err != nil {
return "", "", err
}
localDir, err := loadLocalDir()
if err != nil {
return "", "", err
}
return localDir, app.Key, nil
}

View File

@ -37,7 +37,7 @@ func NewIRedisService() IRedisService {
}
func (u *RedisService) UpdateConf(req dto.RedisConfUpdate) error {
redisInfo, err := mysqlRepo.LoadRedisBaseInfo()
redisInfo, err := mysqlRepo.LoadBaseInfoByKey("redis")
if err != nil {
return err
}
@ -70,7 +70,7 @@ func (u *RedisService) UpdateConf(req dto.RedisConfUpdate) error {
}
func (u *RedisService) UpdatePersistenceConf(req dto.RedisConfPersistenceUpdate) error {
redisInfo, err := mysqlRepo.LoadRedisBaseInfo()
redisInfo, err := mysqlRepo.LoadBaseInfoByKey("redis")
if err != nil {
return err
}
@ -97,7 +97,7 @@ func (u *RedisService) UpdatePersistenceConf(req dto.RedisConfPersistenceUpdate)
}
func (u *RedisService) LoadStatus() (*dto.RedisStatus, error) {
redisInfo, err := mysqlRepo.LoadRedisBaseInfo()
redisInfo, err := mysqlRepo.LoadBaseInfoByKey("redis")
if err != nil {
return nil, err
}
@ -125,7 +125,7 @@ func (u *RedisService) LoadStatus() (*dto.RedisStatus, error) {
}
func (u *RedisService) LoadConf() (*dto.RedisConf, error) {
redisInfo, err := mysqlRepo.LoadRedisBaseInfo()
redisInfo, err := mysqlRepo.LoadBaseInfoByKey("redis")
if err != nil {
return nil, err
}
@ -150,7 +150,7 @@ func (u *RedisService) LoadConf() (*dto.RedisConf, error) {
}
func (u *RedisService) LoadPersistenceConf() (*dto.RedisPersistence, error) {
redisInfo, err := mysqlRepo.LoadRedisBaseInfo()
redisInfo, err := mysqlRepo.LoadBaseInfoByKey("redis")
if err != nil {
return nil, err
}
@ -169,7 +169,7 @@ func (u *RedisService) LoadPersistenceConf() (*dto.RedisPersistence, error) {
}
func (u *RedisService) Backup() error {
redisInfo, err := mysqlRepo.LoadRedisBaseInfo()
redisInfo, err := mysqlRepo.LoadBaseInfoByKey("redis")
if err != nil {
return err
}
@ -214,7 +214,7 @@ func (u *RedisService) Backup() error {
}
func (u *RedisService) Recover(req dto.RedisBackupRecover) error {
redisInfo, err := mysqlRepo.LoadRedisBaseInfo()
redisInfo, err := mysqlRepo.LoadBaseInfoByKey("redis")
if err != nil {
return err
}
@ -254,7 +254,7 @@ func (u *RedisService) SearchBackupListWithPage(req dto.PageInfo) (int64, interf
list []dto.DatabaseFileRecords
backDatas []dto.DatabaseFileRecords
)
redisInfo, err := mysqlRepo.LoadRedisBaseInfo()
redisInfo, err := mysqlRepo.LoadBaseInfoByKey("redis")
if err != nil {
return 0, nil, err
}

View File

@ -5,9 +5,12 @@ import (
"encoding/json"
"io/ioutil"
"os"
"os/exec"
"strings"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/pkg/errors"
)
type DockerService struct{}
@ -32,7 +35,7 @@ type daemonJsonItem struct {
}
func (u *DockerService) LoadDockerConf() (*dto.DaemonJsonConf, error) {
file, err := ioutil.ReadFile("/opt/1Panel/docker/daemon.json")
file, err := ioutil.ReadFile(constant.DaemonJsonDir)
if err != nil {
return nil, err
}
@ -68,7 +71,7 @@ func (u *DockerService) LoadDockerConf() (*dto.DaemonJsonConf, error) {
}
func (u *DockerService) UpdateConf(req dto.DaemonJsonConf) error {
file, err := ioutil.ReadFile("/opt/1Panel/docker/daemon.json")
file, err := ioutil.ReadFile(constant.DaemonJsonDir)
if err != nil {
return err
}
@ -100,9 +103,15 @@ func (u *DockerService) UpdateConf(req dto.DaemonJsonConf) error {
if err != nil {
return err
}
if err := ioutil.WriteFile("/opt/1Panel/docker/daemon.json", newJson, 0640); err != nil {
if err := ioutil.WriteFile(constant.DaemonJsonDir, newJson, 0640); err != nil {
return err
}
cmd := exec.Command("systemctl", "restart", "docker")
stdout, err := cmd.CombinedOutput()
if err != nil {
return errors.New(string(stdout))
}
return nil
}
@ -116,10 +125,10 @@ func (u *DockerService) UpdateConfByFile(req dto.DaemonJsonUpdateByFile) error {
_, _ = write.WriteString(req.File)
write.Flush()
// cmd := exec.Command("systemctl", "restart", "docker")
// stdout, err := cmd.CombinedOutput()
// if err != nil {
// return errors.New(string(stdout))
// }
cmd := exec.Command("systemctl", "restart", "docker")
stdout, err := cmd.CombinedOutput()
if err != nil {
return errors.New(string(stdout))
}
return nil
}

View File

@ -1,32 +0,0 @@
package service
import (
"encoding/json"
"fmt"
"io/ioutil"
"strings"
"testing"
)
func TestDocker(t *testing.T) {
file, err := ioutil.ReadFile("/opt/1Panel/docker/daemon.json")
if err != nil {
fmt.Println(err)
}
var conf daemonJsonItem
deamonMap := make(map[string]interface{})
if err := json.Unmarshal(file, &deamonMap); err != nil {
fmt.Println(err)
}
arr, err := json.Marshal(deamonMap)
if err != nil {
fmt.Println(err)
}
_ = json.Unmarshal(arr, &conf)
for _, opt := range conf.ExecOpts {
if strings.HasPrefix(opt, "native.cgroupdriver=") {
fmt.Println(strings.ReplaceAll(opt, "native.cgroupdriver=", ""))
}
}
}

View File

@ -14,7 +14,7 @@ const (
ComposeOpRestart = "restart"
ComposeOpRemove = "remove"
DaemonJsonDir = "/System/Volumes/Data/Users/slooop/.docker/daemon.json"
DaemonJsonDir = "/opt/1Panel/docker/config/daemon.json"
TmpDockerBuildDir = "/opt/1Panel/data/docker/build"
TmpComposeBuildDir = "/opt/1Panel/data/docker/compose"
)

View File

@ -21,6 +21,7 @@ func (a *AppRouter) InitAppRouter(Router *gin.RouterGroup) {
appRouter.GET("/detail/:appId/:version", baseApi.GetAppDetail)
appRouter.POST("/install", baseApi.InstallApp)
appRouter.GET("/installed/:appInstallId/versions", baseApi.GetUpdateVersions)
appRouter.GET("/installed/check/:key", baseApi.CheckAppInstalld)
appRouter.POST("/installed", baseApi.SearchAppInstalled)
appRouter.POST("/installed/op", baseApi.OperateInstalled)
appRouter.POST("/installed/sync", baseApi.SyncInstalled)

View File

@ -30,14 +30,13 @@ func (s *DatabaseRouter) InitDatabaseRouter(Router *gin.RouterGroup) {
withRecordRouter.POST("/recover", baseApi.RecoverMysql)
withRecordRouter.POST("/backups/search", baseApi.SearchDBBackups)
withRecordRouter.POST("/del", baseApi.DeleteMysql)
withRecordRouter.POST("/variables/update/:mysqlName", baseApi.UpdateMysqlVariables)
withRecordRouter.POST("/variables/update", baseApi.UpdateMysqlVariables)
withRecordRouter.POST("/conf/update/byfile", baseApi.UpdateMysqlConfByFile)
cmdRouter.POST("/search", baseApi.SearchMysql)
cmdRouter.GET("/variables/:name", baseApi.LoadVariables)
cmdRouter.GET("/status/:name", baseApi.LoadStatus)
cmdRouter.GET("/baseinfo/:name", baseApi.LoadBaseinfo)
cmdRouter.GET("/versions", baseApi.LoadVersions)
cmdRouter.GET("/dbs/:name", baseApi.ListDBNameByVersion)
cmdRouter.GET("/variables", baseApi.LoadVariables)
cmdRouter.GET("/status", baseApi.LoadStatus)
cmdRouter.GET("/baseinfo", baseApi.LoadBaseinfo)
cmdRouter.GET("/dbs", baseApi.ListDBName)
cmdRouter.GET("/redis/persistence/conf", baseApi.LoadPersistenceConf)
cmdRouter.GET("/redis/status", baseApi.LoadRedisStatus)

View File

@ -2,10 +2,10 @@ package qqwry
import (
"encoding/binary"
"io/ioutil"
"net"
"strings"
"github.com/1Panel-dev/1Panel/cmd/server/qqwry"
"golang.org/x/text/encoding/simplifiedchinese"
)
@ -23,10 +23,7 @@ type QQwry struct {
}
func NewQQwry() (*QQwry, error) {
IpCommonDictionary, err := ioutil.ReadFile("/opt/1Panel/conf/qqwry.dat")
if err != nil {
return nil, err
}
IpCommonDictionary := qqwry.QQwryByte
return &QQwry{Data: IpCommonDictionary}, nil
}

View File

@ -0,0 +1,6 @@
package qqwry
import _ "embed"
//go:embed qqwry.dat
var QQwryByte []byte

BIN
cmd/server/qqwry/qqwry.dat Normal file

Binary file not shown.

View File

@ -82,6 +82,12 @@ export namespace App {
app: App;
}
export interface CheckInstalled {
name: string;
version: string;
isExist: boolean;
}
export interface AppInstalledOp {
installId: number;
operate: string;

View File

@ -14,7 +14,6 @@ export namespace Cronjob {
script: string;
website: string;
exclusionRules: string;
database: string;
dbName: string;
url: string;
sourceDir: string;
@ -36,7 +35,6 @@ export namespace Cronjob {
script: string;
website: string;
exclusionRules: string;
database: string;
dbName: string;
url: string;
sourceDir: string;
@ -55,7 +53,6 @@ export namespace Cronjob {
script: string;
website: string;
exclusionRules: string;
database: string;
dbName: string;
url: string;
sourceDir: string;

View File

@ -1,9 +1,6 @@
import { ReqPage } from '.';
export namespace Database {
export interface Search extends ReqPage {
mysqlName: string;
}
export interface SearchBackupRecord extends ReqPage {
mysqlName: string;
dbName: string;
@ -47,7 +44,6 @@ export namespace Database {
}
export interface MysqlDBCreate {
name: string;
mysqlName: string;
format: string;
username: string;
password: string;

View File

@ -30,6 +30,10 @@ export const GetAppInstalled = (info: ReqPage) => {
return http.post<ResPage<App.AppInstalled>>('apps/installed', info);
};
export const CheckAppInstalled = (key: string) => {
return http.get<App.CheckInstalled>(`apps/installed/check/${key}`);
};
export const SearchAppInstalled = (search: App.AppInstalledSearch) => {
return http.post<App.AppInstalled[]>('apps/installed', search);
};

View File

@ -4,14 +4,11 @@ import { Backup } from '../interface/backup';
import { Database } from '../interface/database';
import { File } from '@/api/interface/file';
export const searchMysqlDBs = (params: Database.Search) => {
export const searchMysqlDBs = (params: ReqPage) => {
return http.post<ResPage<Database.MysqlDBInfo>>(`/databases/search`, params);
};
export const listDBByVersion = (params: string) => {
return http.get(`/databases/dbs/${params}`);
};
export const searchUpList = (params: Database.Search) => {
export const searchUpList = (params: ReqPage) => {
return http.post<ResPage<Database.FileRecord>>(`/databases/uplist`, params);
};
export const uploadFile = (mysqlName: string, params: FormData) => {
@ -36,8 +33,8 @@ export const addMysqlDB = (params: Database.MysqlDBCreate) => {
export const updateMysqlDBInfo = (params: Database.ChangeInfo) => {
return http.put(`/databases/${params.id}`, params);
};
export const updateMysqlVariables = (mysqlName: string, params: Array<Database.VariablesUpdate>) => {
return http.post(`/databases/variables/update/${mysqlName}`, params);
export const updateMysqlVariables = (params: Array<Database.VariablesUpdate>) => {
return http.post(`/databases/variables/update`, params);
};
export const updateMysqlConfByFile = (params: Database.MysqlConfUpdateByFile) => {
return http.post(`/databases/conf/update/byfile`, params);
@ -46,17 +43,17 @@ export const deleteMysqlDB = (params: { ids: number[] }) => {
return http.post(`/databases/del`, params);
};
export const loadMysqlBaseInfo = (param: string) => {
return http.get<Database.BaseInfo>(`/databases/baseinfo/${param}`);
export const loadMysqlBaseInfo = () => {
return http.get<Database.BaseInfo>(`/databases/baseinfo`);
};
export const loadMysqlVariables = (param: string) => {
return http.get<Database.MysqlVariables>(`/databases/variables/${param}`);
export const loadMysqlVariables = () => {
return http.get<Database.MysqlVariables>(`/databases/variables`);
};
export const loadMysqlStatus = (param: string) => {
return http.get<Database.MysqlStatus>(`/databases/status/${param}`);
export const loadMysqlStatus = () => {
return http.get<Database.MysqlStatus>(`/databases/status`);
};
export const loadVersions = () => {
return http.get(`/databases/versions`);
export const loadDBNames = () => {
return http.get<Array<string>>(`/databases/dbs`);
};
// redis

View File

@ -0,0 +1,53 @@
<template>
<el-dialog v-model="codeVisiable" :destroy-on-close="true" width="70%">
<template #header>
<div class="card-header">
<span>{{ header }}</span>
</div>
</template>
<codemirror
ref="mymirror"
:autofocus="true"
placeholder="None data"
:indent-with-tab="true"
:tabSize="4"
style="max-height: 500px"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="detailInfo"
:readOnly="true"
/>
</el-dialog>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { Codemirror } from 'vue-codemirror';
import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
const mymirror = ref();
const extensions = [javascript(), oneDark];
const header = ref();
const detailInfo = ref();
const codeVisiable = ref(false);
interface DialogProps {
header: string;
detailInfo: string;
}
const acceptParams = (props: DialogProps): void => {
header.value = props.header;
detailInfo.value = props.detailInfo;
codeVisiable.value = true;
};
defineExpose({
acceptParams,
});
</script>

View File

@ -157,6 +157,8 @@ export default {
logout: 'Logout',
},
database: {
noMysql: 'No {0} database is detected, please go to App Store and click Install!',
goInstall: 'Go to install',
source: 'Source',
backup: 'Database backup',
permission: 'Permission',
@ -637,7 +639,7 @@ export default {
issue: 'Feedback',
chat: 'Community Discussion',
star: 'Star',
description: 'A modern Linux panel tool',
description: '1Panel, A modern open source Linux panel.',
},
app: {
installed: 'installed',

View File

@ -157,6 +157,8 @@ export default {
logout: '退出登录',
},
database: {
noMysql: '当前未检测到 {0} 数据库请进入应用商店点击安装',
goInstall: '去安装',
source: '来源',
backup: '备份数据库',
permission: '权限',
@ -649,7 +651,7 @@ export default {
issue: '问题反馈',
chat: '参与讨论',
star: '点亮 Star',
description: '一个现代化的 Linux 面板工具',
description: '1Panel一款现代化的开源 Linux 面板',
},
app: {
app: '应用',

View File

@ -1,7 +1,7 @@
import { Layout } from '@/routers/constant';
const logsRouter = {
sort: 10,
sort: 7,
path: '/logs',
component: Layout,
redirect: '/logs',
@ -12,17 +12,17 @@ const logsRouter = {
children: [
{
path: '',
name: 'LoginLog',
component: () => import('@/views/log/login/index.vue'),
name: 'OperationLog',
component: () => import('@/views/log/operation/index.vue'),
hidden: true,
meta: {
activeMenu: '/logs',
},
},
{
path: 'operation',
name: 'OperationLog',
component: () => import('@/views/log/operation/index.vue'),
path: 'login',
name: 'LoginLog',
component: () => import('@/views/log/login/index.vue'),
hidden: true,
meta: {
activeMenu: '/logs',

View File

@ -1,7 +1,7 @@
import { Layout } from '@/routers/constant';
const settingRouter = {
sort: 7,
sort: 8,
path: '/settings',
component: Layout,
redirect: '/setting',

View File

@ -50,33 +50,7 @@
</ComplexTable>
</el-card>
<el-dialog v-model="detailVisiable" :destroy-on-close="true" :close-on-click-modal="false" width="70%">
<template #header>
<div class="card-header">
<span>{{ $t('commons.button.view') }}</span>
</div>
</template>
<codemirror
:autofocus="true"
placeholder="None data"
:indent-with-tab="true"
:tabSize="4"
style="max-height: 500px"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="detailInfo"
:readOnly="true"
/>
<template #footer>
<span class="dialog-footer">
<el-button @click="detailVisiable = false">{{ $t('commons.button.cancel') }}</el-button>
</span>
</template>
</el-dialog>
<CodemirrorDialog ref="codemirror" />
<CreateDialog @search="search" ref="dialogCreateRef" />
</div>
</template>
@ -84,10 +58,8 @@
<script lang="ts" setup>
import ComplexTable from '@/components/complex-table/index.vue';
import CreateDialog from '@/views/container/network/create/index.vue';
import CodemirrorDialog from '@/components/codemirror-dialog/codemirror.vue';
import Submenu from '@/views/container/index.vue';
import { Codemirror } from 'vue-codemirror';
import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
import { reactive, onMounted, ref } from 'vue';
import { dateFromat } from '@/utils/util';
import { deleteNetwork, searchNetwork, inspect } from '@/api/modules/container';
@ -95,9 +67,8 @@ import { Container } from '@/api/interface/container';
import i18n from '@/lang';
import { useDeleteData } from '@/hooks/use-delete-data';
const detailVisiable = ref<boolean>(false);
const detailInfo = ref();
const extensions = [javascript(), oneDark];
const codemirror = ref();
const data = ref();
const selects = ref<any>([]);
@ -145,7 +116,11 @@ const batchDelete = async (row: Container.NetworkInfo | null) => {
const onInspect = async (id: string) => {
const res = await inspect({ id: id, type: 'network' });
detailInfo.value = JSON.stringify(JSON.parse(res.data), null, 2);
detailVisiable.value = true;
let param = {
header: i18n.global.t('commons.button.view'),
detailInfo: detailInfo.value,
};
codemirror.value!.acceptParams(param);
};
const buttons = [

View File

@ -2,11 +2,11 @@
<div>
<Submenu activeName="setting" />
<el-card style="margin-top: 20px">
<el-radio-group v-model="confShowType">
<el-radio-group v-model="confShowType" @change="changeMode">
<el-radio-button label="base">{{ $t('database.baseConf') }}</el-radio-button>
<el-radio-button label="all">{{ $t('database.allConf') }}</el-radio-button>
</el-radio-group>
<el-form v-if="confShowType === 'base'" :model="form" ref="formRef" :rules="rules" label-width="120px">
<el-form v-if="confShowType === 'base'" :model="form" ref="formRef" label-width="120px">
<el-row style="margin-top: 20px">
<el-col :span="1"><br /></el-col>
<el-col :span="10">
@ -27,7 +27,7 @@
v-model="form.registries"
/>
</el-form-item>
<el-form-item label="bip" prop="bip">
<el-form-item label="bip">
<el-input clearable v-model="form.bip" />
</el-form-item>
<el-form-item label="live-restore" prop="liveRestore">
@ -84,7 +84,6 @@ import { LoadFile } from '@/api/modules/files';
import ConfirmDialog from '@/components/confirm-dialog/index.vue';
import i18n from '@/lang';
import { loadDaemonJson, updateDaemonJson, updateDaemonJsonByfile } from '@/api/modules/container';
import { Rules } from '@/global/form-rules';
const extensions = [javascript(), oneDark];
const confShowType = ref('base');
@ -98,10 +97,6 @@ const form = reactive({
cgroupDriver: '',
});
const rules = reactive({
bip: [Rules.requiredInput],
});
const formRef = ref<FormInstance>();
const dockerConf = ref();
const confirmDialogRef = ref();
@ -132,7 +127,7 @@ const onSubmitSave = async () => {
if (confShowType.value === 'all') {
let param = {
file: dockerConf.value,
path: '/opt/1Panel/docker/daemon.json',
path: '/opt/1Panel/docker/config/daemon.json',
};
await updateDaemonJsonByfile(param);
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
@ -151,10 +146,18 @@ const onSubmitSave = async () => {
};
const loadMysqlConf = async () => {
const res = await LoadFile({ path: '/opt/1Panel/docker/daemon.json' });
const res = await LoadFile({ path: '/opt/1Panel/docker/config/daemon.json' });
dockerConf.value = res.data;
};
const changeMode = async () => {
if (confShowType.value === 'all') {
loadMysqlConf();
} else {
search();
}
};
const search = async () => {
const res = await loadDaemonJson();
form.bip = res.data.bip;
@ -167,6 +170,5 @@ const search = async () => {
onMounted(() => {
search();
loadMysqlConf();
});
</script>

View File

@ -34,33 +34,7 @@
</ComplexTable>
</el-card>
<el-dialog v-model="detailVisiable" :destroy-on-close="true" :close-on-click-modal="false" width="70%">
<template #header>
<div class="card-header">
<span>{{ $t('commons.button.view') }}</span>
</div>
</template>
<codemirror
:autofocus="true"
placeholder="None data"
:indent-with-tab="true"
:tabSize="4"
style="max-height: 500px"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="detailInfo"
:readOnly="true"
/>
<template #footer>
<span class="dialog-footer">
<el-button @click="detailVisiable = false">{{ $t('commons.button.cancel') }}</el-button>
</span>
</template>
</el-dialog>
<CodemirrorDialog ref="codemirror" />
<CreateDialog @search="search" ref="dialogCreateRef" />
</div>
</template>
@ -69,9 +43,7 @@
import ComplexTable from '@/components/complex-table/index.vue';
import CreateDialog from '@/views/container/volume/create/index.vue';
import Submenu from '@/views/container/index.vue';
import { Codemirror } from 'vue-codemirror';
import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
import CodemirrorDialog from '@/components/codemirror-dialog/codemirror.vue';
import { reactive, onMounted, ref } from 'vue';
import { dateFromat } from '@/utils/util';
import { deleteVolume, searchVolume, inspect } from '@/api/modules/container';
@ -79,9 +51,8 @@ import { Container } from '@/api/interface/container';
import i18n from '@/lang';
import { useDeleteData } from '@/hooks/use-delete-data';
const detailVisiable = ref<boolean>(false);
const detailInfo = ref();
const extensions = [javascript(), oneDark];
const codemirror = ref();
const data = ref();
const selects = ref<any>([]);
@ -116,7 +87,11 @@ const search = async () => {
const onInspect = async (id: string) => {
const res = await inspect({ id: id, type: 'volume' });
detailInfo.value = JSON.stringify(JSON.parse(res.data), null, 2);
detailVisiable.value = true;
let param = {
header: i18n.global.t('commons.button.view'),
detailInfo: detailInfo.value,
};
codemirror.value!.acceptParams(param);
};
const batchDelete = async (row: Container.VolumeInfo | null) => {

View File

@ -12,7 +12,11 @@
style="width: 100%"
v-model="dialogData.rowData!.type"
>
<el-option v-for="item in typeOptions" :key="item.label" :value="item.value" :label="item.label" />
<el-option value="shell" :label="$t('cronjob.shell')" />
<el-option value="website" :label="$t('cronjob.website')" />
<el-option value="database" :label="$t('cronjob.database')" />
<el-option value="directory" :label="$t('cronjob.directory')" />
<el-option value="curl" :label="$t('cronjob.curl')" />
</el-select>
</el-form-item>
@ -76,14 +80,9 @@
</el-form-item>
<div v-if="dialogData.rowData!.type === 'database'">
<el-form-item :label="$t('cronjob.database')" prop="database">
<el-radio-group v-model="dialogData.rowData!.database" @change="changeDBVersion" class="ml-4">
<el-radio v-for="item in mysqlVersionOptions" :key="item" :label="item" :value="item" />
</el-radio-group>
</el-form-item>
<el-form-item :label="$t('cronjob.database')" prop="dbName">
<el-select style="width: 100%" clearable v-model="dialogData.rowData!.dbName">
<el-option v-for="item in dbOptions" :key="item" :label="item" :value="item" />
<el-option v-for="item in mysqlInfo.dbNames" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
</div>
@ -170,7 +169,8 @@ import i18n from '@/lang';
import { ElForm, ElMessage } from 'element-plus';
import { Cronjob } from '@/api/interface/cronjob';
import { addCronjob, editCronjob } from '@/api/modules/cronjob';
import { listDBByVersion, loadVersions } from '@/api/modules/database';
import { loadDBNames } from '@/api/modules/database';
import { CheckAppInstalled } from '@/api/modules/app';
interface DialogProps {
title: string;
@ -186,12 +186,10 @@ const acceptParams = (params: DialogProps): void => {
dialogData.value = params;
title.value = i18n.global.t('commons.button.' + dialogData.value.title);
cronjobVisiable.value = true;
loadRunningOptions();
checkMysqlInstalled();
loadBackups();
};
const mysqlVersionOptions = ref();
const dbOptions = ref();
const localDirID = ref();
const websiteOptions = ref([
@ -203,6 +201,13 @@ const backupOptions = ref();
const emit = defineEmits<{ (e: 'search'): void }>();
const mysqlInfo = reactive({
isExist: false,
name: '',
version: '',
dbNames: [] as Array<string>,
});
const varifySpec = (rule: any, value: any, callback: any) => {
switch (dialogData.value.rowData!.specType) {
case 'perMonth':
@ -247,13 +252,6 @@ const varifySpec = (rule: any, value: any, callback: any) => {
}
callback();
};
const typeOptions = [
{ label: i18n.global.t('cronjob.shell'), value: 'shell' },
{ label: i18n.global.t('cronjob.website'), value: 'website' },
{ label: i18n.global.t('cronjob.database'), value: 'database' },
{ label: i18n.global.t('cronjob.directory'), value: 'directory' },
{ label: i18n.global.t('cronjob.curl') + ' URL', value: 'curl' },
];
const specOptions = [
{ label: i18n.global.t('cronjob.perMonth'), value: 'perMonth' },
@ -287,7 +285,6 @@ const rules = reactive({
script: [Rules.requiredInput],
website: [Rules.requiredSelect],
database: [Rules.requiredSelect],
dbName: [Rules.requiredSelect],
url: [Rules.requiredInput],
sourceDir: [Rules.requiredSelect],
@ -313,20 +310,14 @@ const loadBackups = async () => {
}
};
const loadRunningOptions = async () => {
const res = await loadVersions();
mysqlVersionOptions.value = res.data;
if (mysqlVersionOptions.value.length != 0) {
dialogData.value.rowData!.database = mysqlVersionOptions.value[0];
changeDBVersion();
}
};
const changeDBVersion = async () => {
dialogData.value.rowData!.dbName = '';
const res = await listDBByVersion(dialogData.value.rowData!.database);
dbOptions.value = res.data;
if (dbOptions.value.length != 0) {
dialogData.value.rowData!.dbName = dbOptions.value[0];
const checkMysqlInstalled = async () => {
const res = await CheckAppInstalled('mysql');
mysqlInfo.isExist = res.data.isExist;
mysqlInfo.name = res.data.name;
mysqlInfo.version = res.data.version;
if (mysqlInfo.isExist) {
const data = await loadDBNames();
mysqlInfo.dbNames = data.data;
}
};

View File

@ -114,7 +114,7 @@
</el-col>
<el-col :span="8" v-if="dialogData.rowData!.type === 'database'">
<el-form-item :label="$t('cronjob.database')">
{{ dialogData.rowData!.database }}
{{ dialogData.rowData!.dbName }}
</el-form-item>
</el-col>
<el-col :span="8" v-if="dialogData.rowData!.type === 'directory'">

View File

@ -1,86 +1,77 @@
<template>
<div>
<Submenu activeName="mysql" />
<el-dropdown size="default" split-button style="margin-top: 20px; margin-bottom: 5px">
{{ mysqlName }}
<template #dropdown>
<el-dropdown-menu v-model="mysqlName">
<el-dropdown-item v-for="item in mysqlVersions" :key="item" @click="onChangeVersion(item)">
{{ item }}
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
<el-button
v-if="!isOnSetting"
style="margin-top: 20px; margin-left: 10px"
size="default"
icon="Setting"
@click="onSetting"
>
{{ $t('database.setting') }}
</el-button>
<el-button
v-if="isOnSetting"
style="margin-top: 20px; margin-left: 10px"
size="default"
icon="Back"
@click="onBacklist"
>
{{ $t('database.backList') }}
</el-button>
<div v-if="!mysqlInfo.isExist" style="margin-top: 20px">
<el-alert :closable="false" :title="$t('database.noMysql', ['Mysql'])" type="info">
<el-link icon="Position" @click="goRouter('/apps')" type="primary">
{{ $t('database.goInstall') }}
</el-link>
</el-alert>
</div>
<div v-else>
<el-button v-if="!isOnSetting" style="margin-top: 20px" size="default" icon="Setting" @click="onSetting">
{{ $t('database.setting') }}
</el-button>
<el-button v-if="isOnSetting" style="margin-top: 20px" size="default" icon="Back" @click="onBacklist">
{{ $t('database.backList') }}
</el-button>
<Setting ref="settingRef"></Setting>
<Setting ref="settingRef"></Setting>
<el-card v-if="!isOnSetting">
<ComplexTable :pagination-config="paginationConfig" v-model:selects="selects" @search="search" :data="data">
<template #toolbar>
<el-button type="primary" @click="onOpenDialog()">{{ $t('commons.button.create') }}</el-button>
<el-button>phpMyAdmin</el-button>
<el-button type="danger" plain :disabled="selects.length === 0" @click="onBatchDelete(null)">
{{ $t('commons.button.delete') }}
</el-button>
</template>
<el-table-column type="selection" fix />
<el-table-column :label="$t('commons.table.name')" prop="name" />
<el-table-column :label="$t('auth.username')" prop="username" />
<el-table-column :label="$t('auth.password')" prop="password">
<template #default="{ row }">
<div v-if="!row.showPassword">
<span style="float: left">***********</span>
<div style="margin-top: 2px; cursor: pointer">
<el-icon style="margin-left: 5px" @click="row.showPassword = true" :size="16">
<View />
</el-icon>
</div>
</div>
<div v-else>
<span style="float: left">{{ row.password }}</span>
<div style="margin-top: 4px; cursor: pointer">
<el-icon style="margin-left: 5px" @click="row.showPassword = false" :size="16">
<Hide />
</el-icon>
</div>
</div>
<el-card v-if="!isOnSetting" style="margin-top: 5px">
<ComplexTable
:pagination-config="paginationConfig"
v-model:selects="selects"
@search="search"
:data="data"
>
<template #toolbar>
<el-button type="primary" @click="onOpenDialog()">{{ $t('commons.button.create') }}</el-button>
<el-button>phpMyAdmin</el-button>
<el-button type="danger" plain :disabled="selects.length === 0" @click="onBatchDelete(null)">
{{ $t('commons.button.delete') }}
</el-button>
</template>
</el-table-column>
<el-table-column :label="$t('commons.table.description')" prop="description" />
<el-table-column
prop="createdAt"
:label="$t('commons.table.date')"
:formatter="dateFromat"
show-overflow-tooltip
/>
<fu-table-operations
width="300px"
:buttons="buttons"
:ellipsis="10"
:label="$t('commons.table.operate')"
fix
/>
</ComplexTable>
</el-card>
<el-table-column type="selection" fix />
<el-table-column :label="$t('commons.table.name')" prop="name" />
<el-table-column :label="$t('auth.username')" prop="username" />
<el-table-column :label="$t('auth.password')" prop="password">
<template #default="{ row }">
<div v-if="!row.showPassword">
<span style="float: left">***********</span>
<div style="margin-top: 2px; cursor: pointer">
<el-icon style="margin-left: 5px" @click="row.showPassword = true" :size="16">
<View />
</el-icon>
</div>
</div>
<div v-else>
<span style="float: left">{{ row.password }}</span>
<div style="margin-top: 4px; cursor: pointer">
<el-icon style="margin-left: 5px" @click="row.showPassword = false" :size="16">
<Hide />
</el-icon>
</div>
</div>
</template>
</el-table-column>
<el-table-column :label="$t('commons.table.description')" prop="description" />
<el-table-column
prop="createdAt"
:label="$t('commons.table.date')"
:formatter="dateFromat"
show-overflow-tooltip
/>
<fu-table-operations
width="300px"
:buttons="buttons"
:ellipsis="10"
:label="$t('commons.table.operate')"
fix
/>
</ComplexTable>
</el-card>
</div>
<el-dialog v-model="changeVisiable" :destroy-on-close="true" width="30%">
<template #header>
<div class="card-header">
@ -140,16 +131,22 @@ import Setting from '@/views/database/mysql/setting/index.vue';
import Submenu from '@/views/database/index.vue';
import { dateFromat } from '@/utils/util';
import { onMounted, reactive, ref } from 'vue';
import { deleteMysqlDB, loadVersions, searchMysqlDBs, updateMysqlDBInfo } from '@/api/modules/database';
import { deleteMysqlDB, searchMysqlDBs, updateMysqlDBInfo } from '@/api/modules/database';
import i18n from '@/lang';
import { useDeleteData } from '@/hooks/use-delete-data';
import { ElForm, ElMessage } from 'element-plus';
import { Database } from '@/api/interface/database';
import { Rules } from '@/global/form-rules';
import { CheckAppInstalled } from '@/api/modules/app';
import { useRouter } from 'vue-router';
const router = useRouter();
const selects = ref<any>([]);
const mysqlVersions = ref();
const mysqlName = ref<string>('5.7');
const mysqlInfo = reactive({
name: '',
version: '',
isExist: false,
});
const isOnSetting = ref<boolean>();
const data = ref();
@ -162,7 +159,7 @@ const paginationConfig = reactive({
const dialogRef = ref();
const onOpenDialog = async () => {
let params = {
mysqlName: mysqlName.value,
mysqlName: mysqlInfo.name,
};
dialogRef.value!.acceptParams(params);
};
@ -170,7 +167,7 @@ const onOpenDialog = async () => {
const dialogBackupRef = ref();
const onOpenBackupDialog = async (dbName: string) => {
let params = {
mysqlName: mysqlName.value,
mysqlName: mysqlInfo.name,
dbName: dbName,
};
dialogBackupRef.value!.acceptParams(params);
@ -182,7 +179,7 @@ const settingRef = ref();
const onSetting = async () => {
isOnSetting.value = true;
let params = {
mysqlName: mysqlName.value,
mysqlName: mysqlInfo.name,
};
settingRef.value!.acceptParams(params);
};
@ -210,7 +207,7 @@ const submitChangeInfo = async (formEl: FormInstance | undefined) => {
formEl.validate(async (valid) => {
if (!valid) return;
changeForm.value = changeForm.operation === 'password' ? changeForm.password : changeForm.privilege;
changeForm.mysqlName = mysqlName.value;
changeForm.mysqlName = mysqlInfo.name;
await updateMysqlDBInfo(changeForm);
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
search();
@ -218,31 +215,24 @@ const submitChangeInfo = async (formEl: FormInstance | undefined) => {
});
};
const loadRunningOptions = async () => {
const res = await loadVersions();
mysqlVersions.value = res.data;
if (mysqlVersions.value.length != 0) {
mysqlName.value = mysqlVersions.value[0];
const checkMysqlInstalled = async () => {
const res = await CheckAppInstalled('mysql');
mysqlInfo.isExist = res.data.isExist;
mysqlInfo.name = res.data.name;
mysqlInfo.version = res.data.version;
if (mysqlInfo.isExist) {
search();
}
};
const onChangeVersion = async (val: string) => {
mysqlName.value = val;
search();
if (isOnSetting.value) {
let params = {
mysqlName: mysqlName.value,
};
settingRef.value!.acceptParams(params);
}
const goRouter = async (path: string) => {
router.push({ path: path });
};
const search = async () => {
let params = {
page: paginationConfig.currentPage,
pageSize: paginationConfig.pageSize,
mysqlName: mysqlName.value,
};
const res = await searchMysqlDBs(params);
data.value = res.data.items || [];
@ -295,7 +285,7 @@ const buttons = [
label: i18n.global.t('database.loadBackup'),
click: (row: Database.MysqlDBInfo) => {
let params = {
mysqlName: mysqlName.value,
mysqlName: mysqlInfo.name,
dbName: row.name,
};
uploadRef.value!.acceptParams(params);
@ -310,6 +300,6 @@ const buttons = [
];
onMounted(() => {
loadRunningOptions();
checkMysqlInstalled();
});
</script>

View File

@ -1,6 +1,6 @@
<template>
<div class="demo-collapse" v-show="onSetting">
<el-card>
<el-card style="margin-top: 5px">
<el-collapse v-model="activeName" accordion>
<el-collapse-item :title="$t('database.baseSetting')" name="1">
<el-form :model="baseInfo" ref="panelFormRef" label-width="120px">
@ -116,7 +116,6 @@ const baseInfo = reactive({
port: 3306,
password: '',
remoteConn: false,
mysqlKey: '',
containerID: '',
});
const panelFormRef = ref<FormInstance>();
@ -137,7 +136,6 @@ interface DialogProps {
const dialogContainerLogRef = ref();
const acceptParams = (params: DialogProps): void => {
onSetting.value = true;
mysqlName.value = params.mysqlName;
loadBaseInfo();
loadVariables();
loadSlowLogs();
@ -155,7 +153,7 @@ const onSave = async (formEl: FormInstance | undefined, key: string, val: any) =
}
if (key === 'port') {
let params = {
key: baseInfo.mysqlKey,
key: 'mysql',
name: mysqlName.value,
port: val,
};
@ -197,19 +195,19 @@ const loadContainerLog = async (containerID: string) => {
};
const loadBaseInfo = async () => {
const res = await loadMysqlBaseInfo(mysqlName.value);
const res = await loadMysqlBaseInfo();
mysqlName.value = res.data?.name;
baseInfo.name = res.data?.name;
baseInfo.port = res.data?.port;
baseInfo.password = res.data?.password;
baseInfo.remoteConn = res.data?.remoteConn;
baseInfo.mysqlKey = res.data?.mysqlKey;
baseInfo.containerID = res.data?.containerName;
loadMysqlConf(`/opt/1Panel/data/apps/${baseInfo.mysqlKey}/${baseInfo.name}/conf/my.cnf`);
loadMysqlConf(`/opt/1Panel/data/apps/mysql/${baseInfo.name}/conf/my.cnf`);
loadContainerLog(baseInfo.containerID);
};
const loadVariables = async () => {
const res = await loadMysqlVariables(mysqlName.value);
const res = await loadMysqlVariables();
variables.value = res.data;
variablesRef.value!.acceptParams({ mysqlName: mysqlName.value, variables: res.data });
};
@ -218,7 +216,6 @@ const loadSlowLogs = async () => {
await Promise.all([loadBaseInfo(), loadVariables()]);
let param = {
mysqlName: mysqlName.value,
mysqlKey: baseInfo.mysqlKey,
variables: variables.value,
};
slowLogRef.value!.acceptParams(param);

View File

@ -52,7 +52,6 @@ const slowLogs = ref();
const confirmDialogRef = ref();
const mysqlName = ref();
const mysqlKey = ref();
const variables = reactive({
slow_query_log: 'OFF',
long_query_time: 10,
@ -61,17 +60,15 @@ const oldVariables = ref();
interface DialogProps {
mysqlName: string;
mysqlKey: string;
variables: Database.MysqlVariables;
}
const acceptParams = (params: DialogProps): void => {
mysqlName.value = params.mysqlName;
mysqlKey.value = params.mysqlKey;
variables.slow_query_log = params.variables.slow_query_log;
variables.long_query_time = Number(params.variables.long_query_time);
if (variables.slow_query_log === 'ON') {
let path = `/opt/1Panel/data/apps/${mysqlKey.value}/${mysqlName.value}/data/1Panel-slow.log`;
let path = `/opt/1Panel/data/apps/mysql/${mysqlName.value}/data/1Panel-slow.log`;
loadMysqlSlowlogs(path);
}
oldVariables.value = { ...variables };
@ -95,7 +92,7 @@ const onSave = async () => {
param.push({ param: 'long_query_time', value: variables.long_query_time });
param.push({ param: 'slow_query_log_file', value: '/var/lib/mysql/1Panel-slow.log' });
}
await updateMysqlVariables(mysqlName.value, param);
await updateMysqlVariables(param);
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
};

View File

@ -110,7 +110,7 @@
<script lang="ts" setup>
import { loadMysqlStatus } from '@/api/modules/database';
import { computeSize } from '@/utils/util';
import { reactive, ref } from 'vue';
import { reactive } from 'vue';
let mysqlStatus = reactive({
run: 0,
@ -136,17 +136,12 @@ let mysqlStatus = reactive({
tableLocksWaited: 0,
});
const mysqlName = ref();
interface DialogProps {
mysqlName: string;
}
const acceptParams = (params: DialogProps): void => {
mysqlName.value = params.mysqlName;
const acceptParams = (): void => {
loadStatus();
};
const loadStatus = async () => {
const res = await loadMysqlStatus(mysqlName.value);
const res = await loadMysqlStatus();
let queryPerSecond = res.data.Questions / res.data.Uptime;
let txPerSecond = (res.data!.Com_commit + res.data.Com_rollback) / res.data.Uptime;

View File

@ -1,23 +1,32 @@
<template>
<div>
<Submenu activeName="redis" />
<el-button style="margin-top: 20px" size="default" icon="Tickets" @click="changeView('status')">
{{ $t('database.status') }}
</el-button>
<el-button style="margin-top: 20px" size="default" icon="Setting" @click="changeView('setting')">
{{ $t('database.setting') }}
</el-button>
<el-button style="margin-top: 20px" size="default" icon="Files" @click="changeView('persistence')">
{{ $t('database.persistence') }}
</el-button>
<el-button style="margin-top: 20px" size="default" icon="Setting" @click="changeView('terminal')">
{{ $t('database.terminal') }}
</el-button>
<div v-show="!redisInfo.isExist" style="margin-top: 20px">
<el-alert :closable="false" :title="$t('database.noMysql', ['Redis'])" type="info">
<el-link icon="Position" @click="goRouter('/apps')" type="primary">
{{ $t('database.goInstall') }}
</el-link>
</el-alert>
</div>
<div v-show="redisInfo.isExist">
<el-button style="margin-top: 20px" size="default" icon="Tickets" @click="changeView('status')">
{{ $t('database.status') }}
</el-button>
<el-button style="margin-top: 20px" size="default" icon="Setting" @click="changeView('setting')">
{{ $t('database.setting') }}
</el-button>
<el-button style="margin-top: 20px" size="default" icon="Files" @click="changeView('persistence')">
{{ $t('database.persistence') }}
</el-button>
<el-button style="margin-top: 20px" size="default" icon="Setting" @click="changeView('terminal')">
{{ $t('database.terminal') }}
</el-button>
<Status ref="statusRef"></Status>
<Setting ref="settingRef"></Setting>
<Persistence ref="persistenceRef"></Persistence>
<Terminal ref="terminalRef"></Terminal>
<Status ref="statusRef"></Status>
<Setting ref="settingRef"></Setting>
<Persistence ref="persistenceRef"></Persistence>
<Terminal ref="terminalRef"></Terminal>
</div>
</div>
</template>
@ -27,13 +36,22 @@ import Status from '@/views/database/redis/status/index.vue';
import Setting from '@/views/database/redis/setting/index.vue';
import Persistence from '@/views/database/redis/persistence/index.vue';
import Terminal from '@/views/database/redis/terminal/index.vue';
import { onMounted, ref } from 'vue';
import { onMounted, reactive, ref } from 'vue';
import { CheckAppInstalled } from '@/api/modules/app';
import { useRouter } from 'vue-router';
const router = useRouter();
const statusRef = ref();
const settingRef = ref();
const persistenceRef = ref();
const terminalRef = ref();
const redisInfo = reactive({
name: '',
version: '',
isExist: false,
});
const changeView = async (params: string) => {
switch (params) {
case 'status':
@ -62,8 +80,21 @@ const changeView = async (params: string) => {
break;
}
};
const checkRedisInstalled = async () => {
const res = await CheckAppInstalled('redis');
redisInfo.isExist = res.data.isExist;
redisInfo.name = res.data.name;
redisInfo.version = res.data.version;
if (redisInfo.isExist) {
changeView('status');
}
};
const goRouter = async (path: string) => {
router.push({ path: path });
};
onMounted(() => {
changeView('status');
checkRedisInstalled();
});
</script>

View File

@ -1,7 +1,7 @@
<template>
<div v-if="settingShow">
<el-card style="margin-top: 5px">
<el-radio-group v-model="confShowType">
<el-radio-group v-model="confShowType" @change="onChangeMode">
<el-radio-button label="base">{{ $t('database.baseConf') }}</el-radio-button>
<el-radio-button label="all">{{ $t('database.allConf') }}</el-radio-button>
</el-radio-group>
@ -135,6 +135,14 @@ function callback(error: any) {
}
}
const onChangeMode = async () => {
if (confShowType.value === 'all') {
loadMysqlConf();
} else {
loadform();
}
};
const onSave = async (formEl: FormInstance | undefined) => {
if (confShowType.value === 'all') {
onSaveFile();
@ -149,6 +157,7 @@ const onSave = async (formEl: FormInstance | undefined) => {
maxmemory: form.maxmemory + '',
};
await updateRedisConf(param);
loadform();
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
});
};
@ -179,10 +188,10 @@ const loadform = async () => {
form.requirepass = res.data?.requirepass;
form.maxmemory = Number(res.data?.maxmemory);
form.port = Number(res.data?.port);
loadMysqlConf(`/opt/1Panel/data/apps/redis/${form.name}/conf/redis.conf`);
};
const loadMysqlConf = async (path: string) => {
const loadMysqlConf = async () => {
let path = `/opt/1Panel/data/apps/redis/${form.name}/conf/redis.conf`;
const res = await LoadFile({ path: path });
mysqlConf.value = res.data;
};

View File

@ -2,12 +2,12 @@
<div>
<el-card class="topCard">
<el-radio-group v-model="active">
<el-radio-button class="topButton" size="large" @click="routerTo('/logs')" label="login">
{{ $t('logs.login') }}
</el-radio-button>
<el-radio-button class="topButton" size="large" @click="routerTo('/logs/operation')" label="operation">
<el-radio-button class="topButton" size="large" @click="routerTo('/logs')" label="operation">
{{ $t('logs.operation') }}
</el-radio-button>
<el-radio-button class="topButton" size="large" @click="routerTo('/logs/login')" label="login">
{{ $t('logs.login') }}
</el-radio-button>
<el-radio-button class="topButton" size="large" @click="routerTo('/logs/system')" label="system">
{{ $t('logs.system') }}
</el-radio-button>

View File

@ -18,8 +18,18 @@
</el-radio-button>
</el-radio-group>
</el-card>
<Panel v-if="activeNames === 'all' || activeNames === 'panel'" :settingInfo="form" @on-save="SaveSetting" />
<Safe v-if="activeNames === 'all' || activeNames === 'safe'" :settingInfo="form" @on-save="SaveSetting" />
<Panel
v-if="activeNames === 'all' || activeNames === 'panel'"
:settingInfo="form"
@on-save="SaveSetting"
@search="search"
/>
<Safe
v-if="activeNames === 'all' || activeNames === 'safe'"
:settingInfo="form"
@on-save="SaveSetting"
@search="search"
/>
<Backup v-if="activeNames === 'all' || activeNames === 'backup'" :settingInfo="form" @on-save="SaveSetting" />
<Monitor v-if="activeNames === 'all' || activeNames === 'monitor'" :settingInfo="form" @on-save="SaveSetting" />
<About v-if="activeNames === 'all' || activeNames === 'about'" />

View File

@ -9,24 +9,23 @@
<div style="justify-self: center">
<img style="width: 80px" src="@/assets/images/ko_image.png" />
</div>
<h1>1Panel</h1>
<h3>{{ $t('setting.description') }}</h3>
<h3>v0.0.1</h3>
<h3>v1.0.0</h3>
<div style="margin-top: 10px">
<svg-icon style="font-size: 9px" iconName="p-huaban88"></svg-icon>
<el-link @click="toGithub">
<span>{{ $t('setting.project') }}</span>
<svg-icon style="font-size: 9px; margin-bottom: 8px" iconName="p-huaban88"></svg-icon>
<span style="line-height: 20px">{{ $t('setting.project') }}</span>
</el-link>
<svg-icon style="font-size: 9px; margin-left: 15px" iconName="p-bug"></svg-icon>
<el-link @click="toIssue">
<el-link @click="toIssue" style="margin-left: 15px">
<svg-icon style="font-size: 9px; margin-bottom: 8px" iconName="p-bug"></svg-icon>
<span>{{ $t('setting.issue') }}</span>
</el-link>
<svg-icon style="font-size: 9px; margin-left: 15px" iconName="p-taolun"></svg-icon>
<el-link @click="toTalk">
<el-link @click="toTalk" style="margin-left: 15px">
<svg-icon style="font-size: 9px; margin-bottom: 8px" iconName="p-taolun"></svg-icon>
<span>{{ $t('setting.chat') }}</span>
</el-link>
<svg-icon style="font-size: 9px; margin-left: 15px" iconName="p-star"></svg-icon>
<el-link @click="toGithubStar">
<el-link @click="toGithubStar" style="margin-left: 15px">
<svg-icon style="font-size: 9px; margin-bottom: 6px" iconName="p-star"></svg-icon>
<span>{{ $t('setting.star') }}</span>
</el-link>
</div>

View File

@ -32,22 +32,6 @@
</el-input>
</el-form-item>
<el-form-item :label="$t('auth.email')" :rules="Rules.email" prop="settingInfo.email">
<el-input clearable v-model="form.settingInfo.email">
<template #append>
<el-button
@click="onSave(panelFormRef, 'Email', form.settingInfo.email)"
icon="Collection"
>
{{ $t('commons.button.save') }}
</el-button>
</template>
</el-input>
<div>
<span class="input-help">{{ $t('setting.emailHelper') }}</span>
</div>
</el-form-item>
<el-form-item
:label="$t('setting.title')"
:rules="Rules.requiredInput"
@ -180,7 +164,7 @@ import i18n from '@/lang';
import { GlobalStore } from '@/store';
const globalStore = GlobalStore();
const emit = defineEmits<{ (e: 'on-save', formEl: FormInstance | undefined, key: string, val: any): void }>();
const emit = defineEmits(['on-save', 'search']);
type FormInstance = InstanceType<typeof ElForm>;
const passFormRef = ref<FormInstance>();
@ -251,6 +235,7 @@ const submitChangePassword = async (formEl: FormInstance | undefined) => {
const onSyncTime = async () => {
const res = await syncTime();
emit('search');
form.settingInfo.localTime = res.data;
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
};

View File

@ -175,7 +175,7 @@ import i18n from '@/lang';
import { Rules } from '@/global/form-rules';
import { dateFromat } from '@/utils/util';
const emit = defineEmits<{ (e: 'on-save', formEl: FormInstance | undefined, key: string, val: any): void }>();
const emit = defineEmits(['on-save', 'search']);
interface Props {
settingInfo: any;
@ -217,12 +217,14 @@ const handleMFA = async () => {
isMFAShow.value = true;
} else {
await updateSetting({ key: 'MFAStatus', value: 'disable' });
emit('search');
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
}
};
const onBind = async () => {
await bindMFA({ code: mfaCode.value, secret: otp.secret });
emit('search');
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
isMFAShow.value = false;
};
@ -238,6 +240,7 @@ const submitTimeout = async (formEl: FormInstance | undefined) => {
if (!valid) return;
let time = new Date(new Date().getTime() + 3600 * 1000 * 24 * timeoutForm.days);
await updateSetting({ key: 'ExpirationDays', value: timeoutForm.days + '' });
emit('search');
form.settingInfo.expirationTime = dateFromat(0, 0, time);
timeoutVisiable.value = false;
});