mirror of
https://github.com/acepanel/panel.git
synced 2026-02-04 04:22:33 +08:00
feat: 数据库管理优化2
This commit is contained in:
@@ -20,10 +20,12 @@ type Database struct {
|
||||
Server string `json:"server"`
|
||||
ServerID uint `json:"server_id"`
|
||||
Encoding string `json:"encoding"`
|
||||
Comment string `json:"comment"`
|
||||
}
|
||||
|
||||
type DatabaseRepo interface {
|
||||
List(page, limit uint) ([]*Database, int64, error)
|
||||
Create(req *request.DatabaseCreate) error
|
||||
Delete(serverID uint, name string) error
|
||||
Comment(req *request.DatabaseComment) error
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package data
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"slices"
|
||||
|
||||
@@ -53,6 +54,7 @@ func (r databaseRepo) List(page, limit uint) ([]*biz.Database, int64, error) {
|
||||
Server: server.Name,
|
||||
ServerID: server.ID,
|
||||
Encoding: item.Encoding,
|
||||
Comment: item.Comment,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -134,3 +136,23 @@ func (r databaseRepo) Delete(serverID uint, name string) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r databaseRepo) Comment(req *request.DatabaseComment) error {
|
||||
server, err := NewDatabaseServerRepo().Get(req.ServerID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch server.Type {
|
||||
case biz.DatabaseTypeMysql:
|
||||
return errors.New("mysql not support database comment")
|
||||
case biz.DatabaseTypePostgresql:
|
||||
postgres, err := db.NewPostgres(server.Username, server.Password, server.Host, server.Port)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return postgres.DatabaseComment(req.Name, req.Comment)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -14,3 +14,9 @@ type DatabaseDelete struct {
|
||||
ServerID uint `form:"server_id" json:"server_id" validate:"required,exists=database_servers id"`
|
||||
Name string `form:"name" json:"name" validate:"required"`
|
||||
}
|
||||
|
||||
type DatabaseComment struct {
|
||||
ServerID uint `form:"server_id" json:"server_id" validate:"required,exists=database_servers id"`
|
||||
Name string `form:"name" json:"name" validate:"required"`
|
||||
Comment string `form:"comment" json:"comment"`
|
||||
}
|
||||
|
||||
@@ -67,6 +67,7 @@ func Http(r chi.Router) {
|
||||
r.Get("/", database.List)
|
||||
r.Post("/", database.Create)
|
||||
r.Delete("/", database.Delete)
|
||||
r.Post("/comment", database.Comment)
|
||||
})
|
||||
|
||||
r.Route("/databaseServer", func(r chi.Router) {
|
||||
|
||||
@@ -39,6 +39,7 @@ func Success(w http.ResponseWriter, data any) {
|
||||
func Error(w http.ResponseWriter, code int, format string, args ...any) {
|
||||
render := chix.NewRender(w)
|
||||
defer render.Release()
|
||||
render.Header(chix.HeaderContentType, chix.MIMEApplicationJSONCharsetUTF8) // must before Status()
|
||||
render.Status(code)
|
||||
render.JSON(&ErrorResponse{
|
||||
Message: fmt.Sprintf(format, args...),
|
||||
@@ -49,6 +50,7 @@ func Error(w http.ResponseWriter, code int, format string, args ...any) {
|
||||
func ErrorSystem(w http.ResponseWriter) {
|
||||
render := chix.NewRender(w)
|
||||
defer render.Release()
|
||||
render.Header(chix.HeaderContentType, chix.MIMEApplicationJSONCharsetUTF8) // must before Status()
|
||||
render.Status(http.StatusInternalServerError)
|
||||
render.JSON(&ErrorResponse{
|
||||
Message: "系统内部错误",
|
||||
|
||||
@@ -68,3 +68,18 @@ func (s *Database) Delete(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
Success(w, nil)
|
||||
}
|
||||
|
||||
func (s *Database) Comment(w http.ResponseWriter, r *http.Request) {
|
||||
req, err := Bind[request.DatabaseComment](r)
|
||||
if err != nil {
|
||||
Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if err = s.databaseRepo.Comment(req); err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
Success(w, nil)
|
||||
}
|
||||
|
||||
@@ -95,6 +95,11 @@ func (r *Postgres) DatabaseSize(name string) (int64, error) {
|
||||
return size, nil
|
||||
}
|
||||
|
||||
func (r *Postgres) DatabaseComment(name, comment string) error {
|
||||
_, err := r.Exec(fmt.Sprintf("COMMENT ON DATABASE %s IS '%s'", name, comment))
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *Postgres) UserCreate(user, password string) error {
|
||||
_, err := r.Exec(fmt.Sprintf("CREATE USER %s WITH PASSWORD '%s'", user, password))
|
||||
if err != nil {
|
||||
@@ -221,7 +226,11 @@ func (r *Postgres) Users() ([]types.PostgresUser, error) {
|
||||
|
||||
func (r *Postgres) Databases() ([]types.PostgresDatabase, error) {
|
||||
query := `
|
||||
SELECT d.datname, pg_catalog.pg_get_userbyid(d.datdba), pg_catalog.pg_encoding_to_char(d.encoding)
|
||||
SELECT
|
||||
d.datname,
|
||||
pg_catalog.pg_get_userbyid(d.datdba),
|
||||
pg_catalog.pg_encoding_to_char(d.encoding),
|
||||
COALESCE(pg_catalog.shobj_description(d.oid, 'pg_database'), '')
|
||||
FROM pg_catalog.pg_database d
|
||||
WHERE datistemplate = false;
|
||||
`
|
||||
@@ -234,7 +243,7 @@ func (r *Postgres) Databases() ([]types.PostgresDatabase, error) {
|
||||
var databases []types.PostgresDatabase
|
||||
for rows.Next() {
|
||||
var db types.PostgresDatabase
|
||||
if err := rows.Scan(&db.Name, &db.Owner, &db.Encoding); err != nil {
|
||||
if err := rows.Scan(&db.Name, &db.Owner, &db.Encoding, &db.Comment); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if slices.Contains([]string{"template0", "template1", "postgres"}, db.Name) {
|
||||
|
||||
@@ -9,4 +9,5 @@ type PostgresDatabase struct {
|
||||
Name string `json:"name"`
|
||||
Owner string `json:"owner"`
|
||||
Encoding string `json:"encoding"`
|
||||
Comment string `json:"comment"`
|
||||
}
|
||||
|
||||
@@ -7,6 +7,9 @@ export default {
|
||||
create: (data: any) => http.Post(`/database`, data),
|
||||
// 删除数据库
|
||||
delete: (server_id: number, name: string) => http.Delete(`/database`, { server_id, name }),
|
||||
// 更新评论
|
||||
comment: (server_id: number, name: string, comment: string) =>
|
||||
http.Post(`/database/comment`, { server_id, name, comment }),
|
||||
// 获取数据库服务器列表
|
||||
serverList: (page: number, limit: number) =>
|
||||
http.Get('/databaseServer', { params: { page, limit } }),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { renderIcon } from '@/utils'
|
||||
import { NButton, NPopconfirm, NTag } from 'naive-ui'
|
||||
import { NButton, NInput, NPopconfirm, NTag } from 'naive-ui'
|
||||
|
||||
import database from '@/api/panel/database'
|
||||
|
||||
@@ -50,6 +50,23 @@ const columns: any = [
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '备注',
|
||||
key: 'comment',
|
||||
minWidth: 250,
|
||||
resizable: true,
|
||||
ellipsis: { tooltip: true },
|
||||
render(row: any) {
|
||||
return h(NInput, {
|
||||
size: 'small',
|
||||
value: row.comment,
|
||||
onBlur: () => handleComment(row),
|
||||
onUpdateValue(v) {
|
||||
row.comment = v
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'actions',
|
||||
@@ -104,6 +121,12 @@ const handleDelete = async (serverID: number, name: string) => {
|
||||
})
|
||||
}
|
||||
|
||||
const handleComment = (row: any) => {
|
||||
database.comment(row.server_id, row.name, row.comment).then(() => {
|
||||
window.$message.success('修改成功')
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
window.$bus.on('database:refresh', () => {
|
||||
refresh()
|
||||
@@ -119,7 +142,7 @@ onUnmounted(() => {
|
||||
<n-data-table
|
||||
striped
|
||||
remote
|
||||
:scroll-x="800"
|
||||
:scroll-x="1000"
|
||||
:loading="loading"
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
|
||||
@@ -215,7 +215,7 @@ onUnmounted(() => {
|
||||
<n-data-table
|
||||
striped
|
||||
remote
|
||||
:scroll-x="1200"
|
||||
:scroll-x="1500"
|
||||
:loading="loading"
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
|
||||
@@ -188,7 +188,7 @@ onUnmounted(() => {
|
||||
<n-data-table
|
||||
striped
|
||||
remote
|
||||
:scroll-x="1400"
|
||||
:scroll-x="1500"
|
||||
:loading="loading"
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
|
||||
Reference in New Issue
Block a user