mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2026-10-24 23:12:09 +08:00
feat: mysql 与应用商店联调
This commit is contained in:
@@ -1,4 +1,9 @@
|
||||
import { ReqPage } from '.';
|
||||
|
||||
export namespace Database {
|
||||
export interface Search extends ReqPage {
|
||||
version: string;
|
||||
}
|
||||
export interface MysqlDBInfo {
|
||||
id: number;
|
||||
createdAt: Date;
|
||||
@@ -9,6 +14,12 @@ export namespace Database {
|
||||
permission: string;
|
||||
description: string;
|
||||
}
|
||||
export interface BaseInfo {
|
||||
name: string;
|
||||
port: number;
|
||||
password: string;
|
||||
remoteConn: boolean;
|
||||
}
|
||||
export interface MysqlDBCreate {
|
||||
name: string;
|
||||
version: string;
|
||||
@@ -74,6 +85,7 @@ export namespace Database {
|
||||
}
|
||||
export interface ChangeInfo {
|
||||
id: number;
|
||||
version: string;
|
||||
operation: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import http from '@/api';
|
||||
import { ResPage, ReqPage } from '../interface';
|
||||
import { ResPage } from '../interface';
|
||||
import { Database } from '../interface/database';
|
||||
|
||||
export const searchMysqlDBs = (params: ReqPage) => {
|
||||
export const searchMysqlDBs = (params: Database.Search) => {
|
||||
return http.post<ResPage<Database.MysqlDBInfo>>(`databases/search`, params);
|
||||
};
|
||||
|
||||
@@ -19,9 +19,15 @@ export const deleteMysqlDB = (params: { ids: number[] }) => {
|
||||
return http.post(`/databases/del`, params);
|
||||
};
|
||||
|
||||
export const loadMysqlVariables = () => {
|
||||
return http.get<Database.MysqlVariables>(`/databases/conf`);
|
||||
export const loadMysqlBaseInfo = (param: string) => {
|
||||
return http.get<Database.BaseInfo>(`/databases/baseinfo/${param}`);
|
||||
};
|
||||
export const loadMysqlStatus = () => {
|
||||
return http.get<Database.MysqlStatus>(`/databases/status`);
|
||||
export const loadMysqlVariables = (param: string) => {
|
||||
return http.get<Database.MysqlVariables>(`/databases/variables/${param}`);
|
||||
};
|
||||
export const loadMysqlStatus = (param: string) => {
|
||||
return http.get<Database.MysqlStatus>(`/databases/status/${param}`);
|
||||
};
|
||||
export const loadVersions = () => {
|
||||
return http.get(`/databases/versions`);
|
||||
};
|
||||
|
||||
@@ -164,6 +164,7 @@ export default {
|
||||
changePassword: '改密',
|
||||
|
||||
baseSetting: '基础设置',
|
||||
remoteConnHelper: 'root 帐号远程连接 mysql 有安全风险,开启需谨慎!',
|
||||
confChange: '配置修改',
|
||||
|
||||
currentStatus: '当前状态',
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
<div>
|
||||
<Submenu activeName="mysql" />
|
||||
<el-dropdown size="default" split-button style="margin-top: 20px; margin-bottom: 5px">
|
||||
Mysql 版本 {{ version }}
|
||||
{{ version }}
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu v-model="version">
|
||||
<el-dropdown-item @click="version = '5.7.39'">5.7.39</el-dropdown-item>
|
||||
<el-dropdown-item @click="version = '8.0.30'">8.0.30</el-dropdown-item>
|
||||
<el-dropdown-item v-for="item in mysqlVersions" :key="item" @click="onChangeVersion(item)">
|
||||
{{ item }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
@@ -116,16 +117,16 @@ import Setting from '@/views/database/mysql/setting/index.vue';
|
||||
import Submenu from '@/views/database/index.vue';
|
||||
import { dateFromat } from '@/utils/util';
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { deleteMysqlDB, searchMysqlDBs, updateMysqlDBInfo } from '@/api/modules/database';
|
||||
import { deleteMysqlDB, loadVersions, searchMysqlDBs, updateMysqlDBInfo } from '@/api/modules/database';
|
||||
import i18n from '@/lang';
|
||||
import { Cronjob } from '@/api/interface/cronjob';
|
||||
import { useDeleteData } from '@/hooks/use-delete-data';
|
||||
import { ElForm, ElMessage } from 'element-plus';
|
||||
import { Database } from '@/api/interface/database';
|
||||
import { Rules } from '@/global/form-rules';
|
||||
|
||||
const selects = ref<any>([]);
|
||||
const version = ref<string>('5.7.39');
|
||||
const mysqlVersions = ref();
|
||||
const version = ref<string>('5.7');
|
||||
const isOnSetting = ref<boolean>();
|
||||
|
||||
const data = ref();
|
||||
@@ -162,6 +163,7 @@ type FormInstance = InstanceType<typeof ElForm>;
|
||||
const changeFormRef = ref<FormInstance>();
|
||||
const changeForm = reactive({
|
||||
id: 0,
|
||||
version: '',
|
||||
userName: '',
|
||||
password: '',
|
||||
operation: '',
|
||||
@@ -170,11 +172,11 @@ const changeForm = reactive({
|
||||
value: '',
|
||||
});
|
||||
const submitChangeInfo = async (formEl: FormInstance | undefined) => {
|
||||
console.log(formEl);
|
||||
if (!formEl) return;
|
||||
formEl.validate(async (valid) => {
|
||||
if (!valid) return;
|
||||
changeForm.value = changeForm.operation === 'password' ? changeForm.password : changeForm.privilege;
|
||||
changeForm.version = version.value;
|
||||
await updateMysqlDBInfo(changeForm);
|
||||
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
|
||||
search();
|
||||
@@ -182,22 +184,43 @@ const submitChangeInfo = async (formEl: FormInstance | undefined) => {
|
||||
});
|
||||
};
|
||||
|
||||
const loadRunningOptions = async () => {
|
||||
const res = await loadVersions();
|
||||
mysqlVersions.value = res.data;
|
||||
if (mysqlVersions.value.length != 0) {
|
||||
version.value = mysqlVersions.value[0];
|
||||
search();
|
||||
}
|
||||
};
|
||||
|
||||
const onChangeVersion = async (val: string) => {
|
||||
version.value = val;
|
||||
search();
|
||||
if (isOnSetting.value) {
|
||||
let params = {
|
||||
version: version.value,
|
||||
};
|
||||
settingRef.value!.acceptParams(params);
|
||||
}
|
||||
};
|
||||
|
||||
const search = async () => {
|
||||
let params = {
|
||||
page: paginationConfig.currentPage,
|
||||
pageSize: paginationConfig.pageSize,
|
||||
version: version.value,
|
||||
};
|
||||
const res = await searchMysqlDBs(params);
|
||||
data.value = res.data.items || [];
|
||||
paginationConfig.total = res.data.total;
|
||||
};
|
||||
|
||||
const onBatchDelete = async (row: Cronjob.CronjobInfo | null) => {
|
||||
const onBatchDelete = async (row: Database.MysqlDBInfo | null) => {
|
||||
let ids: Array<number> = [];
|
||||
if (row) {
|
||||
ids.push(row.id);
|
||||
} else {
|
||||
selects.value.forEach((item: Cronjob.CronjobInfo) => {
|
||||
selects.value.forEach((item: Database.MysqlDBInfo) => {
|
||||
ids.push(item.id);
|
||||
});
|
||||
}
|
||||
@@ -230,25 +253,25 @@ const buttons = [
|
||||
},
|
||||
{
|
||||
label: i18n.global.t('database.backupList') + '(1)',
|
||||
click: (row: Cronjob.CronjobInfo) => {
|
||||
click: (row: Database.MysqlDBInfo) => {
|
||||
onBatchDelete(row);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: i18n.global.t('database.loadBackup'),
|
||||
click: (row: Cronjob.CronjobInfo) => {
|
||||
click: (row: Database.MysqlDBInfo) => {
|
||||
onBatchDelete(row);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: i18n.global.t('commons.button.delete'),
|
||||
click: (row: Cronjob.CronjobInfo) => {
|
||||
click: (row: Database.MysqlDBInfo) => {
|
||||
onBatchDelete(row);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
onMounted(() => {
|
||||
search();
|
||||
loadRunningOptions();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
<el-card>
|
||||
<el-collapse v-model="activeName" accordion>
|
||||
<el-collapse-item :title="$t('database.baseSetting')" name="1">
|
||||
<el-form :model="form" ref="panelFormRef" label-width="120px">
|
||||
<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">
|
||||
<el-input clearable v-model="form.port">
|
||||
<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', form.port)"
|
||||
@click="onSave(panelFormRef, 'port', baseInfo.port)"
|
||||
icon="Collection"
|
||||
>
|
||||
{{ $t('commons.button.save') }}
|
||||
@@ -19,11 +19,15 @@
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('setting.password')" prop="password">
|
||||
<el-input clearable v-model="form.port">
|
||||
<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', form.password)"
|
||||
@click="onSave(panelFormRef, 'password', baseInfo.password)"
|
||||
icon="Collection"
|
||||
>
|
||||
{{ $t('commons.button.save') }}
|
||||
@@ -31,17 +35,16 @@
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('database.remoteAccess')" prop="remoteAccess">
|
||||
<el-input clearable v-model="form.port">
|
||||
<template #append>
|
||||
<el-button
|
||||
@click="onSave(panelFormRef, 'remoteAccess', form.remoteAccess)"
|
||||
icon="Collection"
|
||||
>
|
||||
{{ $t('commons.button.save') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
<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>
|
||||
@@ -65,7 +68,7 @@
|
||||
<el-button
|
||||
type="primary"
|
||||
style="width: 120px; margin-top: 10px"
|
||||
@click="onSave(panelFormRef, 'remoteAccess', form.remoteAccess)"
|
||||
@click="onSave(panelFormRef, 'remoteAccess', baseInfo.port)"
|
||||
>
|
||||
{{ $t('commons.button.save') }}
|
||||
</el-button>
|
||||
@@ -317,7 +320,13 @@ import { javascript } from '@codemirror/lang-javascript';
|
||||
import { oneDark } from '@codemirror/theme-one-dark';
|
||||
import { LoadFile } from '@/api/modules/files';
|
||||
import { planOptions } from './helper';
|
||||
import { loadMysqlStatus, loadMysqlVariables, updateMysqlVariables } from '@/api/modules/database';
|
||||
import {
|
||||
loadMysqlBaseInfo,
|
||||
loadMysqlStatus,
|
||||
loadMysqlVariables,
|
||||
updateMysqlDBInfo,
|
||||
updateMysqlVariables,
|
||||
} from '@/api/modules/database';
|
||||
import { computeSize } from '@/utils/util';
|
||||
import { Rules } from '@/global/form-rules';
|
||||
import i18n from '@/lang';
|
||||
@@ -325,16 +334,11 @@ import i18n from '@/lang';
|
||||
const extensions = [javascript(), oneDark];
|
||||
const activeName = ref('1');
|
||||
|
||||
const form = reactive({
|
||||
port: '',
|
||||
const baseInfo = reactive({
|
||||
name: '',
|
||||
port: 3306,
|
||||
password: '',
|
||||
remoteAccess: '',
|
||||
sessionTimeout: 0,
|
||||
localTime: '',
|
||||
panelName: '',
|
||||
theme: '',
|
||||
language: '',
|
||||
complexityVerification: '',
|
||||
remoteConn: false,
|
||||
});
|
||||
const panelFormRef = ref<FormInstance>();
|
||||
const mysqlConf = ref();
|
||||
@@ -407,17 +411,48 @@ interface DialogProps {
|
||||
}
|
||||
const acceptParams = (params: DialogProps): void => {
|
||||
onSetting.value = true;
|
||||
loadMysqlConf('/opt/1Panel/conf/mysql.conf');
|
||||
paramVersion.value = params.version;
|
||||
loadBaseInfo();
|
||||
loadStatus();
|
||||
loadVariables();
|
||||
paramVersion.value = params.version;
|
||||
};
|
||||
const onClose = (): void => {
|
||||
onSetting.value = false;
|
||||
};
|
||||
|
||||
const onSave = async (formEl: FormInstance | undefined, key: string, val: any) => {
|
||||
console.log(formEl, key, val);
|
||||
if (!formEl) return;
|
||||
const result = await formEl.validateField(key, callback);
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
let changeForm = {
|
||||
id: 0,
|
||||
version: paramVersion.value,
|
||||
value: val,
|
||||
operation: key === 'remoteConn' ? 'privilege' : key,
|
||||
};
|
||||
if (changeForm.operation === 'privilege') {
|
||||
changeForm.value = val ? '%' : 'localhost';
|
||||
}
|
||||
await updateMysqlDBInfo(changeForm);
|
||||
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
|
||||
};
|
||||
function callback(error: any) {
|
||||
if (error) {
|
||||
return error.message;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const loadBaseInfo = async () => {
|
||||
const res = await loadMysqlBaseInfo(paramVersion.value);
|
||||
baseInfo.name = res.data?.name;
|
||||
baseInfo.port = res.data?.port;
|
||||
baseInfo.password = res.data?.password;
|
||||
baseInfo.remoteConn = res.data?.remoteConn;
|
||||
loadMysqlConf(`/opt/1Panel/data/apps/${paramVersion.value}/${baseInfo.name}/conf/my.cnf`);
|
||||
};
|
||||
|
||||
const loadMysqlConf = async (path: string) => {
|
||||
@@ -426,7 +461,7 @@ const loadMysqlConf = async (path: string) => {
|
||||
};
|
||||
|
||||
const loadVariables = async () => {
|
||||
const res = await loadMysqlVariables();
|
||||
const res = await loadMysqlVariables(paramVersion.value);
|
||||
mysqlVariables.key_buffer_size = Number(res.data.key_buffer_size) / 1024 / 1024;
|
||||
mysqlVariables.query_cache_size = Number(res.data.query_cache_size) / 1024 / 1024;
|
||||
mysqlVariables.tmp_table_size = Number(res.data.tmp_table_size) / 1024 / 1024;
|
||||
@@ -494,7 +529,7 @@ const onSaveVariables = async (formEl: FormInstance | undefined) => {
|
||||
};
|
||||
|
||||
const loadStatus = async () => {
|
||||
const res = await loadMysqlStatus();
|
||||
const res = await loadMysqlStatus(paramVersion.value);
|
||||
let queryPerSecond = res.data.Questions / res.data.Uptime;
|
||||
let txPerSecond = (res.data!.Com_commit + res.data.Com_rollback) / res.data.Uptime;
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ const { switchDark } = useTheme();
|
||||
|
||||
const SaveSetting = async (formEl: FormInstance | undefined, key: string, val: any) => {
|
||||
if (!formEl) return;
|
||||
const result = await formEl.validateField('settingInfo.' + key.replace(key[0], key[0].toLowerCase()), callback);
|
||||
const result = await formEl.validateField('settingInfo.' + key[0].toLowerCase(), callback);
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user