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

fix: 状态栏增加重启 loading

This commit is contained in:
ssongliu 2022-12-12 17:17:39 +08:00 committed by ssongliu
parent 62d0d3fc2c
commit 23996b25c3
14 changed files with 125 additions and 104 deletions

View File

@ -263,36 +263,7 @@ func (a AppInstallService) GetUpdateVersions(installId uint) ([]dto.AppVersion,
} }
func (a AppInstallService) ChangeAppPort(req dto.PortUpdate) error { func (a AppInstallService) ChangeAppPort(req dto.PortUpdate) error {
var (
files []string
newFiles []string
)
ComposeDir := fmt.Sprintf("%s/%s/%s", constant.AppInstallDir, req.Key, req.Name)
ComposeFile := fmt.Sprintf("%s/%s/%s/docker-compose.yml", constant.AppInstallDir, req.Key, req.Name) ComposeFile := fmt.Sprintf("%s/%s/%s/docker-compose.yml", constant.AppInstallDir, req.Key, req.Name)
path := fmt.Sprintf("%s/.env", ComposeDir)
lineBytes, err := ioutil.ReadFile(path)
if err != nil {
return err
} else {
files = strings.Split(string(lineBytes), "\n")
}
for _, line := range files {
if strings.HasPrefix(line, "PANEL_APP_PORT_HTTP=") {
newFiles = append(newFiles, fmt.Sprintf("PANEL_APP_PORT_HTTP=%v", req.Port))
} else {
newFiles = append(newFiles, line)
}
}
file, err := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0666)
if err != nil {
return err
}
defer file.Close()
_, err = file.WriteString(strings.Join(newFiles, "\n"))
if err != nil {
return err
}
updateInstallInfoInDB(req.Key, "port", strconv.FormatInt(req.Port, 10)) updateInstallInfoInDB(req.Key, "port", strconv.FormatInt(req.Port, 10))
@ -484,6 +455,34 @@ func updateInstallInfoInDB(appKey, param string, value interface{}) {
if err != nil { if err != nil {
return return
} }
envPath := fmt.Sprintf("%s/%s/%s/.env", constant.AppInstallDir, appKey, appInstall.Name)
lineBytes, err := ioutil.ReadFile(envPath)
if err != nil {
return
}
envKey := "PANEL_DB_ROOT_PASSWORD="
if param == "port" {
envKey = "PANEL_APP_PORT_HTTP="
}
files := strings.Split(string(lineBytes), "\n")
var newFiles []string
for _, line := range files {
if strings.HasPrefix(line, envKey) {
newFiles = append(newFiles, fmt.Sprintf("%s%v", envKey, value))
} else {
newFiles = append(newFiles, line)
}
}
file, err := os.OpenFile(envPath, os.O_WRONLY|os.O_TRUNC, 0666)
if err != nil {
return
}
defer file.Close()
_, err = file.WriteString(strings.Join(newFiles, "\n"))
if err != nil {
return
}
oldVal, newVal := "", "" oldVal, newVal := "", ""
if param == "password" { if param == "password" {
oldVal = fmt.Sprintf("\"PANEL_DB_ROOT_PASSWORD\":\"%v\"", appInstall.Password) oldVal = fmt.Sprintf("\"PANEL_DB_ROOT_PASSWORD\":\"%v\"", appInstall.Password)
@ -492,6 +491,7 @@ func updateInstallInfoInDB(appKey, param string, value interface{}) {
"param": strings.ReplaceAll(appInstall.Param, oldVal, newVal), "param": strings.ReplaceAll(appInstall.Param, oldVal, newVal),
"env": strings.ReplaceAll(appInstall.Env, oldVal, newVal), "env": strings.ReplaceAll(appInstall.Env, oldVal, newVal),
}, commonRepo.WithByID(appInstall.ID)) }, commonRepo.WithByID(appInstall.ID))
} }
if param == "port" { if param == "port" {
oldVal = fmt.Sprintf("\"PANEL_APP_PORT_HTTP\":%v", appInstall.Port) oldVal = fmt.Sprintf("\"PANEL_APP_PORT_HTTP\":%v", appInstall.Port)

View File

@ -79,7 +79,7 @@ func (u *ContainerService) PageCompose(req dto.PageInfo) (int64, interface{}, er
} }
for i := 0; i < len(composeCreatedByLocal); i++ { for i := 0; i < len(composeCreatedByLocal); i++ {
if composeCreatedByLocal[i].Name == name { if composeCreatedByLocal[i].Name == name {
composeItem.CreatedBy = "local" composeItem.CreatedBy = "1panel"
composeCreatedByLocal = append(composeCreatedByLocal[:i], composeCreatedByLocal[i+1:]...) composeCreatedByLocal = append(composeCreatedByLocal[:i], composeCreatedByLocal[i+1:]...)
break break
} }

View File

@ -63,40 +63,11 @@ func (u *RedisService) UpdateConf(req dto.RedisConfUpdate) error {
} }
func (u *RedisService) ChangePassword(req dto.ChangeDBInfo) error { func (u *RedisService) ChangePassword(req dto.ChangeDBInfo) error {
var (
files []string
newFiles []string
)
redisInfo, err := appInstallRepo.LoadBaseInfoByKey("redis") redisInfo, err := appInstallRepo.LoadBaseInfoByKey("redis")
if err != nil { if err != nil {
return err return err
} }
ComposeDir := fmt.Sprintf("%s/redis/%s", constant.AppInstallDir, redisInfo.Name)
ComposeFile := fmt.Sprintf("%s/redis/%s/docker-compose.yml", constant.AppInstallDir, redisInfo.Name) ComposeFile := fmt.Sprintf("%s/redis/%s/docker-compose.yml", constant.AppInstallDir, redisInfo.Name)
path := fmt.Sprintf("%s/.env", ComposeDir)
lineBytes, err := ioutil.ReadFile(path)
if err != nil {
return err
} else {
files = strings.Split(string(lineBytes), "\n")
}
for _, line := range files {
if strings.HasPrefix(line, "PANEL_DB_ROOT_PASSWORD=") {
newFiles = append(newFiles, fmt.Sprintf("PANEL_DB_ROOT_PASSWORD=%v", req.Value))
} else {
newFiles = append(newFiles, line)
}
}
file, err := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0666)
if err != nil {
return err
}
defer file.Close()
_, err = file.WriteString(strings.Join(newFiles, "\n"))
if err != nil {
return err
}
updateInstallInfoInDB("redis", "password", req.Value) updateInstallInfoInDB("redis", "password", req.Value)
updateInstallInfoInDB("redis-commander", "password", req.Value) updateInstallInfoInDB("redis-commander", "password", req.Value)

View File

@ -42,15 +42,8 @@ func (sws *LocalWsSession) handleSlaveEvent(exitCh chan bool) {
case <-exitCh: case <-exitCh:
return return
default: default:
n, err := sws.slave.Read(buffer) n, _ := sws.slave.Read(buffer)
if err != nil { _ = sws.masterWrite(buffer[:n])
global.LOG.Errorf("read buffer from slave failed, err: %v", err)
}
err = sws.masterWrite(buffer[:n])
if err != nil {
global.LOG.Errorf("handle master read event failed, err: %v", err)
}
} }
} }
} }

View File

@ -1,7 +1,7 @@
<template> <template>
<div> <div>
<div class="app-content" v-if="data.isExist"> <div class="app-content" v-if="data.isExist">
<el-card class="app-card" v-loading="loading"> <el-card class="app-card">
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :lg="3" :xl="2"> <el-col :lg="3" :xl="2">
<div> <div>
@ -71,14 +71,13 @@ let data = ref({
isExist: false, isExist: false,
containerName: '', containerName: '',
}); });
let loading = ref(false);
let operateReq = reactive({ let operateReq = reactive({
installId: 0, installId: 0,
operate: '', operate: '',
}); });
let refresh = ref(1); let refresh = ref(1);
const em = defineEmits(['setting', 'isExist']); const em = defineEmits(['setting', 'isExist', 'before', 'update:loading']);
const setting = () => { const setting = () => {
em('setting', false); em('setting', false);
}; };
@ -88,12 +87,10 @@ const goRouter = async (path: string) => {
}; };
const onCheck = async () => { const onCheck = async () => {
loading.value = true;
const res = await CheckAppInstalled(key.value); const res = await CheckAppInstalled(key.value);
data.value = res.data; data.value = res.data;
em('isExist', res.data); em('isExist', res.data);
operateReq.installId = res.data.appInstallId; operateReq.installId = res.data.appInstallId;
loading.value = false;
refresh.value++; refresh.value++;
}; };
@ -108,14 +105,16 @@ const onOperate = async (operation: string) => {
type: 'info', type: 'info',
}, },
).then(() => { ).then(() => {
loading.value = true; em('update:loading', true);
em('before');
InstalledOp(operateReq) InstalledOp(operateReq)
.then(() => { .then(() => {
em('update:loading', false);
ElMessage.success(i18n.global.t('commons.msg.operationSuccess')); ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
onCheck(); onCheck();
}) })
.finally(() => { .catch(() => {
loading.value = false; em('update:loading', false);
}); });
}); });
}; };

View File

@ -32,7 +32,7 @@ const checkName = (rule: any, value: any, callback: any) => {
if (value === '' || typeof value === 'undefined' || value == null) { if (value === '' || typeof value === 'undefined' || value == null) {
callback(new Error(i18n.global.t('commons.rule.commonName'))); callback(new Error(i18n.global.t('commons.rule.commonName')));
} else { } else {
const reg = /^[a-zA-Z0-9\u4e00-\u9fa5]{1}[a-zA-Z0-9_.\u4e00-\u9fa5-]{0,30}$/; const reg = /^[a-zA-Z0-9]{1}[a-zA-Z0-9_]{0,30}$/;
if (!reg.test(value) && value !== '') { if (!reg.test(value) && value !== '') {
callback(new Error(i18n.global.t('commons.rule.commonName'))); callback(new Error(i18n.global.t('commons.rule.commonName')));
} else { } else {

View File

@ -101,7 +101,7 @@ export default {
rePassword: 'The passwords are inconsistent. Please check and re-enter the password', rePassword: 'The passwords are inconsistent. Please check and re-enter the password',
requiredInput: 'Please enter the required fields', requiredInput: 'Please enter the required fields',
requiredSelect: 'Please select the required fields', requiredSelect: 'Please select the required fields',
commonName: 'Support English, Chinese, numbers, .-_, length 1-30', commonName: 'Support English, numbers, _, length 1-30',
imageName: 'Support English, Chinese, numbers, :.-_, length 1-30', imageName: 'Support English, Chinese, numbers, :.-_, length 1-30',
complexityPassword: complexityPassword:
'Please enter a password with more than 8 characters and must contain letters, digits, and special symbols', 'Please enter a password with more than 8 characters and must contain letters, digits, and special symbols',

View File

@ -101,7 +101,7 @@ export default {
rePassword: '密码不一致请检查后重新输入', rePassword: '密码不一致请检查后重新输入',
requiredInput: '请填写必填项', requiredInput: '请填写必填项',
requiredSelect: '请选择必选项', requiredSelect: '请选择必选项',
commonName: '支持英文中文数字.-_,长度1-30', commonName: '支持英文数字_,长度1-30',
imageName: '支持英文中文数字:.-_,长度1-30', imageName: '支持英文中文数字:.-_,长度1-30',
complexityPassword: '请输入 8 位以上必须含有字母数字特殊符号的密码', complexityPassword: '请输入 8 位以上必须含有字母数字特殊符号的密码',
commonPassword: '请输入 6 位以上长度密码', commonPassword: '请输入 6 位以上长度密码',

View File

@ -32,7 +32,12 @@
<el-link @click="loadDetail(row)" type="primary">{{ row.name }}</el-link> <el-link @click="loadDetail(row)" type="primary">{{ row.name }}</el-link>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column :label="$t('container.from')" prop="createdBy" min-width="80" fix /> <el-table-column :label="$t('container.from')" prop="createdBy" min-width="80" fix>
<template #default="{ row }">
<span v-if="row.createdBy === ''">local</span>
<span v-else>{{ row.createdBy }}</span>
</template>
</el-table-column>
<el-table-column <el-table-column
:label="$t('container.containerNumber')" :label="$t('container.containerNumber')"
prop="containerNumber" prop="containerNumber"

View File

@ -1,7 +1,13 @@
<template> <template>
<div> <div v-loading="loading">
<Submenu activeName="mysql" /> <Submenu activeName="mysql" />
<AppStatus :app-key="'mysql'" style="margin-top: 20px" @setting="onSetting" @is-exist="checkExist" /> <AppStatus
:app-key="'mysql'"
style="margin-top: 20px"
v-model:loading="loading"
@setting="onSetting"
@is-exist="checkExist"
/>
<Setting ref="settingRef" style="margin-top: 20px" /> <Setting ref="settingRef" style="margin-top: 20px" />
<el-card width="30%" v-if="mysqlStatus != 'Running' && !isOnSetting && mysqlIsExist" class="mask-prompt"> <el-card width="30%" v-if="mysqlStatus != 'Running' && !isOnSetting && mysqlIsExist" class="mask-prompt">
@ -193,6 +199,8 @@ import { App } from '@/api/interface/app';
import { GetAppPort } from '@/api/modules/app'; import { GetAppPort } from '@/api/modules/app';
import router from '@/routers'; import router from '@/routers';
const loading = ref(false);
const selects = ref<any>([]); const selects = ref<any>([]);
const mysqlName = ref(); const mysqlName = ref();
const isOnSetting = ref<boolean>(); const isOnSetting = ref<boolean>();
@ -353,6 +361,7 @@ const onDelete = async (row: Database.MysqlDBInfo) => {
search(); search();
} }
}; };
const buttons = [ const buttons = [
{ {
label: i18n.global.t('database.changePassword'), label: i18n.global.t('database.changePassword'),

View File

@ -1,15 +1,23 @@
<template> <template>
<div> <div v-loading="loading">
<Submenu activeName="redis" /> <Submenu activeName="redis" />
<AppStatus :app-key="'redis'" style="margin-top: 20px" @setting="onSetting" @is-exist="checkExist"></AppStatus> <AppStatus
:app-key="'redis'"
style="margin-top: 20px"
@before="onBefore"
@setting="onSetting"
@is-exist="checkExist"
v-model:loading="loading"
></AppStatus>
<Setting ref="settingRef" style="margin-top: 10px" />
<div v-show="redisIsExist"> <div v-show="redisIsExist">
<el-button style="margin-top: 20px" type="primary" plain @click="goDashboard" icon="Position"> <el-button style="margin-top: 20px" type="primary" plain @click="goDashboard" icon="Position">
Redis-Commander Redis-Commander
</el-button> </el-button>
<Setting ref="settingRef" style="margin-top: 10px" />
<Terminal style="margin-top: 10px" v-show="!isOnSetting" ref="terminalRef" /> <Terminal style="margin-top: 10px" v-show="!isOnSetting" ref="terminalRef" />
</div> </div>
@ -44,6 +52,8 @@ import { App } from '@/api/interface/app';
import { GetAppPort } from '@/api/modules/app'; import { GetAppPort } from '@/api/modules/app';
import router from '@/routers'; import router from '@/routers';
const loading = ref(false);
const terminalRef = ref(); const terminalRef = ref();
const settingRef = ref(); const settingRef = ref();
const isOnSetting = ref(false); const isOnSetting = ref(false);
@ -81,9 +91,15 @@ const loadDashboardPort = async () => {
const checkExist = (data: App.CheckInstalled) => { const checkExist = (data: App.CheckInstalled) => {
redisIsExist.value = data.isExist; redisIsExist.value = data.isExist;
redisSattus.value = data.status; redisSattus.value = data.status;
loading.value = false;
if (redisIsExist.value) { if (redisIsExist.value) {
loadDashboardPort(); loadDashboardPort();
terminalRef.value.acceptParams(); terminalRef.value.acceptParams();
} }
}; };
const onBefore = () => {
terminalRef.value!.onClose();
loading.value = true;
};
</script> </script>

View File

@ -1,5 +1,5 @@
<template> <template>
<div v-if="persistenceShow"> <div v-if="persistenceShow" v-loading="loading">
<el-row :gutter="20" style="margin-top: 5px" class="row-box"> <el-row :gutter="20" style="margin-top: 5px" class="row-box">
<el-col :span="12"> <el-col :span="12">
<el-card class="el-card"> <el-card class="el-card">
@ -133,6 +133,8 @@ import { useDeleteData } from '@/hooks/use-delete-data';
import { computeSize } from '@/utils/util'; import { computeSize } from '@/utils/util';
import { BatchDeleteFile } from '@/api/modules/files'; import { BatchDeleteFile } from '@/api/modules/files';
const loading = ref(false);
interface saveStruct { interface saveStruct {
second: number; second: number;
count: number; count: number;
@ -194,17 +196,31 @@ const loadBackupRecords = async () => {
paginationConfig.total = res.data.total; paginationConfig.total = res.data.total;
}; };
const onBackup = async () => { const onBackup = async () => {
await backupRedis(); loading.value = true;
ElMessage.success(i18n.global.t('commons.msg.operationSuccess')); await backupRedis()
loadBackupRecords(); .then(() => {
loading.value = false;
loadBackupRecords();
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
})
.catch(() => {
loading.value = false;
});
}; };
const onRecover = async () => { const onRecover = async () => {
let param = { let param = {
fileName: currentRow.value.fileName, fileName: currentRow.value.fileName,
fileDir: currentRow.value.fileDir, fileDir: currentRow.value.fileDir,
}; };
await recoverRedis(param); loading.value = true;
ElMessage.success(i18n.global.t('commons.msg.operationSuccess')); await recoverRedis(param)
.then(() => {
loading.value = false;
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
})
.catch(() => {
loading.value = false;
});
}; };
const onBatchDelete = async (row: Database.FileRecord | null) => { const onBatchDelete = async (row: Database.FileRecord | null) => {
@ -249,9 +265,15 @@ const onSave = async (formEl: FormInstance | undefined, type: string) => {
param.type = type; param.type = type;
param.appendfsync = form.appendfsync; param.appendfsync = form.appendfsync;
param.appendonly = form.appendonly; param.appendonly = form.appendonly;
await updateRedisPersistenceConf(param); loading.value = true;
ElMessage.success(i18n.global.t('commons.msg.operationSuccess')); await updateRedisPersistenceConf(param)
return; .then(() => {
loading.value = false;
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
})
.catch(() => {
loading.value = false;
});
}); });
return; return;
} }
@ -265,8 +287,15 @@ const onSave = async (formEl: FormInstance | undefined, type: string) => {
} }
param.type = type; param.type = type;
param.save = itemSaves.join(' '); param.save = itemSaves.join(' ');
await updateRedisPersistenceConf(param); loading.value = true;
ElMessage.success(i18n.global.t('commons.msg.operationSuccess')); await updateRedisPersistenceConf(param)
.then(() => {
loading.value = false;
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
})
.catch(() => {
loading.value = false;
});
}; };
const loadform = async () => { const loadform = async () => {

View File

@ -142,7 +142,7 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, reactive } from 'vue'; import { ref, reactive, onMounted } from 'vue';
import type { ElForm } from 'element-plus'; import type { ElForm } from 'element-plus';
import { Rules } from '@/global/form-rules'; import { Rules } from '@/global/form-rules';
import { Host } from '@/api/interface/host'; import { Host } from '@/api/interface/host';
@ -311,12 +311,9 @@ const onEdit = async (node: Node, data: Tree) => {
} }
}; };
function onInit() { onMounted(() => {
loadHostTree(); loadHostTree();
loadGroups(); loadGroups();
}
defineExpose({
onInit,
}); });
</script> </script>

View File

@ -1,6 +1,6 @@
<template> <template>
<div> <div v-loading="loading">
<AppStatus :app-key="'nginx'" @setting="setting" @is-exist="checkExist"></AppStatus> <AppStatus :app-key="'nginx'" @setting="setting" v-model:loading="loading" @is-exist="checkExist"></AppStatus>
<div v-if="nginxIsExist" :class="{ mask: nginxStatus != 'Running' }"> <div v-if="nginxIsExist" :class="{ mask: nginxStatus != 'Running' }">
<LayoutContent> <LayoutContent>
<br /> <br />
@ -97,6 +97,8 @@ import i18n from '@/lang';
import router from '@/routers'; import router from '@/routers';
import { App } from '@/api/interface/app'; import { App } from '@/api/interface/app';
const loading = ref(false);
const createRef = ref(); const createRef = ref();
const deleteRef = ref(); const deleteRef = ref();
const groupRef = ref(); const groupRef = ref();