feat(history): complete messaging core before multi-account gateways

This commit is contained in:
wmq
2026-07-28 22:36:58 +08:00
parent cd06d049fe
commit 7f09132fad
54 changed files with 4781 additions and 601 deletions
+31 -11
View File
@@ -26,33 +26,49 @@ export function Sidebar() {
const usagePct = msgUsage ? Math.round((msgUsage.used / msgUsage.total) * 100) : 0
const items = NAV_ITEMS.filter((item) => !item.permission || can(item.permission))
const groups = [
{ key: 'core', label: '核心业务' },
{ key: 'intelligence', label: '知识与洞察' },
{ key: 'admin', label: '企业管理' },
] as const
return (
<aside
className={cn(
'flex h-full flex-col border-e border-border bg-card transition-[width] duration-200',
sidebarCollapsed ? 'w-16' : 'w-60',
'relative z-30 flex h-full flex-col border-e border-slate-300/80 bg-[#f8fafc] shadow-[4px_0_16px_-14px_rgba(15,23,42,.32)] transition-[width] duration-200',
sidebarCollapsed ? 'w-[68px]' : 'w-[228px]',
)}
>
{/* Logo */}
<div
className="flex h-14 cursor-pointer items-center gap-2.5 border-b border-border px-4"
className="flex h-16 cursor-pointer items-center gap-2.5 px-4"
onClick={() => navigate('/dashboard')}
>
<span className="flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-primary text-primary-foreground">
<span className="flex h-9 w-9 shrink-0 items-center justify-center rounded-xl bg-gradient-to-br from-primary-600 to-primary-800 text-primary-foreground shadow-sm shadow-primary-900/10">
<Sparkles className="h-4.5 w-4.5 h-[18px] w-[18px]" />
</span>
{!sidebarCollapsed && (
<div className="min-w-0">
<p className="truncate text-sm font-semibold leading-tight">{t('app.name')}</p>
<p className="truncate text-[15px] font-semibold tracking-tight leading-tight">{t('app.name')}</p>
<p className="truncate text-[11px] text-muted-foreground leading-tight">{t('app.slogan')}</p>
</div>
)}
</div>
{/* 导航 */}
<nav className="flex-1 space-y-0.5 overflow-y-auto px-2 py-3 scrollbar-thin">
{items.map((item) => (
<nav className="flex-1 overflow-y-auto px-2.5 py-2 scrollbar-thin">
{groups.map((group) => {
const groupItems = items.filter((item) => item.group === group.key)
if (!groupItems.length) return null
return (
<div key={group.key} className="mb-3">
{!sidebarCollapsed && (
<p className="mb-1.5 px-3 pt-2 text-[10px] font-semibold uppercase tracking-[0.14em] text-slate-400">
{group.label}
</p>
)}
<div className="space-y-1">
{groupItems.map((item) => (
<NavLink
key={item.key}
to={item.path}
@@ -60,10 +76,10 @@ export function Sidebar() {
title={sidebarCollapsed ? t(item.labelKey as never) : undefined}
className={({ isActive }) =>
cn(
'flex items-center gap-2.5 rounded-md px-2.5 py-2 text-sm transition-colors',
'flex items-center gap-3 rounded-xl px-3 py-2.5 text-[13px] transition-all duration-150',
isActive
? 'bg-primary-50 font-medium text-primary-700'
: 'text-secondary-foreground hover:bg-muted',
? 'bg-primary-50/90 font-semibold text-primary-800 shadow-[inset_0_0_0_1px_rgba(37,99,235,.08)]'
: 'text-slate-600 hover:bg-slate-50 hover:text-slate-900',
sidebarCollapsed && 'justify-center px-0',
)
}
@@ -71,7 +87,11 @@ export function Sidebar() {
<item.icon className="h-[18px] w-[18px] shrink-0" />
{!sidebarCollapsed && <span className="truncate">{t(item.labelKey as never)}</span>}
</NavLink>
))}
))}
</div>
</div>
)
})}
</nav>
{/* 底部:套餐与企业信息 */}