页签导航栏

This commit is contained in:
2026-05-21 14:22:51 +08:00
parent f0aa2625e9
commit 3f1ad80a8f
6 changed files with 154 additions and 99 deletions

View File

@ -22,9 +22,9 @@
> >
<router-view v-slot="{ Component }"> <router-view v-slot="{ Component }">
<KeepAlive v-if="route.meta.keepAlive"> <KeepAlive v-if="route.meta.keepAlive">
<component :is="Component" :key="route.path" /> <component :is="Component" :key="refreshKey" />
</KeepAlive> </KeepAlive>
<component v-else :is="Component" :key="route.path" /> <component v-else :is="Component" :key="refreshKey" />
</router-view> </router-view>
</transition> </transition>
</main> </main>
@ -40,8 +40,19 @@ defineOptions({
import Header from './Header.vue' import Header from './Header.vue'
import Sidebar from './Sidebar.vue' import Sidebar from './Sidebar.vue'
import Tabs from './Tabs.vue' import Tabs from './Tabs.vue'
import { useTabsStore } from '@/stores/modules/tabs'
const route = useRoute() const route = useRoute()
const tabsStore = useTabsStore()
// key
const refreshKey = computed(() => {
// refreshKey
if (tabsStore.refreshKey.startsWith(route.path)) {
return tabsStore.refreshKey
}
return route.path
})
// //
const sidebarCollapsed = ref(false) const sidebarCollapsed = ref(false)

View File

@ -82,7 +82,11 @@
:style="contextMenuStyle" :style="contextMenuStyle"
@click.stop @click.stop
> >
<div class="context-menu-item" @click="handleContextMenuCommand('refresh')"> <div
class="context-menu-item"
:class="{ 'is-disabled': !canRefresh }"
@click="canRefresh && handleContextMenuCommand('refresh')"
>
<el-icon><Refresh /></el-icon> <el-icon><Refresh /></el-icon>
<span>刷新当前页</span> <span>刷新当前页</span>
</div> </div>
@ -140,6 +144,12 @@ const canCloseCurrent = computed(() => {
return !isFixedTab(path) return !isFixedTab(path)
}) })
// tab
const canRefresh = computed(() => {
const path = contextMenuPath.value || ''
return path === route.path
})
// //
const canCloseOther = computed(() => { const canCloseOther = computed(() => {
const path = contextMenuPath.value || tabsStore.activeTab || '' const path = contextMenuPath.value || tabsStore.activeTab || ''
@ -393,11 +403,32 @@ const handleDragEnd = () => {
const handleContextMenuCommand = (command: string) => { const handleContextMenuCommand = (command: string) => {
// 使 // 使
const currentPath = contextMenuPath.value || tabsStore.activeTab const currentPath = contextMenuPath.value || tabsStore.activeTab
//
const rightClickedPath = contextMenuPath.value
closeContextMenu() closeContextMenu()
switch (command) { switch (command) {
case 'refresh': case 'refresh':
router.go(0) // tab tab
const refreshPath = rightClickedPath || tabsStore.activeTab
if (refreshPath) {
const targetTab = tabsStore.tabs.find(item => item.path === refreshPath)
// activeTab
if (refreshPath !== route.path) {
tabsStore.setActiveTab(refreshPath)
router.push({ path: refreshPath, query: targetTab?.query }).then(() => {
//
nextTick(() => {
tabsStore.refreshTab(refreshPath)
})
})
} else {
//
tabsStore.refreshTab(refreshPath)
}
}
break break
case 'close': case 'close':
if (currentPath) { if (currentPath) {

View File

@ -241,6 +241,14 @@ export const useTabsStore = defineStore('tabs', () => {
saveTabs() saveTabs()
} }
// 刷新指定 tab 的 key用于触发组件刷新
const refreshKey = ref<string>('')
// 刷新指定路径的 tab
const refreshTab = (path: string) => {
refreshKey.value = path + '-' + Date.now()
}
// 保存到本地存储 // 保存到本地存储
const saveTabs = () => { const saveTabs = () => {
setStorage('tabs', tabs.value) setStorage('tabs', tabs.value)
@ -283,6 +291,8 @@ export const useTabsStore = defineStore('tabs', () => {
closeRightTabs, closeRightTabs,
setActiveTab, setActiveTab,
clearTabs, clearTabs,
setTabs setTabs,
refreshKey,
refreshTab
} }
}) })

View File

@ -1,3 +1,6 @@
import dayjs from 'dayjs'
/** /**
* *
* @param format 'YYYY-MM-DD HH:mm:ss' * @param format 'YYYY-MM-DD HH:mm:ss'
@ -37,22 +40,22 @@ export const getRecentSevenDays = (format = 'YYYY-MM-DD HH:mm:ss'):{ start: stri
* @returns {string} UTC+8 YYYY-MM-DD HH:mm:ss * @returns {string} UTC+8 YYYY-MM-DD HH:mm:ss
*/ */
export function utcToUtc8(utcStr: string): string { export function utcToUtc8(utcStr: string): string {
// 将字符串解析为 UTC 时间 // // 将字符串解析为 UTC 时间
const utcDate = new Date(utcStr.replace(' ', 'T') + 'Z') // const utcDate = new Date(utcStr.replace(' ', 'T') + 'Z')
// 转换为 UTC+8东八区 // // 转换为 UTC+8东八区
const utc8Date = new Date(utcDate.getTime() + 8 * 60 * 60 * 1000) // const utc8Date = new Date(utcDate.getTime() + 8 * 60 * 60 * 1000)
// 格式化为 YYYY-MM-DD HH:mm:ss // // 格式化为 YYYY-MM-DD HH:mm:ss
const pad = (n) => String(n).padStart(2, '0') // const pad = (n) => String(n).padStart(2, '0')
const year = utc8Date.getUTCFullYear() // const year = utc8Date.getUTCFullYear()
const month = pad(utc8Date.getUTCMonth() + 1) // const month = pad(utc8Date.getUTCMonth() + 1)
const day = pad(utc8Date.getUTCDate()) // const day = pad(utc8Date.getUTCDate())
const hour = pad(utc8Date.getUTCHours()) // const hour = pad(utc8Date.getUTCHours())
const minute = pad(utc8Date.getUTCMinutes()) // const minute = pad(utc8Date.getUTCMinutes())
const second = pad(utc8Date.getUTCSeconds()) // const second = pad(utc8Date.getUTCSeconds())
return `${year}-${month}-${day} ${hour}:${minute}:${second}` return dayjs(utcStr).format('YYYY-MM-DD HH:mm:ss')
} }

View File

@ -1,12 +1,8 @@
<template> <template>
<div class="table_form-container"> <div class="table_form-container">
<!-- 搜索 --> <!-- 搜索 -->
<FundDetailSearch <FundDetailSearch :search-form="searchForm" :search-options="searchOptions" @search="handleSearch"
:search-form="searchForm" @reset="handleReset">
:search-options="searchOptions"
@search="handleSearch"
@reset="handleReset"
>
<template #button="{ form }"> <template #button="{ form }">
<el-button type="primary" @click="handleExport()"> 导出 </el-button> <el-button type="primary" @click="handleExport()"> 导出 </el-button>
</template> </template>
@ -14,12 +10,8 @@
<!-- 表格 --> <!-- 表格 -->
<FundDetailTable :table-data="tableTree" :columns="tableColumnsOptions" row-key="id" :loading="loading" /> <FundDetailTable :table-data="tableTree" :columns="tableColumnsOptions" row-key="id" :loading="loading" />
<!-- 分页 --> <!-- 分页 -->
<FundDetailPagination <FundDetailPagination v-model="currentPage" v-model:pageSizeValue="pageSize" :total="total"
v-model="currentPage" @pagination-change="handlePaginationChange" />
v-model:pageSizeValue="pageSize"
:total="total"
@pagination-change="handlePaginationChange"
/>
</div> </div>
</template> </template>
@ -71,6 +63,7 @@ const total = ref(0)
// //
const getFundDetailList = async () => { const getFundDetailList = async () => {
startLoading() startLoading()
try {
const params = { const params = {
page: currentPage.value, page: currentPage.value,
page_size: pageSize.value, page_size: pageSize.value,
@ -87,7 +80,6 @@ const getFundDetailList = async () => {
} }
// //
const data: any = await getFundDetailListApi(params) const data: any = await getFundDetailListApi(params)
stopLoading()
console.log(data) console.log(data)
tableTree.value = data.data.map((item: any) => ({ tableTree.value = data.data.map((item: any) => ({
...item, ...item,
@ -106,6 +98,9 @@ const getFundDetailList = async () => {
total.value = data.total total.value = data.total
currentPage.value = data.current_page currentPage.value = data.current_page
pageSize.value = Number(data.per_page) pageSize.value = Number(data.per_page)
} finally {
stopLoading()
}
} }
/** /**

View File

@ -10,7 +10,8 @@
<div>交易盈亏:0.00 USD</div> <div>交易盈亏:0.00 USD</div>
</div> </div>
<!-- 表格 --> <!-- 表格 -->
<CustomerTradeOrderTable :table-data="tableTree" :columns="tableColumnsOptions" row-key="id" :loading="loading" /> <CustomerTradeOrderTable :table-data="tableTree" :columns="tableColumnsOptions" row-key="id"
:loading="loading" />
<!-- 分页 --> <!-- 分页 -->
<CustomerTradeOrderPagination v-model="currentPage" v-model:pageSizeValue="pageSize" :total="total" <CustomerTradeOrderPagination v-model="currentPage" v-model:pageSizeValue="pageSize" :total="total"
@ -82,6 +83,7 @@ const total = ref(0)
* @description: 定义公共请求数据方法 * @description: 定义公共请求数据方法
*/ */
const getCustomerTradeOrderList = async () => { const getCustomerTradeOrderList = async () => {
try {
startLoading() startLoading()
const params = { const params = {
page: currentPage.value, page: currentPage.value,
@ -95,7 +97,6 @@ const getCustomerTradeOrderList = async () => {
} }
console.log(params) console.log(params)
const data: any = await getCustomTradeOrderListApi(params) const data: any = await getCustomTradeOrderListApi(params)
stopLoading()
// //
// table // table
tableTree.value = data.data.map((item: any) => ({ tableTree.value = data.data.map((item: any) => ({
@ -115,6 +116,10 @@ const getCustomerTradeOrderList = async () => {
total.value = data.total total.value = data.total
currentPage.value = data.current_page currentPage.value = data.current_page
pageSize.value = Number(data.per_page) pageSize.value = Number(data.per_page)
} finally {
stopLoading()
}
} }
const getSubAccountList = async () => { const getSubAccountList = async () => {