页签导航栏
This commit is contained in:
parent
f0aa2625e9
commit
3f1ad80a8f
|
|
@ -22,9 +22,9 @@
|
|||
>
|
||||
<router-view v-slot="{ Component }">
|
||||
<KeepAlive v-if="route.meta.keepAlive">
|
||||
<component :is="Component" :key="route.path" />
|
||||
<component :is="Component" :key="refreshKey" />
|
||||
</KeepAlive>
|
||||
<component v-else :is="Component" :key="route.path" />
|
||||
<component v-else :is="Component" :key="refreshKey" />
|
||||
</router-view>
|
||||
</transition>
|
||||
</main>
|
||||
|
|
@ -40,8 +40,19 @@ defineOptions({
|
|||
import Header from './Header.vue'
|
||||
import Sidebar from './Sidebar.vue'
|
||||
import Tabs from './Tabs.vue'
|
||||
import { useTabsStore } from '@/stores/modules/tabs'
|
||||
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -82,7 +82,11 @@
|
|||
:style="contextMenuStyle"
|
||||
@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>
|
||||
<span>刷新当前页</span>
|
||||
</div>
|
||||
|
|
@ -140,6 +144,12 @@ const canCloseCurrent = computed(() => {
|
|||
return !isFixedTab(path)
|
||||
})
|
||||
|
||||
// 能否刷新(右键点击的 tab 是当前打开的页面)
|
||||
const canRefresh = computed(() => {
|
||||
const path = contextMenuPath.value || ''
|
||||
return path === route.path
|
||||
})
|
||||
|
||||
// 能否关闭其他(除了固定标签和右键点击的标签外还有其他标签)
|
||||
const canCloseOther = computed(() => {
|
||||
const path = contextMenuPath.value || tabsStore.activeTab || ''
|
||||
|
|
@ -393,11 +403,32 @@ const handleDragEnd = () => {
|
|||
const handleContextMenuCommand = (command: string) => {
|
||||
// 使用右键选中的路径,如果没有则用当前激活的标签
|
||||
const currentPath = contextMenuPath.value || tabsStore.activeTab
|
||||
|
||||
// 保存右键点击的路径(在关闭菜单前保存)
|
||||
const rightClickedPath = contextMenuPath.value
|
||||
|
||||
closeContextMenu()
|
||||
|
||||
switch (command) {
|
||||
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
|
||||
case 'close':
|
||||
if (currentPath) {
|
||||
|
|
|
|||
|
|
@ -241,6 +241,14 @@ export const useTabsStore = defineStore('tabs', () => {
|
|||
saveTabs()
|
||||
}
|
||||
|
||||
// 刷新指定 tab 的 key(用于触发组件刷新)
|
||||
const refreshKey = ref<string>('')
|
||||
|
||||
// 刷新指定路径的 tab
|
||||
const refreshTab = (path: string) => {
|
||||
refreshKey.value = path + '-' + Date.now()
|
||||
}
|
||||
|
||||
// 保存到本地存储
|
||||
const saveTabs = () => {
|
||||
setStorage('tabs', tabs.value)
|
||||
|
|
@ -283,6 +291,8 @@ export const useTabsStore = defineStore('tabs', () => {
|
|||
closeRightTabs,
|
||||
setActiveTab,
|
||||
clearTabs,
|
||||
setTabs
|
||||
setTabs,
|
||||
refreshKey,
|
||||
refreshTab
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
|
||||
import dayjs from 'dayjs'
|
||||
|
||||
/**
|
||||
* 获取近七天的开始和结束时间
|
||||
* @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
|
||||
*/
|
||||
export function utcToUtc8(utcStr: string): string {
|
||||
// 将字符串解析为 UTC 时间
|
||||
const utcDate = new Date(utcStr.replace(' ', 'T') + 'Z')
|
||||
// // 将字符串解析为 UTC 时间
|
||||
// const utcDate = new Date(utcStr.replace(' ', 'T') + 'Z')
|
||||
|
||||
// 转换为 UTC+8(东八区)
|
||||
const utc8Date = new Date(utcDate.getTime() + 8 * 60 * 60 * 1000)
|
||||
// // 转换为 UTC+8(东八区)
|
||||
// const utc8Date = new Date(utcDate.getTime() + 8 * 60 * 60 * 1000)
|
||||
|
||||
// 格式化为 YYYY-MM-DD HH:mm:ss
|
||||
const pad = (n) => String(n).padStart(2, '0')
|
||||
// // 格式化为 YYYY-MM-DD HH:mm:ss
|
||||
// const pad = (n) => String(n).padStart(2, '0')
|
||||
|
||||
const year = utc8Date.getUTCFullYear()
|
||||
const month = pad(utc8Date.getUTCMonth() + 1)
|
||||
const day = pad(utc8Date.getUTCDate())
|
||||
const hour = pad(utc8Date.getUTCHours())
|
||||
const minute = pad(utc8Date.getUTCMinutes())
|
||||
const second = pad(utc8Date.getUTCSeconds())
|
||||
// const year = utc8Date.getUTCFullYear()
|
||||
// const month = pad(utc8Date.getUTCMonth() + 1)
|
||||
// const day = pad(utc8Date.getUTCDate())
|
||||
// const hour = pad(utc8Date.getUTCHours())
|
||||
// const minute = pad(utc8Date.getUTCMinutes())
|
||||
// const second = pad(utc8Date.getUTCSeconds())
|
||||
|
||||
return `${year}-${month}-${day} ${hour}:${minute}:${second}`
|
||||
return dayjs(utcStr).format('YYYY-MM-DD HH:mm:ss')
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,8 @@
|
|||
<template>
|
||||
<div class="table_form-container">
|
||||
<!-- 搜索 -->
|
||||
<FundDetailSearch
|
||||
:search-form="searchForm"
|
||||
:search-options="searchOptions"
|
||||
@search="handleSearch"
|
||||
@reset="handleReset"
|
||||
>
|
||||
<FundDetailSearch :search-form="searchForm" :search-options="searchOptions" @search="handleSearch"
|
||||
@reset="handleReset">
|
||||
<template #button="{ form }">
|
||||
<el-button type="primary" @click="handleExport()"> 导出 </el-button>
|
||||
</template>
|
||||
|
|
@ -14,12 +10,8 @@
|
|||
<!-- 表格 -->
|
||||
<FundDetailTable :table-data="tableTree" :columns="tableColumnsOptions" row-key="id" :loading="loading" />
|
||||
<!-- 分页 -->
|
||||
<FundDetailPagination
|
||||
v-model="currentPage"
|
||||
v-model:pageSizeValue="pageSize"
|
||||
:total="total"
|
||||
@pagination-change="handlePaginationChange"
|
||||
/>
|
||||
<FundDetailPagination v-model="currentPage" v-model:pageSizeValue="pageSize" :total="total"
|
||||
@pagination-change="handlePaginationChange" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
@ -71,41 +63,44 @@ const total = ref(0)
|
|||
//获取资金明细列表
|
||||
const getFundDetailList = async () => {
|
||||
startLoading()
|
||||
const params = {
|
||||
page: currentPage.value,
|
||||
page_size: pageSize.value,
|
||||
start_time:
|
||||
searchForm.value.startTime.length > 0
|
||||
? `${searchForm.value.startTime} 0:00:00`
|
||||
: '2026-01-01 0:00:00',
|
||||
end_time:
|
||||
searchForm.value.endTime.length > 0
|
||||
? `${searchForm.value.endTime} 23:59:59`
|
||||
: '2026-03-15 23:59:59',
|
||||
user_name: searchForm.value.username,
|
||||
account_id: searchForm.value.subAccountId,
|
||||
}
|
||||
// 调用接口获取数据
|
||||
const data: any = await getFundDetailListApi(params)
|
||||
stopLoading()
|
||||
console.log(data)
|
||||
tableTree.value = data.data.map((item: any) => ({
|
||||
try {
|
||||
const params = {
|
||||
page: currentPage.value,
|
||||
page_size: pageSize.value,
|
||||
start_time:
|
||||
searchForm.value.startTime.length > 0
|
||||
? `${searchForm.value.startTime} 0:00:00`
|
||||
: '2026-01-01 0:00:00',
|
||||
end_time:
|
||||
searchForm.value.endTime.length > 0
|
||||
? `${searchForm.value.endTime} 23:59:59`
|
||||
: '2026-03-15 23:59:59',
|
||||
user_name: searchForm.value.username,
|
||||
account_id: searchForm.value.subAccountId,
|
||||
}
|
||||
// 调用接口获取数据
|
||||
const data: any = await getFundDetailListApi(params)
|
||||
console.log(data)
|
||||
tableTree.value = data.data.map((item: any) => ({
|
||||
...item,
|
||||
// 用户名
|
||||
username: item.user.username,
|
||||
//单号
|
||||
orderNo: item.trade_id,
|
||||
//操作类型
|
||||
type: item.enum_dic.value,
|
||||
//创建时间
|
||||
createTime: utcToUtc8(item.created_at),
|
||||
//钱包类型
|
||||
walletType: item.wallet_type === '1' ? '主钱包' : '子钱包',
|
||||
}))
|
||||
//分页数据
|
||||
total.value = data.total
|
||||
currentPage.value = data.current_page
|
||||
pageSize.value = Number(data.per_page)
|
||||
// 用户名
|
||||
username: item.user.username,
|
||||
//单号
|
||||
orderNo: item.trade_id,
|
||||
//操作类型
|
||||
type: item.enum_dic.value,
|
||||
//创建时间
|
||||
createTime: utcToUtc8(item.created_at),
|
||||
//钱包类型
|
||||
walletType: item.wallet_type === '1' ? '主钱包' : '子钱包',
|
||||
}))
|
||||
//分页数据
|
||||
total.value = data.total
|
||||
currentPage.value = data.current_page
|
||||
pageSize.value = Number(data.per_page)
|
||||
} finally {
|
||||
stopLoading()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<div class="table_form-container">
|
||||
<!-- 搜索 -->
|
||||
<CustomerTradeOrderSearch :search-form="searchForm" :search-options="searchOptions" @search="handleSearch"
|
||||
@reset="handleReset" @blur-input="getSubAccountList">
|
||||
@reset="handleReset" @blur-input="getSubAccountList">
|
||||
</CustomerTradeOrderSearch>
|
||||
<div class="bar" v-if="searchForm.orderId === '1'">
|
||||
<div>持仓量:0</div>
|
||||
|
|
@ -10,7 +10,8 @@
|
|||
<div>交易盈亏:0.00 USD</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"
|
||||
|
|
@ -22,7 +23,7 @@
|
|||
<script setup lang="ts">
|
||||
|
||||
defineOptions({
|
||||
name: 'History'
|
||||
name: 'History'
|
||||
})
|
||||
// 组件
|
||||
import CustomerTradeOrderSearch from '@/components/common/Search.vue'
|
||||
|
|
@ -82,39 +83,43 @@ const total = ref(0)
|
|||
* @description: 定义公共请求数据方法
|
||||
*/
|
||||
const getCustomerTradeOrderList = async () => {
|
||||
startLoading()
|
||||
const params = {
|
||||
page: currentPage.value,
|
||||
page_size: pageSize.value,
|
||||
user_name: searchForm.value.accountName,
|
||||
account_id: searchForm.value.subAccountName,
|
||||
order_no: '',
|
||||
type: searchForm.value.tradeType,
|
||||
start_time: dateRange.start,
|
||||
end_time: dateRange.end,
|
||||
}
|
||||
console.log(params)
|
||||
const data: any = await getCustomTradeOrderListApi(params)
|
||||
stopLoading()
|
||||
//表格数据
|
||||
// table数据映射
|
||||
tableTree.value = data.data.map((item: any) => ({
|
||||
accountName: item.user.username,
|
||||
orderId: item.order_id,
|
||||
variety: item.variety.name,
|
||||
type: item.type === 1 ? '买入' : '卖出',
|
||||
quantity: item.num,
|
||||
openPrice: item.build_price,
|
||||
closePrice: item.close_price,
|
||||
closeProfitLoss: item.profit_loss,
|
||||
amount: item.amount,
|
||||
createdTime: item.created_at,
|
||||
}))
|
||||
try {
|
||||
startLoading()
|
||||
const params = {
|
||||
page: currentPage.value,
|
||||
page_size: pageSize.value,
|
||||
user_name: searchForm.value.accountName,
|
||||
account_id: searchForm.value.subAccountName,
|
||||
order_no: '',
|
||||
type: searchForm.value.tradeType,
|
||||
start_time: dateRange.start,
|
||||
end_time: dateRange.end,
|
||||
}
|
||||
console.log(params)
|
||||
const data: any = await getCustomTradeOrderListApi(params)
|
||||
//表格数据
|
||||
// table数据映射
|
||||
tableTree.value = data.data.map((item: any) => ({
|
||||
accountName: item.user.username,
|
||||
orderId: item.order_id,
|
||||
variety: item.variety.name,
|
||||
type: item.type === 1 ? '买入' : '卖出',
|
||||
quantity: item.num,
|
||||
openPrice: item.build_price,
|
||||
closePrice: item.close_price,
|
||||
closeProfitLoss: item.profit_loss,
|
||||
amount: item.amount,
|
||||
createdTime: item.created_at,
|
||||
}))
|
||||
|
||||
//分页数据
|
||||
total.value = data.total
|
||||
currentPage.value = data.current_page
|
||||
pageSize.value = Number(data.per_page)
|
||||
//分页数据
|
||||
total.value = data.total
|
||||
currentPage.value = data.current_page
|
||||
pageSize.value = Number(data.per_page)
|
||||
} finally {
|
||||
|
||||
stopLoading()
|
||||
}
|
||||
}
|
||||
|
||||
const getSubAccountList = async () => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue