1
0
mirror of https://github.com/1Panel-dev/1Panel.git synced 2025-01-31 14:08:06 +08:00

feat: 实现本地远程数据库切换

This commit is contained in:
ssongliu 2023-07-24 14:55:26 +08:00 committed by ssongliu
parent cd742b0933
commit bbd649188a
15 changed files with 1071 additions and 27 deletions

View File

@ -188,12 +188,12 @@ func (b *BaseApi) UpdateMysqlConfByFile(c *gin.Context) {
// @Summary Page mysql databases // @Summary Page mysql databases
// @Description 获取 mysql 数据库列表分页 // @Description 获取 mysql 数据库列表分页
// @Accept json // @Accept json
// @Param request body dto.SearchWithPage true "request" // @Param request body dto.MysqlDBSearch true "request"
// @Success 200 {object} dto.PageResult // @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth // @Security ApiKeyAuth
// @Router /databases/search [post] // @Router /databases/search [post]
func (b *BaseApi) SearchMysql(c *gin.Context) { func (b *BaseApi) SearchMysql(c *gin.Context) {
var req dto.SearchWithPage var req dto.MysqlDBSearch
if err := c.ShouldBindJSON(&req); err != nil { if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return return

View File

@ -12,7 +12,7 @@ import (
// @Summary Create remote database // @Summary Create remote database
// @Description 创建远程数据库 // @Description 创建远程数据库
// @Accept json // @Accept json
// @Param request body dto.DatabaseCreate true "request" // @Param request body dto.RemoteDBCreate true "request"
// @Success 200 // @Success 200
// @Security ApiKeyAuth // @Security ApiKeyAuth
// @Router /databases/remote [post] // @Router /databases/remote [post]
@ -38,7 +38,7 @@ func (b *BaseApi) CreateRemoteDB(c *gin.Context) {
// @Summary Page remote databases // @Summary Page remote databases
// @Description 获取远程数据库列表分页 // @Description 获取远程数据库列表分页
// @Accept json // @Accept json
// @Param request body dto.SearchWithPage true "request" // @Param request body dto.RemoteDBSearch true "request"
// @Success 200 {object} dto.PageResult // @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth // @Security ApiKeyAuth
// @Router /databases/remote/search [post] // @Router /databases/remote/search [post]
@ -113,7 +113,7 @@ func (b *BaseApi) DeleteRemoteDB(c *gin.Context) {
// @Summary Update remote database // @Summary Update remote database
// @Description 更新远程数据库 // @Description 更新远程数据库
// @Accept json // @Accept json
// @Param request body dto.DatabaseUpdate true "request" // @Param request body dto.RemoteDBUpdate true "request"
// @Success 200 // @Success 200
// @Security ApiKeyAuth // @Security ApiKeyAuth
// @Router /databases/remote/update [post] // @Router /databases/remote/update [post]

View File

@ -2,6 +2,14 @@ package dto
import "time" import "time"
type MysqlDBSearch struct {
PageInfo
Info string `json:"info"`
From string `json:"from"`
OrderBy string `json:"orderBy"`
Order string `json:"order"`
}
type MysqlDBInfo struct { type MysqlDBInfo struct {
ID uint `json:"id"` ID uint `json:"id"`
CreatedAt time.Time `json:"createdAt"` CreatedAt time.Time `json:"createdAt"`

View File

@ -13,6 +13,7 @@ type MysqlRepo struct{}
type IMysqlRepo interface { type IMysqlRepo interface {
Get(opts ...DBOption) (model.DatabaseMysql, error) Get(opts ...DBOption) (model.DatabaseMysql, error)
WithByMysqlName(mysqlName string) DBOption WithByMysqlName(mysqlName string) DBOption
WithByFrom(from string) DBOption
List(opts ...DBOption) ([]model.DatabaseMysql, error) List(opts ...DBOption) ([]model.DatabaseMysql, error)
Page(limit, offset int, opts ...DBOption) (int64, []model.DatabaseMysql, error) Page(limit, offset int, opts ...DBOption) (int64, []model.DatabaseMysql, error)
Create(ctx context.Context, mysql *model.DatabaseMysql) error Create(ctx context.Context, mysql *model.DatabaseMysql) error
@ -86,3 +87,12 @@ func (u *MysqlRepo) WithByMysqlName(mysqlName string) DBOption {
return g.Where("mysql_name = ?", mysqlName) return g.Where("mysql_name = ?", mysqlName)
} }
} }
func (u *MysqlRepo) WithByFrom(from string) DBOption {
return func(g *gorm.DB) *gorm.DB {
if len(from) != 0 {
return g.Where("`from` = ?", from)
}
return g
}
}

View File

@ -30,7 +30,7 @@ import (
type MysqlService struct{} type MysqlService struct{}
type IMysqlService interface { type IMysqlService interface {
SearchWithPage(search dto.SearchWithPage) (int64, interface{}, error) SearchWithPage(search dto.MysqlDBSearch) (int64, interface{}, error)
ListDBName() ([]string, error) ListDBName() ([]string, error)
Create(ctx context.Context, req dto.MysqlDBCreate) (*model.DatabaseMysql, error) Create(ctx context.Context, req dto.MysqlDBCreate) (*model.DatabaseMysql, error)
ChangeAccess(info dto.ChangeDBInfo) error ChangeAccess(info dto.ChangeDBInfo) error
@ -50,8 +50,12 @@ func NewIMysqlService() IMysqlService {
return &MysqlService{} return &MysqlService{}
} }
func (u *MysqlService) SearchWithPage(search dto.SearchWithPage) (int64, interface{}, error) { func (u *MysqlService) SearchWithPage(search dto.MysqlDBSearch) (int64, interface{}, error) {
total, mysqls, err := mysqlRepo.Page(search.Page, search.PageSize, commonRepo.WithLikeName(search.Info), commonRepo.WithOrderRuleBy(search.OrderBy, search.Order)) total, mysqls, err := mysqlRepo.Page(search.Page, search.PageSize,
mysqlRepo.WithByFrom(search.From),
commonRepo.WithLikeName(search.Info),
commonRepo.WithOrderRuleBy(search.OrderBy, search.Order),
)
var dtoMysqls []dto.MysqlDBInfo var dtoMysqls []dto.MysqlDBInfo
for _, mysql := range mysqls { for _, mysql := range mysqls {
var item dto.MysqlDBInfo var item dto.MysqlDBInfo

View File

@ -1,5 +1,5 @@
// Package docs GENERATED BY SWAG; DO NOT EDIT // Code generated by swaggo/swag. DO NOT EDIT.
// This file was generated by swaggo/swag
package docs package docs
import "github.com/swaggo/swag" import "github.com/swaggo/swag"
@ -4217,6 +4217,201 @@ const docTemplate = `{
} }
} }
} }
},
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "创建远程数据库",
"consumes": [
"application/json"
],
"tags": [
"Database"
],
"summary": "Create remote database",
"parameters": [
{
"description": "request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.RemoteDBCreate"
}
}
],
"responses": {
"200": {
"description": "OK"
}
},
"x-panel-log": {
"BeforeFuntions": [],
"bodyKeys": [
"name",
"type"
],
"formatEN": "create remote database [name][type]",
"formatZH": "创建远程数据库 [name][type]",
"paramKeys": []
}
}
},
"/databases/remote/del": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "删除远程数据库",
"consumes": [
"application/json"
],
"tags": [
"Database"
],
"summary": "Delete remote database",
"parameters": [
{
"description": "request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.OperateByID"
}
}
],
"responses": {
"200": {
"description": "OK"
}
},
"x-panel-log": {
"BeforeFuntions": [
{
"db": "databases",
"input_column": "id",
"input_value": "ids",
"isList": true,
"output_column": "name",
"output_value": "names"
}
],
"bodyKeys": [
"ids"
],
"formatEN": "delete remote database [names]",
"formatZH": "删除远程数据库 [names]",
"paramKeys": []
}
}
},
"/databases/remote/list/:type": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "获取快速命令列表",
"tags": [
"Database"
],
"summary": "List remote databases",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.RemoteDBOption"
}
}
}
}
}
},
"/databases/remote/search": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "获取远程数据库列表分页",
"consumes": [
"application/json"
],
"tags": [
"Database"
],
"summary": "Page remote databases",
"parameters": [
{
"description": "request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.RemoteDBSearch"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/dto.PageResult"
}
}
}
}
},
"/databases/remote/update": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "更新远程数据库",
"consumes": [
"application/json"
],
"tags": [
"Database"
],
"summary": "Update remote database",
"parameters": [
{
"description": "request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.RemoteDBUpdate"
}
}
],
"responses": {
"200": {
"description": "OK"
}
},
"x-panel-log": {
"BeforeFuntions": [],
"bodyKeys": [
"name"
],
"formatEN": "update remote database [name]",
"formatZH": "更新远程数据库 [name]",
"paramKeys": []
}
} }
}, },
"/databases/search": { "/databases/search": {
@ -4241,7 +4436,7 @@ const docTemplate = `{
"in": "body", "in": "body",
"required": true, "required": true,
"schema": { "schema": {
"$ref": "#/definitions/dto.SearchWithPage" "$ref": "#/definitions/dto.MysqlDBSearch"
} }
} }
], ],
@ -10898,9 +11093,13 @@ const docTemplate = `{
"dto.ChangeDBInfo": { "dto.ChangeDBInfo": {
"type": "object", "type": "object",
"required": [ "required": [
"from",
"value" "value"
], ],
"properties": { "properties": {
"from": {
"type": "string"
},
"id": { "id": {
"type": "integer" "type": "integer"
}, },
@ -12348,6 +12547,7 @@ const docTemplate = `{
"type": "object", "type": "object",
"required": [ "required": [
"format", "format",
"from",
"name", "name",
"password", "password",
"permission", "permission",
@ -12366,6 +12566,9 @@ const docTemplate = `{
"big5" "big5"
] ]
}, },
"from": {
"type": "string"
},
"name": { "name": {
"type": "string" "type": "string"
}, },
@ -12397,6 +12600,33 @@ const docTemplate = `{
} }
} }
}, },
"dto.MysqlDBSearch": {
"type": "object",
"required": [
"page",
"pageSize"
],
"properties": {
"from": {
"type": "string"
},
"info": {
"type": "string"
},
"order": {
"type": "string"
},
"orderBy": {
"type": "string"
},
"page": {
"type": "integer"
},
"pageSize": {
"type": "integer"
}
}
},
"dto.MysqlStatus": { "dto.MysqlStatus": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -12972,6 +13202,125 @@ const docTemplate = `{
} }
} }
}, },
"dto.RemoteDBCreate": {
"type": "object",
"required": [
"from",
"name",
"password",
"type",
"username",
"version"
],
"properties": {
"address": {
"type": "string"
},
"description": {
"type": "string"
},
"from": {
"type": "string",
"enum": [
"local",
"remote"
]
},
"name": {
"type": "string"
},
"password": {
"type": "string"
},
"port": {
"type": "integer"
},
"type": {
"type": "string",
"enum": [
"mysql"
]
},
"username": {
"type": "string"
},
"version": {
"type": "string"
}
}
},
"dto.RemoteDBOption": {
"type": "object",
"properties": {
"address": {
"type": "string"
},
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
}
},
"dto.RemoteDBSearch": {
"type": "object",
"required": [
"page",
"pageSize"
],
"properties": {
"info": {
"type": "string"
},
"order": {
"type": "string"
},
"orderBy": {
"type": "string"
},
"page": {
"type": "integer"
},
"pageSize": {
"type": "integer"
},
"type": {
"type": "string"
}
}
},
"dto.RemoteDBUpdate": {
"type": "object",
"required": [
"password",
"username",
"version"
],
"properties": {
"address": {
"type": "string"
},
"description": {
"type": "string"
},
"id": {
"type": "integer"
},
"password": {
"type": "string"
},
"port": {
"type": "integer"
},
"username": {
"type": "string"
},
"version": {
"type": "string"
}
}
},
"dto.ResourceLimit": { "dto.ResourceLimit": {
"type": "object", "type": "object",
"properties": { "properties": {

View File

@ -4210,6 +4210,201 @@
} }
} }
} }
},
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "创建远程数据库",
"consumes": [
"application/json"
],
"tags": [
"Database"
],
"summary": "Create remote database",
"parameters": [
{
"description": "request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.RemoteDBCreate"
}
}
],
"responses": {
"200": {
"description": "OK"
}
},
"x-panel-log": {
"BeforeFuntions": [],
"bodyKeys": [
"name",
"type"
],
"formatEN": "create remote database [name][type]",
"formatZH": "创建远程数据库 [name][type]",
"paramKeys": []
}
}
},
"/databases/remote/del": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "删除远程数据库",
"consumes": [
"application/json"
],
"tags": [
"Database"
],
"summary": "Delete remote database",
"parameters": [
{
"description": "request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.OperateByID"
}
}
],
"responses": {
"200": {
"description": "OK"
}
},
"x-panel-log": {
"BeforeFuntions": [
{
"db": "databases",
"input_column": "id",
"input_value": "ids",
"isList": true,
"output_column": "name",
"output_value": "names"
}
],
"bodyKeys": [
"ids"
],
"formatEN": "delete remote database [names]",
"formatZH": "删除远程数据库 [names]",
"paramKeys": []
}
}
},
"/databases/remote/list/:type": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "获取快速命令列表",
"tags": [
"Database"
],
"summary": "List remote databases",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.RemoteDBOption"
}
}
}
}
}
},
"/databases/remote/search": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "获取远程数据库列表分页",
"consumes": [
"application/json"
],
"tags": [
"Database"
],
"summary": "Page remote databases",
"parameters": [
{
"description": "request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.RemoteDBSearch"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/dto.PageResult"
}
}
}
}
},
"/databases/remote/update": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "更新远程数据库",
"consumes": [
"application/json"
],
"tags": [
"Database"
],
"summary": "Update remote database",
"parameters": [
{
"description": "request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.RemoteDBUpdate"
}
}
],
"responses": {
"200": {
"description": "OK"
}
},
"x-panel-log": {
"BeforeFuntions": [],
"bodyKeys": [
"name"
],
"formatEN": "update remote database [name]",
"formatZH": "更新远程数据库 [name]",
"paramKeys": []
}
} }
}, },
"/databases/search": { "/databases/search": {
@ -4234,7 +4429,7 @@
"in": "body", "in": "body",
"required": true, "required": true,
"schema": { "schema": {
"$ref": "#/definitions/dto.SearchWithPage" "$ref": "#/definitions/dto.MysqlDBSearch"
} }
} }
], ],
@ -10891,9 +11086,13 @@
"dto.ChangeDBInfo": { "dto.ChangeDBInfo": {
"type": "object", "type": "object",
"required": [ "required": [
"from",
"value" "value"
], ],
"properties": { "properties": {
"from": {
"type": "string"
},
"id": { "id": {
"type": "integer" "type": "integer"
}, },
@ -12341,6 +12540,7 @@
"type": "object", "type": "object",
"required": [ "required": [
"format", "format",
"from",
"name", "name",
"password", "password",
"permission", "permission",
@ -12359,6 +12559,9 @@
"big5" "big5"
] ]
}, },
"from": {
"type": "string"
},
"name": { "name": {
"type": "string" "type": "string"
}, },
@ -12390,6 +12593,33 @@
} }
} }
}, },
"dto.MysqlDBSearch": {
"type": "object",
"required": [
"page",
"pageSize"
],
"properties": {
"from": {
"type": "string"
},
"info": {
"type": "string"
},
"order": {
"type": "string"
},
"orderBy": {
"type": "string"
},
"page": {
"type": "integer"
},
"pageSize": {
"type": "integer"
}
}
},
"dto.MysqlStatus": { "dto.MysqlStatus": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -12965,6 +13195,125 @@
} }
} }
}, },
"dto.RemoteDBCreate": {
"type": "object",
"required": [
"from",
"name",
"password",
"type",
"username",
"version"
],
"properties": {
"address": {
"type": "string"
},
"description": {
"type": "string"
},
"from": {
"type": "string",
"enum": [
"local",
"remote"
]
},
"name": {
"type": "string"
},
"password": {
"type": "string"
},
"port": {
"type": "integer"
},
"type": {
"type": "string",
"enum": [
"mysql"
]
},
"username": {
"type": "string"
},
"version": {
"type": "string"
}
}
},
"dto.RemoteDBOption": {
"type": "object",
"properties": {
"address": {
"type": "string"
},
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
}
},
"dto.RemoteDBSearch": {
"type": "object",
"required": [
"page",
"pageSize"
],
"properties": {
"info": {
"type": "string"
},
"order": {
"type": "string"
},
"orderBy": {
"type": "string"
},
"page": {
"type": "integer"
},
"pageSize": {
"type": "integer"
},
"type": {
"type": "string"
}
}
},
"dto.RemoteDBUpdate": {
"type": "object",
"required": [
"password",
"username",
"version"
],
"properties": {
"address": {
"type": "string"
},
"description": {
"type": "string"
},
"id": {
"type": "integer"
},
"password": {
"type": "string"
},
"port": {
"type": "integer"
},
"username": {
"type": "string"
},
"version": {
"type": "string"
}
}
},
"dto.ResourceLimit": { "dto.ResourceLimit": {
"type": "object", "type": "object",
"properties": { "properties": {

View File

@ -120,11 +120,14 @@ definitions:
type: object type: object
dto.ChangeDBInfo: dto.ChangeDBInfo:
properties: properties:
from:
type: string
id: id:
type: integer type: integer
value: value:
type: string type: string
required: required:
- from
- value - value
type: object type: object
dto.ChangeHostGroup: dto.ChangeHostGroup:
@ -1104,6 +1107,8 @@ definitions:
- gbk - gbk
- big5 - big5
type: string type: string
from:
type: string
name: name:
type: string type: string
password: password:
@ -1114,6 +1119,7 @@ definitions:
type: string type: string
required: required:
- format - format
- from
- name - name
- password - password
- permission - permission
@ -1130,6 +1136,24 @@ definitions:
required: required:
- id - id
type: object type: object
dto.MysqlDBSearch:
properties:
from:
type: string
info:
type: string
order:
type: string
orderBy:
type: string
page:
type: integer
pageSize:
type: integer
required:
- page
- pageSize
type: object
dto.MysqlStatus: dto.MysqlStatus:
properties: properties:
Aborted_clients: Aborted_clients:
@ -1515,6 +1539,87 @@ definitions:
used_memory_rss: used_memory_rss:
type: string type: string
type: object type: object
dto.RemoteDBCreate:
properties:
address:
type: string
description:
type: string
from:
enum:
- local
- remote
type: string
name:
type: string
password:
type: string
port:
type: integer
type:
enum:
- mysql
type: string
username:
type: string
version:
type: string
required:
- from
- name
- password
- type
- username
- version
type: object
dto.RemoteDBOption:
properties:
address:
type: string
id:
type: integer
name:
type: string
type: object
dto.RemoteDBSearch:
properties:
info:
type: string
order:
type: string
orderBy:
type: string
page:
type: integer
pageSize:
type: integer
type:
type: string
required:
- page
- pageSize
type: object
dto.RemoteDBUpdate:
properties:
address:
type: string
description:
type: string
id:
type: integer
password:
type: string
port:
type: integer
username:
type: string
version:
type: string
required:
- password
- username
- version
type: object
dto.ResourceLimit: dto.ResourceLimit:
properties: properties:
cpu: cpu:
@ -6288,6 +6393,130 @@ paths:
summary: Load mysql remote access summary: Load mysql remote access
tags: tags:
- Database Mysql - Database Mysql
post:
consumes:
- application/json
description: 创建远程数据库
parameters:
- description: request
in: body
name: request
required: true
schema:
$ref: '#/definitions/dto.RemoteDBCreate'
responses:
"200":
description: OK
security:
- ApiKeyAuth: []
summary: Create remote database
tags:
- Database
x-panel-log:
BeforeFuntions: []
bodyKeys:
- name
- type
formatEN: create remote database [name][type]
formatZH: 创建远程数据库 [name][type]
paramKeys: []
/databases/remote/del:
post:
consumes:
- application/json
description: 删除远程数据库
parameters:
- description: request
in: body
name: request
required: true
schema:
$ref: '#/definitions/dto.OperateByID'
responses:
"200":
description: OK
security:
- ApiKeyAuth: []
summary: Delete remote database
tags:
- Database
x-panel-log:
BeforeFuntions:
- db: databases
input_column: id
input_value: ids
isList: true
output_column: name
output_value: names
bodyKeys:
- ids
formatEN: delete remote database [names]
formatZH: 删除远程数据库 [names]
paramKeys: []
/databases/remote/list/:type:
get:
description: 获取快速命令列表
responses:
"200":
description: OK
schema:
items:
$ref: '#/definitions/dto.RemoteDBOption'
type: array
security:
- ApiKeyAuth: []
summary: List remote databases
tags:
- Database
/databases/remote/search:
post:
consumes:
- application/json
description: 获取远程数据库列表分页
parameters:
- description: request
in: body
name: request
required: true
schema:
$ref: '#/definitions/dto.RemoteDBSearch'
responses:
"200":
description: OK
schema:
$ref: '#/definitions/dto.PageResult'
security:
- ApiKeyAuth: []
summary: Page remote databases
tags:
- Database
/databases/remote/update:
post:
consumes:
- application/json
description: 更新远程数据库
parameters:
- description: request
in: body
name: request
required: true
schema:
$ref: '#/definitions/dto.RemoteDBUpdate'
responses:
"200":
description: OK
security:
- ApiKeyAuth: []
summary: Update remote database
tags:
- Database
x-panel-log:
BeforeFuntions: []
bodyKeys:
- name
formatEN: update remote database [name]
formatZH: 更新远程数据库 [name]
paramKeys: []
/databases/search: /databases/search:
post: post:
consumes: consumes:
@ -6299,7 +6528,7 @@ paths:
name: request name: request
required: true required: true
schema: schema:
$ref: '#/definitions/dto.SearchWithPage' $ref: '#/definitions/dto.MysqlDBSearch'
responses: responses:
"200": "200":
description: OK description: OK

View File

@ -1,6 +1,14 @@
import { ReqPage } from '.'; import { ReqPage } from '.';
export namespace Database { export namespace Database {
export interface SearchDBWithPage {
info: string;
from: string;
page: number;
pageSize: number;
orderBy?: string;
order?: string;
}
export interface SearchBackupRecord extends ReqPage { export interface SearchBackupRecord extends ReqPage {
mysqlName: string; mysqlName: string;
dbName: string; dbName: string;

View File

@ -1,10 +1,10 @@
import http from '@/api'; import http from '@/api';
import { deepCopy } from '@/utils/util'; import { deepCopy } from '@/utils/util';
import { Base64 } from 'js-base64'; import { Base64 } from 'js-base64';
import { SearchWithPage, ResPage, DescriptionUpdate } from '../interface'; import { ResPage, DescriptionUpdate } from '../interface';
import { Database } from '../interface/database'; import { Database } from '../interface/database';
export const searchMysqlDBs = (params: SearchWithPage) => { export const searchMysqlDBs = (params: Database.SearchDBWithPage) => {
return http.post<ResPage<Database.MysqlDBInfo>>(`/databases/search`, params); return http.post<ResPage<Database.MysqlDBInfo>>(`/databases/search`, params);
}; };

View File

@ -335,6 +335,14 @@ const message = {
portHelper: portHelper:
'This port is the exposed port of the container. You need to save the modification separately and restart the container!', 'This port is the exposed port of the container. You need to save the modification separately and restart the container!',
remote: 'Remote',
remoteDB: 'Remote DB',
createRemoteDB: 'Create Remote DB',
editRemoteDB: 'Edit Remote DB',
localDB: 'Local DB',
address: 'DB address',
version: 'DB version',
selectFile: 'Select file', selectFile: 'Select file',
dropHelper: 'You can drag and drop the uploaded file here or', dropHelper: 'You can drag and drop the uploaded file here or',
clickHelper: 'click to upload', clickHelper: 'click to upload',

View File

@ -330,6 +330,14 @@ const message = {
confChange: '配置修改', confChange: '配置修改',
remote: '遠程',
remoteDB: '遠程數據庫',
createRemoteDB: '創建遠程數據庫',
editRemoteDB: '編輯遠程數據庫',
localDB: '本地數據庫',
address: '數據庫地址',
version: '數據庫版本',
selectFile: '選擇文件', selectFile: '選擇文件',
dropHelper: '將上傳文件拖拽到此處或者', dropHelper: '將上傳文件拖拽到此處或者',
clickHelper: '點擊上傳', clickHelper: '點擊上傳',

View File

@ -330,6 +330,7 @@ const message = {
confChange: '配置修改', confChange: '配置修改',
remote: '远程',
remoteDB: '远程数据库', remoteDB: '远程数据库',
createRemoteDB: '创建远程数据库', createRemoteDB: '创建远程数据库',
editRemoteDB: '编辑远程数据库', editRemoteDB: '编辑远程数据库',

View File

@ -133,7 +133,7 @@ const handleClose = () => {
const loadDBOptions = async () => { const loadDBOptions = async () => {
const res = await listRemoteDBs('mysql'); const res = await listRemoteDBs('mysql');
dbOptions.value = res.data; dbOptions.value = res.data || [];
}; };
function loadLabel(item: any) { function loadLabel(item: any) {

View File

@ -1,7 +1,7 @@
<template> <template>
<div v-loading="loading"> <div v-loading="loading">
<LayoutContent :title="'MySQL ' + $t('menu.database')"> <LayoutContent :title="'MySQL ' + $t('menu.database')">
<template #app> <template #app v-if="mysqlIsExist">
<AppStatus <AppStatus
:app-key="'mysql'" :app-key="'mysql'"
v-model:loading="loading" v-model:loading="loading"
@ -11,19 +11,38 @@
></AppStatus> ></AppStatus>
</template> </template>
<template #toolbar v-if="mysqlIsExist && !isOnSetting"> <template v-if="!isOnSetting" #search>
<el-row :class="{ mask: mysqlStatus != 'Running' }"> <el-select v-model="paginationConfig.from" @change="search()">
<template #prefix>{{ $t('website.group') }}</template>
<el-option-group>
<el-option :label="$t('database.localDB')" value="local" />
</el-option-group>
<el-option-group :label="$t('database.remote')" v-if="dbOptions.length !== 0">
<el-option
v-for="(item, index) in dbOptions"
:key="index"
:value="item.address"
:label="item.name"
></el-option>
</el-option-group>
</el-select>
</template>
<template #toolbar v-if="(mysqlIsExist && !isOnSetting) || !isLocal()">
<el-row :class="{ mask: mysqlStatus != 'Running' && isLocal() }">
<el-col :xs="24" :sm="20" :md="20" :lg="20" :xl="20"> <el-col :xs="24" :sm="20" :md="20" :lg="20" :xl="20">
<el-button type="primary" @click="onOpenDialog()"> <el-button type="primary" @click="onOpenDialog()">
{{ $t('database.create') }} {{ $t('database.create') }}
</el-button> </el-button>
<el-button @click="onChangeRootPassword" type="primary" plain> <el-button v-if="isLocal()" @click="onChangeRootPassword" type="primary" plain>
{{ $t('database.databaseConnInfo') }} {{ $t('database.databaseConnInfo') }}
</el-button> </el-button>
<el-button @click="goRemoteDB" type="primary" plain> <el-button @click="goRemoteDB" type="primary" plain>
{{ $t('database.remoteDB') }} {{ $t('database.remoteDB') }}
</el-button> </el-button>
<el-button @click="goDashboard" icon="Position" type="primary" plain>phpMyAdmin</el-button> <el-button v-if="isLocal()" @click="goDashboard" icon="Position" type="primary" plain>
phpMyAdmin
</el-button>
</el-col> </el-col>
<el-col :xs="24" :sm="4" :md="4" :lg="4" :xl="4"> <el-col :xs="24" :sm="4" :md="4" :lg="4" :xl="4">
<div class="search-button"> <div class="search-button">
@ -40,13 +59,13 @@
</el-col> </el-col>
</el-row> </el-row>
</template> </template>
<template #main v-if="mysqlIsExist && !isOnSetting"> <template #main v-if="(mysqlIsExist && !isOnSetting) || !isLocal()">
<ComplexTable <ComplexTable
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
@sort-change="search" @sort-change="search"
@search="search" @search="search"
:data="data" :data="data"
:class="{ mask: mysqlStatus != 'Running' }" :class="{ mask: mysqlStatus != 'Running' && isLocal() }"
> >
<el-table-column :label="$t('commons.table.name')" prop="name" sortable /> <el-table-column :label="$t('commons.table.name')" prop="name" sortable />
<el-table-column :label="$t('commons.login.username')" prop="from"> <el-table-column :label="$t('commons.login.username')" prop="from">
@ -110,8 +129,27 @@
</template> </template>
</LayoutContent> </LayoutContent>
<div v-if="!mysqlIsExist && isLocal()">
<LayoutContent :title="'MySQL ' + $t('menu.database')" :divider="true">
<template #main>
<div class="app-warn">
<div>
<span>{{ $t('app.checkInstalledWarn', ['Mysql']) }}</span>
<span @click="goRouter">
<el-icon><Position /></el-icon>
{{ $t('database.goInstall') }}
</span>
<div>
<img src="@/assets/images/no_app.svg" />
</div>
</div>
</div>
</template>
</LayoutContent>
</div>
<el-card <el-card
v-if="mysqlStatus != 'Running' && !isOnSetting && mysqlIsExist && !loading && maskShow" v-if="mysqlStatus != 'Running' && !isOnSetting && mysqlIsExist && !loading && maskShow && isLocal"
class="mask-prompt" class="mask-prompt"
> >
<span>{{ $t('commons.service.serviceNotStarted', ['MySQL']) }}</span> <span>{{ $t('commons.service.serviceNotStarted', ['MySQL']) }}</span>
@ -162,8 +200,8 @@ import Backups from '@/components/backup/index.vue';
import UploadDialog from '@/components/upload/index.vue'; import UploadDialog from '@/components/upload/index.vue';
import PortJumpDialog from '@/components/port-jump/index.vue'; import PortJumpDialog from '@/components/port-jump/index.vue';
import { dateFormat } from '@/utils/util'; import { dateFormat } from '@/utils/util';
import { reactive, ref } from 'vue'; import { onMounted, reactive, ref } from 'vue';
import { deleteCheckMysqlDB, searchMysqlDBs, updateMysqlDescription } from '@/api/modules/database'; import { deleteCheckMysqlDB, listRemoteDBs, searchMysqlDBs, updateMysqlDescription } from '@/api/modules/database';
import i18n from '@/lang'; import i18n from '@/lang';
import { Database } from '@/api/interface/database'; import { Database } from '@/api/interface/database';
import { App } from '@/api/interface/app'; import { App } from '@/api/interface/app';
@ -176,6 +214,8 @@ const { toClipboard } = useClipboard();
const loading = ref(false); const loading = ref(false);
const maskShow = ref(true); const maskShow = ref(true);
const dbOptions = ref<Array<Database.RemoteDBOption>>([]);
const mysqlName = ref(); const mysqlName = ref();
const isOnSetting = ref<boolean>(); const isOnSetting = ref<boolean>();
@ -192,10 +232,11 @@ const paginationConfig = reactive({
currentPage: 1, currentPage: 1,
pageSize: 10, pageSize: 10,
total: 0, total: 0,
from: 'local',
}); });
const searchName = ref(); const searchName = ref();
const mysqlIsExist = ref(false); const mysqlIsExist = ref(true);
const mysqlContainer = ref(); const mysqlContainer = ref();
const mysqlStatus = ref(); const mysqlStatus = ref();
const mysqlVersion = ref(); const mysqlVersion = ref();
@ -229,6 +270,10 @@ const goRemoteDB = async () => {
router.push({ name: 'MySQL-Remote' }); router.push({ name: 'MySQL-Remote' });
}; };
function isLocal() {
return paginationConfig.from === 'local';
}
const passwordRef = ref(); const passwordRef = ref();
const settingRef = ref(); const settingRef = ref();
@ -247,6 +292,7 @@ const search = async (column?: any) => {
page: paginationConfig.currentPage, page: paginationConfig.currentPage,
pageSize: paginationConfig.pageSize, pageSize: paginationConfig.pageSize,
info: searchName.value, info: searchName.value,
from: paginationConfig.from,
orderBy: column?.order ? column.prop : 'created_at', orderBy: column?.order ? column.prop : 'created_at',
order: column?.order ? column.order : 'null', order: column?.order ? column.order : 'null',
}; };
@ -255,6 +301,10 @@ const search = async (column?: any) => {
paginationConfig.total = res.data.total; paginationConfig.total = res.data.total;
}; };
const goRouter = async () => {
router.push({ name: 'AppDetail', params: { appKey: 'mysql' } });
};
const onChange = async (info: any) => { const onChange = async (info: any) => {
if (!info.edit) { if (!info.edit) {
await updateMysqlDescription({ id: info.id, description: info.description }); await updateMysqlDescription({ id: info.id, description: info.description });
@ -291,6 +341,16 @@ const checkExist = (data: App.CheckInstalled) => {
} }
}; };
const loadDBOptions = async () => {
const res = await listRemoteDBs('mysql');
dbOptions.value = res.data || [];
for (let i = 0; i < dbOptions.value.length; i++) {
if (dbOptions.value[i].name === 'local') {
dbOptions.value.splice(i, 1);
}
}
};
const onCopy = async (row: any) => { const onCopy = async (row: any) => {
try { try {
await toClipboard(row.password); await toClipboard(row.password);
@ -347,12 +407,18 @@ const buttons = [
}, },
{ {
label: i18n.global.t('database.backupList'), label: i18n.global.t('database.backupList'),
disabled: (row: Database.MysqlDBInfo) => {
return row.from !== 'local';
},
click: (row: Database.MysqlDBInfo) => { click: (row: Database.MysqlDBInfo) => {
onOpenBackupDialog(row.name); onOpenBackupDialog(row.name);
}, },
}, },
{ {
label: i18n.global.t('database.loadBackup'), label: i18n.global.t('database.loadBackup'),
disabled: (row: Database.MysqlDBInfo) => {
return row.from !== 'local';
},
click: (row: Database.MysqlDBInfo) => { click: (row: Database.MysqlDBInfo) => {
let params = { let params = {
type: 'mysql', type: 'mysql',
@ -369,4 +435,8 @@ const buttons = [
}, },
}, },
]; ];
onMounted(() => {
loadDBOptions();
});
</script> </script>