1
0
mirror of https://github.com/1Panel-dev/1Panel.git synced 2025-01-19 00:09:16 +08:00

feat: PostgreSQL 增加权限设置 (#3537)

This commit is contained in:
ssongliu 2024-01-09 12:43:33 +08:00 committed by GitHub
parent 51077b0597
commit 9a905750af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 423 additions and 58 deletions

View File

@ -85,6 +85,28 @@ func (b *BaseApi) UpdatePostgresqlDescription(c *gin.Context) {
helper.SuccessWithData(c, nil)
}
// @Tags Database Postgresql
// @Summary Change postgresql privileges
// @Description 修改 postgresql 用户权限
// @Accept json
// @Param request body dto.ChangeDBInfo true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /databases/pg/privileges [post]
// @x-panel-log {"bodyKeys":["database", "username"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新数据库 [database] 用户 [username] 权限","formatEN":"Update [user] privileges of database [database]"}
func (b *BaseApi) ChangePostgresqlPrivileges(c *gin.Context) {
var req dto.PostgresqlPrivileges
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := postgresqlService.ChangePrivileges(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
// @Tags Database Postgresql
// @Summary Change postgresql password
// @Description 修改 postgresql 密码

View File

@ -19,7 +19,7 @@ type PostgresqlDBInfo struct {
Format string `json:"format"`
Username string `json:"username"`
Password string `json:"password"`
Permission string `json:"permission"`
SuperUser bool `json:"superUser"`
BackupCount int `json:"backupCount"`
Description string `json:"description"`
}
@ -39,15 +39,23 @@ type PostgresqlDBCreate struct {
Format string `json:"format"`
Username string `json:"username" validate:"required"`
Password string `json:"password" validate:"required"`
Permission string `json:"permission" validate:"required"`
SuperUser bool `json:"superUser"`
Description string `json:"description"`
}
type PostgresqlBindUser struct {
Name string `json:"name" validate:"required"`
Database string `json:"database" validate:"required"`
Username string `json:"username" validate:"required"`
Password string `json:"password" validate:"required"`
Name string `json:"name" validate:"required"`
Database string `json:"database" validate:"required"`
Username string `json:"username" validate:"required"`
Password string `json:"password" validate:"required"`
SuperUser bool `json:"superUser"`
}
type PostgresqlPrivileges struct {
Name string `json:"name" validate:"required"`
Database string `json:"database" validate:"required"`
Username string `json:"username" validate:"required"`
SuperUser bool `json:"superUser"`
}
type PostgresqlLoadDB struct {

View File

@ -8,5 +8,6 @@ type DatabasePostgresql struct {
Format string `json:"format" gorm:"type:varchar(64);not null"`
Username string `json:"username" gorm:"type:varchar(256);not null"`
Password string `json:"password" gorm:"type:varchar(256);not null"`
SuperUser bool `json:"superUser" gorm:"type:varchar(64)" `
Description string `json:"description" gorm:"type:varchar(256);"`
}

View File

@ -4,13 +4,14 @@ import (
"context"
"encoding/json"
"fmt"
"github.com/1Panel-dev/1Panel/backend/buserr"
"io/fs"
"os"
"path"
"strings"
"time"
"github.com/1Panel-dev/1Panel/backend/buserr"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/app/model"
"github.com/1Panel-dev/1Panel/backend/constant"
@ -307,13 +308,13 @@ func reCreatePostgresqlDB(dbID uint, database model.Database, oldEnv string) (*m
oldUser, _ := envMap["PANEL_DB_USER"].(string)
oldPassword, _ := envMap["PANEL_DB_USER_PASSWORD"].(string)
createDB, err := postgresqlService.Create(context.Background(), dto.PostgresqlDBCreate{
Name: oldName,
From: database.From,
Database: database.Name,
Format: "UTF8",
Username: oldUser,
Password: oldPassword,
Permission: "%",
Name: oldName,
From: database.From,
Database: database.Name,
Format: "UTF8",
Username: oldUser,
Password: oldPassword,
SuperUser: true,
})
if err != nil {
return nil, envMap, err

View File

@ -29,6 +29,7 @@ type IPostgresqlService interface {
BindUser(req dto.PostgresqlBindUser) error
Create(ctx context.Context, req dto.PostgresqlDBCreate) (*model.DatabasePostgresql, error)
LoadFromRemote(database string) error
ChangePrivileges(req dto.PostgresqlPrivileges) error
ChangePassword(info dto.ChangeDBInfo) error
UpdateDescription(req dto.UpdateDescription) error
DeleteCheck(req dto.PostgresqlDBDeleteCheck) ([]string, error)
@ -84,6 +85,9 @@ func (u *PostgresqlService) ListDBOption() ([]dto.PostgresqlOption, error) {
}
func (u *PostgresqlService) BindUser(req dto.PostgresqlBindUser) error {
if cmd.CheckIllegal(req.Name, req.Username, req.Password) {
return buserr.New(constant.ErrCmdIllegal)
}
dbItem, err := postgresqlRepo.Get(postgresqlRepo.WithByPostgresqlName(req.Database), commonRepo.WithByName(req.Name))
if err != nil {
return err
@ -94,10 +98,11 @@ func (u *PostgresqlService) BindUser(req dto.PostgresqlBindUser) error {
return err
}
if err := pgClient.CreateUser(client.CreateInfo{
Name: req.Name,
Username: req.Username,
Password: req.Password,
Timeout: 300,
Name: req.Name,
Username: req.Username,
Password: req.Password,
SuperUser: req.SuperUser,
Timeout: 300,
}, false); err != nil {
return err
}
@ -106,8 +111,9 @@ func (u *PostgresqlService) BindUser(req dto.PostgresqlBindUser) error {
return fmt.Errorf("decrypt database db password failed, err: %v", err)
}
if err := postgresqlRepo.Update(dbItem.ID, map[string]interface{}{
"username": req.Username,
"password": pass,
"username": req.Username,
"password": pass,
"super_user": req.SuperUser,
}); err != nil {
return err
}
@ -142,10 +148,11 @@ func (u *PostgresqlService) Create(ctx context.Context, req dto.PostgresqlDBCrea
createItem.PostgresqlName = req.Database
defer cli.Close()
if err := cli.Create(client.CreateInfo{
Name: req.Name,
Username: req.Username,
Password: req.Password,
Timeout: 300,
Name: req.Name,
Username: req.Username,
Password: req.Password,
SuperUser: req.SuperUser,
Timeout: 300,
}); err != nil {
return nil, err
}
@ -306,6 +313,31 @@ func (u *PostgresqlService) Delete(ctx context.Context, req dto.PostgresqlDBDele
return nil
}
func (u *PostgresqlService) ChangePrivileges(req dto.PostgresqlPrivileges) error {
if cmd.CheckIllegal(req.Database, req.Username) {
return buserr.New(constant.ErrCmdIllegal)
}
dbItem, err := postgresqlRepo.Get(postgresqlRepo.WithByPostgresqlName(req.Database), commonRepo.WithByName(req.Name))
if err != nil {
return err
}
cli, err := LoadPostgresqlClientByFrom(req.Database)
if err != nil {
return err
}
defer cli.Close()
if err := cli.ChangePrivileges(client.Privileges{Username: req.Username, SuperUser: req.SuperUser, Timeout: 300}); err != nil {
return err
}
if err := postgresqlRepo.Update(dbItem.ID, map[string]interface{}{
"super_user": req.SuperUser,
}); err != nil {
return err
}
return nil
}
func (u *PostgresqlService) ChangePassword(req dto.ChangeDBInfo) error {
if cmd.CheckIllegal(req.Value) {
return buserr.New(constant.ErrCmdIllegal)

View File

@ -64,6 +64,7 @@ func Init() {
migrations.AddTablePHPExtensions,
migrations.AddTableDatabasePostgresql,
migrations.AddPostgresqlSuperUser,
})
if err := m.Migrate(); err != nil {
global.LOG.Error(err)

View File

@ -148,3 +148,13 @@ var AddTableDatabasePostgresql = &gormigrate.Migration{
return nil
},
}
var AddPostgresqlSuperUser = &gormigrate.Migration{
ID: "20231225-add-postgresql-super_user",
Migrate: func(tx *gorm.DB) error {
if err := tx.AutoMigrate(&model.DatabasePostgresql{}); err != nil {
return err
}
return nil
},
}

View File

@ -60,6 +60,7 @@ func (s *DatabaseRouter) InitRouter(Router *gin.RouterGroup) {
cmdRouter.POST("/pg/bind", baseApi.BindPostgresqlUser)
cmdRouter.POST("/pg/del/check", baseApi.DeleteCheckPostgresql)
cmdRouter.POST("/pg/del", baseApi.DeletePostgresql)
cmdRouter.POST("/pg/privileges", baseApi.ChangePostgresqlPrivileges)
cmdRouter.POST("/pg/password", baseApi.ChangePostgresqlPassword)
cmdRouter.POST("/pg/description", baseApi.UpdatePostgresqlDescription)
}

View File

@ -16,6 +16,7 @@ type PostgresqlClient interface {
Create(info client.CreateInfo) error
CreateUser(info client.CreateInfo, withDeleteDB bool) error
Delete(info client.DeleteInfo) error
ChangePrivileges(info client.Privileges) error
ChangePassword(info client.PasswordChangeInfo) error
Backup(info client.BackupInfo) error

View File

@ -16,9 +16,17 @@ type DBInfo struct {
}
type CreateInfo struct {
Name string `json:"name"`
Username string `json:"userName"`
Password string `json:"password"`
Name string `json:"name"`
Username string `json:"userName"`
Password string `json:"password"`
SuperUser bool `json:"superUser"`
Timeout uint `json:"timeout"` // second
}
type Privileges struct {
Username string `json:"userName"`
SuperUser bool `json:"superUser"`
Timeout uint `json:"timeout"` // second
}

View File

@ -46,6 +46,15 @@ func (r *Local) Create(info CreateInfo) error {
return nil
}
func (r *Local) ChangePrivileges(info Privileges) error {
super := "SUPERUSER"
if !info.SuperUser {
super = "NOSUPERUSER"
}
changeSql := fmt.Sprintf("ALTER USER \"%s\" WITH %s", info.Username, super)
return r.ExecSQL(changeSql, info.Timeout)
}
func (r *Local) CreateUser(info CreateInfo, withDeleteDB bool) error {
createSql := fmt.Sprintf("CREATE USER \"%s\" WITH PASSWORD '%s'", info.Username, info.Password)
if err := r.ExecSQL(createSql, info.Timeout); err != nil {
@ -61,6 +70,18 @@ func (r *Local) CreateUser(info CreateInfo, withDeleteDB bool) error {
}
return err
}
if info.SuperUser {
if err := r.ChangePrivileges(Privileges{SuperUser: true, Username: info.Username, Timeout: info.Timeout}); err != nil {
if withDeleteDB {
_ = r.Delete(DeleteInfo{
Name: info.Name,
Username: info.Username,
ForceDelete: true,
Timeout: 300})
}
return err
}
}
grantStr := fmt.Sprintf("GRANT ALL PRIVILEGES ON DATABASE \"%s\" TO \"%s\"", info.Name, info.Username)
if err := r.ExecSQL(grantStr, info.Timeout); err != nil {
if withDeleteDB {

View File

@ -65,6 +65,18 @@ func (r *Remote) CreateUser(info CreateInfo, withDeleteDB bool) error {
}
return err
}
if info.SuperUser {
if err := r.ChangePrivileges(Privileges{SuperUser: true, Username: info.Username, Timeout: info.Timeout}); err != nil {
if withDeleteDB {
_ = r.Delete(DeleteInfo{
Name: info.Name,
Username: info.Username,
ForceDelete: true,
Timeout: 300})
}
return err
}
}
grantSql := fmt.Sprintf("GRANT ALL PRIVILEGES ON DATABASE \"%s\" TO \"%s\"", info.Name, info.Username)
if err := r.ExecSQL(grantSql, info.Timeout); err != nil {
if withDeleteDB {
@ -97,6 +109,14 @@ func (r *Remote) Delete(info DeleteInfo) error {
return nil
}
func (r *Remote) ChangePrivileges(info Privileges) error {
super := "SUPERUSER"
if !info.SuperUser {
super = "NOSUPERUSER"
}
return r.ExecSQL(fmt.Sprintf("ALTER USER \"%s\" WITH %s", info.Username, super), info.Timeout)
}
func (r *Remote) ChangePassword(info PasswordChangeInfo) error {
return r.ExecSQL(fmt.Sprintf("ALTER USER \"%s\" WITH ENCRYPTED PASSWORD '%s'", info.Username, info.Password), info.Timeout)
}

View File

@ -5016,6 +5016,49 @@ const docTemplate = `{
}
}
},
"/databases/pg/privileges": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "修改 postgresql 用户权限",
"consumes": [
"application/json"
],
"tags": [
"Database Postgresql"
],
"summary": "Change postgresql privileges",
"parameters": [
{
"description": "request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.ChangeDBInfo"
}
}
],
"responses": {
"200": {
"description": "OK"
}
},
"x-panel-log": {
"BeforeFunctions": [],
"bodyKeys": [
"database",
"username"
],
"formatEN": "Update [user] privileges of database [database]",
"formatZH": "更新数据库 [database] 用户 [username] 权限",
"paramKeys": []
}
}
},
"/databases/pg/search": {
"post": {
"security": [
@ -16942,6 +16985,9 @@ const docTemplate = `{
"password": {
"type": "string"
},
"superUser": {
"type": "boolean"
},
"username": {
"type": "string"
}
@ -16954,7 +17000,6 @@ const docTemplate = `{
"from",
"name",
"password",
"permission",
"username"
],
"properties": {
@ -16980,8 +17025,8 @@ const docTemplate = `{
"password": {
"type": "string"
},
"permission": {
"type": "string"
"superUser": {
"type": "boolean"
},
"username": {
"type": "string"

View File

@ -5009,6 +5009,49 @@
}
}
},
"/databases/pg/privileges": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "修改 postgresql 用户权限",
"consumes": [
"application/json"
],
"tags": [
"Database Postgresql"
],
"summary": "Change postgresql privileges",
"parameters": [
{
"description": "request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.ChangeDBInfo"
}
}
],
"responses": {
"200": {
"description": "OK"
}
},
"x-panel-log": {
"BeforeFunctions": [],
"bodyKeys": [
"database",
"username"
],
"formatEN": "Update [user] privileges of database [database]",
"formatZH": "更新数据库 [database] 用户 [username] 权限",
"paramKeys": []
}
}
},
"/databases/pg/search": {
"post": {
"security": [
@ -16935,6 +16978,9 @@
"password": {
"type": "string"
},
"superUser": {
"type": "boolean"
},
"username": {
"type": "string"
}
@ -16947,7 +16993,6 @@
"from",
"name",
"password",
"permission",
"username"
],
"properties": {
@ -16973,8 +17018,8 @@
"password": {
"type": "string"
},
"permission": {
"type": "string"
"superUser": {
"type": "boolean"
},
"username": {
"type": "string"

View File

@ -2008,6 +2008,8 @@ definitions:
type: string
password:
type: string
superUser:
type: boolean
username:
type: string
required:
@ -2033,8 +2035,8 @@ definitions:
type: string
password:
type: string
permission:
type: string
superUser:
type: boolean
username:
type: string
required:
@ -2042,7 +2044,6 @@ definitions:
- from
- name
- password
- permission
- username
type: object
dto.PostgresqlDBDelete:
@ -8160,6 +8161,34 @@ paths:
formatEN: Update database [name] password
formatZH: 更新数据库 [name] 密码
paramKeys: []
/databases/pg/privileges:
post:
consumes:
- application/json
description: 修改 postgresql 用户权限
parameters:
- description: request
in: body
name: request
required: true
schema:
$ref: '#/definitions/dto.ChangeDBInfo'
responses:
"200":
description: OK
security:
- ApiKeyAuth: []
summary: Change postgresql privileges
tags:
- Database Postgresql
x-panel-log:
BeforeFunctions: []
bodyKeys:
- database
- username
formatEN: Update [user] privileges of database [database]
formatZH: 更新数据库 [database] 用户 [username] 权限
paramKeys: []
/databases/pg/search:
post:
consumes:

View File

@ -151,6 +151,13 @@ export namespace Database {
database: string;
username: string;
password: string;
superUser: boolean;
}
export interface PgChangePrivileges {
name: string;
database: string;
username: string;
superUser: boolean;
}
export interface PostgresqlDBDelete {
id: number;
@ -159,18 +166,6 @@ export namespace Database {
forceDelete: boolean;
deleteBackup: boolean;
}
export interface PostgresqlStatus {
uptime: string;
version: string;
max_connections: string;
autovacuum: string;
current_connections: string;
hit_ratio: string;
shared_buffers: string;
buffers_clean: string;
maxwritten_clean: string;
buffers_backend_fsync: string;
}
export interface PostgresqlDBDeleteCheck {
id: number;
type: string;
@ -199,7 +194,7 @@ export namespace Database {
format: string;
username: string;
password: string;
permission: string;
superUser: boolean;
description: string;
}
export interface PostgresqlDBInfo {
@ -211,7 +206,7 @@ export namespace Database {
format: string;
username: string;
password: string;
permission: string;
superUser: boolean;
description: string;
}
export interface ChangeInfo {

View File

@ -27,6 +27,9 @@ export const addPostgresqlDB = (params: Database.PostgresqlDBCreate) => {
export const bindPostgresqlUser = (params: Database.PgBind) => {
return http.post(`/databases/pg/bind`, params, TimeoutEnum.T_40S);
};
export const changePrivileges = (params: Database.PgChangePrivileges) => {
return http.post(`/databases/pg/privileges`, params, TimeoutEnum.T_40S);
};
export const searchPostgresqlDBs = (params: Database.SearchDBWithPage) => {
return http.post<ResPage<Database.PostgresqlDBInfo>>(`/databases/pg/search`, params);
};

View File

@ -383,7 +383,9 @@ const message = {
loadFromRemote: 'Load from server',
userBind: 'Bind User',
pgBind: 'Bind User (Binding existing users is not currently supported)',
pgBindHelper:
'This operation is used to create a new user and bind it to the target database. Currently, selecting users already existing in the database is not supported.',
pgSuperUser: 'Super User',
loadFromRemoteHelper:
'This action will synchronize the database info on the server to 1Panel, do you want to continue?',
passwordHelper: 'Unable to retrieve, please modify',

View File

@ -376,7 +376,8 @@ const message = {
loadFromRemote: '從服務器獲取',
userBind: '綁定使用者',
pgBind: '綁定用戶 (暫不支持綁定已有用戶)',
pgBindHelper: '此操作用於創建新使用者並將其綁定到目標資料庫暫不支援選擇已存在於資料庫中的使用者',
pgSuperUser: '超級使用者',
loadFromRemoteHelper: '此操作將同步服務器上數據庫信息到 1Panel是否繼續',
passwordHelper: '無法獲取密碼請修改',
local: '本地',

View File

@ -376,7 +376,8 @@ const message = {
loadFromRemote: '从服务器获取',
userBind: '绑定用户',
pgBind: '绑定用户 (暂不支持绑定已有用户)',
pgBindHelper: '该操作用于创建新用户并将其绑定到目标数据库暂不支持选择已存在于数据库中的用户',
pgSuperUser: '超级用户',
loadFromRemoteHelper: '此操作将同步服务器上数据库信息到 1Panel是否继续',
passwordHelper: '无法获取密码请修改',
local: '本地',

View File

@ -7,12 +7,16 @@
<el-form v-loading="loading" ref="changeFormRef" :model="form" :rules="rules" label-position="top">
<el-row type="flex" justify="center">
<el-col :span="22">
<el-form-item :label="$t('database.pgBind')" prop="username">
<el-alert type="warning" :title="$t('database.pgBindHelper')" :closable="false" />
<el-form-item class="mt-5" :label="$t('database.userBind')" prop="username">
<el-input v-model="form.username" />
</el-form-item>
<el-form-item :label="$t('commons.login.password')" prop="password">
<el-input type="password" clearable show-password v-model="form.password" />
</el-form-item>
<el-form-item :label="$t('database.permission')" prop="superUser">
<el-checkbox v-model="form.superUser">{{ $t('database.pgSuperUser') }}</el-checkbox>
</el-form-item>
</el-col>
</el-row>
</el-form>
@ -49,6 +53,7 @@ const form = reactive({
name: '',
username: '',
password: '',
superUser: true,
});
const confirmDialogRef = ref();
@ -81,6 +86,7 @@ const onSubmit = async (formEl: FormInstance | undefined) => {
database: form.database,
username: form.username,
password: form.password,
superUser: form.superUser,
};
loading.value = true;
await bindPostgresqlUser(param)

View File

@ -20,6 +20,9 @@
</template>
</el-input>
</el-form-item>
<el-form-item :label="$t('database.permission')" prop="superUser">
<el-checkbox v-model="form.superUser">{{ $t('database.pgSuperUser') }}</el-checkbox>
</el-form-item>
<el-form-item :label="$t('commons.table.type')" prop="database">
<el-tag>{{ form.database + ' [' + form.type + ']' }}</el-tag>
@ -66,8 +69,7 @@ const form = reactive({
format: '',
username: '',
password: '',
permission: '',
permissionIPs: '',
superUser: true,
description: '',
});
const rules = reactive({
@ -91,8 +93,7 @@ const acceptParams = (params: DialogProps): void => {
form.database = params.database;
form.format = 'UTF8';
form.username = '';
form.permission = '%';
form.permissionIPs = '';
form.superUser = true;
form.description = '';
random();
createVisible.value = true;

View File

@ -207,6 +207,7 @@
</template>
</el-dialog>
<PrivilegesDialog ref="privilegesRef" @search="search" />
<BindDialog ref="bindRef" @search="search" />
<PasswordDialog ref="passwordRef" @search="search" />
<RootPasswordDialog ref="connRef" />
@ -226,6 +227,7 @@ import BindDialog from '@/views/database/postgresql/bind/index.vue';
import OperateDialog from '@/views/database/postgresql/create/index.vue';
import DeleteDialog from '@/views/database/postgresql/delete/index.vue';
import PasswordDialog from '@/views/database/postgresql/password/index.vue';
import PrivilegesDialog from '@/views/database/postgresql/privileges/index.vue';
import RootPasswordDialog from '@/views/database/postgresql/conn/index.vue';
import AppResources from '@/views/database/postgresql/check/index.vue';
import AppStatus from '@/components/app-status/index.vue';
@ -264,6 +266,7 @@ const currentDBName = ref();
const checkRef = ref();
const deleteRef = ref();
const bindRef = ref();
const privilegesRef = ref();
const pgadminPort = ref();
const dashboardName = ref();
@ -508,6 +511,21 @@ const buttons = [
onChangePassword(row);
},
},
{
label: i18n.global.t('database.permission'),
disabled: (row: Database.PostgresqlDBInfo) => {
return !row.username;
},
click: (row: Database.PostgresqlDBInfo) => {
let param = {
database: currentDBName.value,
name: row.name,
username: row.username,
superUser: row.superUser,
};
privilegesRef.value.acceptParams(param);
},
},
{
label: i18n.global.t('database.backupList'),
click: (row: Database.PostgresqlDBInfo) => {

View File

@ -0,0 +1,93 @@
<template>
<div>
<el-drawer v-model="changeVisible" :destroy-on-close="true" :close-on-click-modal="false" width="30%">
<template #header>
<DrawerHeader :header="$t('database.permission')" :resource="form.name" :back="handleClose" />
</template>
<el-form v-loading="loading" :model="form" label-position="top">
<el-row type="flex" justify="center">
<el-col :span="22">
<el-form-item :label="$t('database.userBind')">
<el-tag>
{{ form.username }}
</el-tag>
</el-form-item>
<el-form-item :label="$t('database.permission')" prop="superUser">
<el-checkbox v-model="form.superUser">{{ $t('database.pgSuperUser') }}</el-checkbox>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button :disabled="loading" @click="changeVisible = false">
{{ $t('commons.button.cancel') }}
</el-button>
<el-button :disabled="loading" type="primary" @click="onSubmit()">
{{ $t('commons.button.confirm') }}
</el-button>
</span>
</template>
</el-drawer>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref } from 'vue';
import i18n from '@/lang';
import { ElForm } from 'element-plus';
import { changePrivileges } from '@/api/modules/database';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { MsgSuccess } from '@/utils/message';
const loading = ref();
const changeVisible = ref(false);
const form = reactive({
database: '',
name: '',
username: '',
superUser: true,
});
interface DialogProps {
database: string;
name: string;
username: string;
superUser: boolean;
}
const acceptParams = (params: DialogProps): void => {
form.database = params.database;
form.name = params.name;
form.username = params.username;
form.superUser = params.superUser;
changeVisible.value = true;
};
const emit = defineEmits<{ (e: 'search'): void }>();
const handleClose = () => {
changeVisible.value = false;
};
const onSubmit = async () => {
let param = {
name: form.name,
database: form.database,
username: form.username,
superUser: form.superUser,
};
loading.value = true;
await changePrivileges(param)
.then(() => {
loading.value = false;
emit('search');
changeVisible.value = false;
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
})
.catch(() => {
loading.value = false;
});
};
defineExpose({
acceptParams,
});
</script>