mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-31 14:08:06 +08:00
feat: 同步用户时,移除创建用户逻辑 (#3442)
This commit is contained in:
parent
57f496fe12
commit
33484a9436
@ -41,6 +41,37 @@ func (b *BaseApi) CreateMysql(c *gin.Context) {
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Database Mysql
|
||||
// @Summary Bind user of mysql database
|
||||
// @Description 绑定 mysql 数据库用户
|
||||
// @Accept json
|
||||
// @Param request body dto.BindUser true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/bind [post]
|
||||
// @x-panel-log {"bodyKeys":["database", "username"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"绑定 mysql 数据库名 [database] [username]","formatEN":"bind mysql database [database] [username]"}
|
||||
func (b *BaseApi) BindUser(c *gin.Context) {
|
||||
var req dto.BindUser
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if len(req.Password) != 0 {
|
||||
password, err := base64.StdEncoding.DecodeString(req.Password)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
req.Password = string(password)
|
||||
}
|
||||
|
||||
if err := mysqlService.BindUser(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Database Mysql
|
||||
// @Summary Update mysql database description
|
||||
// @Description 更新 mysql 数据库库描述信息
|
||||
|
@ -43,6 +43,14 @@ type MysqlDBCreate struct {
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
type BindUser struct {
|
||||
Database string `json:"database" validate:"required"`
|
||||
DB string `json:"db" validate:"required"`
|
||||
Username string `json:"username" validate:"required"`
|
||||
Password string `json:"password" validate:"required"`
|
||||
Permission string `json:"permission" validate:"required"`
|
||||
}
|
||||
|
||||
type MysqlLoadDB struct {
|
||||
From string `json:"from" validate:"required,oneof=local remote"`
|
||||
Type string `json:"type" validate:"required,oneof=mysql mariadb"`
|
||||
|
@ -35,6 +35,7 @@ type IMysqlService interface {
|
||||
SearchWithPage(search dto.MysqlDBSearch) (int64, interface{}, error)
|
||||
ListDBOption() ([]dto.MysqlOption, error)
|
||||
Create(ctx context.Context, req dto.MysqlDBCreate) (*model.DatabaseMysql, error)
|
||||
BindUser(req dto.BindUser) error
|
||||
LoadFromRemote(req dto.MysqlLoadDB) error
|
||||
ChangeAccess(info dto.ChangeDBInfo) error
|
||||
ChangePassword(info dto.ChangeDBInfo) error
|
||||
@ -144,6 +145,42 @@ func (u *MysqlService) Create(ctx context.Context, req dto.MysqlDBCreate) (*mode
|
||||
return &createItem, nil
|
||||
}
|
||||
|
||||
func (u *MysqlService) BindUser(req dto.BindUser) error {
|
||||
dbItem, err := mysqlRepo.Get(mysqlRepo.WithByMysqlName(req.Database), commonRepo.WithByName(req.DB))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cli, version, err := LoadMysqlClientByFrom(req.Database)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer cli.Close()
|
||||
|
||||
if err := cli.CreateUser(client.CreateInfo{
|
||||
Name: dbItem.Name,
|
||||
Format: dbItem.Format,
|
||||
Username: req.Username,
|
||||
Password: req.Password,
|
||||
Permission: req.Permission,
|
||||
Version: version,
|
||||
Timeout: 300,
|
||||
}, false); err != nil {
|
||||
return err
|
||||
}
|
||||
pass, err := encrypt.StringEncrypt(req.Password)
|
||||
if err != nil {
|
||||
return fmt.Errorf("decrypt database db password failed, err: %v", err)
|
||||
}
|
||||
if err := mysqlRepo.Update(dbItem.ID, map[string]interface{}{
|
||||
"username": req.Username,
|
||||
"password": pass,
|
||||
"permission": req.Permission,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *MysqlService) LoadFromRemote(req dto.MysqlLoadDB) error {
|
||||
client, version, err := LoadMysqlClientByFrom(req.Database)
|
||||
if err != nil {
|
||||
|
@ -17,6 +17,7 @@ func (s *DatabaseRouter) InitRouter(Router *gin.RouterGroup) {
|
||||
baseApi := v1.ApiGroupApp.BaseApi
|
||||
{
|
||||
cmdRouter.POST("", baseApi.CreateMysql)
|
||||
cmdRouter.POST("/bind", baseApi.BindUser)
|
||||
cmdRouter.POST("load", baseApi.LoadDBFromRemote)
|
||||
cmdRouter.POST("/change/access", baseApi.ChangeMysqlAccess)
|
||||
cmdRouter.POST("/change/password", baseApi.ChangeMysqlPassword)
|
||||
|
@ -14,6 +14,7 @@ import (
|
||||
|
||||
type MysqlClient interface {
|
||||
Create(info client.CreateInfo) error
|
||||
CreateUser(info client.CreateInfo, withDeleteDB bool) error
|
||||
Delete(info client.DeleteInfo) error
|
||||
|
||||
ChangePassword(info client.PasswordChangeInfo) error
|
||||
|
@ -4,9 +4,7 @@ import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/common"
|
||||
"github.com/go-sql-driver/mysql"
|
||||
)
|
||||
|
||||
@ -103,28 +101,6 @@ var formatMap = map[string]string{
|
||||
"big5": "big5_chinese_ci",
|
||||
}
|
||||
|
||||
func loadNameByDB(name, version string) string {
|
||||
nameItem := common.ConvertToPinyin(name)
|
||||
if strings.HasPrefix(version, "5.6") {
|
||||
if len(nameItem) <= 16 {
|
||||
return nameItem
|
||||
}
|
||||
return strings.TrimSuffix(nameItem[:10], "_") + "_" + common.RandStr(5)
|
||||
}
|
||||
if len(nameItem) <= 32 {
|
||||
return nameItem
|
||||
}
|
||||
return strings.TrimSuffix(nameItem[:25], "_") + "_" + common.RandStr(5)
|
||||
}
|
||||
|
||||
func randomPassword(user string) string {
|
||||
passwdItem := user
|
||||
if len(user) > 6 {
|
||||
passwdItem = user[:6]
|
||||
}
|
||||
return passwdItem + "@" + common.RandStrAndNum(8)
|
||||
}
|
||||
|
||||
func VerifyPeerCertFunc(pool *x509.CertPool) func([][]byte, [][]*x509.Certificate) error {
|
||||
return func(rawCerts [][]byte, _ [][]*x509.Certificate) error {
|
||||
if len(rawCerts) == 0 {
|
||||
|
@ -307,19 +307,6 @@ func (r *Local) SyncDB(version string) ([]SyncDBInfo, error) {
|
||||
}
|
||||
}
|
||||
if len(dataItem.Username) == 0 {
|
||||
dataItem.Username = loadNameByDB(parts[0], version)
|
||||
dataItem.Password = randomPassword(dataItem.Username)
|
||||
if err := r.CreateUser(CreateInfo{
|
||||
Name: parts[0],
|
||||
Format: parts[1],
|
||||
Version: version,
|
||||
Username: dataItem.Username,
|
||||
Password: dataItem.Password,
|
||||
Permission: "%",
|
||||
Timeout: 300,
|
||||
}, false); err != nil {
|
||||
global.LOG.Errorf("sync from remote server failed, err: create user failed %v", err)
|
||||
}
|
||||
dataItem.Permission = "%"
|
||||
} else {
|
||||
if isLocal {
|
||||
|
@ -333,19 +333,6 @@ func (r *Remote) SyncDB(version string) ([]SyncDBInfo, error) {
|
||||
i++
|
||||
}
|
||||
if len(dataItem.Username) == 0 {
|
||||
dataItem.Username = loadNameByDB(dbName, version)
|
||||
dataItem.Password = randomPassword(dataItem.Username)
|
||||
if err := r.CreateUser(CreateInfo{
|
||||
Name: dbName,
|
||||
Format: charsetName,
|
||||
Version: version,
|
||||
Username: dataItem.Username,
|
||||
Password: dataItem.Password,
|
||||
Permission: "%",
|
||||
Timeout: 300,
|
||||
}, false); err != nil {
|
||||
return datas, fmt.Errorf("sync db from remote server failed, err: create user failed %v", err)
|
||||
}
|
||||
dataItem.Permission = "%"
|
||||
} else {
|
||||
if isLocal {
|
||||
|
@ -3952,6 +3952,49 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/databases/bind": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "绑定 mysql 数据库用户",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Database Mysql"
|
||||
],
|
||||
"summary": "Bind user of mysql database",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "request",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.BindUser"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
}
|
||||
},
|
||||
"x-panel-log": {
|
||||
"BeforeFunctions": [],
|
||||
"bodyKeys": [
|
||||
"database",
|
||||
"username"
|
||||
],
|
||||
"formatEN": "bind mysql database [database] [username]",
|
||||
"formatZH": "绑定 mysql 数据库名 [database] [username]",
|
||||
"paramKeys": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"/databases/change/access": {
|
||||
"post": {
|
||||
"security": [
|
||||
@ -10013,7 +10056,7 @@ const docTemplate = `{
|
||||
"bodyKeys": [
|
||||
"version"
|
||||
],
|
||||
"formatEN": "upgrade service =\u003e [version]",
|
||||
"formatEN": "upgrade system =\u003e [version]",
|
||||
"formatZH": "更新系统 =\u003e [version]",
|
||||
"paramKeys": []
|
||||
}
|
||||
@ -13601,6 +13644,33 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.BindUser": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"database",
|
||||
"db",
|
||||
"password",
|
||||
"permission",
|
||||
"username"
|
||||
],
|
||||
"properties": {
|
||||
"database": {
|
||||
"type": "string"
|
||||
},
|
||||
"db": {
|
||||
"type": "string"
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
},
|
||||
"permission": {
|
||||
"type": "string"
|
||||
},
|
||||
"username": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.CaptchaResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
@ -3945,6 +3945,49 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/databases/bind": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "绑定 mysql 数据库用户",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Database Mysql"
|
||||
],
|
||||
"summary": "Bind user of mysql database",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "request",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.BindUser"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
}
|
||||
},
|
||||
"x-panel-log": {
|
||||
"BeforeFunctions": [],
|
||||
"bodyKeys": [
|
||||
"database",
|
||||
"username"
|
||||
],
|
||||
"formatEN": "bind mysql database [database] [username]",
|
||||
"formatZH": "绑定 mysql 数据库名 [database] [username]",
|
||||
"paramKeys": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"/databases/change/access": {
|
||||
"post": {
|
||||
"security": [
|
||||
@ -10006,7 +10049,7 @@
|
||||
"bodyKeys": [
|
||||
"version"
|
||||
],
|
||||
"formatEN": "upgrade service =\u003e [version]",
|
||||
"formatEN": "upgrade system =\u003e [version]",
|
||||
"formatZH": "更新系统 =\u003e [version]",
|
||||
"paramKeys": []
|
||||
}
|
||||
@ -13594,6 +13637,33 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.BindUser": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"database",
|
||||
"db",
|
||||
"password",
|
||||
"permission",
|
||||
"username"
|
||||
],
|
||||
"properties": {
|
||||
"database": {
|
||||
"type": "string"
|
||||
},
|
||||
"db": {
|
||||
"type": "string"
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
},
|
||||
"permission": {
|
||||
"type": "string"
|
||||
},
|
||||
"username": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.CaptchaResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
@ -137,6 +137,25 @@ definitions:
|
||||
- bindAddress
|
||||
- ipv6
|
||||
type: object
|
||||
dto.BindUser:
|
||||
properties:
|
||||
database:
|
||||
type: string
|
||||
db:
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
permission:
|
||||
type: string
|
||||
username:
|
||||
type: string
|
||||
required:
|
||||
- database
|
||||
- db
|
||||
- password
|
||||
- permission
|
||||
- username
|
||||
type: object
|
||||
dto.CaptchaResponse:
|
||||
properties:
|
||||
captchaID:
|
||||
@ -7268,6 +7287,34 @@ paths:
|
||||
summary: Load mysql base info
|
||||
tags:
|
||||
- Database Mysql
|
||||
/databases/bind:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 绑定 mysql 数据库用户
|
||||
parameters:
|
||||
- description: request
|
||||
in: body
|
||||
name: request
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/dto.BindUser'
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Bind user of mysql database
|
||||
tags:
|
||||
- Database Mysql
|
||||
x-panel-log:
|
||||
BeforeFunctions: []
|
||||
bodyKeys:
|
||||
- database
|
||||
- username
|
||||
formatEN: bind mysql database [database] [username]
|
||||
formatZH: 绑定 mysql 数据库名 [database] [username]
|
||||
paramKeys: []
|
||||
/databases/change/access:
|
||||
post:
|
||||
consumes:
|
||||
@ -11106,7 +11153,7 @@ paths:
|
||||
BeforeFunctions: []
|
||||
bodyKeys:
|
||||
- version
|
||||
formatEN: upgrade service => [version]
|
||||
formatEN: upgrade system => [version]
|
||||
formatZH: 更新系统 => [version]
|
||||
paramKeys: []
|
||||
/toolbox/clean:
|
||||
|
@ -48,6 +48,13 @@ export namespace Database {
|
||||
permission: string;
|
||||
description: string;
|
||||
}
|
||||
export interface BindUser {
|
||||
database: string;
|
||||
db: string;
|
||||
username: string;
|
||||
password: string;
|
||||
permission: string;
|
||||
}
|
||||
export interface MysqlLoadDB {
|
||||
from: string;
|
||||
type: string;
|
||||
|
@ -19,6 +19,13 @@ export const addMysqlDB = (params: Database.MysqlDBCreate) => {
|
||||
}
|
||||
return http.post(`/databases`, request);
|
||||
};
|
||||
export const bindUser = (params: Database.BindUser) => {
|
||||
let request = deepCopy(params) as Database.BindUser;
|
||||
if (request.password) {
|
||||
request.password = Base64.encode(request.password);
|
||||
}
|
||||
return http.post(`/databases/bind`, request);
|
||||
};
|
||||
export const loadDBFromRemote = (params: Database.MysqlLoadDB) => {
|
||||
return http.post(`/databases/load`, params);
|
||||
};
|
||||
|
@ -380,6 +380,7 @@ const message = {
|
||||
'This port is the exposed port of the container. You need to save the modification separately and restart the container!',
|
||||
|
||||
loadFromRemote: 'Load from server',
|
||||
userBind: 'Bind 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',
|
||||
|
@ -373,6 +373,7 @@ const message = {
|
||||
confNotFound: '未能找到該應用配置文件,請在應用商店升級該應用至最新版本後重試!',
|
||||
|
||||
loadFromRemote: '從服務器獲取',
|
||||
userBind: '綁定使用者',
|
||||
loadFromRemoteHelper: '此操作將同步服務器上數據庫信息到 1Panel,是否繼續?',
|
||||
passwordHelper: '無法獲取密碼,請修改',
|
||||
local: '本地',
|
||||
|
@ -373,6 +373,7 @@ const message = {
|
||||
confNotFound: '未能找到该应用配置文件,请在应用商店升级该应用至最新版本后重试!',
|
||||
|
||||
loadFromRemote: '从服务器获取',
|
||||
userBind: '绑定用户',
|
||||
loadFromRemoteHelper: '此操作将同步服务器上数据库信息到 1Panel,是否继续?',
|
||||
passwordHelper: '无法获取密码,请修改',
|
||||
local: '本地',
|
||||
|
139
frontend/src/views/database/mysql/bind/index.vue
Normal file
139
frontend/src/views/database/mysql/bind/index.vue
Normal file
@ -0,0 +1,139 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-drawer v-model="bindVisible" :destroy-on-close="true" :close-on-click-modal="false" width="30%">
|
||||
<template #header>
|
||||
<DrawerHeader :header="$t('database.userBind')" :resource="form.mysqlName" :back="handleClose" />
|
||||
</template>
|
||||
<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('commons.login.username')" prop="username">
|
||||
<el-input v-model="form.username"></el-input>
|
||||
</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-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('database.permission')" prop="permission">
|
||||
<el-select v-model="form.permission">
|
||||
<el-option value="%" :label="$t('database.permissionAll')" />
|
||||
<el-option
|
||||
v-if="form.from !== 'local'"
|
||||
value="localhost"
|
||||
:label="$t('terminal.localhost')"
|
||||
/>
|
||||
<el-option value="ip" :label="$t('database.permissionForIP')" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="form.permission === 'ip'" prop="permissionIPs">
|
||||
<el-input
|
||||
clearable
|
||||
:autosize="{ minRows: 2, maxRows: 5 }"
|
||||
type="textarea"
|
||||
v-model="form.permissionIPs"
|
||||
/>
|
||||
<span class="input-help">{{ $t('database.remoteHelper') }}</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button :disabled="loading" @click="bindVisible = false">
|
||||
{{ $t('commons.button.cancel') }}
|
||||
</el-button>
|
||||
<el-button :disabled="loading" type="primary" @click="onSubmit(changeFormRef)">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-drawer>
|
||||
|
||||
<ConfirmDialog ref="confirmDialogRef" @confirm="onSubmit"></ConfirmDialog>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
import i18n from '@/lang';
|
||||
import { ElForm } from 'element-plus';
|
||||
import { bindUser } from '@/api/modules/database';
|
||||
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||
import { Rules } from '@/global/form-rules';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { checkIp } from '@/utils/util';
|
||||
|
||||
const loading = ref();
|
||||
const bindVisible = ref(false);
|
||||
type FormInstance = InstanceType<typeof ElForm>;
|
||||
const changeFormRef = ref<FormInstance>();
|
||||
const form = reactive({
|
||||
database: '',
|
||||
mysqlName: '',
|
||||
username: '',
|
||||
password: '',
|
||||
permission: '',
|
||||
permissionIPs: '',
|
||||
});
|
||||
const confirmDialogRef = ref();
|
||||
|
||||
const rules = reactive({
|
||||
username: [Rules.requiredInput, Rules.name],
|
||||
password: [Rules.paramComplexity],
|
||||
permission: [Rules.requiredSelect],
|
||||
permissionIPs: [{ validator: checkIPs, trigger: 'blur', required: true }],
|
||||
});
|
||||
|
||||
function checkIPs(rule: any, value: any, callback: any) {
|
||||
let ips = form.permissionIPs.split(',');
|
||||
for (const item of ips) {
|
||||
if (checkIp(item)) {
|
||||
return callback(new Error(i18n.global.t('commons.rule.ip')));
|
||||
}
|
||||
}
|
||||
callback();
|
||||
}
|
||||
|
||||
interface DialogProps {
|
||||
database: string;
|
||||
mysqlName: string;
|
||||
}
|
||||
const acceptParams = (params: DialogProps): void => {
|
||||
form.id = params.id;
|
||||
form.database = params.database;
|
||||
form.mysqlName = params.mysqlName;
|
||||
bindVisible.value = true;
|
||||
};
|
||||
const emit = defineEmits<{ (e: 'search'): void }>();
|
||||
|
||||
const handleClose = () => {
|
||||
bindVisible.value = false;
|
||||
};
|
||||
|
||||
const onSubmit = async (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return;
|
||||
formEl.validate(async (valid) => {
|
||||
if (!valid) return;
|
||||
let param = {
|
||||
database: form.database,
|
||||
db: form.mysqlName,
|
||||
username: form.username,
|
||||
password: form.password,
|
||||
permission: form.permission === 'ip' ? form.permissionIPs : form.permission,
|
||||
};
|
||||
loading.value = true;
|
||||
await bindUser(param)
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
emit('search');
|
||||
bindVisible.value = false;
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
</script>
|
@ -124,10 +124,24 @@
|
||||
<template #main v-if="currentDB">
|
||||
<ComplexTable :pagination-config="paginationConfig" @sort-change="search" @search="search" :data="data">
|
||||
<el-table-column :label="$t('commons.table.name')" prop="name" sortable />
|
||||
<el-table-column :label="$t('commons.login.username')" prop="username" />
|
||||
<el-table-column :label="$t('commons.login.username')" prop="username">
|
||||
<template #default="{ row }">
|
||||
<div class="flex items-center" v-if="row.username">
|
||||
<span>
|
||||
{{ row.username }}
|
||||
</span>
|
||||
</div>
|
||||
<div v-else>
|
||||
<el-button style="margin-left: -3px" type="primary" link @click="onBind(row)">
|
||||
{{ $t('database.userBind') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('commons.login.password')" prop="password">
|
||||
<template #default="{ row }">
|
||||
<div class="flex items-center" v-if="row.password">
|
||||
<span v-if="row.username === ''">-</span>
|
||||
<div class="flex items-center" v-if="row.password && row.username">
|
||||
<div class="star-center" v-if="!row.showPassword">
|
||||
<span>**********</span>
|
||||
</div>
|
||||
@ -154,10 +168,10 @@
|
||||
<CopyButton :content="row.password" type="icon" />
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<el-link @click="onChangePassword(row)">
|
||||
<span style="font-size: 12px">{{ $t('database.passwordHelper') }}</span>
|
||||
</el-link>
|
||||
<div v-if="row.password === '' && row.username">
|
||||
<el-button style="margin-left: -3px" link type="primary" @click="onChangePassword(row)">
|
||||
{{ $t('database.passwordHelper') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@ -221,6 +235,7 @@
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<BindDialog ref="bindRef" @search="search" />
|
||||
<PasswordDialog ref="passwordRef" @search="search" />
|
||||
<RootPasswordDialog ref="connRef" />
|
||||
<UploadDialog ref="uploadRef" />
|
||||
@ -235,6 +250,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import BindDialog from '@/views/database/mysql/bind/index.vue';
|
||||
import OperateDialog from '@/views/database/mysql/create/index.vue';
|
||||
import DeleteDialog from '@/views/database/mysql/delete/index.vue';
|
||||
import PasswordDialog from '@/views/database/mysql/password/index.vue';
|
||||
@ -274,6 +290,7 @@ const dbOptionsRemote = ref<Array<Database.DatabaseOption>>([]);
|
||||
const currentDB = ref<Database.DatabaseOption>();
|
||||
const currentDBName = ref();
|
||||
|
||||
const bindRef = ref();
|
||||
const checkRef = ref();
|
||||
const deleteRef = ref();
|
||||
|
||||
@ -508,6 +525,14 @@ const onDelete = async (row: Database.MysqlDBInfo) => {
|
||||
}
|
||||
};
|
||||
|
||||
const onBind = async (row: Database.MysqlDBInfo) => {
|
||||
let param = {
|
||||
database: currentDBName.value,
|
||||
mysqlName: row.name,
|
||||
};
|
||||
bindRef.value.acceptParams(param);
|
||||
};
|
||||
|
||||
const onChangePassword = async (row: Database.MysqlDBInfo) => {
|
||||
let param = {
|
||||
id: row.id,
|
||||
@ -525,6 +550,9 @@ const onChangePassword = async (row: Database.MysqlDBInfo) => {
|
||||
const buttons = [
|
||||
{
|
||||
label: i18n.global.t('database.changePassword'),
|
||||
disabled: (row: Database.MysqlDBInfo) => {
|
||||
return !row.username;
|
||||
},
|
||||
click: (row: Database.MysqlDBInfo) => {
|
||||
onChangePassword(row);
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user