mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-19 08:19:15 +08:00
feat: Mysql 数据库删除增加强制删除、删除备份选项
This commit is contained in:
parent
9ce02b14c8
commit
cfeb158d0a
@ -217,7 +217,7 @@ func (b *BaseApi) DeleteCheckMysql(c *gin.Context) {
|
||||
}
|
||||
|
||||
func (b *BaseApi) DeleteMysql(c *gin.Context) {
|
||||
var req dto.OperateByID
|
||||
var req dto.MysqlDBDelete
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
@ -227,7 +227,7 @@ func (b *BaseApi) DeleteMysql(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := mysqlService.Delete(req.ID); err != nil {
|
||||
if err := mysqlService.Delete(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
@ -28,6 +28,12 @@ type MysqlDBCreate struct {
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
type MysqlDBDelete struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
ForceDelete bool `json:"forceDelete"`
|
||||
DeleteBackup bool `json:"deleteBackup"`
|
||||
}
|
||||
|
||||
type MysqlStatus struct {
|
||||
AbortedClients string `json:"Aborted_clients"`
|
||||
AbortedConnects string `json:"Aborted_connects"`
|
||||
|
@ -44,7 +44,7 @@ type IMysqlService interface {
|
||||
Recover(db dto.RecoverDB) error
|
||||
|
||||
DeleteCheck(id uint) ([]string, error)
|
||||
Delete(id uint) error
|
||||
Delete(req dto.MysqlDBDelete) error
|
||||
LoadStatus() (*dto.MysqlStatus, error)
|
||||
LoadVariables() (*dto.MysqlVariables, error)
|
||||
LoadBaseInfo() (*dto.DBBaseInfo, error)
|
||||
@ -256,37 +256,38 @@ func (u *MysqlService) DeleteCheck(id uint) ([]string, error) {
|
||||
return appInUsed, nil
|
||||
}
|
||||
|
||||
func (u *MysqlService) Delete(id uint) error {
|
||||
func (u *MysqlService) Delete(req dto.MysqlDBDelete) error {
|
||||
app, err := appInstallRepo.LoadBaseInfo("mysql", "")
|
||||
if err != nil {
|
||||
if err != nil && !req.ForceDelete {
|
||||
return err
|
||||
}
|
||||
|
||||
db, err := mysqlRepo.Get(commonRepo.WithByID(id))
|
||||
if err != nil {
|
||||
db, err := mysqlRepo.Get(commonRepo.WithByID(req.ID))
|
||||
if err != nil && !req.ForceDelete {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := excuteSql(app.ContainerName, app.Password, fmt.Sprintf("drop user if exists '%s'@'%s'", db.Name, db.Permission)); err != nil {
|
||||
if err := excuteSql(app.ContainerName, app.Password, fmt.Sprintf("drop user if exists '%s'@'%s'", db.Name, db.Permission)); err != nil && !req.ForceDelete {
|
||||
return err
|
||||
}
|
||||
if err := excuteSql(app.ContainerName, app.Password, fmt.Sprintf("drop database if exists `%s`", db.Name)); err != nil {
|
||||
if err := excuteSql(app.ContainerName, app.Password, fmt.Sprintf("drop database if exists `%s`", db.Name)); err != nil && !req.ForceDelete {
|
||||
return err
|
||||
}
|
||||
|
||||
uploadDir := fmt.Sprintf("%s/uploads/%s/mysql/%s", constant.DefaultDataDir, app.Name, db.Name)
|
||||
uploadDir := fmt.Sprintf("%s/uploads/database/mysql/%s/%s", constant.DefaultDataDir, app.Name, db.Name)
|
||||
if _, err := os.Stat(uploadDir); err == nil {
|
||||
_ = os.RemoveAll(uploadDir)
|
||||
}
|
||||
|
||||
if req.DeleteBackup {
|
||||
localDir, err := loadLocalDir()
|
||||
if err != nil {
|
||||
if err != nil && !req.ForceDelete {
|
||||
return err
|
||||
}
|
||||
backupDir := fmt.Sprintf("%s/database/mysql/%s/%s", localDir, db.MysqlName, db.Name)
|
||||
if _, err := os.Stat(backupDir); err == nil {
|
||||
_ = os.RemoveAll(backupDir)
|
||||
}
|
||||
}
|
||||
_ = backupRepo.DeleteRecord(context.Background(), commonRepo.WithByType("database-mysql"), commonRepo.WithByName(app.Name), backupRepo.WithByDetailName(db.Name))
|
||||
|
||||
_ = mysqlRepo.Delete(context.Background(), commonRepo.WithByID(db.ID))
|
||||
|
@ -68,18 +68,16 @@ func OperationLog() gin.HandlerFunc {
|
||||
if len(operationDic.BeforeFuntions) != 0 {
|
||||
for _, funcs := range operationDic.BeforeFuntions {
|
||||
for key, value := range formatMap {
|
||||
if funcs.Info == key {
|
||||
if funcs.InputValue == key {
|
||||
var names []string
|
||||
if funcs.IsList {
|
||||
if key == "ids" {
|
||||
sql := fmt.Sprintf("SELECT %s FROM %s where id in (?);", funcs.Key, funcs.DB)
|
||||
sql := fmt.Sprintf("SELECT %s FROM %s where %s in (?);", funcs.OutputColume, funcs.DB, funcs.InputColume)
|
||||
fmt.Println(value)
|
||||
_ = global.DB.Raw(sql, value).Scan(&names)
|
||||
}
|
||||
} else {
|
||||
_ = global.DB.Raw(fmt.Sprintf("select %s from %s where %s = ?;", funcs.Key, funcs.DB, key), value).Scan(&names)
|
||||
_ = global.DB.Raw(fmt.Sprintf("select %s from %s where %s = ?;", funcs.OutputColume, funcs.DB, funcs.InputColume), value).Scan(&names)
|
||||
}
|
||||
formatMap[funcs.Value] = strings.Join(names, ",")
|
||||
formatMap[funcs.OutputValue] = strings.Join(names, ",")
|
||||
break
|
||||
}
|
||||
}
|
||||
@ -136,11 +134,12 @@ type operationJson struct {
|
||||
FormatEN string `json:"formatEN"`
|
||||
}
|
||||
type functionInfo struct {
|
||||
Info string `json:"info"`
|
||||
InputColume string `json:"input_colume"`
|
||||
InputValue string `json:"input_value"`
|
||||
IsList bool `json:"isList"`
|
||||
DB string `json:"db"`
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
OutputColume string `json:"output_colume"`
|
||||
OutputValue string `json:"output_value"`
|
||||
}
|
||||
|
||||
type response struct {
|
||||
|
@ -44,11 +44,12 @@
|
||||
"paramKeys": [],
|
||||
"BeforeFuntions": [
|
||||
{
|
||||
"info": "id",
|
||||
"input_column": "id",
|
||||
"input_value": "id",
|
||||
"isList": false,
|
||||
"db": "image_repos",
|
||||
"key": "name",
|
||||
"value": "name"
|
||||
"output_colume": "name",
|
||||
"output_value": "name"
|
||||
}
|
||||
],
|
||||
"formatZH": "更新镜像仓库 [name]",
|
||||
@ -63,11 +64,12 @@
|
||||
"paramKeys": [],
|
||||
"BeforeFuntions": [
|
||||
{
|
||||
"info": "ids",
|
||||
"input_colume": "id",
|
||||
"input_value": "ids",
|
||||
"isList": true,
|
||||
"db": "image_repos",
|
||||
"key": "name",
|
||||
"value": "names"
|
||||
"output_colume": "name",
|
||||
"output_value": "names"
|
||||
}
|
||||
],
|
||||
"formatZH": "删除镜像仓库 [names]",
|
||||
@ -116,11 +118,12 @@
|
||||
"paramKeys": [],
|
||||
"BeforeFuntions": [
|
||||
{
|
||||
"info": "id",
|
||||
"input_colume": "id",
|
||||
"input_value": "id",
|
||||
"isList": false,
|
||||
"db": "compose_templates",
|
||||
"key": "name",
|
||||
"value": "name"
|
||||
"output_colume": "name",
|
||||
"output_value": "name"
|
||||
}
|
||||
],
|
||||
"formatZH": "更新 compose 模版 [name]",
|
||||
@ -146,11 +149,12 @@
|
||||
"paramKeys": [],
|
||||
"BeforeFuntions": [
|
||||
{
|
||||
"info": "ids",
|
||||
"input_colume": "id",
|
||||
"input_value": "ids",
|
||||
"isList": true,
|
||||
"db": "compose_templates",
|
||||
"key": "name",
|
||||
"value": "names"
|
||||
"output_colume": "name",
|
||||
"output_value": "names"
|
||||
}
|
||||
],
|
||||
"formatZH": "删除 compose 模版 [names]",
|
||||
@ -166,11 +170,12 @@
|
||||
"paramKeys": [],
|
||||
"BeforeFuntions": [
|
||||
{
|
||||
"info": "repoID",
|
||||
"input_colume": "id",
|
||||
"input_value": "repoID",
|
||||
"isList": false,
|
||||
"db": "image_repos",
|
||||
"key": "name",
|
||||
"value": "reponame"
|
||||
"output_colume": "name",
|
||||
"output_value": "reponame"
|
||||
}
|
||||
],
|
||||
"formatZH": "镜像拉取 [reponame][imageName]",
|
||||
@ -187,11 +192,12 @@
|
||||
"paramKeys": [],
|
||||
"BeforeFuntions": [
|
||||
{
|
||||
"info": "repoID",
|
||||
"input_colume": "id",
|
||||
"input_value": "repoID",
|
||||
"isList": false,
|
||||
"db": "image_repos",
|
||||
"key": "name",
|
||||
"value": "reponame"
|
||||
"output_colume": "name",
|
||||
"output_value": "reponame"
|
||||
}
|
||||
],
|
||||
"formatZH": "[tagName] 推送到 [reponame][name]",
|
||||
@ -242,11 +248,12 @@
|
||||
"paramKeys": [],
|
||||
"BeforeFuntions": [
|
||||
{
|
||||
"info": "repoID",
|
||||
"input_colume": "id",
|
||||
"input_value": "repoID",
|
||||
"isList": false,
|
||||
"db": "image_repos",
|
||||
"key": "name",
|
||||
"value": "reponame"
|
||||
"output_colume": "name",
|
||||
"output_value": "reponame"
|
||||
}
|
||||
],
|
||||
"formatZH": "tag 镜像 [reponame][targetName]",
|
||||
@ -345,11 +352,12 @@
|
||||
"paramKeys": [],
|
||||
"BeforeFuntions": [
|
||||
{
|
||||
"info": "ids",
|
||||
"input_colume": "id",
|
||||
"input_value": "ids",
|
||||
"isList": true,
|
||||
"db": "cronjobs",
|
||||
"key": "name",
|
||||
"value": "names"
|
||||
"output_colume": "name",
|
||||
"output_value": "names"
|
||||
}
|
||||
],
|
||||
"formatZH": "删除计划任务 [names]",
|
||||
@ -364,11 +372,12 @@
|
||||
"paramKeys": [],
|
||||
"BeforeFuntions": [
|
||||
{
|
||||
"info": "id",
|
||||
"input_colume": "id",
|
||||
"input_value": "id",
|
||||
"isList": false,
|
||||
"db": "cronjobs",
|
||||
"key": "name",
|
||||
"value": "name"
|
||||
"output_colume": "name",
|
||||
"output_value": "name"
|
||||
}
|
||||
],
|
||||
"formatZH": "更新计划任务 [name]",
|
||||
@ -384,11 +393,12 @@
|
||||
"paramKeys": [],
|
||||
"BeforeFuntions": [
|
||||
{
|
||||
"info": "id",
|
||||
"input_colume": "id",
|
||||
"input_value": "id",
|
||||
"isList": false,
|
||||
"db": "cronjobs",
|
||||
"key": "name",
|
||||
"value": "name"
|
||||
"output_colume": "name",
|
||||
"output_value": "name"
|
||||
}
|
||||
],
|
||||
"formatZH": "修改计划任务 [name] 状态为 [status]",
|
||||
@ -403,11 +413,12 @@
|
||||
"paramKeys": [],
|
||||
"BeforeFuntions": [
|
||||
{
|
||||
"info": "id",
|
||||
"input_colume": "id",
|
||||
"input_value": "id",
|
||||
"isList": false,
|
||||
"db": "cronjobs",
|
||||
"key": "name",
|
||||
"value": "name"
|
||||
"output_colume": "name",
|
||||
"output_value": "name"
|
||||
}
|
||||
],
|
||||
"formatZH": "手动执行计划任务 [name]",
|
||||
@ -472,11 +483,12 @@
|
||||
"paramKeys": [],
|
||||
"BeforeFuntions": [
|
||||
{
|
||||
"info": "id",
|
||||
"input_colume": "id",
|
||||
"input_value": "id",
|
||||
"isList": false,
|
||||
"db": "database_mysqls",
|
||||
"key": "name",
|
||||
"value": "name"
|
||||
"output_colume": "name",
|
||||
"output_value": "name"
|
||||
}
|
||||
],
|
||||
"formatZH": "删除 mysql 数据库 [name]",
|
||||
@ -489,11 +501,12 @@
|
||||
"paramKeys": [],
|
||||
"BeforeFuntions": [
|
||||
{
|
||||
"info": "id",
|
||||
"input_colume": "id",
|
||||
"input_value": "id",
|
||||
"isList": false,
|
||||
"db": "database_mysqls",
|
||||
"key": "name",
|
||||
"value": "name"
|
||||
"output_colume": "name",
|
||||
"output_value": "name"
|
||||
}
|
||||
],
|
||||
"formatZH": "mysql 数据库 [name] 描述信息修改 [description]",
|
||||
@ -595,11 +608,12 @@
|
||||
"paramKeys": [],
|
||||
"BeforeFuntions": [
|
||||
{
|
||||
"info": "ids",
|
||||
"input_colume": "id",
|
||||
"input_value": "ids",
|
||||
"isList": true,
|
||||
"db": "commands",
|
||||
"key": "name",
|
||||
"value": "names"
|
||||
"output_colume": "name",
|
||||
"output_value": "names"
|
||||
}
|
||||
],
|
||||
"formatZH": "删除快捷命令 [names]",
|
||||
@ -636,11 +650,12 @@
|
||||
"paramKeys": [],
|
||||
"BeforeFuntions": [
|
||||
{
|
||||
"info": "ids",
|
||||
"input_colume": "id",
|
||||
"input_value": "ids",
|
||||
"isList": true,
|
||||
"db": "backup_accounts",
|
||||
"key": "type",
|
||||
"value": "types"
|
||||
"output_colume": "type",
|
||||
"output_value": "types"
|
||||
}
|
||||
],
|
||||
"formatZH": "删除备份账号 [types]",
|
||||
@ -678,11 +693,12 @@
|
||||
"paramKeys": [],
|
||||
"BeforeFuntions": [
|
||||
{
|
||||
"info": "ids",
|
||||
"input_colume": "id",
|
||||
"input_value": "ids",
|
||||
"isList": true,
|
||||
"db": "backup_records",
|
||||
"key": "file_name",
|
||||
"value": "files"
|
||||
"output_colume": "file_name",
|
||||
"output_value": "files"
|
||||
}
|
||||
],
|
||||
"formatZH": "删除备份记录 [files]",
|
||||
@ -697,11 +713,12 @@
|
||||
"paramKeys": [],
|
||||
"BeforeFuntions": [
|
||||
{
|
||||
"info": "id",
|
||||
"input_colume": "id",
|
||||
"input_value": "id",
|
||||
"isList": false,
|
||||
"db": "groups",
|
||||
"key": "name",
|
||||
"value": "name"
|
||||
"output_colume": "name",
|
||||
"output_value": "name"
|
||||
}
|
||||
],
|
||||
"formatZH": "删除组 [name]",
|
||||
@ -740,11 +757,12 @@
|
||||
"paramKeys": [],
|
||||
"BeforeFuntions": [
|
||||
{
|
||||
"info": "id",
|
||||
"input_colume": "id",
|
||||
"input_value": "id",
|
||||
"isList": false,
|
||||
"db": "hosts",
|
||||
"key": "addr",
|
||||
"value": "addr"
|
||||
"output_colume": "addr",
|
||||
"output_value": "addr"
|
||||
}
|
||||
],
|
||||
"formatZH": "删除主机 [addr]",
|
||||
@ -849,18 +867,19 @@
|
||||
"paramKeys": [],
|
||||
"BeforeFuntions": [
|
||||
{
|
||||
"info": "name",
|
||||
"input_colume": "name",
|
||||
"input_value": "name",
|
||||
"isList": false,
|
||||
"db": "app_installs",
|
||||
"key": "app_id",
|
||||
"value": "appId"
|
||||
"output_colume": "app_id",
|
||||
"output_value": "appId"
|
||||
},
|
||||
{
|
||||
"info": "appId",
|
||||
"isList": false,
|
||||
"db": "apps",
|
||||
"key": "key",
|
||||
"value": "appKey"
|
||||
"output_colume": "key",
|
||||
"output_value": "appKey"
|
||||
}
|
||||
],
|
||||
"formatZH": "安装应用 [appKey]-[name]",
|
||||
@ -876,29 +895,32 @@
|
||||
"paramKeys": [],
|
||||
"BeforeFuntions": [
|
||||
{
|
||||
"info": "installId",
|
||||
"input_colume": "id",
|
||||
"input_value": "installId",
|
||||
"isList": false,
|
||||
"db": "app_installs",
|
||||
"key": "app_id",
|
||||
"value": "appId"
|
||||
"output_colume": "app_id",
|
||||
"output_value": "appId"
|
||||
},
|
||||
{
|
||||
"info": "installId",
|
||||
"input_colume": "id",
|
||||
"input_value": "installId",
|
||||
"isList": false,
|
||||
"db": "app_installs",
|
||||
"key": "name",
|
||||
"value": "appName"
|
||||
"output_colume": "name",
|
||||
"output_value": "appName"
|
||||
},
|
||||
{
|
||||
"info": "appId",
|
||||
"input_colume": "id",
|
||||
"input_value": "appId",
|
||||
"isList": false,
|
||||
"db": "apps",
|
||||
"key": "key",
|
||||
"value": "appKey"
|
||||
"output_colume": "key",
|
||||
"output_value": "appKey"
|
||||
}
|
||||
],
|
||||
"formatZH": "应用 [appKey]-[appName] [operate]",
|
||||
"formatEN": "App [appKey]-[appName] [operate]"
|
||||
"formatZH": "[appKey] 应用 [appName] [operate]",
|
||||
"formatEN": "[appKey] App [appName] [operate]"
|
||||
},
|
||||
{
|
||||
"api": "/api/v1/apps/installed/sync",
|
||||
@ -918,11 +940,12 @@
|
||||
"paramKeys": [],
|
||||
"BeforeFuntions": [
|
||||
{
|
||||
"info": "ids",
|
||||
"input_colume": "id",
|
||||
"input_value": "ids",
|
||||
"isList": true,
|
||||
"db": "app_install_backups",
|
||||
"key": "name",
|
||||
"value": "names"
|
||||
"output_colume": "name",
|
||||
"output_value": "names"
|
||||
}
|
||||
],
|
||||
"formatZH": "删除应用备份 [names]",
|
||||
@ -1089,11 +1112,12 @@
|
||||
"paramKeys": [],
|
||||
"BeforeFuntions": [
|
||||
{
|
||||
"info": "websiteId",
|
||||
"input_colume": "id",
|
||||
"input_value": "websiteId",
|
||||
"isList": false,
|
||||
"db": "websites",
|
||||
"key": "primary_domain",
|
||||
"value": "domain"
|
||||
"output_colume": "primary_domain",
|
||||
"output_value": "domain"
|
||||
}
|
||||
],
|
||||
"formatZH": "更新 nginx 配置 [domain]",
|
||||
@ -1128,11 +1152,12 @@
|
||||
"paramKeys": [],
|
||||
"BeforeFuntions": [
|
||||
{
|
||||
"info": "id",
|
||||
"input_colume": "id",
|
||||
"input_value": "id",
|
||||
"isList": false,
|
||||
"db": "website_acme_accounts",
|
||||
"key": "email",
|
||||
"value": "email"
|
||||
"output_colume": "email",
|
||||
"output_value": "email"
|
||||
}
|
||||
],
|
||||
"formatZH": "删除网站 acme [email]",
|
||||
@ -1169,11 +1194,12 @@
|
||||
"paramKeys": [],
|
||||
"BeforeFuntions": [
|
||||
{
|
||||
"info": "id",
|
||||
"input_colume": "id",
|
||||
"input_value": "id",
|
||||
"isList": false,
|
||||
"db": "website_dns_accounts",
|
||||
"key": "name",
|
||||
"value": "name"
|
||||
"output_colume": "name",
|
||||
"output_value": "name"
|
||||
}
|
||||
],
|
||||
"formatZH": "删除网站 dns [name]",
|
||||
@ -1210,11 +1236,12 @@
|
||||
"paramKeys": [],
|
||||
"BeforeFuntions": [
|
||||
{
|
||||
"info": "SSLId",
|
||||
"input_colume": "id",
|
||||
"input_value": "SSLId",
|
||||
"isList": false,
|
||||
"db": "website_ssls",
|
||||
"key": "primary_domain",
|
||||
"value": "domain"
|
||||
"output_colume": "primary_domain",
|
||||
"output_value": "domain"
|
||||
}
|
||||
],
|
||||
"formatZH": "重置 ssl [domain]",
|
||||
@ -1251,11 +1278,12 @@
|
||||
"paramKeys": [],
|
||||
"BeforeFuntions": [
|
||||
{
|
||||
"info": "id",
|
||||
"input_colume": "id",
|
||||
"input_value": "id",
|
||||
"isList": false,
|
||||
"db": "websites",
|
||||
"key": "primary_domain",
|
||||
"value": "domain"
|
||||
"output_colume": "primary_domain",
|
||||
"output_value": "domain"
|
||||
}
|
||||
],
|
||||
"formatZH": "删除网站 [domain]",
|
||||
@ -1295,11 +1323,12 @@
|
||||
"paramKeys": [],
|
||||
"BeforeFuntions": [
|
||||
{
|
||||
"info": "id",
|
||||
"input_colume": "id",
|
||||
"input_value": "id",
|
||||
"isList": false,
|
||||
"db": "website_domains",
|
||||
"key": "domain",
|
||||
"value": "domain"
|
||||
"output_colume": "domain",
|
||||
"output_value": "domain"
|
||||
}
|
||||
],
|
||||
"formatZH": "删除域名 [domain]",
|
||||
@ -1325,11 +1354,12 @@
|
||||
"paramKeys": [],
|
||||
"BeforeFuntions": [
|
||||
{
|
||||
"info": "websiteId",
|
||||
"input_colume": "id",
|
||||
"input_value": "websiteId",
|
||||
"isList": false,
|
||||
"db": "websites",
|
||||
"key": "primary_domain",
|
||||
"value": "domain"
|
||||
"output_colume": "primary_domain",
|
||||
"output_value": "domain"
|
||||
}
|
||||
],
|
||||
"formatZH": "nginx 配置修改 [domain]",
|
||||
@ -1344,11 +1374,12 @@
|
||||
"paramKeys": [],
|
||||
"BeforeFuntions": [
|
||||
{
|
||||
"info": "websiteId",
|
||||
"input_colume": "id",
|
||||
"input_value": "websiteId",
|
||||
"isList": false,
|
||||
"db": "websites",
|
||||
"key": "primary_domain",
|
||||
"value": "domain"
|
||||
"output_colume": "primary_domain",
|
||||
"output_value": "domain"
|
||||
}
|
||||
],
|
||||
"formatZH": "WAF 配置修改 [domain]",
|
||||
|
@ -54,6 +54,11 @@ export namespace Database {
|
||||
permission: string;
|
||||
description: string;
|
||||
}
|
||||
export interface MysqlDBDelete {
|
||||
id: number;
|
||||
forceDelete: boolean;
|
||||
deleteBackup: boolean;
|
||||
}
|
||||
export interface MysqlVariables {
|
||||
mysqlName: string;
|
||||
binlog_cache_size: number;
|
||||
|
@ -37,8 +37,8 @@ export const updateMysqlConfByFile = (params: Database.MysqlConfUpdateByFile) =>
|
||||
export const deleteCheckMysqlDB = (id: number) => {
|
||||
return http.post<Array<string>>(`/databases/del/check`, { id: id });
|
||||
};
|
||||
export const deleteMysqlDB = (id: number) => {
|
||||
return http.post(`/databases/del`, { id: id });
|
||||
export const deleteMysqlDB = (params: Database.MysqlDBDelete) => {
|
||||
return http.post(`/databases/del`, params);
|
||||
};
|
||||
|
||||
export const loadMysqlBaseInfo = () => {
|
||||
|
@ -225,6 +225,8 @@ export default {
|
||||
logout: 'Logout',
|
||||
},
|
||||
database: {
|
||||
delete: 'Delete operation cannot be rolled back, please input "',
|
||||
deleteHelper: '" to delete this database',
|
||||
create: 'Create database',
|
||||
noMysql: 'No {0} database is detected, please go to App Store and click Install!',
|
||||
goInstall: 'Go to install',
|
||||
@ -591,7 +593,7 @@ export default {
|
||||
detail: {
|
||||
users: 'User',
|
||||
hosts: 'Host',
|
||||
groups: 'Group',
|
||||
apps: 'App',
|
||||
containers: 'Container',
|
||||
commands: 'Command',
|
||||
backups: 'Backup Account',
|
||||
|
@ -230,6 +230,8 @@ export default {
|
||||
logout: '退出登录',
|
||||
},
|
||||
database: {
|
||||
delete: '删除操作无法回滚,请输入 "',
|
||||
deleteHelper: '" 删除此数据库',
|
||||
create: '创建数据库',
|
||||
noMysql: '当前未检测到 {0} 数据库,请进入应用商店点击安装!',
|
||||
mysqlBadStatus: '当前 mysql 应用状态异常,请在',
|
||||
@ -603,7 +605,7 @@ export default {
|
||||
detail: {
|
||||
users: '用户',
|
||||
hosts: '主机',
|
||||
groups: '组',
|
||||
apps: '应用',
|
||||
containers: '容器',
|
||||
commands: '快捷命令',
|
||||
backups: '备份账号',
|
||||
|
@ -9,23 +9,18 @@
|
||||
<el-form ref="deleteForm" label-position="left">
|
||||
<el-form-item>
|
||||
<el-checkbox v-model="deleteReq.forceDelete" :label="$t('app.forceDelete')" />
|
||||
</el-form-item>
|
||||
<div class="helper">
|
||||
<span class="input-help">
|
||||
{{ $t('app.forceDeleteHelper') }}
|
||||
</span>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-checkbox v-model="deleteReq.deleteBackup" :label="$t('app.deleteBackup')" />
|
||||
</el-form-item>
|
||||
<div class="helper">
|
||||
<span class="input-help">
|
||||
{{ $t('app.deleteBackupHelper') }}
|
||||
</span>
|
||||
</div>
|
||||
<br />
|
||||
<span v-html="deleteHelper"></span>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<span v-html="deleteHelper"></span>
|
||||
<el-input v-model="deleteInfo" :placeholder="appInstallName" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
@ -98,9 +93,3 @@ defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.helper {
|
||||
margin-top: -20px;
|
||||
}
|
||||
</style>
|
||||
|
@ -36,7 +36,7 @@
|
||||
<el-form-item v-if="form.from === 'edit'">
|
||||
<codemirror
|
||||
:autofocus="true"
|
||||
placeholder="None data"
|
||||
placeholder="#Define or paste the content of your docker-compose file here"
|
||||
:indent-with-tab="true"
|
||||
:tabSize="4"
|
||||
style="max-height: 500px; width: 100%; min-height: 200px"
|
||||
|
@ -2,6 +2,12 @@
|
||||
<div v-loading="loading">
|
||||
<LayoutContent :header="composeName" back-name="Compose" :reload="true">
|
||||
<div v-if="createdBy === '1Panel'">
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>{{ $t('container.compose') }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-button-group>
|
||||
<el-button @click="onComposeOperate('start')">{{ $t('container.start') }}</el-button>
|
||||
<el-button @click="onComposeOperate('stop')">{{ $t('container.stop') }}</el-button>
|
||||
@ -9,6 +15,7 @@
|
||||
{{ $t('container.remove') }}
|
||||
</el-button>
|
||||
</el-button-group>
|
||||
</el-card>
|
||||
</div>
|
||||
<div v-else>
|
||||
<el-alert :closable="false" show-icon :title="$t('container.composeDetailHelper')" type="info" />
|
||||
|
@ -8,7 +8,7 @@
|
||||
<div v-loading="loading">
|
||||
<codemirror
|
||||
:autofocus="true"
|
||||
placeholder="None data"
|
||||
placeholder="#Define or paste the content of your docker-compose file here"
|
||||
:indent-with-tab="true"
|
||||
:tabSize="4"
|
||||
style="max-height: 500px; width: 100%; min-height: 200px"
|
||||
|
@ -24,7 +24,7 @@
|
||||
<el-form-item v-if="form.from === 'edit'" :rules="Rules.requiredInput">
|
||||
<codemirror
|
||||
:autofocus="true"
|
||||
placeholder="None data"
|
||||
placeholder="#Define or paste the content of your Dockerfile here"
|
||||
:indent-with-tab="true"
|
||||
:tabSize="4"
|
||||
style="max-height: 500px; width: 100%; min-height: 200px"
|
||||
@ -57,7 +57,7 @@
|
||||
<codemirror
|
||||
v-if="logVisiable"
|
||||
:autofocus="true"
|
||||
placeholder="Wait for build output..."
|
||||
placeholder="Waiting for build output..."
|
||||
:indent-with-tab="true"
|
||||
:tabSize="4"
|
||||
style="max-height: 300px"
|
||||
|
@ -35,7 +35,7 @@
|
||||
<codemirror
|
||||
v-if="logVisiable"
|
||||
:autofocus="true"
|
||||
placeholder="Wait for pull output..."
|
||||
placeholder="Waiting for pull output..."
|
||||
:indent-with-tab="true"
|
||||
:tabSize="4"
|
||||
style="max-height: 300px"
|
||||
|
@ -32,7 +32,7 @@
|
||||
<codemirror
|
||||
v-if="logVisiable"
|
||||
:autofocus="true"
|
||||
placeholder="Wait for pull output..."
|
||||
placeholder="Waiting for push output..."
|
||||
:indent-with-tab="true"
|
||||
:tabSize="4"
|
||||
style="max-height: 300px"
|
||||
|
@ -15,7 +15,7 @@
|
||||
<el-form-item>
|
||||
<codemirror
|
||||
:autofocus="true"
|
||||
placeholder="None data"
|
||||
placeholder="#Define or paste the content of your docker-compose file here"
|
||||
:indent-with-tab="true"
|
||||
:tabSize="4"
|
||||
style="max-height: 500px; width: 100%; min-height: 200px"
|
||||
|
94
frontend/src/views/database/mysql/delete/index.vue
Normal file
94
frontend/src/views/database/mysql/delete/index.vue
Normal file
@ -0,0 +1,94 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisiable"
|
||||
:title="$t('commons.button.delete') + ' - ' + dbName"
|
||||
width="30%"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<el-form ref="deleteForm">
|
||||
<el-form-item>
|
||||
<el-checkbox v-model="deleteReq.forceDelete" :label="$t('app.forceDelete')" />
|
||||
<span class="input-help">
|
||||
{{ $t('app.forceDeleteHelper') }}
|
||||
</span>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-checkbox v-model="deleteReq.deleteBackup" :label="$t('app.deleteBackup')" />
|
||||
<span class="input-help">
|
||||
{{ $t('app.deleteBackupHelper') }}
|
||||
</span>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<div>
|
||||
<span style="font-size: 12px">{{ $t('database.delete') }}</span>
|
||||
<span style="font-size: 12px; color: red; font-weight: 500">{{ dbName }}</span>
|
||||
<span style="font-size: 12px">{{ $t('database.deleteHelper') }}</span>
|
||||
</div>
|
||||
<el-input v-model="deleteInfo" :placeholder="dbName"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="dialogVisiable = false" :loading="loading">
|
||||
{{ $t('commons.button.cancel') }}
|
||||
</el-button>
|
||||
<el-button type="primary" @click="submit" :loading="loading" :disabled="deleteInfo != dbName">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ElMessage, FormInstance } from 'element-plus';
|
||||
import { ref } from 'vue';
|
||||
import i18n from '@/lang';
|
||||
import { deleteMysqlDB } from '@/api/modules/database';
|
||||
|
||||
let deleteReq = ref({
|
||||
id: 0,
|
||||
deleteBackup: false,
|
||||
forceDelete: false,
|
||||
});
|
||||
let dialogVisiable = ref(false);
|
||||
let loading = ref(false);
|
||||
let deleteInfo = ref('');
|
||||
let dbName = ref('');
|
||||
|
||||
const deleteForm = ref<FormInstance>();
|
||||
|
||||
interface DialogProps {
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
||||
const emit = defineEmits<{ (e: 'search'): void }>();
|
||||
|
||||
const acceptParams = async (prop: DialogProps) => {
|
||||
deleteReq.value = {
|
||||
id: prop.id,
|
||||
deleteBackup: false,
|
||||
forceDelete: false,
|
||||
};
|
||||
dbName.value = prop.name;
|
||||
deleteInfo.value = '';
|
||||
dialogVisiable.value = true;
|
||||
};
|
||||
|
||||
const submit = async () => {
|
||||
loading.value = true;
|
||||
deleteMysqlDB(deleteReq.value)
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
emit('search');
|
||||
ElMessage.success(i18n.global.t('commons.msg.deleteSuccess'));
|
||||
dialogVisiable.value = false;
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
</script>
|
@ -19,12 +19,7 @@
|
||||
</el-card>
|
||||
<div v-if="mysqlIsExist" :class="{ mask: mysqlStatus != 'Running' }">
|
||||
<el-card v-if="!isOnSetting" style="margin-top: 20px">
|
||||
<ComplexTable
|
||||
:pagination-config="paginationConfig"
|
||||
v-model:selects="selects"
|
||||
@search="search"
|
||||
:data="data"
|
||||
>
|
||||
<ComplexTable :pagination-config="paginationConfig" @search="search" :data="data">
|
||||
<template #toolbar>
|
||||
<el-button type="primary" icon="Plus" @click="onOpenDialog()">
|
||||
{{ $t('commons.button.create') }}
|
||||
@ -37,7 +32,6 @@
|
||||
</el-button>
|
||||
<el-button @click="goDashboard" type="primary" plain icon="Position">phpMyAdmin</el-button>
|
||||
</template>
|
||||
<el-table-column type="selection" fix />
|
||||
<el-table-column :label="$t('commons.table.name')" prop="name" />
|
||||
<el-table-column :label="$t('commons.login.username')" prop="username" />
|
||||
<el-table-column :label="$t('commons.login.password')" prop="password">
|
||||
@ -170,10 +164,11 @@
|
||||
<RootPasswordDialog ref="rootPasswordRef" />
|
||||
<RemoteAccessDialog ref="remoteAccessRef" />
|
||||
<UploadDialog ref="uploadRef" />
|
||||
<OperatrDialog @search="search" ref="dialogRef" />
|
||||
<OperateDialog @search="search" ref="dialogRef" />
|
||||
<BackupRecords ref="dialogBackupRef" />
|
||||
|
||||
<AppResources ref="checkRef"></AppResources>
|
||||
<DeleteDialog ref="deleteRef" @search="search" />
|
||||
|
||||
<ConfirmDialog ref="confirmDialogRef" @confirm="onSubmit"></ConfirmDialog>
|
||||
</div>
|
||||
@ -181,7 +176,8 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import ComplexTable from '@/components/complex-table/index.vue';
|
||||
import OperatrDialog from '@/views/database/mysql/create/index.vue';
|
||||
import OperateDialog from '@/views/database/mysql/create/index.vue';
|
||||
import DeleteDialog from '@/views/database/mysql/delete/index.vue';
|
||||
import RootPasswordDialog from '@/views/database/mysql/password/index.vue';
|
||||
import RemoteAccessDialog from '@/views/database/mysql/remote/index.vue';
|
||||
import BackupRecords from '@/views/database/mysql/backup/index.vue';
|
||||
@ -195,7 +191,6 @@ import { dateFromat } from '@/utils/util';
|
||||
import { reactive, ref } from 'vue';
|
||||
import {
|
||||
deleteCheckMysqlDB,
|
||||
deleteMysqlDB,
|
||||
loadRemoteAccess,
|
||||
searchMysqlDBs,
|
||||
updateMysqlAccess,
|
||||
@ -203,7 +198,6 @@ import {
|
||||
updateMysqlPassword,
|
||||
} 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';
|
||||
@ -213,11 +207,11 @@ import router from '@/routers';
|
||||
|
||||
const loading = ref(false);
|
||||
|
||||
const selects = ref<any>([]);
|
||||
const mysqlName = ref();
|
||||
const isOnSetting = ref<boolean>();
|
||||
|
||||
const checkRef = ref();
|
||||
const deleteRef = ref();
|
||||
|
||||
const phpadminPort = ref();
|
||||
const phpVisiable = ref(false);
|
||||
@ -403,8 +397,7 @@ const onDelete = async (row: Database.MysqlDBInfo) => {
|
||||
if (res.data && res.data.length > 0) {
|
||||
checkRef.value.acceptParams({ items: res.data });
|
||||
} else {
|
||||
await useDeleteData(deleteMysqlDB, row.id, 'app.deleteWarn');
|
||||
search();
|
||||
deleteRef.value.acceptParams({ id: row.id, name: row.name });
|
||||
}
|
||||
};
|
||||
|
||||
@ -446,6 +439,7 @@ const buttons = [
|
||||
if (row.permission === '%' || row.permission === 'localhost') {
|
||||
changeForm.privilege = row.permission;
|
||||
} else {
|
||||
changeForm.privilegeIPs = row.permission;
|
||||
changeForm.privilege = 'ip';
|
||||
}
|
||||
changeVisiable.value = true;
|
||||
|
@ -75,7 +75,7 @@ import { File } from '@/api/interface/file';
|
||||
import { BatchDeleteFile, GetFilesList, UploadFileData } from '@/api/modules/files';
|
||||
|
||||
const selects = ref<any>([]);
|
||||
const baseDir = '/opt/1Panel/data/uploads/database/';
|
||||
const baseDir = ref();
|
||||
|
||||
const data = ref();
|
||||
const paginationConfig = reactive({
|
||||
@ -94,6 +94,7 @@ interface DialogProps {
|
||||
const acceptParams = (params: DialogProps): void => {
|
||||
mysqlName.value = params.mysqlName;
|
||||
dbName.value = params.dbName;
|
||||
baseDir.value = '/opt/1Panel/data/uploads/database/mysql/' + mysqlName.value + '/' + dbName.value + '/';
|
||||
upVisiable.value = true;
|
||||
search();
|
||||
};
|
||||
@ -102,7 +103,7 @@ const search = async () => {
|
||||
let params = {
|
||||
page: paginationConfig.currentPage,
|
||||
pageSize: paginationConfig.pageSize,
|
||||
path: baseDir,
|
||||
path: baseDir.value,
|
||||
expand: true,
|
||||
};
|
||||
const res = await GetFilesList(params);
|
||||
@ -114,7 +115,7 @@ const onRecover = async (row: File.File) => {
|
||||
let params = {
|
||||
mysqlName: mysqlName.value,
|
||||
dbName: dbName.value,
|
||||
fileDir: baseDir,
|
||||
fileDir: baseDir.value,
|
||||
fileName: row.name,
|
||||
};
|
||||
await recoverByUpload(params);
|
||||
@ -156,7 +157,7 @@ const onSubmit = () => {
|
||||
if (uploaderFiles.value[0]!.raw != undefined) {
|
||||
formData.append('file', uploaderFiles.value[0]!.raw);
|
||||
}
|
||||
formData.append('path', baseDir);
|
||||
formData.append('path', baseDir.value);
|
||||
UploadFileData(formData, {}).then(() => {
|
||||
ElMessage.success(i18n.global.t('file.uploadSuccess'));
|
||||
handleClose();
|
||||
@ -167,10 +168,10 @@ const onSubmit = () => {
|
||||
const onBatchDelete = async (row: File.File | null) => {
|
||||
let files: Array<string> = [];
|
||||
if (row) {
|
||||
files.push(baseDir + row.name);
|
||||
files.push(baseDir.value + row.name);
|
||||
} else {
|
||||
selects.value.forEach((item: File.File) => {
|
||||
files.push(baseDir + item.name);
|
||||
files.push(baseDir.value + item.name);
|
||||
});
|
||||
}
|
||||
await useDeleteData(BatchDeleteFile, { paths: files, isDir: false }, 'commons.msg.delete');
|
||||
|
@ -21,7 +21,7 @@
|
||||
<el-button style="margin-top: 10px" @click="getDefaultConfig()">
|
||||
{{ $t('app.defaultConfig') }}
|
||||
</el-button>
|
||||
<el-button type="primary" @click="onSaveFile" style="margin-top: 5px">
|
||||
<el-button type="primary" @click="onSaveFile" style="margin-top: 10px">
|
||||
{{ $t('commons.button.save') }}
|
||||
</el-button>
|
||||
<el-row>
|
||||
@ -98,6 +98,7 @@
|
||||
</LayoutContent>
|
||||
</el-card>
|
||||
|
||||
<ConfirmDialog ref="confirmDialogRef" @confirm="submtiFile"></ConfirmDialog>
|
||||
<ConfirmDialog ref="confirmFileRef" @confirm="submtiFile"></ConfirmDialog>
|
||||
<ConfirmDialog ref="confirmFormRef" @confirm="submtiForm"></ConfirmDialog>
|
||||
<ConfirmDialog ref="confirmPortRef" @confirm="onChangePort(formRef)"></ConfirmDialog>
|
||||
|
@ -15,11 +15,11 @@
|
||||
<el-table-column min-width="40" :label="$t('logs.loginStatus')" prop="status">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row.status === 'Success'">
|
||||
<el-tag type="success">{{ row.status }}</el-tag>
|
||||
<el-tag type="success">{{ $t('commons.status.success') }}</el-tag>
|
||||
</div>
|
||||
<div v-else>
|
||||
<el-tooltip class="box-item" effect="dark" :content="row.message" placement="top-start">
|
||||
<el-tag type="danger">{{ row.status }}</el-tag>
|
||||
<el-tag type="danger">{{ $t('commons.status.failed') }}</el-tag>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -19,6 +19,7 @@
|
||||
<el-form-item prop="password">
|
||||
<el-input
|
||||
type="password"
|
||||
clearable
|
||||
v-model="registerForm.password"
|
||||
show-password
|
||||
:placeholder="$t('commons.login.password')"
|
||||
@ -33,6 +34,7 @@
|
||||
<el-form-item prop="rePassword">
|
||||
<el-input
|
||||
type="password"
|
||||
clearable
|
||||
v-model="registerForm.rePassword"
|
||||
show-password
|
||||
:placeholder="$t('commons.login.rePassword')"
|
||||
@ -113,6 +115,7 @@
|
||||
<el-form-item prop="password">
|
||||
<el-input
|
||||
type="password"
|
||||
clearable
|
||||
v-model="loginForm.password"
|
||||
show-password
|
||||
:placeholder="$t('commons.login.password')"
|
||||
|
@ -42,7 +42,7 @@
|
||||
prop="credential"
|
||||
:rules="Rules.requiredInput"
|
||||
>
|
||||
<el-input show-password v-model="dialogData.rowData!.credential" />
|
||||
<el-input show-password clearable v-model="dialogData.rowData!.credential" />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="dialogData.rowData!.type === 'S3'"
|
||||
@ -99,7 +99,7 @@
|
||||
<el-input v-model="dialogData.rowData!.accessKey" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('setting.password')" prop="credential" :rules="[Rules.requiredInput]">
|
||||
<el-input type="password" show-password v-model="dialogData.rowData!.credential" />
|
||||
<el-input type="password" clearable show-password v-model="dialogData.rowData!.credential" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('setting.path')" prop="bucket">
|
||||
<el-input v-model="dialogData.rowData!.bucket" />
|
||||
|
@ -10,31 +10,24 @@
|
||||
<el-form ref="deleteForm" label-position="left">
|
||||
<el-form-item>
|
||||
<el-checkbox v-model="deleteReq.forceDelete" :label="$t('website.forceDelete')" />
|
||||
</el-form-item>
|
||||
<div class="helper">
|
||||
<span class="input-help">
|
||||
{{ $t('website.forceDeleteHelper') }}
|
||||
</span>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="type === 'deployment'">
|
||||
<el-checkbox v-model="deleteReq.deleteApp" :label="$t('website.deleteApp')" />
|
||||
</el-form-item>
|
||||
<div class="helper" v-if="type === 'deployment'">
|
||||
<span class="input-help">
|
||||
{{ $t('website.deleteAppHelper') }}
|
||||
</span>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-checkbox v-model="deleteReq.deleteBackup" :label="$t('website.deleteBackup')" />
|
||||
</el-form-item>
|
||||
<div class="helper">
|
||||
<span class="input-help">
|
||||
{{ $t('website.deleteBackupHelper') }}
|
||||
</span>
|
||||
</div>
|
||||
<br />
|
||||
<span v-html="deleteHelper"></span>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<span v-html="deleteHelper"></span>
|
||||
<el-input v-model="deleteInfo" :placeholder="websiteName" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
@ -114,9 +107,3 @@ defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.helper {
|
||||
margin-top: -20px;
|
||||
}
|
||||
</style>
|
||||
|
Loading…
x
Reference in New Issue
Block a user