feat:更新tabbar显示

This commit is contained in:
2025-10-30 16:50:13 +08:00
parent cc33d3028b
commit 9e0b8ead79
18 changed files with 61 additions and 337 deletions

View File

@@ -1,16 +1,20 @@
<template> <template>
<section class="layout-mobile-home"> <section class="layout-mobile-home"
:class="{ 'hide-tab-bar': appStore.isShowMobileBack }">
<title-bar /> <title-bar />
<router-view /> <router-view />
<tab-bar /> <tab-bar v-if="!appStore.isShowMobileBack"/>
</section> </section>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import TitleBar from '@/layout/TitleBar.vue' import TitleBar from '@/layout/TitleBar.vue'
import TabBar from '@/layout/TabBar.vue' import TabBar from '@/layout/TabBar.vue'
import { useAppStore } from '@/store/app.ts'
const appStore = useAppStore()
</script> </script>
<style lang="scss"> <style lang="scss">

View File

@@ -6,8 +6,19 @@ $tabBar-height: 70px;
.layout-mobile-home { .layout-mobile-home {
height: 100%; height: 100%;
&.hide-tab-bar {
.common-mobile-view {
height: calc(100vh - #{$titleBar-height});
}
}
&:not(.hide-tab-bar) {
.common-mobile-view {
height: calc(100vh - #{$tabBar-height} - #{$titleBar-height});
}
}
.common-mobile-view { .common-mobile-view {
height: calc(100vh - $tabBar-height - $titleBar-height);
overflow: auto; overflow: auto;
background-color: var(--color-bg); background-color: var(--color-bg);
color: var(--color-text); color: var(--color-text);

View File

@@ -93,11 +93,13 @@ const confirmClick = () => {
formRef.value.validate().then(async () => { formRef.value.validate().then(async () => {
await anniversaryStore.handleAnniversaryApi(anniversaryStore.currentAnniversary) await anniversaryStore.handleAnniversaryApi(anniversaryStore.currentAnniversary)
history.back() history.back()
appStore.isShowMobileBack = false
}) })
} }
const cancelClick = () => { const cancelClick = () => {
history.back() history.back()
appStore.isShowMobileBack = false
} }
const deleteClick = () => { const deleteClick = () => {
@@ -105,6 +107,7 @@ const deleteClick = () => {
anniversaryStore.anniversaryApiType = 'DELETE' anniversaryStore.anniversaryApiType = 'DELETE'
await anniversaryStore.handleAnniversaryApi(anniversaryStore.currentAnniversary) await anniversaryStore.handleAnniversaryApi(anniversaryStore.currentAnniversary)
history.back() history.back()
appStore.isShowMobileBack = false
}) })
} }
</script> </script>

View File

@@ -99,6 +99,7 @@ const confirmClick = () => {
const cancelClick = () => { const cancelClick = () => {
history.back() history.back()
appStore.isShowMobileBack = false
} }
const deleteClick = () => { const deleteClick = () => {

View File

@@ -214,11 +214,13 @@ const confirmClick = () => {
formRef.value.validate().then(async () => { formRef.value.validate().then(async () => {
await billStore.handleBillApi(billStore.currentBillRecord) await billStore.handleBillApi(billStore.currentBillRecord)
history.back() history.back()
appStore.isShowMobileBack = false
}) })
} }
const cancelClick = () => { const cancelClick = () => {
history.back() history.back()
appStore.isShowMobileBack = false
} }
const deleteClick = () => { const deleteClick = () => {
@@ -226,6 +228,7 @@ const deleteClick = () => {
billStore.billApiType = 'DELETE' billStore.billApiType = 'DELETE'
await billStore.handleBillApi(billStore.currentBillRecord) await billStore.handleBillApi(billStore.currentBillRecord)
history.back() history.back()
appStore.isShowMobileBack = false
}) })
} }
</script> </script>

View File

@@ -28,10 +28,6 @@
title="账单记录" sub-title="收支一目了然" title="账单记录" sub-title="收支一目了然"
router="/bill/data"/> router="/bill/data"/>
<module-card icon="iconfont icon-caipu" color="#006400"
title="美食记录" sub-title="品味人间烟火"
router="/food/recipe"/>
<module-card icon="iconfont icon-jingdian" color="#FF9966" <module-card icon="iconfont icon-jingdian" color="#FF9966"
title="旅行记录" sub-title="足迹遍及四方" title="旅行记录" sub-title="足迹遍及四方"
router="/travel/spot"/> router="/travel/spot"/>
@@ -71,10 +67,6 @@
<module-card icon="iconfont icon-ai-password" color="#4361EE" <module-card icon="iconfont icon-ai-password" color="#4361EE"
title="密码管家" sub-title="守护数字安全" title="密码管家" sub-title="守护数字安全"
router="/password/list"/> router="/password/list"/>
<module-card icon="iconfont icon-fuwuqi" color="#FF6B6B"
title="服务监控" sub-title="掌握系统健康"
router="/server/monitor"/>
</div> </div>
<!-- <div class="note-container">--> <!-- <div class="note-container">-->

View File

@@ -139,11 +139,13 @@ const confirmClick = () => {
formRef.value.validate().then(async () => { formRef.value.validate().then(async () => {
await journalStore.handleJournalApi(journalStore.currentJournal) await journalStore.handleJournalApi(journalStore.currentJournal)
history.back() history.back()
appStore.isShowMobileBack = false
}) })
} }
const cancelClick = () => { const cancelClick = () => {
history.back() history.back()
appStore.isShowMobileBack = false
} }
const deleteClick = () => { const deleteClick = () => {
@@ -151,6 +153,7 @@ const deleteClick = () => {
journalStore.journalApiType = 'DELETE' journalStore.journalApiType = 'DELETE'
await journalStore.handleJournalApi(journalStore.currentJournal) await journalStore.handleJournalApi(journalStore.currentJournal)
history.back() history.back()
appStore.isShowMobileBack = false
}) })
} }
</script> </script>

View File

@@ -104,11 +104,13 @@ const confirmClick = () => {
formRef.value.validate().then(async () => { formRef.value.validate().then(async () => {
await kpiStore.handleKpiApi(kpiStore.currentKpi) await kpiStore.handleKpiApi(kpiStore.currentKpi)
history.back() history.back()
appStore.isShowMobileBack = false
}) })
} }
const cancelClick = () => { const cancelClick = () => {
history.back() history.back()
appStore.isShowMobileBack = false
} }
const deleteClick = () => { const deleteClick = () => {
@@ -116,6 +118,7 @@ const deleteClick = () => {
kpiStore.kpiApiType = 'DELETE' kpiStore.kpiApiType = 'DELETE'
await kpiStore.handleKpiApi(kpiStore.currentKpi) await kpiStore.handleKpiApi(kpiStore.currentKpi)
history.back() history.back()
appStore.isShowMobileBack = false
}) })
} }
</script> </script>

View File

@@ -106,11 +106,13 @@ const confirmClick = () => {
formRef.value.validate().then(async () => { formRef.value.validate().then(async () => {
await ledgerStore.handleLedgerApi(ledgerStore.currentLedgerRecord) await ledgerStore.handleLedgerApi(ledgerStore.currentLedgerRecord)
history.back() history.back()
appStore.isShowMobileBack = false
}) })
} }
const cancelClick = () => { const cancelClick = () => {
history.back() history.back()
appStore.isShowMobileBack = false
} }
const deleteClick = () => { const deleteClick = () => {
@@ -118,6 +120,7 @@ const deleteClick = () => {
ledgerStore.ledgerApiType = 'DELETE' ledgerStore.ledgerApiType = 'DELETE'
await ledgerStore.handleLedgerApi(ledgerStore.currentLedgerRecord) await ledgerStore.handleLedgerApi(ledgerStore.currentLedgerRecord)
history.back() history.back()
appStore.isShowMobileBack = false
}) })
} }
</script> </script>

View File

@@ -49,28 +49,6 @@ export const mobileHomeMeta: IRouteMetaConfig = {
title: '账单设置', title: '账单设置',
icon: '' icon: ''
}, },
'/food': {
title: '美食记录',
icon: 'home-food',
order: 3,
redirect: '/food/recipe'
},
'/food/recipe': {
title: '美食菜谱',
icon: ''
},
'/food/record': {
title: '美食记录',
icon: ''
},
'/food/detail/id': {
title: '菜谱内容',
icon: ''
},
'/food/recordForm': {
title: '记录表单',
icon: ''
},
'/travel': { '/travel': {
title: '旅行记录', title: '旅行记录',
icon: 'home-food', icon: 'home-food',
@@ -197,24 +175,6 @@ export const mobileHomeMeta: IRouteMetaConfig = {
title: '内容', title: '内容',
icon: '' icon: ''
}, },
'/server': {
title: '服务',
icon: 'home-server',
order: 11,
redirect: '/server/list'
},
'/server/monitor': {
title: '监控',
icon: ''
},
'/server/file': {
title: '文件',
icon: ''
},
'/server/preview/:url': {
title: '预览',
icon: ''
},
'/asset': { '/asset': {
title: '资产', title: '资产',
icon: 'home-asset', icon: 'home-asset',

View File

@@ -91,11 +91,13 @@ const confirmClick = () => {
formRef.value.validate().then(async () => { formRef.value.validate().then(async () => {
await passwordStore.handlePasswordApi(passwordStore.currentPassword) await passwordStore.handlePasswordApi(passwordStore.currentPassword)
history.back() history.back()
appStore.isShowMobileBack = false
}) })
} }
const cancelClick = () => { const cancelClick = () => {
history.back() history.back()
appStore.isShowMobileBack = false
} }
</script> </script>

View File

@@ -177,6 +177,7 @@ const confirmClick = () => {
if (validatePlan()) { if (validatePlan()) {
await planStore.handlePlanApi(planStore.currentPlan) await planStore.handlePlanApi(planStore.currentPlan)
history.back() history.back()
appStore.isShowMobileBack = false
} }
}) })
} }
@@ -186,11 +187,13 @@ const deleteClick = () => {
planStore.planApiType = 'DELETE' planStore.planApiType = 'DELETE'
await planStore.handlePlanApi(planStore.currentPlan) await planStore.handlePlanApi(planStore.currentPlan)
history.back() history.back()
appStore.isShowMobileBack = false
}) })
} }
const cancelClick = () => { const cancelClick = () => {
history.back() history.back()
appStore.isShowMobileBack = false
} }
</script> </script>

View File

@@ -101,11 +101,13 @@ const confirmClick = () => {
formRef.value.validate().then(async () => { formRef.value.validate().then(async () => {
await productStore.handleProductApi(productStore.currentProduct) await productStore.handleProductApi(productStore.currentProduct)
history.back() history.back()
appStore.isShowMobileBack = false
}) })
} }
const cancelClick = () => { const cancelClick = () => {
history.back() history.back()
appStore.isShowMobileBack = false
} }
</script> </script>

View File

@@ -1,171 +0,0 @@
<template>
<div class="mobile-server-file common-mobile-view">
<div class="file-header">
<div class="header-left">
<div class="header-tools">
<i class="fa-solid fa-arrow-left" title="返回" @click="backFileClick"></i>
<i class="fa-solid fa-sync" title="刷新" @click="fileStore.queryFileInfoList()"></i>
</div>
<div class="current-path">当前路径: {{ fileStore.currentFolder }}</div>
</div>
</div>
<div class="file-list card-item">
<div class="file-list-header">
<div>文件名称</div>
<div>文件大小</div>
<div>创建日期</div>
</div>
<div class="file-list-content">
<!-- 文件夹示例 -->
<div v-for="(item, index) in fileStore.fileInfoList"
:key=index class="file-item" @click="getFileClick(item)">
<div class="file-name">
<file-icons :name="item.name" :isFolder="item.type === '文件夹'"/>
<span class="name">{{ item.name }}</span>
</div>
<span class="file-size">{{ item.size }}</span>
<span class="file-creation-time">{{ item.createDate }}</span>
</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import FileIcons from 'file-icons-vue'
import { useAppStore } from '@/store/app.ts'
import { useFileStore } from '@/store/file.ts'
import { useRouter } from 'vue-router'
import { onMounted } from 'vue'
import { IFileInfo } from '@/types/file.ts'
import { ElMessage } from 'element-plus'
const fileStore = useFileStore()
const router = useRouter()
const appStore = useAppStore()
onMounted(() => {
fileStore.queryFileInfoList()
})
const backFileClick = async () => {
if (fileStore.pathHistory.length > 1) {
fileStore.pathHistory.pop()
fileStore.currentFolder = fileStore.pathHistory[fileStore.pathHistory.length - 1]
await fileStore.queryFileInfoList()
}
}
const getFileClick = async (file: IFileInfo) => {
if (file.type === '文件夹') {
fileStore.currentFolder = `${fileStore.currentFolder}/${file.name}`
fileStore.pathHistory.push(fileStore.currentFolder)
await fileStore.queryFileInfoList()
} else if (fileStore.previewFileTypeList.includes(file.type)) {
const fileUrl = fileStore.currentFolder.replace(fileStore.pathHistory[0], '')
const url = `/admin-service/logs${fileUrl}/${file.name}`
appStore.isShowMobileBack = true
await router.push({ name: 'MobileHomeServerPreviewUrl', params: { url } })
} else {
ElMessage.error('暂不支持预览该文件')
}
}
</script>
<style lang="scss">
.mobile-server-file {
display: flex;
flex-direction: column;
gap: 10px;
.file-header {
background-color: var(--el-color-primary);
color: #FFFFFF;
padding: 10px;
display: flex;
justify-content: space-between;
align-items: center;
.header-left {
display: flex;
align-items: center;
gap: 1.25rem;
.header-tools {
display: flex;
gap: 1.25rem;
i {
cursor: pointer;
transition: color 0.3s ease;
font-size: 1.25rem;
}
i:hover {
color: #e0f2fe;
}
}
.current-path {
font-weight: bold;
}
}
}
.file-list {
.file-list-header {
display: grid;
grid-template-columns: 1fr 60px 120px;
justify-items: center;
align-items: center;
gap: 5px;
padding: 10px;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
background-color: var(--el-color-primary);
color: #FFFFFF;
font-weight: bold;
}
.file-list-content {
max-height: calc(100vh - 220px);
overflow: auto;
display: flex;
flex-direction: column;
gap: 5px;
.file-item {
display: grid;
grid-template-columns: 1fr 60px 120px;
align-items: center;
gap: 5px;
padding: 10px;
border-bottom: 1px solid #e0f2fe;
.file-name {
display: grid;
grid-template-columns: 20px 1fr;
align-items: center;
gap: 3px;
.name {
font-weight: 600;
color: #0c4a6e;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
.file-size,
.file-creation-time {
color: #64748b;
font-size: 0.9rem;
}
}
}
}
}
</style>

View File

@@ -1,89 +0,0 @@
<template>
<div class="mobile-server-monitor common-mobile-view">
<server-card :is-online="appStore.isWebSocket"
:server-ip="appStore.serverIp"
:server-monitor="serverInfo.monitor"/>
<server-progress :server-monitor="serverInfo.monitor"/>
<div class="refresh-time">
<el-text >{{ serverInfo.refreshTime }}</el-text>
</div>
</div>
</template>
<script lang="ts" setup>
import ServerCard from '@/components/Server/ServerCard.vue'
import ServerProgress from '@/components/Server/ServerProgress.vue'
import { useAppStore } from '@/store/app.ts'
import { onMounted, onUnmounted, reactive } from 'vue'
import { WebSocketUtil } from 'vue3-common/utils/webSocketUtil'
import { IServerMonitor } from '@/types/server.ts'
import { formatDate } from 'vue3-common/utils/dateUtil'
const appStore = useAppStore()
const webSocket = new WebSocketUtil(`ws://${appStore.serverIp}/ws/`)
const serverInfo = reactive({
monitor: {
cpuCores: 0,
cpuModel: '',
cpuUsage: 0,
diskUsage: 0,
memoryUsage: 0,
networkSpeed: {
rx: 0,
tx: 0
},
systemInfo: '',
systemLoad: {
load1m: 0,
load5m: 0,
load15m: 0
},
topProcesses: [],
totalDisk: 0,
totalMemory: 0,
uptime: 0
} as IServerMonitor,
refreshTime: formatDate(new Date(), 'YYYY-MM-DD HH:mm:ss')
})
onMounted(async () => {
webSocket.connect()
})
onUnmounted(() => {
webSocket.close()
})
webSocket.on('onOpen', () => {
appStore.isWebSocket = true
webSocket.send(webSocket.formatMessage('serverMonitor', {}))
// console.log('连接成功')
})
webSocket.on('onMessage', (message: string) => {
serverInfo.monitor = JSON.parse(message).payload
serverInfo.refreshTime = formatDate(new Date(), 'YYYY-MM-DD HH:mm:ss')
// console.log(serverInfo.monitor)
})
webSocket.on('onClose', (event: CloseEvent) => {
appStore.isWebSocket = false
// console.log('关闭连接')
})
</script>
<style lang="scss">
.mobile-server-monitor {
display: flex;
flex-direction: column;
gap: 10px;
.refresh-time {
align-self: flex-end;
}
}
</style>

View File

@@ -1,24 +0,0 @@
<template>
<div class="mobile-server-preview common-mobile-view">
<span style="text-align: center;">{{ route.params.url }}</span>
<iframe :src="route.params.url" class="preview-file"/>
</div>
</template>
<script lang="ts" setup>
import { useRoute } from 'vue-router'
const route = useRoute()
</script>
<style lang="scss">
.mobile-server-preview {
display: flex;
flex-direction: column;
gap: 5px;
.preview-file {
flex-grow: 1;
}
}
</style>

View File

@@ -64,16 +64,22 @@
<script lang="ts" setup> <script lang="ts" setup>
import { UploadImage, UploadVideo } from 'vue3-common' import { UploadImage, UploadVideo } from 'vue3-common'
import { useTravelStore } from '@/store/travel.ts' import { useTravelStore } from '@/store/travel.ts'
import { ref, reactive } from 'vue' import { ref, reactive, onMounted } from 'vue'
import { FormRules } from 'element-plus' import { FormRules } from 'element-plus'
import { travelRecordRules } from '@/utils/element/elRules.ts' import { travelRecordRules } from '@/utils/element/elRules.ts'
import { fileServiceUrl, serviceFileRootPath } from '@/utils' import { fileServiceUrl, serviceFileRootPath } from '@/utils'
import { commonElMessageBox } from 'vue3-common/utils/elUtil' import { commonElMessageBox } from 'vue3-common/utils/elUtil'
import { useAppStore } from '@/store/app.ts'
const rules = reactive<FormRules>(travelRecordRules) const rules = reactive<FormRules>(travelRecordRules)
const formRef = ref() const formRef = ref()
const travelStore = useTravelStore() const travelStore = useTravelStore()
const appStore = useAppStore()
onMounted(async () => {
appStore.isShowMobileBack = true
})
/** /**
* 点击确认按钮 * 点击确认按钮
@@ -82,11 +88,13 @@ const confirmClick = () => {
formRef.value.validate().then(() => { formRef.value.validate().then(() => {
travelStore.handleTravelRecordApi(travelStore.currentTravelRecord) travelStore.handleTravelRecordApi(travelStore.currentTravelRecord)
history.back() history.back()
appStore.isShowMobileBack = false
}) })
} }
const cancelClick = () => { const cancelClick = () => {
history.back() history.back()
appStore.isShowMobileBack = false
} }
const deleteClick = () => { const deleteClick = () => {
@@ -94,6 +102,7 @@ const deleteClick = () => {
travelStore.travelRecordApiType = 'DELETE' travelStore.travelRecordApiType = 'DELETE'
travelStore.handleTravelRecordApi(travelStore.currentTravelRecord) travelStore.handleTravelRecordApi(travelStore.currentTravelRecord)
history.back() history.back()
appStore.isShowMobileBack = false
}) })
} }
</script> </script>

View File

@@ -80,15 +80,22 @@
<script lang="ts" setup> <script lang="ts" setup>
import { useTravelStore } from '@/store/travel.ts' import { useTravelStore } from '@/store/travel.ts'
import { ref, reactive } from 'vue' import { ref, reactive, onMounted } from 'vue'
import { pcTextArr } from 'element-china-area-data' import { pcTextArr } from 'element-china-area-data'
import { FormRules } from 'element-plus' import { FormRules } from 'element-plus'
import { travelRules } from '@/utils/element/elRules.ts' import { travelRules } from '@/utils/element/elRules.ts'
import { useAppStore } from '@/store/app.ts'
const rules = reactive<FormRules>(travelRules) const rules = reactive<FormRules>(travelRules)
const formRef = ref() const formRef = ref()
const travelStore = useTravelStore() const travelStore = useTravelStore()
const appStore = useAppStore()
onMounted(async () => {
appStore.isShowMobileBack = true
})
/** /**
* 点击确认按钮 * 点击确认按钮
*/ */
@@ -96,11 +103,13 @@ const confirmClick = () => {
formRef.value.validate().then(() => { formRef.value.validate().then(() => {
travelStore.handleTravelSpotApi(travelStore.currentTravelSpot) travelStore.handleTravelSpotApi(travelStore.currentTravelSpot)
history.back() history.back()
appStore.isShowMobileBack = false
}) })
} }
const cancelClick = () => { const cancelClick = () => {
history.back() history.back()
appStore.isShowMobileBack = false
} }
</script> </script>