feat: 项目多标签方案调整
This commit is contained in:
@@ -21,107 +21,16 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, onUnmounted } from 'vue'
|
||||
import { ref } from 'vue'
|
||||
import { menus, type MenuItem } from '@constant/menus'
|
||||
|
||||
const currentId = ref(1)
|
||||
const tabMap = new Map<number, string>()
|
||||
const cleanupListeners: (() => void)[] = []
|
||||
|
||||
const getHtmlPath = (menuUrl: string) => {
|
||||
const cleanUrl = menuUrl.startsWith('/') ? menuUrl.slice(1) : menuUrl
|
||||
let filename = ''
|
||||
switch (cleanUrl) {
|
||||
case 'home':
|
||||
filename = 'home.html'
|
||||
break
|
||||
case 'knowledge':
|
||||
filename = 'knowledge.html'
|
||||
break
|
||||
case 'task':
|
||||
filename = 'task.html'
|
||||
break
|
||||
case 'setting':
|
||||
filename = 'setting.html'
|
||||
break
|
||||
default:
|
||||
filename = 'home.html'
|
||||
}
|
||||
|
||||
if (import.meta.env.DEV) {
|
||||
return `/html/${filename}`
|
||||
}
|
||||
return filename
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
if (window.api && window.api.tabs) {
|
||||
const cleanupClosed = window.api.tabs.on('tab-closed', (payload: any) => {
|
||||
const { tabId } = payload
|
||||
for (const [menuId, id] of tabMap.entries()) {
|
||||
if (id === tabId) {
|
||||
tabMap.delete(menuId)
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
if (cleanupClosed) cleanupListeners.push(cleanupClosed)
|
||||
|
||||
const cleanupCreated = window.api.tabs.on('tab-created', (tab: any) => {
|
||||
for (const menu of menus) {
|
||||
const targetHtml = getHtmlPath(menu.url)
|
||||
if (tab.url.includes(targetHtml)) {
|
||||
tabMap.set(menu.id, tab.id)
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
if (cleanupCreated) cleanupListeners.push(cleanupCreated)
|
||||
|
||||
try {
|
||||
const tabs = await window.api.tabs.list()
|
||||
if (tabs && tabs.length > 0) {
|
||||
for (const tab of tabs) {
|
||||
for (const menu of menus) {
|
||||
const targetHtml = getHtmlPath(menu.url)
|
||||
if (tab.url.includes(targetHtml)) {
|
||||
tabMap.set(menu.id, tab.id)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Failed to sync tabs', e)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
cleanupListeners.forEach(fn => fn())
|
||||
})
|
||||
const router = useRouter()
|
||||
|
||||
const handleClick = async (item: MenuItem) => {
|
||||
console.log("🚀 ~ handleClick ~ item:", item)
|
||||
currentId.value = item.id
|
||||
|
||||
const existingTabId = tabMap.get(item.id)
|
||||
if (existingTabId) {
|
||||
await window.api.tabs.switch(existingTabId)
|
||||
} else {
|
||||
const htmlFile = getHtmlPath(item.url)
|
||||
const targetUrl = new URL(htmlFile, window.location.href).href
|
||||
|
||||
try {
|
||||
const tabInfo = await window.api.tabs.create(targetUrl)
|
||||
if (tabInfo && tabInfo.id) {
|
||||
tabMap.set(item.id, tabInfo.id)
|
||||
await window.api.tabs.switch(tabInfo.id)
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Failed to create tab', e)
|
||||
}
|
||||
}
|
||||
router.push(item.url)
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import locale from 'element-plus/es/locale/lang/zh-cn'
|
||||
|
||||
// 引入 i18n 插件
|
||||
import i18n from './i18n'
|
||||
// import './permission'
|
||||
import './permission'
|
||||
|
||||
// 样式文件隔离
|
||||
import "./styles/index.css";
|
||||
|
||||
@@ -5,12 +5,36 @@ const routes = [
|
||||
path: '/',
|
||||
redirect: '/home'
|
||||
},
|
||||
{
|
||||
path: "/login",
|
||||
component: () => import("@renderer/views/login/index.vue"),
|
||||
name: "Login",
|
||||
meta: { requiresAuth: true },
|
||||
},
|
||||
{
|
||||
path: "/home",
|
||||
component: () => import("@renderer/views/home/index.vue"),
|
||||
name: "Home",
|
||||
meta: { requiresAuth: true },
|
||||
},
|
||||
{
|
||||
path: "/task",
|
||||
component: () => import("@renderer/views/task/index.vue"),
|
||||
name: "Task",
|
||||
meta: { requiresAuth: true },
|
||||
},
|
||||
{
|
||||
path: "/knowledge",
|
||||
component: () => import("@renderer/views/knowledge/index.vue"),
|
||||
name: "Knowledge",
|
||||
meta: { requiresAuth: true },
|
||||
},
|
||||
{
|
||||
path: "/setting",
|
||||
component: () => import("@renderer/views/setting/index.vue"),
|
||||
name: "Setting",
|
||||
meta: { requiresAuth: true },
|
||||
},
|
||||
];
|
||||
|
||||
const router = createRouter({
|
||||
|
||||
@@ -127,6 +127,7 @@ const getVerifyCode = async () => {
|
||||
|
||||
onMounted(() => getVerifyCode())
|
||||
|
||||
const router = useRouter()
|
||||
const formRef = ref()
|
||||
const onSubmit = async () => {
|
||||
const valid = await formRef.value.validate().catch(() => { }); // 表单校验
|
||||
@@ -136,7 +137,7 @@ const onSubmit = async () => {
|
||||
|
||||
try {
|
||||
userStore.login(form).then(() => {
|
||||
window.api.app.loadPage('index');
|
||||
router.push({ path: '/home' })
|
||||
})
|
||||
} finally {
|
||||
getVerifyCode()
|
||||
|
||||
Reference in New Issue
Block a user