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

feat: 数据库设置界面调整

This commit is contained in:
ssongliu 2022-12-08 18:09:14 +08:00 committed by ssongliu
parent de1de365f8
commit 12b668ecd1
10 changed files with 225 additions and 111 deletions

View File

@ -85,7 +85,7 @@ type MysqlVariables struct {
type MysqlVariablesUpdate struct { type MysqlVariablesUpdate struct {
Param string `json:"param"` Param string `json:"param"`
Value interface{} `json:"value"` Value int64 `json:"value"`
} }
type MysqlConfUpdateByFile struct { type MysqlConfUpdateByFile struct {
MysqlName string `json:"mysqlName" validate:"required"` MysqlName string `json:"mysqlName" validate:"required"`

View File

@ -379,14 +379,8 @@ func (u *MysqlService) UpdateVariables(updatas []dto.MysqlVariablesUpdate) error
} else { } else {
files = strings.Split(string(lineBytes), "\n") files = strings.Split(string(lineBytes), "\n")
} }
group := "" group := "[mysqld]"
for _, info := range updatas { for _, info := range updatas {
switch info.Param {
case "key_buffer_size", "sort_buffer_size":
group = "[myisamchk]"
default:
group = "[mysqld]"
}
files = updateMyCnf(files, group, info.Param, info.Value) files = updateMyCnf(files, group, info.Param, info.Value)
} }
file, err := os.OpenFile(path, os.O_WRONLY, 0666) file, err := os.OpenFile(path, os.O_WRONLY, 0666)

View File

@ -88,6 +88,8 @@ func (u *ImageRepoService) Create(imageRepoDto dto.ImageRepoCreate) error {
k = append(k, imageRepoDto.DownloadUrl) k = append(k, imageRepoDto.DownloadUrl)
deamonMap["insecure-registries"] = k deamonMap["insecure-registries"] = k
} }
} else {
deamonMap["insecure-registries"] = []string{imageRepoDto.DownloadUrl}
} }
newJson, err := json.MarshalIndent(deamonMap, "", "\t") newJson, err := json.MarshalIndent(deamonMap, "", "\t")
if err != nil { if err != nil {

View File

@ -228,7 +228,7 @@ export default {
backupList: 'Backup list', backupList: 'Backup list',
backList: 'Return', backList: 'Return',
loadBackup: 'Import the backup', loadBackup: 'Import the backup',
setting: 'Database Settings', setting: 'Mysql Settings',
remoteAccess: 'Remote access', remoteAccess: 'Remote access',
changePassword: 'Password change', changePassword: 'Password change',
@ -345,7 +345,7 @@ export default {
operatorHelper: '{0} will be performed on the selected container. Do you want to continue?', operatorHelper: '{0} will be performed on the selected container. Do you want to continue?',
start: 'Start', start: 'Start',
stop: 'Stop', stop: 'Stop',
reStart: 'Restart', restart: 'Restart',
kill: 'Kill', kill: 'Kill',
pause: 'Pause', pause: 'Pause',
unpause: 'Unpause', unpause: 'Unpause',

View File

@ -231,15 +231,17 @@ export default {
backupList: '备份列表', backupList: '备份列表',
backList: '返回列表', backList: '返回列表',
loadBackup: '导入备份', loadBackup: '导入备份',
setting: '数据库设置', setting: 'Mysql 设置',
remoteAccess: '远程访问', remoteAccess: '远程访问',
remoteConnHelper: 'root 帐号远程连接 mysql 有安全风险开启需谨慎',
changePassword: '改密', changePassword: '改密',
baseSetting: '基础设置', portSetting: '端口',
remoteConnHelper: 'root 帐号远程连接 mysql 有安全风险开启需谨慎',
confChange: '配置修改',
portHelper: '该端口为容器对外暴露端口修改需要单独保存并且重启容器', portHelper: '该端口为容器对外暴露端口修改需要单独保存并且重启容器',
baseSetting: '基础设置',
confChange: '配置修改',
unSupportType: '不支持当前文件类型', unSupportType: '不支持当前文件类型',
unSupportSize: '上传文件超过 10M请确认', unSupportSize: '上传文件超过 10M请确认',
selectFile: '选择文件', selectFile: '选择文件',

View File

@ -19,8 +19,10 @@
<el-button @click="onChangeRootPassword" type="primary" plain> <el-button @click="onChangeRootPassword" type="primary" plain>
{{ $t('database.rootPassword') }} {{ $t('database.rootPassword') }}
</el-button> </el-button>
<el-button @click="goDashboard">远程访问</el-button> <el-button @click="onChangeAccess" type="primary" plain>
<el-button @click="goDashboard" icon="Position">phpMyAdmin</el-button> {{ $t('database.remoteAccess') }}
</el-button>
<el-button @click="goDashboard" type="primary" plain icon="Position">phpMyAdmin</el-button>
</template> </template>
<el-table-column type="selection" fix /> <el-table-column type="selection" fix />
<el-table-column :label="$t('commons.table.name')" prop="name" /> <el-table-column :label="$t('commons.table.name')" prop="name" />
@ -144,7 +146,8 @@
</template> </template>
</el-dialog> </el-dialog>
<RootPasswordDialog @search="search" ref="rootPasswordRef" /> <RootPasswordDialog ref="rootPasswordRef" />
<RemoteAccessDialog ref="remoteAccessRef" />
<UploadDialog ref="uploadRef" /> <UploadDialog ref="uploadRef" />
<OperatrDialog @search="search" ref="dialogRef" /> <OperatrDialog @search="search" ref="dialogRef" />
<BackupRecords ref="dialogBackupRef" /> <BackupRecords ref="dialogBackupRef" />
@ -157,6 +160,7 @@
import ComplexTable from '@/components/complex-table/index.vue'; import ComplexTable from '@/components/complex-table/index.vue';
import OperatrDialog from '@/views/database/mysql/create/index.vue'; import OperatrDialog from '@/views/database/mysql/create/index.vue';
import RootPasswordDialog from '@/views/database/mysql/password/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'; import BackupRecords from '@/views/database/mysql/backup/index.vue';
import UploadDialog from '@/views/database/mysql/upload/index.vue'; import UploadDialog from '@/views/database/mysql/upload/index.vue';
import AppResources from '@/views/database/mysql/check/index.vue'; import AppResources from '@/views/database/mysql/check/index.vue';
@ -165,7 +169,13 @@ import AppStatus from '@/components/app-status/index.vue';
import Submenu from '@/views/database/index.vue'; import Submenu from '@/views/database/index.vue';
import { dateFromat } from '@/utils/util'; import { dateFromat } from '@/utils/util';
import { reactive, ref } from 'vue'; import { reactive, ref } from 'vue';
import { deleteCheckMysqlDB, deleteMysqlDB, searchMysqlDBs, updateMysqlDBInfo } from '@/api/modules/database'; import {
deleteCheckMysqlDB,
deleteMysqlDB,
loadMysqlBaseInfo,
searchMysqlDBs,
updateMysqlDBInfo,
} from '@/api/modules/database';
import i18n from '@/lang'; import i18n from '@/lang';
import { useDeleteData } from '@/hooks/use-delete-data'; import { useDeleteData } from '@/hooks/use-delete-data';
import { ElForm, ElMessage } from 'element-plus'; import { ElForm, ElMessage } from 'element-plus';
@ -217,6 +227,15 @@ const onChangeRootPassword = async () => {
rootPasswordRef.value!.acceptParams(); rootPasswordRef.value!.acceptParams();
}; };
const remoteAccessRef = ref();
const onChangeAccess = async () => {
const res = await loadMysqlBaseInfo();
let param = {
privilege: res.data.remoteConn,
};
remoteAccessRef.value!.acceptParams(param);
};
const settingRef = ref(); const settingRef = ref();
const onSetting = async () => { const onSetting = async () => {
isOnSetting.value = true; isOnSetting.value = true;

View File

@ -49,7 +49,6 @@ const acceptParams = (): void => {
dialogVisiable.value = true; dialogVisiable.value = true;
}; };
const emit = defineEmits<{ (e: 'search'): void }>();
const onSubmit = async () => { const onSubmit = async () => {
let param = { let param = {
id: 0, id: 0,
@ -61,7 +60,6 @@ const onSubmit = async () => {
.then(() => { .then(() => {
loading.value = false; loading.value = false;
ElMessage.success(i18n.global.t('commons.msg.operationSuccess')); ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
emit('search');
dialogVisiable.value = false; dialogVisiable.value = false;
}) })
.catch(() => { .catch(() => {

View File

@ -0,0 +1,91 @@
<template>
<el-dialog v-model="dialogVisiable" :destroy-on-close="true" :close-on-click-modal="false" width="30%">
<template #header>
<div class="card-header">
<span>{{ $t('database.remoteAccess') }}</span>
</div>
</template>
<el-form v-loading="loading" ref="formRef" :model="form" label-width="80px">
<el-form-item :label="$t('database.remoteAccess')" :rules="Rules.requiredInput" prop="privilege">
<el-switch v-model="form.privilege" />
<span class="input-help">{{ $t('database.remoteConnHelper') }}</span>
</el-form-item>
</el-form>
<ConfirmDialog ref="confirmDialogRef" @confirm="onSubmit"></ConfirmDialog>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisiable = false">{{ $t('commons.button.cancel') }}</el-button>
<el-button type="primary" @click="onSave(formRef)">
{{ $t('commons.button.confirm') }}
</el-button>
</span>
</template>
</el-dialog>
</template>
<script lang="ts" setup>
import { reactive, ref } from 'vue';
import { Rules } from '@/global/form-rules';
import i18n from '@/lang';
import { ElForm, ElMessage } from 'element-plus';
import { updateMysqlDBInfo } from '@/api/modules/database';
import ConfirmDialog from '@/components/confirm-dialog/index.vue';
const loading = ref(false);
const dialogVisiable = ref(false);
const form = reactive({
privilege: '',
});
const confirmDialogRef = ref();
type FormInstance = InstanceType<typeof ElForm>;
const formRef = ref<FormInstance>();
interface DialogProps {
privilege: string;
}
const acceptParams = (prop: DialogProps): void => {
form.privilege = prop.privilege;
dialogVisiable.value = true;
};
const onSubmit = async () => {
let param = {
id: 0,
operation: 'privilege',
value: form.privilege ? '%' : 'localhost',
};
loading.value = true;
await updateMysqlDBInfo(param)
.then(() => {
loading.value = false;
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
dialogVisiable.value = false;
})
.catch(() => {
loading.value = false;
});
};
const onSave = async (formEl: FormInstance | undefined) => {
if (!formEl) return;
formEl.validate(async (valid) => {
if (!valid) return;
let params = {
header: i18n.global.t('database.confChange'),
operationInfo: i18n.global.t('database.restartNowHelper'),
submitInputInfo: i18n.global.t('database.restartNow'),
};
confirmDialogRef.value!.acceptParams(params);
});
};
defineExpose({
acceptParams,
});
</script>

View File

@ -1,57 +1,9 @@
<template> <template>
<div class="demo-collapse" v-show="onSetting"> <div class="demo-collapse" v-show="onSetting">
<el-card style="margin-top: 5px"> <el-card style="margin-top: 5px" v-loading="loading">
<LayoutContent :header="$t('database.setting')" :back-name="'Mysql'" :reload="true"> <LayoutContent :header="$t('database.setting')" :back-name="'Mysql'" :reload="true">
<el-collapse v-model="activeName" accordion> <el-collapse v-model="activeName" accordion>
<el-collapse-item :title="$t('database.baseSetting')" name="1"> <el-collapse-item :title="$t('database.confChange')" name="1">
<el-form :model="baseInfo" ref="panelFormRef" label-width="120px">
<el-row>
<el-col :span="1"><br /></el-col>
<el-col :span="10">
<el-form-item :label="$t('setting.port')" prop="port" :rules="Rules.port">
<el-input clearable type="number" v-model.number="baseInfo.port">
<template #append>
<el-button
@click="onSave(panelFormRef, 'port', baseInfo.port)"
icon="Collection"
>
{{ $t('commons.button.save') }}
</el-button>
</template>
</el-input>
</el-form-item>
<el-form-item
:label="$t('setting.password')"
prop="password"
:rules="Rules.requiredInput"
>
<el-input type="password" show-password clearable v-model="baseInfo.password">
<template #append>
<el-button
@click="onSave(panelFormRef, 'password', baseInfo.password)"
icon="Collection"
>
{{ $t('commons.button.save') }}
</el-button>
</template>
</el-input>
</el-form-item>
<el-form-item
:label="$t('database.remoteAccess')"
prop="remoteConn"
:rules="Rules.requiredSelect"
>
<el-switch
v-model="baseInfo.remoteConn"
@change="onSave(panelFormRef, 'remoteConn', baseInfo.remoteConn)"
/>
<span class="input-help">{{ $t('database.remoteConnHelper') }}</span>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-collapse-item>
<el-collapse-item :title="$t('database.confChange')" name="2">
<codemirror <codemirror
:autofocus="true" :autofocus="true"
placeholder="None data" placeholder="None data"
@ -66,16 +18,34 @@
v-model="mysqlConf" v-model="mysqlConf"
:readOnly="true" :readOnly="true"
/> />
<el-button type="primary" style="margin-top: 10px" @click="onSaveFile()"> <el-button type="primary" style="margin-top: 10px" @click="onSaveConf">
{{ $t('commons.button.save') }} {{ $t('commons.button.save') }}
</el-button> </el-button>
</el-collapse-item> </el-collapse-item>
<el-collapse-item :title="$t('database.currentStatus')" name="3"> <el-collapse-item :title="$t('database.currentStatus')" name="2">
<Status ref="statusRef" /> <Status ref="statusRef" />
</el-collapse-item> </el-collapse-item>
<el-collapse-item :title="$t('database.performanceTuning')" name="4"> <el-collapse-item :title="$t('database.performanceTuning')" name="3">
<Variables ref="variablesRef" /> <Variables ref="variablesRef" />
</el-collapse-item> </el-collapse-item>
<el-collapse-item :title="$t('database.portSetting')" name="4">
<el-form :model="baseInfo" ref="panelFormRef" label-width="120px">
<el-row>
<el-col :span="1"><br /></el-col>
<el-col :span="10">
<el-form-item :label="$t('setting.port')" prop="port" :rules="Rules.port">
<el-input clearable type="number" v-model.number="baseInfo.port">
<template #append>
<el-button @click="onSavePort(panelFormRef)" icon="Collection">
{{ $t('commons.button.save') }}
</el-button>
</template>
</el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-collapse-item>
<el-collapse-item :title="$t('database.log')" name="5"> <el-collapse-item :title="$t('database.log')" name="5">
<ContainerLog ref="dialogContainerLogRef" /> <ContainerLog ref="dialogContainerLogRef" />
</el-collapse-item> </el-collapse-item>
@ -86,6 +56,9 @@
</el-collapse> </el-collapse>
</LayoutContent> </LayoutContent>
</el-card> </el-card>
<ConfirmDialog ref="confirmPortRef" @confirm="onSubmitChangePort"></ConfirmDialog>
<ConfirmDialog ref="confirmConfRef" @confirm="onSubmitChangeConf"></ConfirmDialog>
</div> </div>
</template> </template>
@ -96,21 +69,19 @@ import ContainerLog from '@/components/container-log/index.vue';
import Status from '@/views/database/mysql/setting/status/index.vue'; import Status from '@/views/database/mysql/setting/status/index.vue';
import Variables from '@/views/database/mysql/setting/variables/index.vue'; import Variables from '@/views/database/mysql/setting/variables/index.vue';
import SlowLog from '@/views/database/mysql/setting/slow-log/index.vue'; import SlowLog from '@/views/database/mysql/setting/slow-log/index.vue';
import ConfirmDialog from '@/components/confirm-dialog/index.vue';
import { reactive, ref } from 'vue'; import { reactive, ref } from 'vue';
import { Codemirror } from 'vue-codemirror'; import { Codemirror } from 'vue-codemirror';
import { javascript } from '@codemirror/lang-javascript'; import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark'; import { oneDark } from '@codemirror/theme-one-dark';
import { LoadFile } from '@/api/modules/files'; import { LoadFile } from '@/api/modules/files';
import { import { loadMysqlBaseInfo, loadMysqlVariables, updateMysqlConfByFile } from '@/api/modules/database';
loadMysqlBaseInfo,
loadMysqlVariables,
updateMysqlConfByFile,
updateMysqlDBInfo,
} from '@/api/modules/database';
import { ChangePort } from '@/api/modules/app'; import { ChangePort } from '@/api/modules/app';
import { Rules } from '@/global/form-rules'; import { Rules } from '@/global/form-rules';
import i18n from '@/lang'; import i18n from '@/lang';
const loading = ref(false);
const extensions = [javascript(), oneDark]; const extensions = [javascript(), oneDark];
const activeName = ref('1'); const activeName = ref('1');
@ -139,6 +110,7 @@ interface DialogProps {
const dialogContainerLogRef = ref(); const dialogContainerLogRef = ref();
const acceptParams = (params: DialogProps): void => { const acceptParams = (params: DialogProps): void => {
onSetting.value = true; onSetting.value = true;
loading.value = true;
loadBaseInfo(); loadBaseInfo();
loadVariables(); loadVariables();
loadSlowLogs(); loadSlowLogs();
@ -148,33 +120,36 @@ const onClose = (): void => {
onSetting.value = false; onSetting.value = false;
}; };
const onSave = async (formEl: FormInstance | undefined, key: string, val: any) => { const onSubmitChangePort = async () => {
if (!formEl) return;
const result = await formEl.validateField(key, callback);
if (!result) {
return;
}
if (key === 'port') {
let params = { let params = {
key: 'mysql', key: 'mysql',
name: mysqlName.value, name: mysqlName.value,
port: val, port: baseInfo.port,
}; };
await ChangePort(params); loading.value = true;
await ChangePort(params)
.then(() => {
loading.value = false;
ElMessage.success(i18n.global.t('commons.msg.operationSuccess')); ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
})
.catch(() => {
loading.value = false;
});
};
const confirmPortRef = ref();
const onSavePort = async (formEl: FormInstance | undefined) => {
if (!formEl) return;
const result = await formEl.validateField('port', callback);
if (!result) {
return; return;
} }
let changeForm = { let params = {
id: 0, header: i18n.global.t('database.confChange'),
mysqlName: mysqlName.value, operationInfo: i18n.global.t('database.restartNowHelper'),
value: val, submitInputInfo: i18n.global.t('database.restartNow'),
operation: key === 'remoteConn' ? 'privilege' : key,
}; };
if (changeForm.operation === 'privilege') { confirmPortRef.value!.acceptParams(params);
changeForm.value = val ? '%' : 'localhost'; return;
}
await updateMysqlDBInfo(changeForm);
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
}; };
function callback(error: any) { function callback(error: any) {
if (error) { if (error) {
@ -184,13 +159,30 @@ function callback(error: any) {
} }
} }
const onSaveFile = async () => { const onSubmitChangeConf = async () => {
let param = { let param = {
mysqlName: mysqlName.value, mysqlName: mysqlName.value,
file: mysqlConf.value, file: mysqlConf.value,
}; };
await updateMysqlConfByFile(param); loading.value = true;
await updateMysqlConfByFile(param)
.then(() => {
loading.value = false;
ElMessage.success(i18n.global.t('commons.msg.operationSuccess')); ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
})
.catch(() => {
loading.value = false;
});
};
const confirmConfRef = ref();
const onSaveConf = async () => {
let params = {
header: i18n.global.t('database.confChange'),
operationInfo: i18n.global.t('database.restartNowHelper'),
submitInputInfo: i18n.global.t('database.restartNow'),
};
confirmConfRef.value!.acceptParams(params);
return;
}; };
const loadContainerLog = async (containerID: string) => { const loadContainerLog = async (containerID: string) => {
@ -225,8 +217,14 @@ const loadSlowLogs = async () => {
}; };
const loadMysqlConf = async (path: string) => { const loadMysqlConf = async (path: string) => {
const res = await LoadFile({ path: path }); await LoadFile({ path: path })
.then((res) => {
loading.value = false;
mysqlConf.value = res.data; mysqlConf.value = res.data;
})
.catch(() => {
loading.value = false;
});
}; };
defineExpose({ defineExpose({

View File

@ -1,6 +1,6 @@
<template> <template>
<div> <div>
<el-card> <el-card v-loading="loading">
<el-form :model="mysqlVariables" :rules="variablesRules" ref="variableFormRef" label-width="160px"> <el-form :model="mysqlVariables" :rules="variablesRules" ref="variableFormRef" label-width="160px">
<el-row> <el-row>
<el-col :span="1"><br /></el-col> <el-col :span="1"><br /></el-col>
@ -64,7 +64,7 @@
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button @click="onSaveStart(variableFormRef)" type="primary"> <el-button :disabled="loading" @click="onSaveStart(variableFormRef)" type="primary">
{{ $t('commons.button.save') }} {{ $t('commons.button.save') }}
</el-button> </el-button>
</el-form-item> </el-form-item>
@ -111,6 +111,7 @@
</el-row> </el-row>
</el-form> </el-form>
</el-card> </el-card>
<ConfirmDialog ref="confirmDialogRef" @confirm="onSaveVariables"></ConfirmDialog> <ConfirmDialog ref="confirmDialogRef" @confirm="onSaveVariables"></ConfirmDialog>
</div> </div>
</template> </template>
@ -124,6 +125,8 @@ import { updateMysqlVariables } from '@/api/modules/database';
import i18n from '@/lang'; import i18n from '@/lang';
import { planOptions } from './../helper'; import { planOptions } from './../helper';
const loading = ref(false);
const plan = ref(); const plan = ref();
const confirmDialogRef = ref(); const confirmDialogRef = ref();
@ -277,8 +280,15 @@ const onSaveVariables = async () => {
if (oldVariables.value?.max_connections !== mysqlVariables.max_connections) { if (oldVariables.value?.max_connections !== mysqlVariables.max_connections) {
param.push({ param: 'max_connections', value: mysqlVariables.max_connections }); param.push({ param: 'max_connections', value: mysqlVariables.max_connections });
} }
await updateMysqlVariables(param); loading.value = true;
await updateMysqlVariables(param)
.then(() => {
loading.value = false;
ElMessage.success(i18n.global.t('commons.msg.operationSuccess')); ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
})
.catch(() => {
loading.value = false;
});
}; };
defineExpose({ defineExpose({