first commit

This commit is contained in:
wintsa committed 2026-02-22 23:42:49 +08:00
commit d120622de1
36 files changed
+1177

No files matched your search

+62
View File
@@ -0,0 +1,62 @@
<script setup lang="ts">
import { useTabStore } from '@/pinia/tab'
import { defineAsyncComponent, markRaw } from 'vue'
import { Button } from '@/components/ui/button'
import { ScrollArea ,ScrollBar} from '@/components/ui/scroll-area'
import { X } from 'lucide-vue-next'
// 组件映射表:所有的动态组件需要在这里注册
const componentMap: Record<string, any> = {
XmView: markRaw(defineAsyncComponent(() => import('@/components/views/Xm.vue'))),
}
const tabStore = useTabStore()
// useTabStore
</script>
<template>
<div class="flex flex-col w-full h-screen bg-background overflow-hidden">
<div class="flex items-center border-b bg-muted/30 px-2 pt-2 flex-none">
<ScrollArea class="flex-1 whitespace-nowrap">
<div class="flex gap-1">
<div
v-for="(tab, index) in tabStore.tabs"
:key="tab.id"
@click="tabStore.activeTabId = tab.id"
:class="[
'group relative flex items-center h-9 px-4 min-w-[120px] max-w-[200px] cursor-pointer rounded-t-md border-x border-t transition-all text-sm',
tabStore.activeTabId === tab.id
? 'bg-background border-border font-medium'
: 'border-transparent hover:bg-muted text-muted-foreground'
]"
>
<span class="truncate mr-2">{{ tab.title }}</span>
<Button
v-if="index !== 0"
variant="ghost"
size="icon"
class="h-4 w-4 ml-auto opacity-0 group-hover:opacity-100 hover:bg-destructive hover:text-destructive-foreground transition-opacity"
@click="tabStore.removeTab(tab.id)"
>
<X class="h-3 w-3" />
</Button>
</div>
</div>
<ScrollBar orientation="horizontal" class="invisible" />
</ScrollArea>
</div>
<div class="flex-1 overflow-auto relative">
<div
v-for="tab in tabStore.tabs"
:key="tab.id"
v-show="tabStore.activeTabId === tab.id"
class="h-full w-full p-6 animate-in fade-in duration-300"
>
<component :is="componentMap[tab.componentName]" />
</div>
</div>
</div>
</template>
+50
View File
@@ -0,0 +1,50 @@
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import xmView from '@/components/views/xmInfo.vue'
// 使用 sessionStorage 管理左侧分类切换状态
const activeCategory = ref(sessionStorage.getItem('project-active-cat') || 'info')
const switchCategory = (cat: string) => {
activeCategory.value = cat
sessionStorage.setItem('project-active-cat', cat)
}
</script>
<template>
<div class="flex h-full w-full bg-background">
<div class="w-1/5 border-r p-6 flex flex-col gap-8 relative">
<div class="font-bold text-lg mb-4 text-primary">项目配置</div>
<div class="flex flex-col gap-10 relative">
<div class="absolute left-[11px] top-2 bottom-2 w-[2px] bg-muted"></div>
<div class="relative flex items-center gap-4 cursor-pointer group" @click="switchCategory('info')">
<div :class="['z-10 w-6 h-6 rounded-full border-2 flex items-center justify-center transition-all',
activeCategory === 'info' ? 'bg-primary border-primary scale-110' : 'bg-background border-muted-foreground']">
<div v-if="activeCategory === 'info'" class="w-2 h-2 bg-background rounded-full"></div>
</div>
<span :class="['text-sm transition-colors', activeCategory === 'info' ? 'font-bold text-primary' : 'text-muted-foreground group-hover:text-foreground']">
分类信息
</span>
</div>
<div class="relative flex items-center gap-4 cursor-pointer group" @click="switchCategory('contract')">
<div :class="['z-10 w-6 h-6 rounded-full border-2 flex items-center justify-center transition-all',
activeCategory === 'contract' ? 'bg-primary border-primary scale-110' : 'bg-background border-muted-foreground']">
<div v-if="activeCategory === 'contract'" class="w-2 h-2 bg-background rounded-full"></div>
</div>
<span :class="['text-sm transition-colors', activeCategory === 'contract' ? 'font-bold text-primary' : 'text-muted-foreground group-hover:text-foreground']">
合同段管理
</span>
</div>
</div>
</div>
<div class="w-4/5 p-8 overflow-auto">
<keep-alive>
<component :is="activeCategory === 'info' ? xmView : xmView" />
</keep-alive>
</div>
</div>
</template>