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

feat: 应用商店兼容移动端 (#1119)

#### What this PR does / why we need it?

#### Summary of your change

#### Please indicate you've done the following:

- [ ] Made sure tests are passing and test coverage is added if needed.
- [ ] Made sure commit message follow the rule of [Conventional Commits specification](https://www.conventionalcommits.org/).
- [ ] Considered the docs impact and opened a new docs issue or PR with docs changes if needed.
This commit is contained in:
wangdan-fit2cloud 2023-05-23 21:40:03 +08:00 committed by GitHub
parent 13abe8cb66
commit f7c76c012f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 107 additions and 98 deletions

View File

@ -1,82 +0,0 @@
<template>
<Layout v-loading="loading" :element-loading-text="loadinText" fullscreen>
<template #menu v-if="!globalStore.isFullScreen">
<Menu></Menu>
</template>
<template #footer v-if="!globalStore.isFullScreen">
<Footer></Footer>
</template>
</Layout>
</template>
<script setup lang="ts">
import Layout from '@/layout/index.vue';
import Footer from './footer/index.vue';
import Menu from './menu/index.vue';
import { onMounted, computed, ref, watch, onBeforeUnmount } from 'vue';
import { useI18n } from 'vue-i18n';
import { GlobalStore } from '@/store';
import { useTheme } from '@/hooks/use-theme';
import { getSettingInfo, getSystemAvailable } from '@/api/modules/setting';
const i18n = useI18n();
const loading = ref(false);
const loadinText = ref();
const globalStore = GlobalStore();
const themeConfig = computed(() => globalStore.themeConfig);
const { switchDark } = useTheme();
let timer: NodeJS.Timer | null = null;
watch(
() => globalStore.isLoading,
() => {
if (globalStore.isLoading) {
loadStatus();
} else {
loading.value = globalStore.isLoading;
}
},
);
const loadDataFromDB = async () => {
const res = await getSettingInfo();
document.title = res.data.panelName;
i18n.locale.value = res.data.language;
i18n.warnHtmlMessage = false;
globalStore.updateLanguage(res.data.language);
globalStore.setThemeConfig({ ...themeConfig.value, theme: res.data.theme });
globalStore.setThemeConfig({ ...themeConfig.value, panelName: res.data.panelName });
switchDark();
};
const loadStatus = async () => {
loading.value = globalStore.isLoading;
loadinText.value = globalStore.loadingText;
if (loading.value) {
timer = setInterval(async () => {
await getSystemAvailable()
.then((res) => {
if (res) {
location.reload();
clearInterval(Number(timer));
timer = null;
}
})
.catch(() => {
location.reload();
clearInterval(Number(timer));
timer = null;
});
}, 1000 * 10);
}
};
onBeforeUnmount(() => {
clearInterval(Number(timer));
timer = null;
});
onMounted(() => {
loadStatus();
loadDataFromDB();
});
</script>

View File

@ -1,7 +1,7 @@
<template>
<div :class="classObj" class="app-wrapper">
<div :class="classObj" class="app-wrapper" v-loading="loading" :element-loading-text="loadinText" fullscreen>
<div v-if="classObj.mobile && classObj.openSidebar" class="drawer-bg" @click="handleClickOutside" />
<div class="app-sidebar">
<div class="app-sidebar" v-if="!globalStore.isFullScreen">
<Sidebar />
</div>
@ -9,23 +9,34 @@
<mobile-header v-if="classObj.mobile" />
<app-main class="app-main" />
<Footer class="app-footer" />
<Footer class="app-footer" v-if="!globalStore.isFullScreen" />
</div>
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue';
import { onMounted, computed, ref, watch, onBeforeUnmount } from 'vue';
import { Sidebar, Footer, AppMain, MobileHeader } from './components';
import useResize from './hooks/useResize';
import { GlobalStore } from '@/store';
import { MenuStore } from '@/store/modules/menu';
import { DeviceType } from '@/enums/app';
import { useI18n } from 'vue-i18n';
import { useTheme } from '@/hooks/use-theme';
import { getSettingInfo, getSystemAvailable } from '@/api/modules/setting';
useResize();
const menuStore = MenuStore();
const globalStore = GlobalStore();
const i18n = useI18n();
const loading = ref(false);
const loadinText = ref();
const themeConfig = computed(() => globalStore.themeConfig);
const { switchDark } = useTheme();
let timer: NodeJS.Timer | null = null;
const classObj = computed(() => {
return {
hideSidebar: menuStore.isCollapse,
@ -37,6 +48,58 @@ const classObj = computed(() => {
const handleClickOutside = () => {
menuStore.closeSidebar(false);
};
watch(
() => globalStore.isLoading,
() => {
if (globalStore.isLoading) {
loadStatus();
} else {
loading.value = globalStore.isLoading;
}
},
);
const loadDataFromDB = async () => {
const res = await getSettingInfo();
document.title = res.data.panelName;
i18n.locale.value = res.data.language;
i18n.warnHtmlMessage = false;
globalStore.updateLanguage(res.data.language);
globalStore.setThemeConfig({ ...themeConfig.value, theme: res.data.theme });
globalStore.setThemeConfig({ ...themeConfig.value, panelName: res.data.panelName });
switchDark();
};
const loadStatus = async () => {
loading.value = globalStore.isLoading;
loadinText.value = globalStore.loadingText;
if (loading.value) {
timer = setInterval(async () => {
await getSystemAvailable()
.then((res) => {
if (res) {
location.reload();
clearInterval(Number(timer));
timer = null;
}
})
.catch(() => {
location.reload();
clearInterval(Number(timer));
timer = null;
});
}, 1000 * 10);
}
};
onBeforeUnmount(() => {
clearInterval(Number(timer));
timer = null;
});
onMounted(() => {
loadStatus();
loadDataFromDB();
});
</script>
<style scoped lang="scss">

View File

@ -6,4 +6,32 @@
.mobile-monitor-chart {
margin-top: 20px !important;
}
.search-button {
float: none !important;
.table-button {
display: inline-flex !important;
}
}
.app-card {
.app-button {
margin-right: 0 !important;
}
}
.install-card .a-detail {
.d-name {
height: auto !important;
.h-button {
float: none !important;
margin: 5px;
}
}
.d-button {
min-width: auto !important;
}
.d-description {
display: block !important;
overflow: inherit !important;
}
}
}

View File

@ -2,7 +2,7 @@
<LayoutContent v-loading="loading" v-if="!showDetail" :title="$t('app.app')">
<template #toolbar>
<el-row :gutter="5">
<el-col :span="20">
<el-col :xs="24" :sm="24" :md="20" :lg="20" :xl="20">
<el-button
class="tag-button"
:class="activeTag === 'all' ? '' : 'no-active'"
@ -24,7 +24,7 @@
</el-button>
</div>
</el-col>
<el-col :span="4">
<el-col :xs="24" :sm="24" :md="4" :lg="4" :xl="4">
<div class="search-button">
<el-input
v-model="req.name"
@ -45,11 +45,11 @@
</template>
<template #main>
<el-row :gutter="5">
<el-col v-for="(app, index) in apps" :key="index" :xs="12" :sm="12" :md="8" :lg="8" :xl="8">
<el-col v-for="(app, index) in apps" :key="index" :xs="24" :sm="12" :md="8" :lg="8" :xl="8">
<div class="app-card">
<el-card class="e-card">
<el-row :gutter="24">
<el-col :xs="5" :sm="5" :md="6" :lg="6" :xl="5">
<el-row :gutter="20">
<el-col :xs="8" :sm="5" :md="6" :lg="6" :xl="5">
<div class="app-icon">
<el-avatar
shape="square"
@ -58,7 +58,7 @@
/>
</div>
</el-col>
<el-col :xs="19" :sm="19" :md="18" :lg="18" :xl="19">
<el-col :xs="16" :sm="19" :md="18" :lg="18" :xl="19">
<div class="app-content">
<div class="app-header">
<span class="app-title">{{ app.name }}</span>

View File

@ -2,7 +2,7 @@
<LayoutContent v-loading="loading || syncLoading" :title="activeName">
<template #toolbar>
<el-row :gutter="5">
<el-col :span="20">
<el-col :xs="24" :sm="24" :md="20" :lg="20" :xl="20">
<div>
<el-button
class="tag-button"
@ -26,7 +26,7 @@
</div>
</div>
</el-col>
<el-col :span="4">
<el-col :xs="24" :sm="24" :md="4" :lg="4" :xl="4">
<div class="search-button">
<el-input
class="table-button"
@ -68,7 +68,7 @@
>
<div class="install-card">
<el-card class="e-card">
<el-row :gutter="24">
<el-row :gutter="20">
<el-col :xs="3" :sm="3" :md="3" :lg="4" :xl="4">
<div class="icon">
<el-avatar
@ -78,7 +78,7 @@
/>
</div>
</el-col>
<el-col :xs="21" :sm="21" :md="21" :lg="20" :xl="20">
<el-col :xs="24" :sm="21" :md="21" :lg="20" :xl="20">
<div class="a-detail">
<div class="d-name">
<el-button link type="info">

View File

@ -20,7 +20,7 @@
</template>
<template v-if="nginxIsExist && !openNginxConfig" #toolbar>
<el-row :class="{ mask: nginxStatus != 'Running' }">
<el-col :span="20">
<el-col :xs="24" :sm="24" :md="20" :lg="20" :xl="20">
<el-button type="primary" @click="openCreate">
{{ $t('website.create') }}
</el-button>
@ -31,7 +31,7 @@
{{ $t('website.defaultServer') }}
</el-button>
</el-col>
<el-col :span="4">
<el-col :xs="24" :sm="24" :md="4" :lg="4" :xl="4">
<div class="search-button">
<el-input
v-model="req.name"