feat: 新增页面

This commit is contained in:
duanshuwen
2025-12-07 14:54:52 +08:00
parent da7024747a
commit 14d916187c
15 changed files with 201 additions and 101 deletions

View File

@@ -2,21 +2,39 @@
<div class="h-screen w-screen bg-gray-100">
<div class="flex items-center gap-1 px-3 h-10 border-b bg-white" style="-webkit-app-region: drag">
<div class="flex items-center gap-2 mr-2">
<button class="w-3 h-3 rounded-full bg-red-500" style="-webkit-app-region: no-drag" @click="onCloseWindow"></button>
<button class="w-3 h-3 rounded-full bg-yellow-400" style="-webkit-app-region: no-drag" @click="onMinimizeWindow"></button>
<button class="w-3 h-3 rounded-full bg-green-500" style="-webkit-app-region: no-drag" @click="onMaximizeWindow"></button>
<button class="w-3 h-3 rounded-full bg-red-500" style="-webkit-app-region: no-drag" @click="onCloseWindow">
<RiCloseLine />
</button>
<button class="w-3 h-3 rounded-full bg-yellow-400" style="-webkit-app-region: no-drag"
@click="onMinimizeWindow">
<RiSubtractLine />
</button>
<button class="w-3 h-3 rounded-full bg-green-500" style="-webkit-app-region: no-drag" @click="onMaximizeWindow">
<RiSquareLine />
</button>
</div>
<div v-for="t in tabs" :key="t.id" class="flex items-center px-2 py-1 rounded cursor-pointer" :class="t.id===activeId?'bg-blue-100':'hover:bg-gray-200'" @click="onSwitch(t.id)" style="-webkit-app-region: no-drag">
<div v-for="t in tabs" :key="t.id" class="flex items-center px-2 py-1 rounded cursor-pointer"
:class="t.id === activeId ? 'bg-blue-100' : 'hover:bg-gray-200'" @click="onSwitch(t.id)"
style="-webkit-app-region: no-drag">
<span class="text-sm mr-2 truncate max-w-[160px]">{{ t.title || t.url || '新标签页' }}</span>
<button class="text-gray-600 hover:text-black" style="-webkit-app-region: no-drag" @click.stop="onCloseTabId(t.id)"></button>
<button class="text-gray-600 hover:text-black" style="-webkit-app-region: no-drag"
@click.stop="onCloseTabId(t.id)"></button>
</div>
<button class="ml-2 px-2 py-1 rounded bg-gray-200 hover:bg-gray-300" style="-webkit-app-region: no-drag" @click="onNewTab"></button>
<button class="ml-2 px-2 py-1 rounded bg-gray-200 hover:bg-gray-300" style="-webkit-app-region: no-drag"
@click="onNewTab"></button>
</div>
<div class="flex items-center gap-2 px-3 h-12 border-b bg-gray-50">
<button class="px-2 py-1 bg-gray-200 rounded" @click="onBack" :disabled="!active?.canGoBack"></button>
<button class="px-2 py-1 bg-gray-200 rounded" @click="onForward" :disabled="!active?.canGoForward"></button>
<button class="px-2 py-1 bg-gray-200 rounded" @click="onReload"></button>
<input class="flex-1 px-3 py-1 border rounded-full" v-model="address" @keyup.enter="onNavigate" placeholder="输入地址后回车" />
<button class="px-2 py-1 bg-gray-200 rounded" @click="onBack" :disabled="!active?.canGoBack">
<RiArrowLeftSLine />
</button>
<button class="px-2 py-1 bg-gray-200 rounded" @click="onForward" :disabled="!active?.canGoForward">
<RiArrowRightSLine />
</button>
<button class="px-2 py-1 bg-gray-200 rounded" @click="onReload">
<RiResetLeftLine />
</button>
<input class="flex-1 px-3 py-1 border rounded-full" v-model="address" @keyup.enter="onNavigate"
placeholder="输入地址后回车" />
</div>
<div class="h-[calc(100vh-5.5rem)]"></div>
</div>
@@ -24,6 +42,7 @@
<script setup lang="ts">
import { reactive, ref, onMounted, computed } from 'vue'
import { RiArrowRightSLine, RiArrowLeftSLine, RiResetLeftLine, RiCloseLine, RiSubtractLine, RiSquareLine } from '@remixicon/vue'
type TabInfo = { id: string; url: string; title: string; isLoading: boolean; canGoBack: boolean; canGoForward: boolean }
@@ -99,32 +118,31 @@ const onMaximizeWindow = () => (window as any).ipcAPI.window.maximize()
onMounted(async () => {
await syncList()
;(window as any).ipcAPI.tabs.on('tab-created', (info: TabInfo) => {
const i = tabs.findIndex(t => t.id === info.id)
if (i === -1) tabs.push(info)
activeId.value = info.id
refreshActiveAddress()
})
;(window as any).ipcAPI.tabs.on('tab-updated', (info: TabInfo) => {
const i = tabs.findIndex(t => t.id === info.id)
if (i >= 0) tabs[i] = info
if (activeId.value === info.id) refreshActiveAddress()
})
;(window as any).ipcAPI.tabs.on('tab-closed', ({ tabId }: { tabId: string }) => {
const i = tabs.findIndex(t => t.id === tabId)
if (i >= 0) tabs.splice(i, 1)
if (activeId.value === tabId) {
const next = tabs[0]
activeId.value = next?.id || ''
; (window as any).ipcAPI.tabs.on('tab-created', (info: TabInfo) => {
const i = tabs.findIndex(t => t.id === info.id)
if (i === -1) tabs.push(info)
activeId.value = info.id
refreshActiveAddress()
}
})
;(window as any).ipcAPI.tabs.on('tab-switched', ({ tabId }: { tabId: string }) => {
activeId.value = tabId
refreshActiveAddress()
})
})
; (window as any).ipcAPI.tabs.on('tab-updated', (info: TabInfo) => {
const i = tabs.findIndex(t => t.id === info.id)
if (i >= 0) tabs[i] = info
if (activeId.value === info.id) refreshActiveAddress()
})
; (window as any).ipcAPI.tabs.on('tab-closed', ({ tabId }: { tabId: string }) => {
const i = tabs.findIndex(t => t.id === tabId)
if (i >= 0) tabs.splice(i, 1)
if (activeId.value === tabId) {
const next = tabs[0]
activeId.value = next?.id || ''
refreshActiveAddress()
}
})
; (window as any).ipcAPI.tabs.on('tab-switched', ({ tabId }: { tabId: string }) => {
activeId.value = tabId
refreshActiveAddress()
})
})
</script>
<style scoped>
</style>
<style scoped></style>

View File

@@ -1,12 +1,15 @@
<template>
<div class="w-[80px] h-full box-border pt-[12px] pb-[12px] flex flex-col items-center justify-center">
<div :class="['flex flex-col gap-[16px]', {'mt-auto mb-[8px] shrink-1': item.id === 7}]" v-for="(item) in menus" :key="item.id">
<div :class="['flex flex-col gap-[16px]', { 'mt-auto mb-[8px] shrink-1': item.id === 7 }]"
v-for="(item) in menus" :key="item.id">
<div :class="['cursor-pointer flex flex-col items-center justify-center']" @click="handleClick(item)">
<div :class="['box-border rounded-[16px] p-[8px]', {'bg-white': item.id === currentId}]">
<component :is="item.icon" :color="item.id === currentId ? item.activeColor : item.color" :class="['w-[32px] h-[32px]']" />
<div :class="['box-border rounded-[16px] p-[8px]', { 'bg-white': item.id === currentId }]">
<component :is="item.icon" :color="item.id === currentId ? item.activeColor : item.color"
:class="['w-[32px] h-[32px]']" />
</div>
<div :class="['text-[14px] mt-[4px] mb-[8px]', item.id === currentId ? `text-[${item.activeColor}]` : item.color]">
<div
:class="['text-[14px] mt-[4px] mb-[8px]', item.id === currentId ? `text-[${item.activeColor}]` : item.color]">
{{ item.name }}
</div>
</div>
@@ -21,9 +24,10 @@
import { ref } from 'vue'
import { menus } from '@constant/menus'
const currentId = ref(null)
const handleClick = (item: any) => {
const currentId = ref(1)
const handleClick = async (item: any) => {
currentId.value = item.id
await (window as any).ipcAPI.tabs.create(item.url)
}
</script>

View File

@@ -7,6 +7,7 @@ export interface MenuItem {
icon: any
color: string
activeColor: string
url: string
}
export const menus: MenuItem[] = [
@@ -16,6 +17,7 @@ export const menus: MenuItem[] = [
icon: RiHomeLine,
color: '#525866',
activeColor: '#2B7FFF',
url: '/home',
},
{
id: 2,
@@ -23,6 +25,7 @@ export const menus: MenuItem[] = [
icon: RiFileListLine,
color: '#525866',
activeColor: '#2B7FFF',
url: '/order',
},
{
id: 3,
@@ -30,6 +33,7 @@ export const menus: MenuItem[] = [
icon: RiHotelLine,
color: '#525866',
activeColor: '#2B7FFF',
url: '/stock',
},
{
id: 4,
@@ -37,6 +41,7 @@ export const menus: MenuItem[] = [
icon: RiChatQuoteLine,
color: '#525866',
activeColor: '#2B7FFF',
url: '/rate',
},
{
id: 5,
@@ -44,6 +49,7 @@ export const menus: MenuItem[] = [
icon: RiBarChartBoxAiLine,
color: '#525866',
activeColor: '#2B7FFF',
url: '/dashboard',
},
{
id: 6,
@@ -51,6 +57,7 @@ export const menus: MenuItem[] = [
icon: RiMoreLine,
color: '#525866',
activeColor: '#2B7FFF',
url: '/more',
},
{
id: 7,
@@ -58,5 +65,6 @@ export const menus: MenuItem[] = [
icon: RiSettingsLine,
color: '#525866',
activeColor: '#2B7FFF',
url: '/settings',
},
]

View File

@@ -1,13 +1,14 @@
<template>
<div class="bg box-border w-full h-screen flex pt-[8px] pb-[8px] pl-[8px] gap-[8px]">
<div class="flex-1 h-full">
<slot></slot>
<div class="bg box-border w-full h-screen flex pt-[8px] pb-[8px] pl-[8px] ">
<div class="flex-1 flex gap-[8px]">
<div class="flex-1 h-full">
<slot></slot>
</div>
<TaskList>
<slot name="task"></slot>
</TaskList>
</div>
<TaskList>
<slot name="task"></slot>
</TaskList>
<Menus />
</div>
</template>

View File

@@ -9,7 +9,7 @@ const routes = [
{
path: "/browser",
name: "Browser",
component: () => import("@/views/browser/BrowserLayout.vue"),
component: () => import("@/browser/BrowserLayout.vue"),
meta: { requiresAuth: true },
},
{
@@ -43,8 +43,8 @@ router.beforeEach((to: any, from: any, next: any) => {
return;
}
if (token && to.path !== "/rate") {
next({ path: "/rate" });
if (token && to.path !== "/home") {
next({ path: "/home" });
return;
}

View File

@@ -0,0 +1,18 @@
<template>
<Layout>
<template #task>
<Task />
</template>
</Layout>
</template>
<script setup lang="ts">
import Task from '../components/Task/index.vue'
const openBaidu = () => {
(window as any).ipcAPI?.openBaidu()
// 发送日志
(window as any).ipcAPI?.logToMain('info', '打开百度')
}
</script>

View File

@@ -0,0 +1,18 @@
<template>
<Layout>
<template #task>
<Task />
</template>
</Layout>
</template>
<script setup lang="ts">
import Task from '../components/Task/index.vue'
const openBaidu = () => {
(window as any).ipcAPI?.openBaidu()
// 发送日志
(window as any).ipcAPI?.logToMain('info', '打开百度')
}
</script>

View File

@@ -0,0 +1,18 @@
<template>
<Layout>
<template #task>
<Task />
</template>
</Layout>
</template>
<script setup lang="ts">
import Task from '../components/Task/index.vue'
const openBaidu = () => {
(window as any).ipcAPI?.openBaidu()
// 发送日志
(window as any).ipcAPI?.logToMain('info', '打开百度')
}
</script>

View File

@@ -0,0 +1,18 @@
<template>
<Layout>
<template #task>
<Task />
</template>
</Layout>
</template>
<script setup lang="ts">
import Task from '../components/Task/index.vue'
const openBaidu = () => {
(window as any).ipcAPI?.openBaidu()
// 发送日志
(window as any).ipcAPI?.logToMain('info', '打开百度')
}
</script>

View File

@@ -0,0 +1,18 @@
<template>
<Layout>
<template #task>
<Task />
</template>
</Layout>
</template>
<script setup lang="ts">
import Task from '../components/Task/index.vue'
const openBaidu = () => {
(window as any).ipcAPI?.openBaidu()
// 发送日志
(window as any).ipcAPI?.logToMain('info', '打开百度')
}
</script>