Compare commits
2 Commits
5617502713
...
9df17211a5
| Author | SHA1 | Date | |
|---|---|---|---|
| 9df17211a5 | |||
| 80310f710c |
@@ -1,8 +1,13 @@
|
|||||||
# 数据库连接字符串
|
# 数据库连接字符串
|
||||||
DATABASE_URL=
|
DATABASE_HOST=localhost
|
||||||
|
DATABASE_PORT=23306
|
||||||
|
DATABASE_USERNAME=root
|
||||||
|
DATABASE_PASSWORD=root
|
||||||
|
DATABASE_NAME=app
|
||||||
|
|
||||||
# Redis 连接字符串
|
# Redis 连接字符串
|
||||||
REDIS_URL=
|
REDIS_HOST=localhost
|
||||||
|
REDIS_PORT=26379
|
||||||
|
|
||||||
# 京东网关配置
|
# 京东网关配置
|
||||||
JD_BASE=https://smart.jdbox.xyz:58001
|
JD_BASE=https://smart.jdbox.xyz:58001
|
||||||
|
|||||||
@@ -8,13 +8,13 @@ services:
|
|||||||
MYSQL_ROOT_PASSWORD: root
|
MYSQL_ROOT_PASSWORD: root
|
||||||
MYSQL_DATABASE: app
|
MYSQL_DATABASE: app
|
||||||
ports:
|
ports:
|
||||||
- "23306:3306"
|
- "${DATABASE_PORT}:3306"
|
||||||
volumes:
|
volumes:
|
||||||
- .volumes/mysql:/var/lib/mysql
|
- .volumes/mysql:/var/lib/mysql
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
image: redis:7
|
image: redis:7
|
||||||
ports:
|
ports:
|
||||||
- "26379:6379"
|
- "${REDIS_PORT}:6379"
|
||||||
volumes:
|
volumes:
|
||||||
- .volumes/redis:/data
|
- .volumes/redis:/data
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
import { ReactNode, useState } from 'react'
|
import { ReactNode, useState } from 'react'
|
||||||
import { useRouter, usePathname } from 'next/navigation'
|
import { useRouter, usePathname } from 'next/navigation'
|
||||||
import { logout } from '@/actions/auth'
|
import { logout } from '@/actions/auth'
|
||||||
import { LogOutIcon } from 'lucide-react'
|
import { LayoutDashboardIcon, LogOutIcon, User2Icon } from 'lucide-react'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import { cn } from '@/lib/utils'
|
import { cn } from '@/lib/utils'
|
||||||
import { DoorClosedIcon } from 'lucide-react'
|
import { DoorClosedIcon } from 'lucide-react'
|
||||||
@@ -70,14 +70,18 @@ export default function DashboardLayout({
|
|||||||
{/* 主要内容区域 */}
|
{/* 主要内容区域 */}
|
||||||
<div className="flex-auto overflow-hidden flex">
|
<div className="flex-auto overflow-hidden flex">
|
||||||
{/* 侧边栏 */}
|
{/* 侧边栏 */}
|
||||||
<nav className="flex-none basis-64 border-r flex flex-col p-3 gap-2">
|
<nav className="flex-none basis-64 border-r flex flex-col p-3">
|
||||||
<NavbarItem href="/gatewayinfo" active={isActive('/gatewayinfo')}><DoorClosedIcon size={20} />网关信息</NavbarItem>
|
<NavbarTitle>路由节点</NavbarTitle>
|
||||||
<NavbarItem href="/gatewayConfig" active={isActive('/gatewayConfig')}><DoorClosedLockedIcon size={20} />网关配置</NavbarItem>
|
|
||||||
<NavbarItem href="/gatewayMonitor" active={isActive('/gatewayMonitor')}><DoorOpenIcon size={20} />配置总览</NavbarItem>
|
|
||||||
<NavbarItem href="/cityNodeStats" active={isActive('/cityNodeStats')}><MapPinnedIcon size={20} />城市信息</NavbarItem>
|
<NavbarItem href="/cityNodeStats" active={isActive('/cityNodeStats')}><MapPinnedIcon size={20} />城市信息</NavbarItem>
|
||||||
|
<NavbarTitle>代理网关</NavbarTitle>
|
||||||
|
<NavbarItem href="/gatewayinfo" active={isActive('/gatewayinfo')}><DoorClosedIcon size={20} />网关列表</NavbarItem>
|
||||||
|
<NavbarItem href="/gatewayConfig" active={isActive('/gatewayConfig')}><DoorClosedLockedIcon size={20} />网关配置</NavbarItem>
|
||||||
|
<NavbarItem href="/gatewayMonitor" active={isActive('/gatewayMonitor')}><LayoutDashboardIcon size={20} />配置总览</NavbarItem>
|
||||||
|
<NavbarTitle>边缘节点</NavbarTitle>
|
||||||
|
<NavbarItem href="/edge" active={isActive('/edge')}><GitForkIcon size={20} />节点列表</NavbarItem>
|
||||||
<NavbarItem href="/allocationStatus" active={isActive('/allocationStatus')}><ContainerIcon size={20} />分配状态</NavbarItem>
|
<NavbarItem href="/allocationStatus" active={isActive('/allocationStatus')}><ContainerIcon size={20} />分配状态</NavbarItem>
|
||||||
<NavbarItem href="/edge" active={isActive('/edge')}><GitForkIcon size={20} />节点信息</NavbarItem>
|
<NavbarTitle>其他</NavbarTitle>
|
||||||
<NavbarItem href="/settings" active={isActive('/settings')}><SettingsIcon size={20} />设置</NavbarItem>
|
<NavbarItem href="/settings" active={isActive('/settings')}><User2Icon size={20} />用户管理</NavbarItem>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
{/* 内容区域 */}
|
{/* 内容区域 */}
|
||||||
@@ -89,6 +93,16 @@ export default function DashboardLayout({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function NavbarTitle(props: {
|
||||||
|
children: ReactNode
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<h3 className="text-sm text-weak h-8 flex items-end px-2 pb-1">
|
||||||
|
{props.children}
|
||||||
|
</h3>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
function NavbarItem(props: {
|
function NavbarItem(props: {
|
||||||
href: string
|
href: string
|
||||||
active: boolean
|
active: boolean
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
@theme inline {
|
@theme inline {
|
||||||
--color-background: var(--background);
|
--color-background: var(--background);
|
||||||
--color-foreground: var(--foreground);
|
--color-foreground: var(--foreground);
|
||||||
|
--color-weak: var(--weak);
|
||||||
--font-sans: var(--font-geist-sans);
|
--font-sans: var(--font-geist-sans);
|
||||||
--font-mono: var(--font-geist-mono);
|
--font-mono: var(--font-geist-mono);
|
||||||
--color-sidebar-ring: var(--sidebar-ring);
|
--color-sidebar-ring: var(--sidebar-ring);
|
||||||
@@ -45,8 +46,11 @@
|
|||||||
|
|
||||||
:root {
|
:root {
|
||||||
--radius: 0.625rem;
|
--radius: 0.625rem;
|
||||||
|
|
||||||
--background: oklch(1 0 0);
|
--background: oklch(1 0 0);
|
||||||
--foreground: oklch(0.145 0 0);
|
--foreground: oklch(0.145 0 0);
|
||||||
|
--weak: oklch(0.6 0 0);
|
||||||
|
|
||||||
--card: oklch(1 0 0);
|
--card: oklch(1 0 0);
|
||||||
--card-foreground: oklch(0.145 0 0);
|
--card-foreground: oklch(0.145 0 0);
|
||||||
--popover: oklch(1 0 0);
|
--popover: oklch(1 0 0);
|
||||||
|
|||||||
@@ -4,10 +4,13 @@ import * as schema from './schema'
|
|||||||
|
|
||||||
const globalForDrizzle = globalThis as { drizzle?: MySql2Database<typeof schema> }
|
const globalForDrizzle = globalThis as { drizzle?: MySql2Database<typeof schema> }
|
||||||
|
|
||||||
|
const { DATABASE_HOST, DATABASE_PORT, DATABASE_USERNAME, DATABASE_PASSWORD, DATABASE_NAME } = process.env
|
||||||
const proxy = new Proxy({} as MySql2Database<typeof schema>, {
|
const proxy = new Proxy({} as MySql2Database<typeof schema>, {
|
||||||
get(_, prop) {
|
get(_, prop) {
|
||||||
if (!globalForDrizzle.drizzle) {
|
if (!globalForDrizzle.drizzle) {
|
||||||
globalForDrizzle.drizzle = client(process.env.DATABASE_URL!, { mode: 'default', schema })
|
globalForDrizzle.drizzle = client(
|
||||||
|
`mysql://${DATABASE_USERNAME}:${DATABASE_PASSWORD}@${DATABASE_HOST}:${DATABASE_PORT}/${DATABASE_NAME}`,
|
||||||
|
{ mode: 'default', schema })
|
||||||
}
|
}
|
||||||
|
|
||||||
const drizzle = globalForDrizzle.drizzle
|
const drizzle = globalForDrizzle.drizzle
|
||||||
|
|||||||
@@ -3,8 +3,9 @@ import { createClient, type RedisClientType } from 'redis'
|
|||||||
|
|
||||||
const globalForRedis = globalThis as { redis?: RedisClientType }
|
const globalForRedis = globalThis as { redis?: RedisClientType }
|
||||||
|
|
||||||
|
const { REDIS_HOST, REDIS_PORT } = process.env
|
||||||
if (!globalForRedis.redis) {
|
if (!globalForRedis.redis) {
|
||||||
globalForRedis.redis = createClient({ url: process.env.REDIS_URL })
|
globalForRedis.redis = createClient({ url: `redis://${REDIS_HOST}:${REDIS_PORT}` })
|
||||||
}
|
}
|
||||||
|
|
||||||
const redis = globalForRedis.redis
|
const redis = globalForRedis.redis
|
||||||
|
|||||||
Reference in New Issue
Block a user