修复了登录页面还存在顶部导航栏的问题

This commit is contained in:
2025-10-21 09:49:59 +08:00
parent 5c783c73e1
commit 4a5d278d89
121 changed files with 5626 additions and 286 deletions

View File

@@ -0,0 +1,143 @@
"use client"
import { ReactNode } from 'react'
import SideBar from '@/components/layouts/SideBar/SideBar'
// 中心配置路由数据
const centralConfigData = {
versions: ["1.0.0", "2.0.0"],
navMain: [
{
title: "租户管理",
url: "/central-config/tenant-management",
icon: "🏢",
items: [
{
title: "企业审核",
url: "/central-config/tenant-management/enterprise-audit",
isActive: false
},
{
title: "审核历史",
url: "/central-config/tenant-management/audit-history",
isActive: false
},
{
title: "企业信息",
url: "/central-config/tenant-management/enterprise-info",
isActive: false
},
{
title: "平台用户管理",
url: "/central-config/tenant-management/platform-user-management",
isActive: false
}
]
},
{
title: "用户管理",
url: "/central-config/user-management",
icon: "👥",
items: [
{
title: "员工管理",
url: "/central-config/user-management/employee-management",
isActive: false
},
{
title: "角色管理",
url: "/central-config/user-management/role-management",
isActive: false
},
{
title: "菜单管理",
url: "/central-config/user-management/menu-management",
isActive: false
},
{
title: "权限配置管理",
url: "/central-config/user-management/permission-config",
isActive: false
}
]
},
{
title: "系统参数",
url: "/central-config/system-parameters",
icon: "🔧",
items: [
{
title: "系统设置",
url: "/central-config/system-parameters/system-settings",
isActive: false
},
{
title: "分类字典",
url: "/central-config/system-parameters/category-dictionary",
isActive: false
},
{
title: "数据字典",
url: "/central-config/system-parameters/data-dictionary",
isActive: false
}
]
},
{
title: "系统监控",
url: "/central-config/system-monitor",
icon: "📈",
items: [
{
title: "登录日志",
url: "/central-config/system-monitor/login-log",
isActive: false
},
{
title: "操作日志",
url: "/central-config/system-monitor/operation-log",
isActive: false
},
{
title: "性能监控",
url: "/central-config/system-monitor/performance-monitor",
isActive: false
},
{
title: "网络日志",
url: "/central-config/system-monitor/network-log",
isActive: false
}
]
},
{
title: "消息中心",
url: "/central-config/message-center",
icon: "📨",
items: [
{
title: "消息发送",
url: "/central-config/message-center/message-send",
isActive: false
},
{
title: "消息模版",
url: "/central-config/message-center/message-template",
isActive: false
},
{
title: "消息日志",
url: "/central-config/message-center/message-log",
isActive: false
}
]
}
]
}
export default function CentralConfigLayout({
children,
}: {
children: ReactNode
}) {
return <SideBar data={centralConfigData}>{children}</SideBar>
}

View File

@@ -0,0 +1,22 @@
import { ReactNode } from 'react'
export default function MessageCenterLayout({
children,
}: {
children: ReactNode
}) {
return (
<div className="min-h-screen bg-gray-50">
<header className="bg-white shadow-sm border-b">
<div className="container mx-auto px-4 py-4">
<h1 className="text-2xl font-bold text-green-900">
📨
</h1>
</div>
</header>
<main className="container mx-auto px-4 py-8">
{children}
</main>
</div>
)
}

View File

@@ -0,0 +1,8 @@
export default function MessageLogPage() {
return (
<div className="p-6">
<h1 className="text-2xl font-bold mb-4"></h1>
<p></p>
</div>
)
}

View File

@@ -0,0 +1,146 @@
import { Metadata } from 'next'
export const metadata: Metadata = {
title: '消息发送 - Crop-X 智慧农业管理系统',
description: '消息推送管理页面',
}
export default function MessageSendPage() {
return (
<div className="space-y-6">
<div className="bg-white rounded-lg shadow p-6">
<h2 className="text-2xl font-bold text-gray-800 mb-6">
📤
</h2>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
<div className="bg-blue-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-blue-900 mb-4">
</h3>
<form className="space-y-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<input
type="text"
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="请输入消息标题"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<select className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
<option></option>
<option></option>
<option></option>
<option></option>
</select>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<select className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
<option></option>
<option></option>
<option></option>
<option></option>
</select>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<textarea
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
rows={4}
placeholder="请输入消息内容"
></textarea>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<div className="space-y-2">
<label className="flex items-center">
<input type="checkbox" className="mr-2" defaultChecked />
</label>
<label className="flex items-center">
<input type="checkbox" className="mr-2" />
</label>
<label className="flex items-center">
<input type="checkbox" className="mr-2" />
</label>
</div>
</div>
<button
type="submit"
className="w-full px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors"
>
</button>
</form>
</div>
<div className="bg-green-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-green-900 mb-4">
</h3>
<div className="space-y-3">
{[
{ id: 'MSG001', title: '系统维护通知', recipients: '全体用户', time: '2024-10-20 14:30', status: '已发送' },
{ id: 'MSG002', title: '农机任务分配', recipients: '农机操作员', time: '2024-10-20 12:15', status: '已发送' },
{ id: 'MSG003', title: '天气预警', recipients: '农场管理员', time: '2024-10-20 09:45', status: '已发送' },
{ id: 'MSG004', title: '数据备份提醒', recipients: '系统管理员', time: '2024-10-19 23:00', status: '已发送' },
].map((message) => (
<div key={message.id} className="bg-white rounded-lg p-4 shadow-sm">
<div className="flex justify-between items-start">
<div>
<h4 className="font-semibold text-gray-800">{message.title}</h4>
<p className="text-sm text-gray-600">: {message.recipients}</p>
<p className="text-xs text-gray-500">{message.time}</p>
</div>
<span className="inline-block px-2 py-1 text-xs font-medium bg-green-100 text-green-800 rounded-full">
{message.status}
</span>
</div>
</div>
))}
</div>
</div>
</div>
<div className="mt-6 bg-yellow-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-yellow-900 mb-4">
📊
</h3>
<div className="grid grid-cols-1 md:grid-cols-4 gap-4">
<div className="bg-white rounded-lg p-4 text-center">
<div className="text-2xl font-bold text-blue-600 mb-2">156</div>
<div className="text-sm text-gray-600"></div>
</div>
<div className="bg-white rounded-lg p-4 text-center">
<div className="text-2xl font-bold text-green-600 mb-2">98.5%</div>
<div className="text-sm text-gray-600"></div>
</div>
<div className="bg-white rounded-lg p-4 text-center">
<div className="text-2xl font-bold text-purple-600 mb-2">1,234</div>
<div className="text-sm text-gray-600"></div>
</div>
<div className="bg-white rounded-lg p-4 text-center">
<div className="text-2xl font-bold text-orange-600 mb-2">8</div>
<div className="text-sm text-gray-600"></div>
</div>
</div>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,8 @@
export default function MessageTemplatePage() {
return (
<div className="p-6">
<h1 className="text-2xl font-bold mb-4"></h1>
<p></p>
</div>
)
}

View File

@@ -0,0 +1,111 @@
import Link from 'next/link'
import { Metadata } from 'next'
export const metadata: Metadata = {
title: '消息中心 - Crop-X 智慧农业管理系统',
description: '消息推送管理页面',
}
export default function MessageCenterPage() {
return (
<div className="space-y-6">
<div className="bg-white rounded-lg shadow p-6">
<h2 className="text-xl font-semibold text-gray-800 mb-4">
</h2>
<p className="text-gray-600 mb-6">
</p>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<Link
href="/central-config/message-center/message-push-management"
className="block p-4 bg-green-50 rounded-lg hover:bg-green-100 transition-colors"
>
<h3 className="font-semibold text-green-900 mb-2">
📤
</h3>
<p className="text-green-700 text-sm">
</p>
</Link>
<Link
href="/central-config/message-center/message-send"
className="block p-4 bg-blue-50 rounded-lg hover:bg-blue-100 transition-colors"
>
<h3 className="font-semibold text-blue-900 mb-2">
📨
</h3>
<p className="text-blue-700 text-sm">
</p>
</Link>
<Link
href="/central-config/message-center/notification-settings"
className="block p-4 bg-purple-50 rounded-lg hover:bg-purple-100 transition-colors"
>
<h3 className="font-semibold text-purple-900 mb-2">
</h3>
<p className="text-purple-700 text-sm">
</p>
</Link>
<Link
href="/central-config/message-center/feedback-management"
className="block p-4 bg-orange-50 rounded-lg hover:bg-orange-100 transition-colors"
>
<h3 className="font-semibold text-orange-900 mb-2">
💬
</h3>
<p className="text-orange-700 text-sm">
</p>
</Link>
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div className="bg-white rounded-lg shadow p-6">
<h3 className="text-lg font-semibold text-gray-800 mb-4">
📊
</h3>
<div className="space-y-2">
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="text-green-600 font-semibold">156 </span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="text-orange-600 font-semibold">23 </span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="text-blue-600 font-semibold">8 </span>
</div>
</div>
</div>
<div className="bg-white rounded-lg shadow p-6">
<h3 className="text-lg font-semibold text-gray-800 mb-4">
🔧
</h3>
<div className="space-y-2">
<button className="w-full px-4 py-2 bg-green-600 text-white rounded hover:bg-green-700 transition-colors">
</button>
<button className="w-full px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors">
</button>
<button className="w-full px-4 py-2 bg-purple-600 text-white rounded hover:bg-purple-700 transition-colors">
</button>
</div>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,123 @@
import Link from 'next/link'
import { Metadata } from 'next'
export const metadata: Metadata = {
title: '中心配置管理 - Crop-X 智慧农业管理系统',
description: '中心配置管理系统主页面',
}
export default function CentralConfigPage() {
return (
<div className="space-y-6">
<div className="bg-white rounded-lg shadow p-6">
<h2 className="text-xl font-semibold text-gray-800 mb-4">
</h2>
<p className="text-gray-600 mb-6">
</p>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<Link
href="/central-config/tenant-management"
className="block p-4 bg-green-50 rounded-lg hover:bg-green-100 transition-colors"
>
<h3 className="font-semibold text-green-900 mb-2">
🏢
</h3>
<p className="text-green-700 text-sm">
</p>
</Link>
<Link
href="/central-config/user-management"
className="block p-4 bg-blue-50 rounded-lg hover:bg-blue-100 transition-colors"
>
<h3 className="font-semibold text-blue-900 mb-2">
👥
</h3>
<p className="text-blue-700 text-sm">
</p>
</Link>
<Link
href="/central-config/system-parameters"
className="block p-4 bg-purple-50 rounded-lg hover:bg-purple-100 transition-colors"
>
<h3 className="font-semibold text-purple-900 mb-2">
🔧
</h3>
<p className="text-purple-700 text-sm">
</p>
</Link>
<Link
href="/central-config/system-monitoring"
className="block p-4 bg-orange-50 rounded-lg hover:bg-orange-100 transition-colors"
>
<h3 className="font-semibold text-orange-900 mb-2">
📈
</h3>
<p className="text-orange-700 text-sm">
</p>
</Link>
<Link
href="/central-config/message-center"
className="block p-4 bg-teal-50 rounded-lg hover:bg-teal-100 transition-colors"
>
<h3 className="font-semibold text-teal-900 mb-2">
📨
</h3>
<p className="text-teal-700 text-sm">
</p>
</Link>
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div className="bg-white rounded-lg shadow p-6">
<h3 className="text-lg font-semibold text-gray-800 mb-4">
📊
</h3>
<div className="space-y-2">
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="text-green-600 font-semibold">12 </span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="text-blue-600 font-semibold">248 </span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="text-purple-600 font-semibold">99.8%</span>
</div>
</div>
</div>
<div className="bg-white rounded-lg shadow p-6">
<h3 className="text-lg font-semibold text-gray-800 mb-4">
🔧
</h3>
<div className="space-y-2">
<button className="w-full px-4 py-2 bg-green-600 text-white rounded hover:bg-green-700 transition-colors">
</button>
<button className="w-full px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors">
</button>
<button className="w-full px-4 py-2 bg-purple-600 text-white rounded hover:bg-purple-700 transition-colors">
</button>
</div>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,11 @@
export default function SystemMonitorLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<div className="system-monitor-layout">
{children}
</div>
)
}

View File

@@ -0,0 +1,8 @@
export default function LoginLogPage() {
return (
<div className="p-6">
<h1 className="text-2xl font-bold mb-4"></h1>
<p></p>
</div>
)
}

View File

@@ -0,0 +1,8 @@
export default function NetworkLogPage() {
return (
<div className="p-6">
<h1 className="text-2xl font-bold mb-4"></h1>
<p></p>
</div>
)
}

View File

@@ -0,0 +1,8 @@
export default function OperationLogPage() {
return (
<div className="p-6">
<h1 className="text-2xl font-bold mb-4"></h1>
<p></p>
</div>
)
}

View File

@@ -0,0 +1,8 @@
export default function SystemMonitorPage() {
return (
<div className="p-6">
<h1 className="text-2xl font-bold mb-4"></h1>
<p></p>
</div>
)
}

View File

@@ -0,0 +1,8 @@
export default function PerformanceMonitorPage() {
return (
<div className="p-6">
<h1 className="text-2xl font-bold mb-4"></h1>
<p></p>
</div>
)
}

View File

@@ -0,0 +1,185 @@
import { Metadata } from 'next'
export const metadata: Metadata = {
title: '异常处理 - Crop-X 智慧农业管理系统',
description: '系统异常处理管理页面',
}
export default function ExceptionHandlingPage() {
return (
<div className="space-y-6">
<div className="bg-white rounded-lg shadow p-6">
<h2 className="text-2xl font-bold text-gray-800 mb-6">
</h2>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
<div className="bg-red-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-red-900 mb-4">
</h3>
<div className="space-y-3">
{[
{
id: 'ERR001',
type: '数据库连接异常',
severity: '高',
time: '2024-10-20 15:30:25',
status: 'active',
description: 'MySQL连接池耗尽无法获取新连接'
},
{
id: 'ERR002',
type: 'API超时异常',
severity: '中',
time: '2024-10-20 15:28:15',
status: 'active',
description: '第三方天气API调用超时'
},
{
id: 'ERR003',
type: '内存溢出警告',
severity: '中',
time: '2024-10-20 15:25:42',
status: 'resolved',
description: 'JVM内存使用率超过85%阈值'
},
].map((error) => (
<div key={error.id} className="bg-white rounded-lg p-4 shadow-sm border-l-4 border-red-500">
<div className="flex justify-between items-start mb-2">
<div>
<h4 className="font-semibold text-gray-800">{error.type}</h4>
<p className="text-sm text-gray-600">{error.description}</p>
<p className="text-xs text-gray-500 mt-1">{error.time}</p>
</div>
<div className="flex flex-col items-end space-y-1">
<span className={`px-2 py-1 text-xs font-medium rounded-full ${
error.severity === '高' ? 'bg-red-100 text-red-800' : 'bg-yellow-100 text-yellow-800'
}`}>
{error.severity}
</span>
<span className={`px-2 py-1 text-xs font-medium rounded-full ${
error.status === 'active' ? 'bg-orange-100 text-orange-800' : 'bg-green-100 text-green-800'
}`}>
{error.status === 'active' ? '活跃' : '已解决'}
</span>
</div>
</div>
<div className="flex space-x-2 mt-3">
<button className="px-3 py-1 bg-blue-600 text-white text-xs rounded hover:bg-blue-700">
</button>
<button className="px-3 py-1 bg-green-600 text-white text-xs rounded hover:bg-green-700">
</button>
<button className="px-3 py-1 bg-purple-600 text-white text-xs rounded hover:bg-purple-700">
</button>
</div>
</div>
))}
</div>
</div>
<div className="bg-yellow-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-yellow-900 mb-4">
</h3>
<div className="space-y-4">
<div className="bg-white rounded-lg p-4">
<h4 className="font-medium text-gray-800 mb-3"></h4>
<div className="space-y-2">
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="font-semibold text-red-600">23 </span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="font-semibold text-green-600">18 </span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="font-semibold text-orange-600">5 </span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="font-semibold text-blue-600">15</span>
</div>
</div>
</div>
<div className="bg-white rounded-lg p-4">
<h4 className="font-medium text-gray-800 mb-3"></h4>
<div className="space-y-2">
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="font-semibold text-purple-600">8 </span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="font-semibold text-blue-600">6 </span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="font-semibold text-green-600">5 </span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="font-semibold text-orange-600">4 </span>
</div>
</div>
</div>
</div>
</div>
</div>
<div className="mt-6 bg-green-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-green-900 mb-4">
🔧
</h3>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<h4 className="font-medium text-gray-800 mb-3"></h4>
<div className="space-y-2">
<div className="flex justify-between items-center p-2 bg-white rounded">
<span className="text-sm text-gray-700"></span>
<span className="text-sm text-green-600"></span>
</div>
<div className="flex justify-between items-center p-2 bg-white rounded">
<span className="text-sm text-gray-700"></span>
<span className="text-sm text-green-600"></span>
</div>
<div className="flex justify-between items-center p-2 bg-white rounded">
<span className="text-sm text-gray-700"></span>
<span className="text-sm text-gray-600"></span>
</div>
<div className="flex justify-between items-center p-2 bg-white rounded">
<span className="text-sm text-gray-700"></span>
<span className="text-sm text-green-600"></span>
</div>
</div>
</div>
<div>
<h4 className="font-medium text-gray-800 mb-3"></h4>
<div className="grid grid-cols-2 gap-2">
<button className="px-3 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors text-sm">
</button>
<button className="px-3 py-2 bg-green-600 text-white rounded-md hover:bg-green-700 transition-colors text-sm">
</button>
<button className="px-3 py-2 bg-purple-600 text-white rounded-md hover:bg-purple-700 transition-colors text-sm">
</button>
<button className="px-3 py-2 bg-orange-600 text-white rounded-md hover:bg-orange-700 transition-colors text-sm">
</button>
</div>
</div>
</div>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,22 @@
import { ReactNode } from 'react'
export default function SystemMonitoringLayout({
children,
}: {
children: ReactNode
}) {
return (
<div className="min-h-screen bg-gray-50">
<header className="bg-white shadow-sm border-b">
<div className="container mx-auto px-4 py-4">
<h1 className="text-2xl font-bold text-green-900">
📈
</h1>
</div>
</header>
<main className="container mx-auto px-4 py-8">
{children}
</main>
</div>
)
}

View File

@@ -0,0 +1,160 @@
import { Metadata } from 'next'
export const metadata: Metadata = {
title: '日志管理 - Crop-X 智慧农业管理系统',
description: '系统日志管理页面',
}
export default function LogManagementPage() {
return (
<div className="space-y-6">
<div className="bg-white rounded-lg shadow p-6">
<h2 className="text-2xl font-bold text-gray-800 mb-6">
📋
</h2>
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
<div className="lg:col-span-2">
<div className="bg-gray-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-gray-800 mb-4">
</h3>
<div className="mb-4 flex space-x-4">
<select className="px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
<option></option>
<option>ERROR</option>
<option>WARN</option>
<option>INFO</option>
<option>DEBUG</option>
</select>
<input
type="text"
placeholder="搜索日志内容..."
className="flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
<button className="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors">
</button>
</div>
<div className="bg-white rounded-lg p-4 max-h-96 overflow-y-auto">
<div className="space-y-3">
{[
{ time: '2024-10-20 15:30:25', level: 'INFO', module: '用户管理', message: '用户登录成功: admin', status: 'normal' },
{ time: '2024-10-20 15:28:15', level: 'WARN', module: '农机管理', message: '农机NJ001离线超时', status: 'warning' },
{ time: '2024-10-20 15:25:42', level: 'ERROR', module: '数据同步', message: 'API调用失败: timeout', status: 'error' },
{ time: '2024-10-20 15:22:18', level: 'INFO', module: '任务调度', message: '定时任务执行完成', status: 'normal' },
{ time: '2024-10-20 15:20:05', level: 'INFO', module: '系统监控', message: '系统性能指标正常', status: 'normal' },
].map((log, index) => (
<div key={index} className="border-l-4 border-gray-300 pl-4 py-2 hover:bg-gray-50">
<div className="flex justify-between items-start">
<div className="flex-1">
<div className="flex items-center space-x-2 mb-1">
<span className={`text-xs font-medium px-2 py-1 rounded ${
log.level === 'ERROR' ? 'bg-red-100 text-red-800' :
log.level === 'WARN' ? 'bg-yellow-100 text-yellow-800' :
log.level === 'INFO' ? 'bg-blue-100 text-blue-800' :
'bg-gray-100 text-gray-800'
}`}>
{log.level}
</span>
<span className="text-sm text-gray-500">{log.time}</span>
<span className="text-sm text-gray-600">[{log.module}]</span>
</div>
<p className="text-sm text-gray-700">{log.message}</p>
</div>
</div>
</div>
))}
</div>
</div>
<div className="mt-4 flex justify-between items-center">
<div className="text-sm text-gray-600">
1-5 1,245
</div>
<div className="flex space-x-2">
<button className="px-3 py-1 border border-gray-300 rounded-md hover:bg-gray-50">
</button>
<button className="px-3 py-1 bg-blue-600 text-white rounded-md">
1
</button>
<button className="px-3 py-1 border border-gray-300 rounded-md hover:bg-gray-50">
2
</button>
<button className="px-3 py-1 border border-gray-300 rounded-md hover:bg-gray-50">
</button>
</div>
</div>
</div>
</div>
<div className="space-y-4">
<div className="bg-green-50 rounded-lg p-4">
<h4 className="font-semibold text-green-900 mb-3"></h4>
<div className="space-y-2">
<div className="flex justify-between">
<span className="text-gray-600"></span>
<span className="font-semibold text-green-600">1,245</span>
</div>
<div className="flex justify-between">
<span className="text-gray-600"></span>
<span className="font-semibold text-red-600">12</span>
</div>
<div className="flex justify-between">
<span className="text-gray-600"></span>
<span className="font-semibold text-yellow-600">45</span>
</div>
<div className="flex justify-between">
<span className="text-gray-600"></span>
<span className="font-semibold text-blue-600">1,188</span>
</div>
</div>
</div>
<div className="bg-blue-50 rounded-lg p-4">
<h4 className="font-semibold text-blue-900 mb-3"></h4>
<div className="space-y-2">
<button className="w-full px-3 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors text-sm">
</button>
<button className="w-full px-3 py-2 bg-green-600 text-white rounded-md hover:bg-green-700 transition-colors text-sm">
</button>
<button className="w-full px-3 py-2 bg-purple-600 text-white rounded-md hover:bg-purple-700 transition-colors text-sm">
</button>
</div>
</div>
<div className="bg-purple-50 rounded-lg p-4">
<h4 className="font-semibold text-purple-900 mb-3"></h4>
<div className="space-y-2">
<div className="flex justify-between items-center">
<span className="text-sm text-gray-600"></span>
<select className="text-xs px-2 py-1 border border-gray-300 rounded">
<option>INFO</option>
<option>DEBUG</option>
<option>WARN</option>
<option>ERROR</option>
</select>
</div>
<div className="flex justify-between items-center">
<span className="text-sm text-gray-600"></span>
<span className="text-sm font-semibold">30</span>
</div>
<div className="flex justify-between items-center">
<span className="text-sm text-gray-600"></span>
<span className="text-sm text-green-600"></span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,103 @@
import Link from 'next/link'
import { Metadata } from 'next'
export const metadata: Metadata = {
title: '系统监控 - Crop-X 智慧农业管理系统',
description: '系统监控管理页面',
}
export default function SystemMonitoringPage() {
return (
<div className="space-y-6">
<div className="bg-white rounded-lg shadow p-6">
<h2 className="text-xl font-semibold text-gray-800 mb-4">
</h2>
<p className="text-gray-600 mb-6">
</p>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<Link
href="/central-config/system-monitoring/performance-monitoring"
className="block p-4 bg-green-50 rounded-lg hover:bg-green-100 transition-colors"
>
<h3 className="font-semibold text-green-900 mb-2">
📊
</h3>
<p className="text-green-700 text-sm">
</p>
</Link>
<Link
href="/central-config/system-monitoring/log-management"
className="block p-4 bg-blue-50 rounded-lg hover:bg-blue-100 transition-colors"
>
<h3 className="font-semibold text-blue-900 mb-2">
📋
</h3>
<p className="text-blue-700 text-sm">
</p>
</Link>
<Link
href="/central-config/system-monitoring/exception-handling"
className="block p-4 bg-purple-50 rounded-lg hover:bg-purple-100 transition-colors"
>
<h3 className="font-semibold text-purple-900 mb-2">
</h3>
<p className="text-purple-700 text-sm">
</p>
</Link>
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div className="bg-white rounded-lg shadow p-6">
<h3 className="text-lg font-semibold text-gray-800 mb-4">
📊
</h3>
<div className="space-y-2">
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="text-green-600 font-semibold">15 8</span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600">CPU使用率</span>
<span className="text-blue-600 font-semibold">45.2%</span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600">使</span>
<span className="text-purple-600 font-semibold">68.7%</span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="text-orange-600 font-semibold">3 </span>
</div>
</div>
</div>
<div className="bg-white rounded-lg shadow p-6">
<h3 className="text-lg font-semibold text-gray-800 mb-4">
🔧
</h3>
<div className="space-y-2">
<button className="w-full px-4 py-2 bg-green-600 text-white rounded hover:bg-green-700 transition-colors">
</button>
<button className="w-full px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors">
</button>
<button className="w-full px-4 py-2 bg-purple-600 text-white rounded hover:bg-purple-700 transition-colors">
</button>
</div>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,119 @@
import { Metadata } from 'next'
export const metadata: Metadata = {
title: '性能监控 - Crop-X 智慧农业管理系统',
description: '系统性能监控管理页面',
}
export default function PerformanceMonitoringPage() {
return (
<div className="space-y-6">
<div className="bg-white rounded-lg shadow p-6">
<h2 className="text-2xl font-bold text-gray-800 mb-6">
📊
</h2>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
<div className="bg-green-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-green-900 mb-4">
</h3>
<div className="space-y-4">
<div>
<div className="flex justify-between items-center mb-2">
<span className="text-gray-700">CPU 使</span>
<span className="font-semibold text-green-600">45.2%</span>
</div>
<div className="w-full bg-gray-200 rounded-full h-2">
<div className="bg-green-600 h-2 rounded-full" style={{ width: '45.2%' }}></div>
</div>
</div>
<div>
<div className="flex justify-between items-center mb-2">
<span className="text-gray-700">使</span>
<span className="font-semibold text-blue-600">68.7%</span>
</div>
<div className="w-full bg-gray-200 rounded-full h-2">
<div className="bg-blue-600 h-2 rounded-full" style={{ width: '68.7%' }}></div>
</div>
</div>
<div>
<div className="flex justify-between items-center mb-2">
<span className="text-gray-700">使</span>
<span className="font-semibold text-purple-600">32.1%</span>
</div>
<div className="w-full bg-gray-200 rounded-full h-2">
<div className="bg-purple-600 h-2 rounded-full" style={{ width: '32.1%' }}></div>
</div>
</div>
<div>
<div className="flex justify-between items-center mb-2">
<span className="text-gray-700"></span>
<span className="font-semibold text-orange-600">28.5%</span>
</div>
<div className="w-full bg-gray-200 rounded-full h-2">
<div className="bg-orange-600 h-2 rounded-full" style={{ width: '28.5%' }}></div>
</div>
</div>
</div>
</div>
<div className="bg-blue-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-blue-900 mb-4">
</h3>
<div className="bg-white rounded-lg p-4 h-64 flex items-center justify-center">
<div className="text-center">
<div className="text-4xl mb-2">📈</div>
<p className="text-gray-600">
</p>
<p className="text-sm text-gray-500">
()
</p>
</div>
</div>
</div>
</div>
<div className="mt-6 grid grid-cols-1 md:grid-cols-3 gap-4">
<div className="bg-white rounded-lg p-4 border-l-4 border-green-500">
<h4 className="font-semibold text-gray-800 mb-2"></h4>
<div className="text-2xl font-bold text-green-600 mb-1">125ms</div>
<div className="text-sm text-gray-600"></div>
</div>
<div className="bg-white rounded-lg p-4 border-l-4 border-blue-500">
<h4 className="font-semibold text-gray-800 mb-2"></h4>
<div className="text-2xl font-bold text-blue-600 mb-1">1,245</div>
<div className="text-sm text-gray-600">/</div>
</div>
<div className="bg-white rounded-lg p-4 border-l-4 border-purple-500">
<h4 className="font-semibold text-gray-800 mb-2"></h4>
<div className="text-2xl font-bold text-purple-600 mb-1">99.9%</div>
<div className="text-sm text-gray-600"></div>
</div>
</div>
<div className="mt-6 bg-yellow-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-yellow-900 mb-4">
</h3>
<div className="space-y-2">
<div className="flex items-center">
<div className="w-2 h-2 bg-yellow-500 rounded-full mr-3"></div>
<span className="text-gray-700">使</span>
</div>
<div className="flex items-center">
<div className="w-2 h-2 bg-green-500 rounded-full mr-3"></div>
<span className="text-gray-700">CPU使用率正常</span>
</div>
<div className="flex items-center">
<div className="w-2 h-2 bg-blue-500 rounded-full mr-3"></div>
<span className="text-gray-700"></span>
</div>
</div>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,223 @@
import { Metadata } from 'next'
export const metadata: Metadata = {
title: '基础配置 - Crop-X 智慧农业管理系统',
description: '基础配置管理页面',
}
export default function BasicConfigurationPage() {
return (
<div className="space-y-6">
<div className="bg-white rounded-lg shadow p-6">
<h2 className="text-2xl font-bold text-gray-800 mb-6">
</h2>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
<div className="space-y-6">
<div className="bg-green-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-green-900 mb-4">
</h3>
<div className="space-y-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<input
type="text"
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500"
defaultValue="Crop-X 智慧农业管理系统"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<input
type="text"
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500"
defaultValue="v2.1.0"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<select className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500">
<option>Asia/Shanghai (UTC+8)</option>
<option>Asia/Beijing (UTC+8)</option>
<option>UTC (UTC+0)</option>
</select>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<select className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500">
<option></option>
<option>English</option>
</select>
</div>
</div>
</div>
<div className="bg-blue-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-blue-900 mb-4">
</h3>
<div className="space-y-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
()
</label>
<input
type="number"
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
defaultValue="30"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<input
type="number"
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
defaultValue="8"
/>
</div>
<div className="flex items-center">
<input
type="checkbox"
className="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded"
defaultChecked
/>
<label className="ml-2 block text-sm text-gray-700">
</label>
</div>
<div className="flex items-center">
<input
type="checkbox"
className="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded"
defaultChecked
/>
<label className="ml-2 block text-sm text-gray-700">
HTTPS访问
</label>
</div>
</div>
</div>
</div>
<div className="space-y-6">
<div className="bg-purple-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-purple-900 mb-4">
</h3>
<div className="space-y-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<input
type="number"
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-purple-500"
defaultValue="20"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
()
</label>
<input
type="number"
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-purple-500"
defaultValue="24"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
(MB)
</label>
<input
type="number"
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-purple-500"
defaultValue="10"
/>
</div>
<div className="flex items-center">
<input
type="checkbox"
className="h-4 w-4 text-purple-600 focus:ring-purple-500 border-gray-300 rounded"
defaultChecked
/>
<label className="ml-2 block text-sm text-gray-700">
Gzip压缩
</label>
</div>
</div>
</div>
<div className="bg-orange-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-orange-900 mb-4">
</h3>
<div className="space-y-4">
<div className="flex items-center">
<input
type="checkbox"
className="h-4 w-4 text-orange-600 focus:ring-orange-500 border-gray-300 rounded"
defaultChecked
/>
<label className="ml-2 block text-sm text-gray-700">
</label>
</div>
<div className="flex items-center">
<input
type="checkbox"
className="h-4 w-4 text-orange-600 focus:ring-orange-500 border-gray-300 rounded"
defaultChecked
/>
<label className="ml-2 block text-sm text-gray-700">
</label>
</div>
<div className="flex items-center">
<input
type="checkbox"
className="h-4 w-4 text-orange-600 focus:ring-orange-500 border-gray-300 rounded"
/>
<label className="ml-2 block text-sm text-gray-700">
</label>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<input
type="email"
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-orange-500"
defaultValue="admin@crop-x.com"
/>
</div>
</div>
</div>
</div>
</div>
<div className="mt-6 flex justify-end space-x-4">
<button className="px-6 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50 transition-colors">
</button>
<button className="px-6 py-2 bg-green-600 text-white rounded-md hover:bg-green-700 transition-colors">
</button>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,243 @@
import { Metadata } from 'next'
export const metadata: Metadata = {
title: '业务规则设置 - Crop-X 智慧农业管理系统',
description: '业务规则设置管理页面',
}
export default function BusinessRuleSettingsPage() {
return (
<div className="space-y-6">
<div className="bg-white rounded-lg shadow p-6">
<h2 className="text-2xl font-bold text-gray-800 mb-6">
📋
</h2>
<div className="space-y-6">
<div className="bg-green-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-green-900 mb-4">
🚙
</h3>
<div className="space-y-4">
<div className="bg-white rounded-lg p-4">
<div className="flex justify-between items-center mb-2">
<h4 className="font-medium text-gray-800">线</h4>
<span className="text-sm text-green-600"></span>
</div>
<p className="text-sm text-gray-600 mb-3">线</p>
<div className="flex items-center space-x-4">
<input
type="number"
className="w-20 px-2 py-1 border border-gray-300 rounded"
defaultValue="8"
/>
<span className="text-sm text-gray-600">/</span>
<button className="px-3 py-1 bg-green-600 text-white text-sm rounded hover:bg-green-700">
</button>
</div>
</div>
<div className="bg-white rounded-lg p-4">
<div className="flex justify-between items-center mb-2">
<h4 className="font-medium text-gray-800"></h4>
<span className="text-sm text-green-600"></span>
</div>
<p className="text-sm text-gray-600 mb-3"></p>
<div className="flex items-center space-x-4">
<input
type="number"
className="w-20 px-2 py-1 border border-gray-300 rounded"
defaultValue="30"
/>
<span className="text-sm text-gray-600"></span>
<button className="px-3 py-1 bg-green-600 text-white text-sm rounded hover:bg-green-700">
</button>
</div>
</div>
<div className="bg-white rounded-lg p-4">
<div className="flex justify-between items-center mb-2">
<h4 className="font-medium text-gray-800"></h4>
<span className="text-sm text-green-600"></span>
</div>
<p className="text-sm text-gray-600 mb-3"></p>
<div className="flex items-center space-x-4">
<select className="px-3 py-1 border border-gray-300 rounded">
<option></option>
<option></option>
<option></option>
</select>
<button className="px-3 py-1 bg-green-600 text-white text-sm rounded hover:bg-green-700">
</button>
</div>
</div>
</div>
</div>
<div className="bg-blue-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-blue-900 mb-4">
🌾
</h3>
<div className="space-y-4">
<div className="bg-white rounded-lg p-4">
<div className="flex justify-between items-center mb-2">
<h4 className="font-medium text-gray-800"></h4>
<span className="text-sm text-green-600"></span>
</div>
<p className="text-sm text-gray-600 mb-3"></p>
<div className="flex items-center space-x-4">
<input
type="number"
className="w-24 px-2 py-1 border border-gray-300 rounded"
defaultValue="1000"
/>
<span className="text-sm text-gray-600"></span>
<button className="px-3 py-1 bg-green-600 text-white text-sm rounded hover:bg-green-700">
</button>
</div>
</div>
<div className="bg-white rounded-lg p-4">
<div className="flex justify-between items-center mb-2">
<h4 className="font-medium text-gray-800"></h4>
<span className="text-sm text-green-600"></span>
</div>
<p className="text-sm text-gray-600 mb-3"></p>
<div className="flex items-center space-x-4">
<select className="px-3 py-1 border border-gray-300 rounded">
<option>A/B/C三级</option>
<option>//</option>
<option>//</option>
</select>
<button className="px-3 py-1 bg-green-600 text-white text-sm rounded hover:bg-green-700">
</button>
</div>
</div>
</div>
</div>
<div className="bg-purple-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-purple-900 mb-4">
📋
</h3>
<div className="space-y-4">
<div className="bg-white rounded-lg p-4">
<div className="flex justify-between items-center mb-2">
<h4 className="font-medium text-gray-800"></h4>
<span className="text-sm text-green-600"></span>
</div>
<p className="text-sm text-gray-600 mb-3"></p>
<div className="flex items-center space-x-4">
<select className="px-3 py-1 border border-gray-300 rounded">
<option></option>
<option></option>
<option></option>
</select>
<button className="px-3 py-1 bg-green-600 text-white text-sm rounded hover:bg-green-700">
</button>
</div>
</div>
<div className="bg-white rounded-lg p-4">
<div className="flex justify-between items-center mb-2">
<h4 className="font-medium text-gray-800"></h4>
<span className="text-sm text-green-600"></span>
</div>
<p className="text-sm text-gray-600 mb-3"></p>
<div className="flex items-center space-x-4">
<input
type="number"
className="w-20 px-2 py-1 border border-gray-300 rounded"
defaultValue="2"
/>
<span className="text-sm text-gray-600"></span>
<button className="px-3 py-1 bg-green-600 text-white text-sm rounded hover:bg-green-700">
</button>
</div>
</div>
<div className="bg-white rounded-lg p-4">
<div className="flex justify-between items-center mb-2">
<h4 className="font-medium text-gray-800"></h4>
<span className="text-sm text-orange-600"></span>
</div>
<p className="text-sm text-gray-600 mb-3"></p>
<div className="flex items-center space-x-4">
<input
type="number"
className="w-20 px-2 py-1 border border-gray-300 rounded"
defaultValue="85"
/>
<span className="text-sm text-gray-600">% 线</span>
<button className="px-3 py-1 bg-green-600 text-white text-sm rounded hover:bg-green-700">
</button>
</div>
</div>
</div>
</div>
<div className="bg-orange-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-orange-900 mb-4">
📊
</h3>
<div className="space-y-4">
<div className="bg-white rounded-lg p-4">
<div className="flex justify-between items-center mb-2">
<h4 className="font-medium text-gray-800"></h4>
<span className="text-sm text-green-600"></span>
</div>
<p className="text-sm text-gray-600 mb-3"></p>
<div className="flex items-center space-x-4">
<select className="px-3 py-1 border border-gray-300 rounded">
<option></option>
<option></option>
<option></option>
</select>
<button className="px-3 py-1 bg-green-600 text-white text-sm rounded hover:bg-green-700">
</button>
</div>
</div>
<div className="bg-white rounded-lg p-4">
<div className="flex justify-between items-center mb-2">
<h4 className="font-medium text-gray-800"></h4>
<span className="text-sm text-green-600"></span>
</div>
<p className="text-sm text-gray-600 mb-3"></p>
<div className="flex items-center space-x-4">
<input
type="number"
className="w-20 px-2 py-1 border border-gray-300 rounded"
defaultValue="90"
/>
<span className="text-sm text-gray-600"></span>
<button className="px-3 py-1 bg-green-600 text-white text-sm rounded hover:bg-green-700">
</button>
</div>
</div>
</div>
</div>
</div>
<div className="mt-6 flex justify-end space-x-4">
<button className="px-6 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors">
</button>
<button className="px-6 py-2 bg-green-600 text-white rounded-md hover:bg-green-700 transition-colors">
</button>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,8 @@
export default function CategoryDictionaryPage() {
return (
<div className="p-6">
<h1 className="text-2xl font-bold mb-4"></h1>
<p></p>
</div>
)
}

View File

@@ -0,0 +1,8 @@
export default function DataDictionaryPage() {
return (
<div className="p-6">
<h1 className="text-2xl font-bold mb-4"></h1>
<p></p>
</div>
)
}

View File

@@ -0,0 +1,299 @@
import { Metadata } from 'next'
export const metadata: Metadata = {
title: '接口配置 - Crop-X 智慧农业管理系统',
description: '接口配置管理页面',
}
export default function InterfaceConfigurationPage() {
return (
<div className="space-y-6">
<div className="bg-white rounded-lg shadow p-6">
<h2 className="text-2xl font-bold text-gray-800 mb-6">
🔌
</h2>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
<div className="space-y-6">
<div className="bg-green-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-green-900 mb-4">
🌤
</h3>
<div className="space-y-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
API提供商
</label>
<select className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500">
<option></option>
<option></option>
<option>OpenWeatherMap</option>
</select>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
API密钥
</label>
<input
type="password"
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500"
defaultValue="••••••••••••••••"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<div className="flex items-center space-x-2">
<input
type="number"
className="w-20 px-2 py-1 border border-gray-300 rounded"
defaultValue="1000"
/>
<span className="text-sm text-gray-600">/</span>
</div>
</div>
<div className="flex items-center">
<input
type="checkbox"
className="h-4 w-4 text-green-600 focus:ring-green-500 border-gray-300 rounded"
defaultChecked
/>
<label className="ml-2 block text-sm text-gray-700">
</label>
</div>
<button className="w-full px-4 py-2 bg-green-600 text-white rounded-md hover:bg-green-700 transition-colors">
</button>
</div>
</div>
<div className="bg-blue-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-blue-900 mb-4">
📱
</h3>
<div className="space-y-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<select className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
<option></option>
<option></option>
<option></option>
</select>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
Access Key ID
</label>
<input
type="password"
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
defaultValue="••••••••••••••••"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
Access Key Secret
</label>
<input
type="password"
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
defaultValue="••••••••••••••••"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<input
type="text"
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
defaultValue="Crop-X农业"
/>
</div>
<button className="w-full px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors">
</button>
</div>
</div>
</div>
<div className="space-y-6">
<div className="bg-purple-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-purple-900 mb-4">
📧
</h3>
<div className="space-y-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
SMTP服务器
</label>
<input
type="text"
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-purple-500"
defaultValue="smtp.crop-x.com"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<input
type="number"
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-purple-500"
defaultValue="587"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<input
type="email"
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-purple-500"
defaultValue="noreply@crop-x.com"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<input
type="password"
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-purple-500"
defaultValue="••••••••••••••••"
/>
</div>
<div className="flex items-center">
<input
type="checkbox"
className="h-4 w-4 text-purple-600 focus:ring-purple-500 border-gray-300 rounded"
defaultChecked
/>
<label className="ml-2 block text-sm text-gray-700">
SSL/TLS加密
</label>
</div>
<button className="w-full px-4 py-2 bg-purple-600 text-white rounded-md hover:bg-purple-700 transition-colors">
</button>
</div>
</div>
<div className="bg-orange-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-orange-900 mb-4">
🗺
</h3>
<div className="space-y-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<select className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-orange-500">
<option></option>
<option></option>
<option></option>
</select>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
API Key
</label>
<input
type="password"
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-orange-500"
defaultValue="••••••••••••••••"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<div className="flex space-x-2">
<input
type="text"
className="flex-1 px-2 py-1 border border-gray-300 rounded"
placeholder="经度"
defaultValue="116.397428"
/>
<input
type="text"
className="flex-1 px-2 py-1 border border-gray-300 rounded"
placeholder="纬度"
defaultValue="39.90923"
/>
</div>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<select className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-orange-500">
<option>10 - </option>
<option>12 - </option>
<option>14 - </option>
<option>16 - </option>
</select>
</div>
<button className="w-full px-4 py-2 bg-orange-600 text-white rounded-md hover:bg-orange-700 transition-colors">
</button>
</div>
</div>
</div>
</div>
<div className="mt-6 bg-gray-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-gray-800 mb-4">
📊
</h3>
<div className="grid grid-cols-1 md:grid-cols-4 gap-4">
<div className="bg-white rounded-lg p-4 border-l-4 border-green-500">
<h4 className="font-medium text-gray-800 mb-2"></h4>
<div className="flex items-center justify-between">
<span className="text-sm text-green-600"></span>
<span className="text-xs text-gray-500">响应: 125ms</span>
</div>
</div>
<div className="bg-white rounded-lg p-4 border-l-4 border-green-500">
<h4 className="font-medium text-gray-800 mb-2"></h4>
<div className="flex items-center justify-between">
<span className="text-sm text-green-600"></span>
<span className="text-xs text-gray-500">响应: 89ms</span>
</div>
</div>
<div className="bg-white rounded-lg p-4 border-l-4 border-yellow-500">
<h4 className="font-medium text-gray-800 mb-2"></h4>
<div className="flex items-center justify-between">
<span className="text-sm text-yellow-600"></span>
<span className="text-xs text-gray-500">响应: 456ms</span>
</div>
</div>
<div className="bg-white rounded-lg p-4 border-l-4 border-green-500">
<h4 className="font-medium text-gray-800 mb-2"></h4>
<div className="flex items-center justify-between">
<span className="text-sm text-green-600"></span>
<span className="text-xs text-gray-500">响应: 67ms</span>
</div>
</div>
</div>
</div>
<div className="mt-6 flex justify-end space-x-4">
<button className="px-6 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50 transition-colors">
</button>
<button className="px-6 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors">
</button>
<button className="px-6 py-2 bg-green-600 text-white rounded-md hover:bg-green-700 transition-colors">
</button>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,22 @@
import { ReactNode } from 'react'
export default function SystemParametersLayout({
children,
}: {
children: ReactNode
}) {
return (
<div className="min-h-screen bg-gray-50">
<header className="bg-white shadow-sm border-b">
<div className="container mx-auto px-4 py-4">
<h1 className="text-2xl font-bold text-green-900">
🔧
</h1>
</div>
</header>
<main className="container mx-auto px-4 py-8">
{children}
</main>
</div>
)
}

View File

@@ -0,0 +1,103 @@
import Link from 'next/link'
import { Metadata } from 'next'
export const metadata: Metadata = {
title: '系统参数 - Crop-X 智慧农业管理系统',
description: '系统参数管理页面',
}
export default function SystemParametersPage() {
return (
<div className="space-y-6">
<div className="bg-white rounded-lg shadow p-6">
<h2 className="text-xl font-semibold text-gray-800 mb-4">
</h2>
<p className="text-gray-600 mb-6">
</p>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<Link
href="/central-config/system-parameters/basic-configuration"
className="block p-4 bg-green-50 rounded-lg hover:bg-green-100 transition-colors"
>
<h3 className="font-semibold text-green-900 mb-2">
</h3>
<p className="text-green-700 text-sm">
</p>
</Link>
<Link
href="/central-config/system-parameters/business-rule-settings"
className="block p-4 bg-blue-50 rounded-lg hover:bg-blue-100 transition-colors"
>
<h3 className="font-semibold text-blue-900 mb-2">
📋
</h3>
<p className="text-blue-700 text-sm">
</p>
</Link>
<Link
href="/central-config/system-parameters/interface-configuration"
className="block p-4 bg-purple-50 rounded-lg hover:bg-purple-100 transition-colors"
>
<h3 className="font-semibold text-purple-900 mb-2">
🔌
</h3>
<p className="text-purple-700 text-sm">
API接口和第三方服务配置
</p>
</Link>
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div className="bg-white rounded-lg shadow p-6">
<h3 className="text-lg font-semibold text-gray-800 mb-4">
📊
</h3>
<div className="space-y-2">
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="text-green-600 font-semibold">45 </span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="text-blue-600 font-semibold">23 </span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="text-purple-600 font-semibold">12 </span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="text-orange-600 font-semibold">3 </span>
</div>
</div>
</div>
<div className="bg-white rounded-lg shadow p-6">
<h3 className="text-lg font-semibold text-gray-800 mb-4">
🔧
</h3>
<div className="space-y-2">
<button className="w-full px-4 py-2 bg-green-600 text-white rounded hover:bg-green-700 transition-colors">
</button>
<button className="w-full px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors">
</button>
<button className="w-full px-4 py-2 bg-purple-600 text-white rounded hover:bg-purple-700 transition-colors">
</button>
</div>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,8 @@
export default function SystemSettingsPage() {
return (
<div className="p-6">
<h1 className="text-2xl font-bold mb-4"></h1>
<p></p>
</div>
)
}

View File

@@ -0,0 +1,8 @@
export default function AuditHistoryPage() {
return (
<div className="p-6">
<h1 className="text-2xl font-bold mb-4"></h1>
<p></p>
</div>
)
}

View File

@@ -0,0 +1,48 @@
'use client'
import { Card } from '@/components/ui/card'
import { Enterprise, AuditStatus } from '@/types/user-management'
interface AuditStatsCardProps {
enterprises: Enterprise[]
}
export function AuditStatsCard({ enterprises }: AuditStatsCardProps) {
const stats = [
{
label: '待审核',
value: enterprises.filter(e => e.auditStatus === 'pending').length,
color: 'text-yellow-600',
bg: 'bg-yellow-100',
},
{
label: '已通过',
value: enterprises.filter(e => e.auditStatus === 'approved').length,
color: 'text-green-600',
bg: 'bg-green-100',
},
{
label: '已驳回',
value: enterprises.filter(e => e.auditStatus === 'rejected').length,
color: 'text-red-600',
bg: 'bg-red-100',
},
{
label: '总企业数',
value: enterprises.length,
color: 'text-blue-600',
bg: 'bg-blue-100',
},
]
return (
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
{stats.map((stat, index) => (
<Card key={index} className="p-4">
<div className="text-sm text-muted-foreground">{stat.label}</div>
<div className={`mt-2 ${stat.color}`}>{stat.value}</div>
</Card>
))}
</div>
)
}

View File

@@ -0,0 +1,65 @@
'use client'
import { Label } from '@/components/ui/label'
import { Image as ImageIcon } from 'lucide-react'
import { Enterprise } from '@/types/user-management'
interface EnterpriseBankInfoProps {
enterprise: Enterprise
}
export function EnterpriseBankInfo({ enterprise }: EnterpriseBankInfoProps) {
return (
<div className="space-y-4">
<div className="grid grid-cols-2 gap-6">
<div>
<Label></Label>
<div className="field-value mt-1 p-2 bg-gray-50 rounded">
{enterprise.bankAccount ? (
<code className="text-sm font-mono">
{enterprise.bankAccount}
</code>
) : '-'}
</div>
</div>
<div>
<Label></Label>
<div className="field-value mt-1 p-2 bg-gray-50 rounded">
{enterprise.bankName || '-'}
</div>
</div>
<div className="col-span-2">
<Label></Label>
<div className="field-value mt-1 p-2 bg-gray-50 rounded">
{enterprise.bankFullName || '-'}
</div>
</div>
<div className="col-span-2">
<Label></Label>
<div className="field-value mt-1 p-2 bg-gray-50 rounded">
{enterprise.bankAddress || '-'}
</div>
</div>
<div className="col-span-2">
<Label></Label>
<div className="mt-2">
{enterprise.bankLicense ? (
<div className="border rounded-lg p-2 inline-block">
<img
src={enterprise.bankLicense}
alt="开户许可证"
className="w-64 h-auto"
/>
</div>
) : (
<div className="flex items-center gap-2 text-muted-foreground p-4 border-2 border-dashed rounded-lg">
<ImageIcon className="w-6 h-6" />
<span></span>
</div>
)}
</div>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,43 @@
'use client'
import { Label } from '@/components/ui/label'
import { Enterprise } from '@/types/user-management'
interface EnterpriseBasicInfoProps {
enterprise: Enterprise
}
export function EnterpriseBasicInfo({ enterprise }: EnterpriseBasicInfoProps) {
return (
<div className="space-y-4">
<div className="grid grid-cols-2 gap-6">
<div>
<Label></Label>
<div className="field-value mt-1 p-2 bg-gray-50 rounded">{enterprise.name}</div>
</div>
<div>
<Label></Label>
<div className="field-value mt-1 p-2 bg-gray-50 rounded">{enterprise.type}</div>
</div>
<div>
<Label></Label>
<div className="field-value mt-1 p-2 bg-gray-50 rounded">
{enterprise.province} {enterprise.city} {enterprise.district}
</div>
</div>
<div>
<Label></Label>
<div className="field-value mt-1 p-2 bg-gray-50 rounded">{enterprise.address}</div>
</div>
<div>
<Label></Label>
<div className="field-value mt-1 p-2 bg-gray-50 rounded">{enterprise.registrant}</div>
</div>
<div>
<Label></Label>
<div className="field-value mt-1 p-2 bg-gray-50 rounded">{enterprise.contactPhone}</div>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,192 @@
'use client'
import { useState } from 'react'
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogFooter } from '@/components/ui/dialog'
import { Button } from '@/components/ui/button'
import { Label } from '@/components/ui/label'
import { Textarea } from '@/components/ui/textarea'
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
import { ScrollArea } from '@/components/ui/scroll-area'
import { Card } from '@/components/ui/card'
import { Badge } from '@/components/ui/badge'
import { Building, FileText, CreditCard, User, CheckCircle, XCircle } from 'lucide-react'
import { Enterprise, AuditStatus } from '@/types/user-management'
import { EnterpriseBasicInfo } from './EnterpriseBasicInfo'
import { EnterpriseOtherInfo } from './EnterpriseOtherInfo'
import { EnterpriseBankInfo } from './EnterpriseBankInfo'
import { EnterpriseLegalInfo } from './EnterpriseLegalInfo'
interface EnterpriseDetailDialogProps {
open: boolean
onOpenChange: (open: boolean) => void
enterprise: Enterprise | null
onApprove: (auditReason: string) => void
onReject: (auditReason: string) => void
}
export function EnterpriseDetailDialog({
open,
onOpenChange,
enterprise,
onApprove,
onReject
}: EnterpriseDetailDialogProps) {
const [auditReason, setAuditReason] = useState('')
const getAuditStatusBadge = (status: AuditStatus) => {
switch (status) {
case 'pending':
return <Badge className="bg-yellow-100 text-yellow-700"></Badge>
case 'approved':
return <Badge className="bg-green-100 text-green-700"></Badge>
case 'rejected':
return <Badge className="bg-red-100 text-red-700"></Badge>
default:
return <Badge>{status}</Badge>
}
}
const handleApprove = () => {
onApprove(auditReason)
setAuditReason('')
}
const handleReject = () => {
onReject(auditReason)
setAuditReason('')
}
const handleClose = () => {
onOpenChange(false)
setAuditReason('')
}
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="max-w-5xl max-h-[90vh]">
<DialogHeader>
<div className="flex items-center justify-between pr-8">
<DialogTitle></DialogTitle>
{enterprise && getAuditStatusBadge(enterprise.auditStatus)}
</div>
<DialogDescription className="sr-only">
</DialogDescription>
</DialogHeader>
{enterprise && (
<ScrollArea className="max-h-[calc(90vh-200px)]">
<Tabs defaultValue="basic" className="space-y-4">
<TabsList className="grid grid-cols-4 w-full">
<TabsTrigger value="basic">
<Building className="w-4 h-4 mr-2" />
</TabsTrigger>
<TabsTrigger value="other">
<FileText className="w-4 h-4 mr-2" />
</TabsTrigger>
<TabsTrigger value="bank">
<CreditCard className="w-4 h-4 mr-2" />
</TabsTrigger>
<TabsTrigger value="legal">
<User className="w-4 h-4 mr-2" />
</TabsTrigger>
</TabsList>
<TabsContent value="basic">
<EnterpriseBasicInfo enterprise={enterprise} />
</TabsContent>
<TabsContent value="other">
<EnterpriseOtherInfo enterprise={enterprise} />
</TabsContent>
<TabsContent value="bank">
<EnterpriseBankInfo enterprise={enterprise} />
</TabsContent>
<TabsContent value="legal">
<EnterpriseLegalInfo enterprise={enterprise} />
</TabsContent>
</Tabs>
{/* 审核信息 */}
<div className="mt-6 pt-6 border-t">
<h4 className="mb-4 font-bold"></h4>
<Card className="p-6 bg-gray-50 border">
<div className="grid grid-cols-2 gap-x-8 gap-y-4">
<div>
<Label className="text-xs"></Label>
<div className="mt-1.5 text-base">
{new Date(enterprise.createdAt).toLocaleString('zh-CN')}
</div>
</div>
{enterprise.auditTime && (
<div>
<Label className="text-xs"></Label>
<div className="mt-1.5 text-base">
{new Date(enterprise.auditTime).toLocaleString('zh-CN')}
</div>
</div>
)}
{enterprise.auditor && (
<div>
<Label className="text-xs"></Label>
<div className="mt-1.5 text-base">
{enterprise.auditor}
</div>
</div>
)}
{enterprise.auditReason && (
<div className="col-span-2 pt-4 mt-2 border-t">
<Label className="text-xs"></Label>
<div className="mt-1.5 text-base">
{enterprise.auditReason}
</div>
</div>
)}
</div>
</Card>
{/* 审核操作区 - 仅待审核状态显示 */}
{enterprise.auditStatus === 'pending' && (
<div className="mt-6">
<Label></Label>
<Textarea
value={auditReason}
onChange={(e) => setAuditReason(e.target.value)}
rows={3}
placeholder="请填写审核意见(驳回时必填)..."
className="mt-2"
/>
</div>
)}
</div>
</ScrollArea>
)}
<DialogFooter className="border-t pt-4">
<Button variant="outline" onClick={handleClose}>
</Button>
{enterprise?.auditStatus === 'pending' && (
<>
<Button
variant="destructive"
onClick={handleReject}
>
<XCircle className="w-4 h-4 mr-2" />
</Button>
<Button onClick={handleApprove}>
<CheckCircle className="w-4 h-4 mr-2" />
</Button>
</>
)}
</DialogFooter>
</DialogContent>
</Dialog>
)
}

View File

@@ -0,0 +1,62 @@
'use client'
import { Label } from '@/components/ui/label'
import { Image as ImageIcon } from 'lucide-react'
import { Enterprise } from '@/types/user-management'
interface EnterpriseLegalInfoProps {
enterprise: Enterprise
}
export function EnterpriseLegalInfo({ enterprise }: EnterpriseLegalInfoProps) {
return (
<div className="space-y-4">
<div className="grid grid-cols-1 gap-6">
<div>
<Label></Label>
<div className="field-value mt-1 p-2 bg-gray-50 rounded">
{enterprise.legalPerson || '-'}
</div>
</div>
<div>
<Label></Label>
<div className="mt-2">
{enterprise.idCardFront ? (
<div className="border rounded-lg p-2 inline-block">
<img
src={enterprise.idCardFront}
alt="身份证正面"
className="w-80 h-auto"
/>
</div>
) : (
<div className="flex items-center gap-2 text-muted-foreground p-4 border-2 border-dashed rounded-lg">
<ImageIcon className="w-6 h-6" />
<span></span>
</div>
)}
</div>
</div>
<div>
<Label></Label>
<div className="mt-2">
{enterprise.idCardBack ? (
<div className="border rounded-lg p-2 inline-block">
<img
src={enterprise.idCardBack}
alt="身份证反面"
className="w-80 h-auto"
/>
</div>
) : (
<div className="flex items-center gap-2 text-muted-foreground p-4 border-2 border-dashed rounded-lg">
<ImageIcon className="w-6 h-6" />
<span></span>
</div>
)}
</div>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,75 @@
'use client'
import { Label } from '@/components/ui/label'
import { Image as ImageIcon } from 'lucide-react'
import { Enterprise } from '@/types/user-management'
interface EnterpriseOtherInfoProps {
enterprise: Enterprise
}
export function EnterpriseOtherInfo({ enterprise }: EnterpriseOtherInfoProps) {
return (
<div className="space-y-4">
<div className="grid grid-cols-2 gap-6">
<div>
<Label></Label>
<div className="field-value mt-1 p-2 bg-gray-50 rounded">
{enterprise.companySize || '-'}
</div>
</div>
<div>
<Label></Label>
<div className="field-value mt-1 p-2 bg-gray-50 rounded">
{enterprise.registeredCapital || '-'}
</div>
</div>
<div>
<Label></Label>
<div className="field-value mt-1 p-2 bg-gray-50 rounded">
{enterprise.establishmentDate || '-'}
</div>
</div>
<div>
<Label></Label>
<div className="field-value mt-1 p-2 bg-gray-50 rounded">
{enterprise.invoiceType || '-'}
</div>
</div>
<div className="col-span-2">
<Label></Label>
<div className="field-value mt-1 p-2 bg-gray-50 rounded">
<code className="text-sm font-mono">
{enterprise.socialCreditCode}
</code>
</div>
</div>
<div className="col-span-2">
<Label></Label>
<div className="field-value mt-1 p-2 bg-gray-50 rounded">
{enterprise.businessScope || '-'}
</div>
</div>
<div className="col-span-2">
<Label></Label>
<div className="mt-2">
{enterprise.businessLicense ? (
<div className="border rounded-lg p-2 inline-block">
<img
src={enterprise.businessLicense}
alt="营业执照"
className="w-64 h-auto"
/>
</div>
) : (
<div className="flex items-center gap-2 text-muted-foreground p-4 border-2 border-dashed rounded-lg">
<ImageIcon className="w-6 h-6" />
<span></span>
</div>
)}
</div>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,82 @@
'use client'
import { Card } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'
import { Eye } from 'lucide-react'
import { Enterprise, AuditStatus } from '@/types/user-management'
interface EnterpriseTableProps {
enterprises: Enterprise[]
onViewDetail: (enterprise: Enterprise) => void
}
export function EnterpriseTable({ enterprises, onViewDetail }: EnterpriseTableProps) {
const getAuditStatusBadge = (status: AuditStatus) => {
switch (status) {
case 'pending':
return <Badge className="bg-yellow-100 text-yellow-700"></Badge>
case 'approved':
return <Badge className="bg-green-100 text-green-700"></Badge>
case 'rejected':
return <Badge className="bg-red-100 text-red-700"></Badge>
default:
return <Badge>{status}</Badge>
}
}
return (
<Card>
<Table>
<TableHeader>
<TableRow>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
</TableRow>
</TableHeader>
<TableBody>
{enterprises.length === 0 ? (
<TableRow>
<TableCell colSpan={8} className="text-center text-muted-foreground py-8">
</TableCell>
</TableRow>
) : (
enterprises.map((enterprise) => (
<TableRow key={enterprise.id}>
<TableCell>{enterprise.name}</TableCell>
<TableCell className="text-muted-foreground">{enterprise.type}</TableCell>
<TableCell className="text-muted-foreground">
<code className="text-xs">{enterprise.socialCreditCode}</code>
</TableCell>
<TableCell>{enterprise.legalPerson || '-'}</TableCell>
<TableCell>{`${enterprise.province} ${enterprise.city}`}</TableCell>
<TableCell>{getAuditStatusBadge(enterprise.auditStatus)}</TableCell>
<TableCell className="text-muted-foreground">
{new Date(enterprise.createdAt).toLocaleDateString('zh-CN')}
</TableCell>
<TableCell>
<Button
variant="ghost"
size="sm"
onClick={() => onViewDetail(enterprise)}
>
<Eye className="w-4 h-4 mr-1" />
</Button>
</TableCell>
</TableRow>
))
)}
</TableBody>
</Table>
</Card>
)
}

View File

@@ -0,0 +1,49 @@
'use client'
import { Card } from '@/components/ui/card'
import { Input } from '@/components/ui/input'
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
import { Search } from 'lucide-react'
interface SearchAndFilterProps {
searchKeyword: string
onSearchChange: (value: string) => void
statusFilter: string
onStatusFilterChange: (value: string) => void
}
export function SearchAndFilter({
searchKeyword,
onSearchChange,
statusFilter,
onStatusFilterChange
}: SearchAndFilterProps) {
return (
<Card className="p-4">
<div className="flex gap-4">
<div className="flex-1">
<div className="relative">
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-muted-foreground" />
<Input
placeholder="搜索企业名称、信用代码、登记人..."
value={searchKeyword}
onChange={(e) => onSearchChange(e.target.value)}
className="pl-10"
/>
</div>
</div>
<Select value={statusFilter} onValueChange={onStatusFilterChange}>
<SelectTrigger className="w-40">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="all"></SelectItem>
<SelectItem value="pending"></SelectItem>
<SelectItem value="approved"></SelectItem>
<SelectItem value="rejected"></SelectItem>
</SelectContent>
</Select>
</div>
</Card>
)
}

View File

@@ -0,0 +1,8 @@
export { AuditStatsCard } from './AuditStatsCard'
export { SearchAndFilter } from './SearchAndFilter'
export { EnterpriseTable } from './EnterpriseTable'
export { EnterpriseDetailDialog } from './EnterpriseDetailDialog'
export { EnterpriseBasicInfo } from './EnterpriseBasicInfo'
export { EnterpriseOtherInfo } from './EnterpriseOtherInfo'
export { EnterpriseBankInfo } from './EnterpriseBankInfo'
export { EnterpriseLegalInfo } from './EnterpriseLegalInfo'

View File

@@ -0,0 +1,255 @@
'use client'
import { useState, useEffect } from 'react'
import { toast } from 'sonner'
import {
AuditStatsCard,
SearchAndFilter,
EnterpriseTable,
EnterpriseDetailDialog
} from './components'
import { Enterprise, AuditStatus } from '@/types/user-management'
export default function EnterpriseAuditPage() {
const [enterprises, setEnterprises] = useState<Enterprise[]>([])
const [searchKeyword, setSearchKeyword] = useState('')
const [statusFilter, setStatusFilter] = useState<string>('all')
const [showDetailDialog, setShowDetailDialog] = useState(false)
const [selectedEnterprise, setSelectedEnterprise] = useState<Enterprise | null>(null)
useEffect(() => {
loadEnterprises()
}, [])
const loadEnterprises = () => {
const data = localStorage.getItem('smart_agriculture_enterprises')
if (data) {
setEnterprises(JSON.parse(data))
} else {
// 初始化示例数据
const mockEnterprises: Enterprise[] = [
{
id: 'ent-1',
name: '绿野农业科技有限公司',
type: '有限责任公司',
province: '北京市',
city: '海淀区',
district: '中关村街道',
companySize: '50-200人',
registeredCapital: '1000万元',
establishmentDate: '2020-03-15',
invoiceType: '增值税专用发票',
socialCreditCode: '91110000123456789X',
businessScope: '农业技术开发、技术咨询、技术服务;销售机械设备、电子产品。',
bankAccount: '1234567890123456789',
bankName: '中国工商银行',
bankFullName: '中国工商银行股份有限公司北京中关村支行',
bankAddress: '北京市海淀区中关村大街1号',
legalPerson: '张伟',
registrant: '张经理',
contactPhone: '13800138001',
address: '北京市海淀区中关村大街1号科技大厦',
status: 'active',
auditStatus: 'pending',
createdAt: '2024-10-10T08:00:00',
updatedAt: '2024-10-10T08:00:00',
},
{
id: 'ent-2',
name: '丰收现代农业集团',
type: '股份有限公司',
province: '江苏省',
city: '南京市',
district: '江宁区',
companySize: '200-500人',
registeredCapital: '5000万元',
establishmentDate: '2018-06-20',
invoiceType: '增值税专用发票',
socialCreditCode: '91320000987654321Y',
businessScope: '现代农业种植、农产品加工与销售、农业技术推广服务。',
bankAccount: '9876543210987654321',
bankName: '中国农业银行',
bankFullName: '中国农业银行股份有限公司南京江宁支行',
bankAddress: '江苏省南京市江宁区农业大道88号',
legalPerson: '李明',
registrant: '李总',
contactPhone: '13900139002',
address: '江苏省南京市江宁区农业大道88号',
status: 'active',
auditStatus: 'approved',
auditTime: '2024-10-08T14:30:00',
auditor: '系统管理员',
createdAt: '2024-10-05T10:00:00',
updatedAt: '2024-10-08T14:30:00',
},
{
id: 'ent-3',
name: '金穗农机服务中心',
type: '个人独资企业',
province: '山东省',
city: '济南市',
district: '历城区',
companySize: '1-50人',
registeredCapital: '200万元',
establishmentDate: '2021-09-10',
invoiceType: '增值税普通发票',
socialCreditCode: '91370000456789012Z',
businessScope: '农业机械租赁、维修服务、农机作业服务。',
bankAccount: '5555666677778888',
bankName: '中国建设银行',
bankFullName: '中国建设银行股份有限公司济南历城支行',
bankAddress: '山东省济南市历城区农机路66号',
legalPerson: '王刚',
registrant: '王主任',
contactPhone: '13700137003',
address: '山东省济南市历城区农机路66号',
status: 'inactive',
auditStatus: 'rejected',
auditReason: '资质材料不完整,请补充营业执照副本和法人身份证复印件',
auditTime: '2024-10-09T16:00:00',
auditor: '系统管理员',
createdAt: '2024-10-06T09:00:00',
updatedAt: '2024-10-09T16:00:00',
},
];
localStorage.setItem('smart_agriculture_enterprises', JSON.stringify(mockEnterprises));
setEnterprises(mockEnterprises);
}
};
const filteredEnterprises = enterprises.filter(ent => {
const matchKeyword = !searchKeyword ||
ent.name.includes(searchKeyword) ||
ent.socialCreditCode.includes(searchKeyword) ||
ent.registrant.includes(searchKeyword);
const matchStatus = statusFilter === 'all' || ent.auditStatus === statusFilter;
return matchKeyword && matchStatus;
});
const handleViewDetail = (enterprise: Enterprise) => {
setSelectedEnterprise(enterprise);
setShowDetailDialog(true);
};
const handleApprove = (auditReason: string) => {
if (!selectedEnterprise) return;
const now = new Date().toISOString();
const updated = enterprises.map(ent =>
ent.id === selectedEnterprise.id
? {
...ent,
auditStatus: 'approved' as AuditStatus,
status: 'active' as const,
auditTime: now,
auditor: '系统管理员',
auditReason: auditReason || undefined,
updatedAt: now,
}
: ent
);
// 创建审核历史记录
const auditRecords = JSON.parse(localStorage.getItem('smart_agriculture_audit_records') || '[]');
const newRecord = {
id: `audit-${Date.now()}`,
enterpriseId: selectedEnterprise.id,
enterpriseName: selectedEnterprise.name,
auditType: 'register',
submitTime: selectedEnterprise.createdAt,
auditTime: now,
auditor: '系统管理员',
result: 'approved',
remarks: auditReason || '审核通过',
};
auditRecords.push(newRecord);
localStorage.setItem('smart_agriculture_audit_records', JSON.stringify(auditRecords));
setEnterprises(updated);
localStorage.setItem('smart_agriculture_enterprises', JSON.stringify(updated));
setShowDetailDialog(false);
toast.success('审核通过');
};
const handleReject = (auditReason: string) => {
if (!selectedEnterprise) return;
if (!auditReason.trim()) {
toast.error('请填写驳回原因');
return;
}
const now = new Date().toISOString();
const updated = enterprises.map(ent =>
ent.id === selectedEnterprise.id
? {
...ent,
auditStatus: 'rejected' as AuditStatus,
status: 'inactive' as const,
auditTime: now,
auditor: '系统管理员',
auditReason: auditReason,
updatedAt: now,
}
: ent
);
// 创建审核历史记录
const auditRecords = JSON.parse(localStorage.getItem('smart_agriculture_audit_records') || '[]');
const newRecord = {
id: `audit-${Date.now()}`,
enterpriseId: selectedEnterprise.id,
enterpriseName: selectedEnterprise.name,
auditType: 'register',
submitTime: selectedEnterprise.createdAt,
auditTime: now,
auditor: '系统管理员',
result: 'rejected',
reason: auditReason,
remarks: '审核驳回',
};
auditRecords.push(newRecord);
localStorage.setItem('smart_agriculture_audit_records', JSON.stringify(auditRecords));
setEnterprises(updated);
localStorage.setItem('smart_agriculture_enterprises', JSON.stringify(updated));
setShowDetailDialog(false);
toast.success('已驳回');
};
return (
<div className="space-y-6 p-6">
<div>
<h2 className="text-green-800"></h2>
<p className="text-muted-foreground"></p>
</div>
{/* 统计卡片 */}
<AuditStatsCard enterprises={enterprises} />
{/* 搜索和筛选 */}
<SearchAndFilter
searchKeyword={searchKeyword}
onSearchChange={setSearchKeyword}
statusFilter={statusFilter}
onStatusFilterChange={setStatusFilter}
/>
{/* 企业列表 */}
<EnterpriseTable
enterprises={filteredEnterprises}
onViewDetail={handleViewDetail}
/>
{/* 详情审核对话框 */}
<EnterpriseDetailDialog
open={showDetailDialog}
onOpenChange={setShowDetailDialog}
enterprise={selectedEnterprise}
onApprove={handleApprove}
onReject={handleReject}
/>
</div>
)
}

View File

@@ -0,0 +1,8 @@
export default function EnterpriseInfoPage() {
return (
<div className="p-6">
<h1 className="text-2xl font-bold mb-4"></h1>
<p></p>
</div>
)
}

View File

@@ -0,0 +1,22 @@
import { ReactNode } from 'react'
export default function TenantManagementLayout({
children,
}: {
children: ReactNode
}) {
return (
<div className="min-h-screen bg-gray-50">
<header className="bg-white shadow-sm border-b">
<div className="container mx-auto px-4 py-4">
<h1 className="text-2xl font-bold text-green-900">
🏢
</h1>
</div>
</header>
<main className="container mx-auto px-4 py-8">
{children}
</main>
</div>
)
}

View File

@@ -0,0 +1,163 @@
import Link from 'next/link'
import { Metadata } from 'next'
export const metadata: Metadata = {
title: '租户管理 - Crop-X 智慧农业管理系统',
description: '租户管理页面',
}
export default function TenantManagementPage() {
return (
<div className="space-y-6">
<div className="bg-white rounded-lg shadow p-6">
<h2 className="text-xl font-semibold text-gray-800 mb-4">
</h2>
<p className="text-gray-600 mb-6">
</p>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<Link
href="/central-config/tenant-management/tenant-creation"
className="block p-4 bg-green-50 rounded-lg hover:bg-green-100 transition-colors"
>
<h3 className="font-semibold text-green-900 mb-2">
</h3>
<p className="text-green-700 text-sm">
</p>
</Link>
<Link
href="/central-config/tenant-management/tenant-configuration"
className="block p-4 bg-blue-50 rounded-lg hover:bg-blue-100 transition-colors"
>
<h3 className="font-semibold text-blue-900 mb-2">
</h3>
<p className="text-blue-700 text-sm">
</p>
</Link>
<Link
href="/central-config/tenant-management/tenant-authorization"
className="block p-4 bg-purple-50 rounded-lg hover:bg-purple-100 transition-colors"
>
<h3 className="font-semibold text-purple-900 mb-2">
🔐
</h3>
<p className="text-purple-700 text-sm">
访
</p>
</Link>
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div className="bg-white rounded-lg shadow p-6">
<h3 className="text-lg font-semibold text-gray-800 mb-4">
📊
</h3>
<div className="space-y-2">
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="text-green-600 font-semibold">12 </span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="text-blue-600 font-semibold">10 </span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="text-orange-600 font-semibold">2 </span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="text-purple-600 font-semibold">1,248 </span>
</div>
</div>
</div>
<div className="bg-white rounded-lg shadow p-6">
<h3 className="text-lg font-semibold text-gray-800 mb-4">
🔧
</h3>
<div className="space-y-2">
<button className="w-full px-4 py-2 bg-green-600 text-white rounded hover:bg-green-700 transition-colors">
</button>
<button className="w-full px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors">
</button>
<button className="w-full px-4 py-2 bg-purple-600 text-white rounded hover:bg-purple-700 transition-colors">
</button>
</div>
</div>
</div>
<div className="bg-white rounded-lg shadow p-6">
<h3 className="text-lg font-semibold text-gray-800 mb-4">
📋
</h3>
<div className="overflow-x-auto">
<table className="min-w-full divide-y divide-gray-200">
<thead className="bg-gray-50">
<tr>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
ID
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
</th>
</tr>
</thead>
<tbody className="bg-white divide-y divide-gray-200">
{[
{ id: 'T001', name: '绿色农业合作社', status: 'active', time: '2024-10-20 10:30' },
{ id: 'T002', name: '丰收农场', status: 'active', time: '2024-10-19 14:15' },
{ id: 'T003', name: '智慧农业科技', status: 'pending', time: '2024-10-18 09:45' },
{ id: 'T004', name: '现代农业示范园', status: 'active', time: '2024-10-17 16:20' },
].map((tenant) => (
<tr key={tenant.id}>
<td className="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">
{tenant.id}
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
{tenant.name}
</td>
<td className="px-6 py-4 whitespace-nowrap">
<span className={`px-2 py-1 text-xs font-medium rounded-full ${
tenant.status === 'active' ? 'bg-green-100 text-green-800' : 'bg-yellow-100 text-yellow-800'
}`}>
{tenant.status === 'active' ? '活跃' : '待审核'}
</span>
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
{tenant.time}
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm font-medium">
<button className="text-blue-600 hover:text-blue-900 mr-3"></button>
<button className="text-red-600 hover:text-red-900"></button>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,8 @@
export default function PlatformUserManagementPage() {
return (
<div className="p-6">
<h1 className="text-2xl font-bold mb-4"></h1>
<p></p>
</div>
)
}

View File

@@ -0,0 +1,243 @@
import { Metadata } from 'next'
export const metadata: Metadata = {
title: '租户授权 - Crop-X 智慧农业管理系统',
description: '租户授权管理页面',
}
export default function TenantAuthorizationPage() {
return (
<div className="space-y-6">
<div className="bg-white rounded-lg shadow p-6">
<h2 className="text-2xl font-bold text-gray-800 mb-6">
🔐
</h2>
<div className="mb-6">
<div className="flex items-center space-x-4">
<select className="px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
<option></option>
<option>T001 - 绿</option>
<option>T002 - </option>
<option>T003 - </option>
<option>T004 - </option>
</select>
<button className="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors">
</button>
</div>
</div>
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
<div className="lg:col-span-2">
<div className="bg-green-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-green-900 mb-4">
📋
</h3>
<div className="space-y-4">
{[
{ module: '智能农机管理', code: 'machinery', enabled: true, features: ['档案管理', '实时监控', '任务调度', '数据分析'] },
{ module: '地块信息管理', code: 'land', enabled: true, features: ['地块档案', '地图管理', '空间分析', '环境监测'] },
{ module: '农事操作管理', code: 'farming', enabled: true, features: ['农事计划', '任务管理', '操作执行', '知识库'] },
{ module: '农业资产管理', code: 'asset', enabled: false, features: ['基础信息', '采购管理', '库存管理', '物资领用'] },
{ module: 'AI作物模型', code: 'ai-model', enabled: false, features: ['数据感知', '模型应用', '智能决策', '监控中心'] },
{ module: '水肥控制', code: 'irrigation', enabled: true, features: ['水肥机管理', '智能灌溉', '施肥配方', '实时监测'] },
{ module: '中心配置', code: 'config', enabled: false, features: ['租户管理', '用户管理', '系统参数', '消息中心'] },
].map((item, index) => (
<div key={index} className="bg-white rounded-lg p-4">
<div className="flex justify-between items-center mb-3">
<div className="flex items-center">
<input
type="checkbox"
className="h-4 w-4 text-green-600 focus:ring-green-500 border-gray-300 rounded mr-3"
defaultChecked={item.enabled}
/>
<h4 className="font-medium text-gray-800">{item.module}</h4>
<span className="ml-2 text-xs text-gray-500 bg-gray-100 px-2 py-1 rounded">
{item.code}
</span>
</div>
<button className="text-blue-600 hover:text-blue-800 text-sm">
</button>
</div>
<div className="grid grid-cols-2 md:grid-cols-4 gap-2">
{item.features.map((feature, featureIndex) => (
<label key={featureIndex} className="flex items-center text-sm">
<input
type="checkbox"
className="h-3 w-3 text-green-600 focus:ring-green-500 border-gray-300 rounded mr-2"
defaultChecked={item.enabled}
/>
<span className={item.enabled ? 'text-gray-700' : 'text-gray-400'}>
{feature}
</span>
</label>
))}
</div>
</div>
))}
</div>
</div>
</div>
<div className="space-y-6">
<div className="bg-blue-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-blue-900 mb-4">
🔑 API访问权限
</h3>
<div className="space-y-4">
<div className="flex items-center justify-between">
<span className="text-gray-700">API访问</span>
<span className="text-sm text-green-600"></span>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
API Key
</label>
<div className="flex space-x-2">
<input
type="password"
className="flex-1 px-3 py-2 border border-gray-300 rounded-md bg-gray-50"
value="••••••••••••••••••••••••••••••••"
readOnly
/>
<button className="px-3 py-1 bg-blue-600 text-white text-sm rounded hover:bg-blue-700">
</button>
</div>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
访
</label>
<select className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
<option>1000/</option>
<option>5000/</option>
<option>10000/</option>
<option></option>
</select>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
IP白名单
</label>
<textarea
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
rows={3}
placeholder="输入允许访问的IP地址每行一个"
></textarea>
</div>
</div>
</div>
<div className="bg-purple-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-purple-900 mb-4">
📊
</h3>
<div className="space-y-2">
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="font-semibold text-green-600">4 / 7</span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="font-semibold text-blue-600">18 / 28</span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600">API权限</span>
<span className="font-semibold text-purple-600"></span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="text-sm text-gray-500">2024-10-20 15:30</span>
</div>
</div>
</div>
<div className="bg-orange-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-orange-900 mb-4">
</h3>
<div className="space-y-2">
<button className="w-full px-4 py-2 bg-green-600 text-white rounded-md hover:bg-green-700 transition-colors">
</button>
<button className="w-full px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors">
</button>
<button className="w-full px-4 py-2 bg-purple-600 text-white rounded-md hover:bg-purple-700 transition-colors">
</button>
</div>
</div>
</div>
</div>
<div className="mt-6 bg-yellow-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-yellow-900 mb-4">
📋
</h3>
<div className="overflow-x-auto">
<table className="min-w-full divide-y divide-gray-200">
<thead className="bg-yellow-100">
<tr>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-700 uppercase tracking-wider">
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-700 uppercase tracking-wider">
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-700 uppercase tracking-wider">
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-700 uppercase tracking-wider">
</th>
</tr>
</thead>
<tbody className="bg-white divide-y divide-gray-200">
{[
{ time: '2024-10-20 15:30', type: '模块授权', content: '启用智能农机管理模块', operator: 'admin' },
{ time: '2024-10-20 14:15', type: '权限调整', content: '关闭农业资产管理模块', operator: 'admin' },
{ time: '2024-10-20 10:45', type: 'API配置', content: '重置API密钥', operator: 'admin' },
{ time: '2024-10-19 16:20', type: '权限调整', content: '启用水肥控制模块', operator: 'admin' },
].map((record, index) => (
<tr key={index}>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
{record.time}
</td>
<td className="px-6 py-4 whitespace-nowrap">
<span className={`px-2 py-1 text-xs font-medium rounded-full ${
record.type === '模块授权' ? 'bg-green-100 text-green-800' :
record.type === '权限调整' ? 'bg-blue-100 text-blue-800' :
'bg-purple-100 text-purple-800'
}`}>
{record.type}
</span>
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
{record.content}
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
{record.operator}
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
<div className="mt-6 flex justify-end space-x-4">
<button className="px-6 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50 transition-colors">
</button>
<button className="px-6 py-2 bg-green-600 text-white rounded-md hover:bg-green-700 transition-colors">
</button>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,287 @@
import { Metadata } from 'next'
export const metadata: Metadata = {
title: '租户配置 - Crop-X 智慧农业管理系统',
description: '租户配置管理页面',
}
export default function TenantConfigurationPage() {
return (
<div className="space-y-6">
<div className="bg-white rounded-lg shadow p-6">
<h2 className="text-2xl font-bold text-gray-800 mb-6">
</h2>
<div className="mb-6">
<div className="flex items-center space-x-4">
<select className="px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
<option></option>
<option>T001 - 绿</option>
<option>T002 - </option>
<option>T003 - </option>
<option>T004 - </option>
</select>
<button className="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors">
</button>
</div>
</div>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
<div className="space-y-6">
<div className="bg-green-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-green-900 mb-4">
</h3>
<div className="space-y-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<input
type="text"
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500"
defaultValue="绿色农业合作社"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
Logo
</label>
<div className="flex items-center space-x-4">
<div className="w-16 h-16 bg-gray-200 rounded-lg flex items-center justify-center">
<span className="text-gray-500">Logo</span>
</div>
<button className="px-3 py-1 bg-green-600 text-white text-sm rounded hover:bg-green-700">
Logo
</button>
<button className="px-3 py-1 border border-gray-300 text-sm rounded hover:bg-gray-50">
</button>
</div>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<input
type="text"
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500"
defaultValue="张三"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<input
type="tel"
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500"
defaultValue="13800138000"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<select className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500">
<option></option>
<option></option>
<option></option>
</select>
</div>
</div>
</div>
<div className="bg-blue-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-blue-900 mb-4">
</h3>
<div className="space-y-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<input
type="number"
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
defaultValue="100"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
(GB)
</label>
<input
type="number"
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
defaultValue="50"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
()
</label>
<input
type="number"
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
defaultValue="365"
/>
</div>
<div className="flex items-center">
<input
type="checkbox"
className="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded"
defaultChecked
/>
<label className="ml-2 block text-sm text-gray-700">
</label>
</div>
<div className="flex items-center">
<input
type="checkbox"
className="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded"
defaultChecked
/>
<label className="ml-2 block text-sm text-gray-700">
API访问
</label>
</div>
</div>
</div>
</div>
<div className="space-y-6">
<div className="bg-purple-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-purple-900 mb-4">
</h3>
<div className="space-y-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<select className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-purple-500">
<option></option>
<option>绿</option>
<option></option>
<option></option>
</select>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<select className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-purple-500">
<option></option>
<option>English</option>
<option></option>
</select>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<select className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-purple-500">
<option>Asia/Shanghai (UTC+8)</option>
<option>Asia/Beijing (UTC+8)</option>
<option>UTC (UTC+0)</option>
</select>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<select className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-purple-500">
<option>YYYY-MM-DD</option>
<option>YYYY/MM/DD</option>
<option>DD/MM/YYYY</option>
<option>MM/DD/YYYY</option>
</select>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<select className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-purple-500">
<option>1,234.56</option>
<option>1.234,56</option>
<option>1234.56</option>
</select>
</div>
</div>
</div>
<div className="bg-orange-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-orange-900 mb-4">
</h3>
<div className="space-y-4">
<div className="flex items-center">
<input
type="checkbox"
className="h-4 w-4 text-orange-600 focus:ring-orange-500 border-gray-300 rounded"
defaultChecked
/>
<label className="ml-2 block text-sm text-gray-700">
</label>
</div>
<div className="flex items-center">
<input
type="checkbox"
className="h-4 w-4 text-orange-600 focus:ring-orange-500 border-gray-300 rounded"
defaultChecked
/>
<label className="ml-2 block text-sm text-gray-700">
</label>
</div>
<div className="flex items-center">
<input
type="checkbox"
className="h-4 w-4 text-orange-600 focus:ring-orange-500 border-gray-300 rounded"
/>
<label className="ml-2 block text-sm text-gray-700">
</label>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<input
type="email"
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-orange-500"
defaultValue="admin@green-agri.com"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<input
type="tel"
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-orange-500"
defaultValue="13800138000"
/>
</div>
</div>
</div>
</div>
</div>
<div className="mt-6 flex justify-end space-x-4">
<button className="px-6 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50 transition-colors">
</button>
<button className="px-6 py-2 bg-green-600 text-white rounded-md hover:bg-green-700 transition-colors">
</button>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,221 @@
import { Metadata } from 'next'
export const metadata: Metadata = {
title: '租户创建 - Crop-X 智慧农业管理系统',
description: '租户创建管理页面',
}
export default function TenantCreationPage() {
return (
<div className="space-y-6">
<div className="bg-white rounded-lg shadow p-6">
<h2 className="text-2xl font-bold text-gray-800 mb-6">
</h2>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
<div className="bg-green-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-green-900 mb-4">
</h3>
<form className="space-y-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
<span className="text-red-500">*</span>
</label>
<input
type="text"
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500"
placeholder="请输入租户名称"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
<span className="text-red-500">*</span>
</label>
<input
type="text"
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500"
placeholder="请输入租户代码(英文)"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
<span className="text-red-500">*</span>
</label>
<input
type="text"
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500"
placeholder="请输入联系人姓名"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
<span className="text-red-500">*</span>
</label>
<input
type="tel"
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500"
placeholder="请输入联系电话"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
<span className="text-red-500">*</span>
</label>
<input
type="email"
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500"
placeholder="请输入电子邮箱"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
<span className="text-red-500">*</span>
</label>
<select className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500">
<option></option>
<option></option>
<option></option>
<option></option>
<option></option>
<option></option>
<option></option>
</select>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<select className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500">
<option></option>
<option></option>
<option></option>
<option>广</option>
<option></option>
<option></option>
<option></option>
</select>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<textarea
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500"
rows={3}
placeholder="请输入详细地址"
></textarea>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<textarea
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500"
rows={3}
placeholder="请输入备注说明"
></textarea>
</div>
<div className="flex items-center">
<input
type="checkbox"
className="h-4 w-4 text-green-600 focus:ring-green-500 border-gray-300 rounded"
defaultChecked
/>
<label className="ml-2 block text-sm text-gray-700">
</label>
</div>
<div className="flex space-x-4">
<button
type="submit"
className="flex-1 px-4 py-2 bg-green-600 text-white rounded-md hover:bg-green-700 transition-colors"
>
</button>
<button
type="button"
className="flex-1 px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50 transition-colors"
>
</button>
</div>
</form>
</div>
<div className="space-y-6">
<div className="bg-blue-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-blue-900 mb-4">
📋
</h3>
<div className="space-y-3 text-sm text-gray-700">
<div className="flex items-start">
<div className="w-2 h-2 bg-blue-500 rounded-full mt-1.5 mr-3"></div>
<p>2-50</p>
</div>
<div className="flex items-start">
<div className="w-2 h-2 bg-blue-500 rounded-full mt-1.5 mr-3"></div>
<p>3-20</p>
</div>
<div className="flex items-start">
<div className="w-2 h-2 bg-blue-500 rounded-full mt-1.5 mr-3"></div>
<p></p>
</div>
<div className="flex items-start">
<div className="w-2 h-2 bg-blue-500 rounded-full mt-1.5 mr-3"></div>
<p></p>
</div>
<div className="flex items-start">
<div className="w-2 h-2 bg-blue-500 rounded-full mt-1.5 mr-3"></div>
<p></p>
</div>
</div>
</div>
<div className="bg-purple-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-purple-900 mb-4">
</h3>
<div className="space-y-2">
<button className="w-full px-4 py-2 bg-purple-600 text-white rounded-md hover:bg-purple-700 transition-colors">
📥
</button>
<button className="w-full px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors">
📄
</button>
<button className="w-full px-4 py-2 bg-green-600 text-white rounded-md hover:bg-green-700 transition-colors">
📊
</button>
</div>
</div>
<div className="bg-yellow-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-yellow-900 mb-4">
📈
</h3>
<div className="space-y-2">
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="font-semibold text-green-600">3 </span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="font-semibold text-orange-600">2 </span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="font-semibold text-blue-600">1 </span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="font-semibold text-purple-600">100%</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,8 @@
export default function EmployeeManagementPage() {
return (
<div className="p-6">
<h1 className="text-2xl font-bold mb-4"></h1>
<p></p>
</div>
)
}

View File

@@ -0,0 +1,22 @@
import { ReactNode } from 'react'
export default function UserManagementLayout({
children,
}: {
children: ReactNode
}) {
return (
<div className="min-h-screen bg-gray-50">
<header className="bg-white shadow-sm border-b">
<div className="container mx-auto px-4 py-4">
<h1 className="text-2xl font-bold text-green-900">
👥
</h1>
</div>
</header>
<main className="container mx-auto px-4 py-8">
{children}
</main>
</div>
)
}

View File

@@ -0,0 +1,8 @@
export default function MenuManagementPage() {
return (
<div className="p-6">
<h1 className="text-2xl font-bold mb-4"></h1>
<p></p>
</div>
)
}

View File

@@ -0,0 +1,178 @@
import Link from 'next/link'
import { Metadata } from 'next'
export const metadata: Metadata = {
title: '用户管理 - Crop-X 智慧农业管理系统',
description: '用户管理页面',
}
export default function UserManagementPage() {
return (
<div className="space-y-6">
<div className="bg-white rounded-lg shadow p-6">
<h2 className="text-xl font-semibold text-gray-800 mb-4">
</h2>
<p className="text-gray-600 mb-6">
</p>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<Link
href="/central-config/user-management/user-account-management"
className="block p-4 bg-green-50 rounded-lg hover:bg-green-100 transition-colors"
>
<h3 className="font-semibold text-green-900 mb-2">
👤
</h3>
<p className="text-green-700 text-sm">
</p>
</Link>
<Link
href="/central-config/user-management/role-permission-management"
className="block p-4 bg-blue-50 rounded-lg hover:bg-blue-100 transition-colors"
>
<h3 className="font-semibold text-blue-900 mb-2">
🔐
</h3>
<p className="text-blue-700 text-sm">
</p>
</Link>
<Link
href="/central-config/user-management/user-behavior-tracking"
className="block p-4 bg-purple-50 rounded-lg hover:bg-purple-100 transition-colors"
>
<h3 className="font-semibold text-purple-900 mb-2">
📊
</h3>
<p className="text-purple-700 text-sm">
</p>
</Link>
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div className="bg-white rounded-lg shadow p-6">
<h3 className="text-lg font-semibold text-gray-800 mb-4">
📊
</h3>
<div className="space-y-2">
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="text-green-600 font-semibold">248 </span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="text-blue-600 font-semibold">186 </span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="text-purple-600 font-semibold">12 </span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="text-orange-600 font-semibold">5 </span>
</div>
</div>
</div>
<div className="bg-white rounded-lg shadow p-6">
<h3 className="text-lg font-semibold text-gray-800 mb-4">
🔧
</h3>
<div className="space-y-2">
<button className="w-full px-4 py-2 bg-green-600 text-white rounded hover:bg-green-700 transition-colors">
</button>
<button className="w-full px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors">
</button>
<button className="w-full px-4 py-2 bg-purple-600 text-white rounded hover:bg-purple-700 transition-colors">
</button>
</div>
</div>
</div>
<div className="bg-white rounded-lg shadow p-6">
<h3 className="text-lg font-semibold text-gray-800 mb-4">
📋
</h3>
<div className="overflow-x-auto">
<table className="min-w-full divide-y divide-gray-200">
<thead className="bg-gray-50">
<tr>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
</th>
</tr>
</thead>
<tbody className="bg-white divide-y divide-gray-200">
{[
{ username: 'admin', name: '系统管理员', role: '超级管理员', tenant: '系统', lastLogin: '2024-10-20 15:30', status: 'active' },
{ username: 'zhangsan', name: '张三', role: '农场管理员', tenant: '绿色农业合作社', lastLogin: '2024-10-20 14:15', status: 'active' },
{ username: 'lisi', name: '李四', role: '农机操作员', tenant: '丰收农场', lastLogin: '2024-10-20 12:45', status: 'active' },
{ username: 'wangwu', name: '王五', role: '技术员', tenant: '智慧农业科技', lastLogin: '2024-10-19 16:20', status: 'inactive' },
{ username: 'zhaoliu', name: '赵六', role: '观察员', tenant: '现代农业示范园', lastLogin: '2024-10-18 09:30', status: 'pending' },
].map((user, index) => (
<tr key={index}>
<td className="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">
{user.username}
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
{user.name}
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
{user.role}
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
{user.tenant}
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
{user.lastLogin}
</td>
<td className="px-6 py-4 whitespace-nowrap">
<span className={`px-2 py-1 text-xs font-medium rounded-full ${
user.status === 'active' ? 'bg-green-100 text-green-800' :
user.status === 'inactive' ? 'bg-gray-100 text-gray-800' :
'bg-yellow-100 text-yellow-800'
}`}>
{user.status === 'active' ? '活跃' : user.status === 'inactive' ? '未激活' : '待审核'}
</span>
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm font-medium">
<button className="text-blue-600 hover:text-blue-900 mr-3"></button>
<button className="text-red-600 hover:text-red-900"></button>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,8 @@
export default function PermissionConfigPage() {
return (
<div className="p-6">
<h1 className="text-2xl font-bold mb-4"></h1>
<p></p>
</div>
)
}

View File

@@ -0,0 +1,8 @@
export default function RoleManagementPage() {
return (
<div className="p-6">
<h1 className="text-2xl font-bold mb-4"></h1>
<p></p>
</div>
)
}

View File

@@ -0,0 +1,245 @@
import { Metadata } from 'next'
export const metadata: Metadata = {
title: '角色权限管理 - Crop-X 智慧农业管理系统',
description: '角色权限管理页面',
}
export default function RolePermissionManagementPage() {
return (
<div className="space-y-6">
<div className="bg-white rounded-lg shadow p-6">
<h2 className="text-2xl font-bold text-gray-800 mb-6">
🔐
</h2>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
<div className="space-y-6">
<div className="bg-green-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-green-900 mb-4">
🎭
</h3>
<div className="space-y-4">
<div className="flex justify-between items-center mb-4">
<h4 className="font-medium text-gray-800"></h4>
<button className="px-3 py-1 bg-green-600 text-white text-sm rounded hover:bg-green-700">
</button>
</div>
{[
{ name: '超级管理员', code: 'super_admin', users: 3, description: '拥有系统所有权限' },
{ name: '农场管理员', code: 'farm_admin', users: 45, description: '管理农场整体运营' },
{ name: '农机操作员', code: 'machine_operator', users: 89, description: '操作和维护农机设备' },
{ name: '技术员', code: 'technician', users: 67, description: '负责技术支持和分析' },
{ name: '观察员', code: 'observer', users: 44, description: '只读权限,查看数据' },
].map((role, index) => (
<div key={index} className="bg-white rounded-lg p-4">
<div className="flex justify-between items-start mb-2">
<div>
<h5 className="font-medium text-gray-800">{role.name}</h5>
<p className="text-sm text-gray-600">{role.description}</p>
<p className="text-xs text-gray-500 mt-1">: {role.code}</p>
</div>
<div className="flex items-center space-x-2">
<span className="px-2 py-1 text-xs bg-blue-100 text-blue-800 rounded-full">
{role.users}
</span>
<button className="text-blue-600 hover:text-blue-800 text-sm">
</button>
<button className="text-red-600 hover:text-red-800 text-sm">
</button>
</div>
</div>
</div>
))}
</div>
</div>
<div className="bg-blue-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-blue-900 mb-4">
</h3>
<div className="space-y-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<input
type="text"
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="请输入角色名称"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<input
type="text"
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="请输入角色代码(英文)"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<textarea
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
rows={3}
placeholder="请输入角色描述"
></textarea>
</div>
<button className="w-full px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors">
</button>
</div>
</div>
</div>
<div className="space-y-6">
<div className="bg-purple-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-purple-900 mb-4">
🔑
</h3>
<div className="mb-4">
<select className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-purple-500">
<option></option>
<option></option>
<option></option>
<option></option>
<option></option>
<option></option>
</select>
</div>
<div className="space-y-3">
{[
{
module: '智能农机管理',
permissions: ['查看', '创建', '编辑', '删除', '导出']
},
{
module: '地块信息管理',
permissions: ['查看', '创建', '编辑', '删除', '导出']
},
{
module: '农事操作管理',
permissions: ['查看', '创建', '编辑', '删除', '导出']
},
{
module: '农业资产管理',
permissions: ['查看', '创建', '编辑', '删除', '导出']
},
{
module: 'AI作物模型',
permissions: ['查看', '创建', '编辑', '删除', '导出']
},
{
module: '水肥控制',
permissions: ['查看', '创建', '编辑', '删除', '导出']
},
{
module: '系统配置',
permissions: ['查看', '创建', '编辑', '删除', '导出']
},
].map((module, index) => (
<div key={index} className="bg-white rounded-lg p-3">
<div className="flex items-center justify-between mb-2">
<h4 className="font-medium text-gray-800">{module.module}</h4>
<label className="flex items-center text-sm">
<input
type="checkbox"
className="h-4 w-4 text-purple-600 focus:ring-purple-500 border-gray-300 rounded mr-2"
/>
</label>
</div>
<div className="flex flex-wrap gap-2">
{module.permissions.map((permission, permIndex) => (
<label key={permIndex} className="flex items-center">
<input
type="checkbox"
className="h-3 w-3 text-purple-600 focus:ring-purple-500 border-gray-300 rounded mr-1"
/>
<span className="text-xs text-gray-700">{permission}</span>
</label>
))}
</div>
</div>
))}
</div>
<button className="w-full mt-4 px-4 py-2 bg-purple-600 text-white rounded-md hover:bg-purple-700 transition-colors">
</button>
</div>
<div className="bg-orange-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-orange-900 mb-4">
👥
</h3>
<div className="space-y-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<select className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-orange-500">
<option></option>
<option> - </option>
<option> - </option>
<option> - </option>
<option> - </option>
</select>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
</label>
<div className="space-y-2">
{['超级管理员', '农场管理员', '农机操作员', '技术员', '观察员'].map((role, index) => (
<label key={index} className="flex items-center">
<input
type="checkbox"
className="h-4 w-4 text-orange-600 focus:ring-orange-500 border-gray-300 rounded mr-2"
/>
<span className="text-sm text-gray-700">{role}</span>
</label>
))}
</div>
</div>
<button className="w-full px-4 py-2 bg-orange-600 text-white rounded-md hover:bg-orange-700 transition-colors">
</button>
</div>
</div>
</div>
</div>
<div className="mt-6 bg-gray-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-gray-800 mb-4">
📊 使
</h3>
<div className="grid grid-cols-1 md:grid-cols-4 gap-4">
<div className="bg-white rounded-lg p-4 text-center">
<div className="text-2xl font-bold text-green-600 mb-2">5</div>
<div className="text-sm text-gray-600"></div>
</div>
<div className="bg-white rounded-lg p-4 text-center">
<div className="text-2xl font-bold text-blue-600 mb-2">35</div>
<div className="text-sm text-gray-600"></div>
</div>
<div className="bg-white rounded-lg p-4 text-center">
<div className="text-2xl font-bold text-purple-600 mb-2">18</div>
<div className="text-sm text-gray-600"></div>
</div>
<div className="bg-white rounded-lg p-4 text-center">
<div className="text-2xl font-bold text-orange-600 mb-2">42</div>
<div className="text-sm text-gray-600"></div>
</div>
</div>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,283 @@
import { Metadata } from 'next'
export const metadata: Metadata = {
title: '用户账号管理 - Crop-X 智慧农业管理系统',
description: '用户账号管理页面',
}
export default function UserAccountManagementPage() {
return (
<div className="space-y-6">
<div className="bg-white rounded-lg shadow p-6">
<h2 className="text-2xl font-bold text-gray-800 mb-6">
👤
</h2>
<div className="mb-6 flex justify-between items-center">
<div className="flex items-center space-x-4">
<input
type="text"
placeholder="搜索用户名、姓名或邮箱..."
className="px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 w-80"
/>
<select className="px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
<option></option>
<option></option>
<option></option>
<option></option>
<option></option>
<option></option>
</select>
<select className="px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
<option></option>
<option></option>
<option></option>
<option></option>
<option></option>
</select>
<button className="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors">
</button>
</div>
<button className="px-4 py-2 bg-green-600 text-white rounded-md hover:bg-green-700 transition-colors">
</button>
</div>
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
<div className="lg:col-span-2">
<div className="bg-gray-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-gray-800 mb-4">
</h3>
<div className="overflow-x-auto">
<table className="min-w-full divide-y divide-gray-200">
<thead className="bg-gray-100">
<tr>
<th className="px-4 py-3 text-left text-xs font-medium text-gray-700 uppercase tracking-wider">
<input type="checkbox" className="h-4 w-4 text-gray-600 focus:ring-gray-500 border-gray-300 rounded" />
</th>
<th className="px-4 py-3 text-left text-xs font-medium text-gray-700 uppercase tracking-wider">
</th>
<th className="px-4 py-3 text-left text-xs font-medium text-gray-700 uppercase tracking-wider">
</th>
<th className="px-4 py-3 text-left text-xs font-medium text-gray-700 uppercase tracking-wider">
</th>
<th className="px-4 py-3 text-left text-xs font-medium text-gray-700 uppercase tracking-wider">
</th>
<th className="px-4 py-3 text-left text-xs font-medium text-gray-700 uppercase tracking-wider">
</th>
<th className="px-4 py-3 text-left text-xs font-medium text-gray-700 uppercase tracking-wider">
</th>
</tr>
</thead>
<tbody className="bg-white divide-y divide-gray-200">
{[
{
username: 'admin',
name: '系统管理员',
email: 'admin@crop-x.com',
avatar: '👨‍💼',
role: '超级管理员',
tenant: '系统',
status: 'active',
createTime: '2024-01-01'
},
{
username: 'zhangsan',
name: '张三',
email: 'zhangsan@green-agri.com',
avatar: '👨‍🌾',
role: '农场管理员',
tenant: '绿色农业合作社',
status: 'active',
createTime: '2024-03-15'
},
{
username: 'lisi',
name: '李四',
email: 'lisi@harvest.com',
avatar: '👩‍🌾',
role: '农机操作员',
tenant: '丰收农场',
status: 'active',
createTime: '2024-05-20'
},
{
username: 'wangwu',
name: '王五',
email: 'wangwu@smart-agri.com',
avatar: '👨‍🔧',
role: '技术员',
tenant: '智慧农业科技',
status: 'inactive',
createTime: '2024-07-10'
},
{
username: 'zhaoliu',
name: '赵六',
email: 'zhaoliu@modern-agri.com',
avatar: '👩‍🔬',
role: '观察员',
tenant: '现代农业示范园',
status: 'pending',
createTime: '2024-09-05'
},
].map((user, index) => (
<tr key={index} className="hover:bg-gray-50">
<td className="px-4 py-3 whitespace-nowrap">
<input type="checkbox" className="h-4 w-4 text-gray-600 focus:ring-gray-500 border-gray-300 rounded" />
</td>
<td className="px-4 py-3 whitespace-nowrap">
<div className="flex items-center">
<div className="text-2xl mr-3">{user.avatar}</div>
<div>
<div className="text-sm font-medium text-gray-900">{user.name}</div>
<div className="text-sm text-gray-500">@{user.username}</div>
<div className="text-xs text-gray-400">{user.email}</div>
</div>
</div>
</td>
<td className="px-4 py-3 whitespace-nowrap">
<span className="px-2 py-1 text-xs font-medium bg-blue-100 text-blue-800 rounded-full">
{user.role}
</span>
</td>
<td className="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
{user.tenant}
</td>
<td className="px-4 py-3 whitespace-nowrap">
<span className={`px-2 py-1 text-xs font-medium rounded-full ${
user.status === 'active' ? 'bg-green-100 text-green-800' :
user.status === 'inactive' ? 'bg-gray-100 text-gray-800' :
'bg-yellow-100 text-yellow-800'
}`}>
{user.status === 'active' ? '活跃' : user.status === 'inactive' ? '未激活' : '待审核'}
</span>
</td>
<td className="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
{user.createTime}
</td>
<td className="px-4 py-3 whitespace-nowrap text-sm font-medium">
<button className="text-blue-600 hover:text-blue-900 mr-2"></button>
<button className="text-green-600 hover:text-green-900 mr-2"></button>
<button className="text-red-600 hover:text-red-900"></button>
</td>
</tr>
))}
</tbody>
</table>
</div>
<div className="mt-4 flex justify-between items-center">
<div className="text-sm text-gray-600">
1-5 248
</div>
<div className="flex space-x-2">
<button className="px-3 py-1 border border-gray-300 rounded-md hover:bg-gray-50">
</button>
<button className="px-3 py-1 bg-blue-600 text-white rounded-md">
1
</button>
<button className="px-3 py-1 border border-gray-300 rounded-md hover:bg-gray-50">
2
</button>
<button className="px-3 py-1 border border-gray-300 rounded-md hover:bg-gray-50">
3
</button>
<button className="px-3 py-1 border border-gray-300 rounded-md hover:bg-gray-50">
...
</button>
<button className="px-3 py-1 border border-gray-300 rounded-md hover:bg-gray-50">
</button>
</div>
</div>
</div>
</div>
<div className="space-y-6">
<div className="bg-green-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-green-900 mb-4">
📊
</h3>
<div className="space-y-3">
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="font-semibold text-green-600">248</span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="font-semibold text-blue-600">186</span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="font-semibold text-orange-600">5</span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="font-semibold text-red-600">12</span>
</div>
</div>
</div>
<div className="bg-blue-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-blue-900 mb-4">
🎭
</h3>
<div className="space-y-2">
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="font-semibold text-purple-600">3</span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="font-semibold text-green-600">45</span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="font-semibold text-blue-600">89</span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="font-semibold text-orange-600">67</span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="font-semibold text-gray-600">44</span>
</div>
</div>
</div>
<div className="bg-purple-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-purple-900 mb-4">
</h3>
<div className="space-y-2">
<button className="w-full px-4 py-2 bg-purple-600 text-white rounded-md hover:bg-purple-700 transition-colors">
</button>
<button className="w-full px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors">
</button>
<button className="w-full px-4 py-2 bg-green-600 text-white rounded-md hover:bg-green-700 transition-colors">
</button>
<button className="w-full px-4 py-2 bg-orange-600 text-white rounded-md hover:bg-orange-700 transition-colors">
</button>
</div>
</div>
</div>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,337 @@
import { Metadata } from 'next'
export const metadata: Metadata = {
title: '用户行为跟踪 - Crop-X 智慧农业管理系统',
description: '用户行为跟踪管理页面',
}
export default function UserBehaviorTrackingPage() {
return (
<div className="space-y-6">
<div className="bg-white rounded-lg shadow p-6">
<h2 className="text-2xl font-bold text-gray-800 mb-6">
📊
</h2>
<div className="mb-6 flex items-center space-x-4">
<input
type="text"
placeholder="搜索用户..."
className="px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
<select className="px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
<option></option>
<option></option>
<option></option>
<option></option>
<option></option>
<option></option>
<option></option>
</select>
<input
type="date"
className="px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
<button className="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors">
</button>
<button className="px-4 py-2 bg-green-600 text-white rounded-md hover:bg-green-700 transition-colors">
</button>
</div>
<div className="grid grid-cols-1 lg:grid-cols-4 gap-6">
<div className="lg:col-span-3">
<div className="bg-gray-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-gray-800 mb-4">
📋
</h3>
<div className="overflow-x-auto">
<table className="min-w-full divide-y divide-gray-200">
<thead className="bg-gray-100">
<tr>
<th className="px-4 py-3 text-left text-xs font-medium text-gray-700 uppercase tracking-wider">
</th>
<th className="px-4 py-3 text-left text-xs font-medium text-gray-700 uppercase tracking-wider">
</th>
<th className="px-4 py-3 text-left text-xs font-medium text-gray-700 uppercase tracking-wider">
</th>
<th className="px-4 py-3 text-left text-xs font-medium text-gray-700 uppercase tracking-wider">
</th>
<th className="px-4 py-3 text-left text-xs font-medium text-gray-700 uppercase tracking-wider">
</th>
<th className="px-4 py-3 text-left text-xs font-medium text-gray-700 uppercase tracking-wider">
IP地址
</th>
<th className="px-4 py-3 text-left text-xs font-medium text-gray-700 uppercase tracking-wider">
</th>
</tr>
</thead>
<tbody className="bg-white divide-y divide-gray-200">
{[
{
time: '2024-10-20 15:30:25',
user: '张三',
type: '登录',
module: '系统认证',
description: '用户登录系统',
ip: '192.168.1.100',
status: 'success'
},
{
time: '2024-10-20 15:28:15',
user: '李四',
type: '查看页面',
module: '智能农机管理',
description: '查看农机列表页面',
ip: '192.168.1.101',
status: 'success'
},
{
time: '2024-10-20 15:25:42',
user: '王五',
type: '创建数据',
module: '地块信息管理',
description: '创建新的地块信息',
ip: '192.168.1.102',
status: 'success'
},
{
time: '2024-10-20 15:22:18',
user: '赵六',
type: '编辑数据',
module: '农事操作管理',
description: '编辑农事任务信息',
ip: '192.168.1.103',
status: 'success'
},
{
time: '2024-10-20 15:20:05',
user: '张三',
type: '导出数据',
module: '系统配置',
description: '导出用户列表',
ip: '192.168.1.100',
status: 'success'
},
{
time: '2024-10-20 15:18:30',
user: '李四',
type: '删除数据',
module: '农业资产管理',
description: '删除资产记录',
ip: '192.168.1.101',
status: 'warning'
},
{
time: '2024-10-20 15:15:45',
user: '王五',
type: '登录',
module: '系统认证',
description: '用户登录失败',
ip: '192.168.1.102',
status: 'error'
},
].map((record, index) => (
<tr key={index} className="hover:bg-gray-50">
<td className="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
{record.time}
</td>
<td className="px-4 py-3 whitespace-nowrap text-sm text-gray-900">
{record.user}
</td>
<td className="px-4 py-3 whitespace-nowrap">
<span className={`px-2 py-1 text-xs font-medium rounded-full ${
record.type === '登录' ? 'bg-green-100 text-green-800' :
record.type === '查看页面' ? 'bg-blue-100 text-blue-800' :
record.type === '创建数据' ? 'bg-purple-100 text-purple-800' :
record.type === '编辑数据' ? 'bg-orange-100 text-orange-800' :
record.type === '导出数据' ? 'bg-teal-100 text-teal-800' :
'bg-red-100 text-red-800'
}`}>
{record.type}
</span>
</td>
<td className="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
{record.module}
</td>
<td className="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
{record.description}
</td>
<td className="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
{record.ip}
</td>
<td className="px-4 py-3 whitespace-nowrap">
<span className={`px-2 py-1 text-xs font-medium rounded-full ${
record.status === 'success' ? 'bg-green-100 text-green-800' :
record.status === 'warning' ? 'bg-yellow-100 text-yellow-800' :
'bg-red-100 text-red-800'
}`}>
{record.status === 'success' ? '成功' : record.status === 'warning' ? '警告' : '失败'}
</span>
</td>
</tr>
))}
</tbody>
</table>
</div>
<div className="mt-4 flex justify-between items-center">
<div className="text-sm text-gray-600">
1-7 1,456
</div>
<div className="flex space-x-2">
<button className="px-3 py-1 border border-gray-300 rounded-md hover:bg-gray-50">
</button>
<button className="px-3 py-1 bg-blue-600 text-white rounded-md">
1
</button>
<button className="px-3 py-1 border border-gray-300 rounded-md hover:bg-gray-50">
2
</button>
<button className="px-3 py-1 border border-gray-300 rounded-md hover:bg-gray-50">
3
</button>
<button className="px-3 py-1 border border-gray-300 rounded-md hover:bg-gray-50">
</button>
</div>
</div>
</div>
</div>
<div className="space-y-6">
<div className="bg-green-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-green-900 mb-4">
📈
</h3>
<div className="space-y-3">
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="font-semibold text-green-600">1,456</span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="font-semibold text-blue-600">1,423</span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="font-semibold text-red-600">25</span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="font-semibold text-purple-600">186</span>
</div>
</div>
</div>
<div className="bg-blue-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-blue-900 mb-4">
🎯
</h3>
<div className="space-y-2">
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="font-semibold text-blue-600">342 </span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="font-semibold text-green-600">298 </span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="font-semibold text-purple-600">256 </span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="font-semibold text-orange-600">189 </span>
</div>
</div>
</div>
<div className="bg-purple-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-purple-900 mb-4">
👥 TOP5
</h3>
<div className="space-y-2">
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="font-semibold text-purple-600">89 </span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="font-semibold text-blue-600">76 </span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="font-semibold text-green-600">65 </span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="font-semibold text-orange-600">54 </span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-600"></span>
<span className="font-semibold text-red-600">43 </span>
</div>
</div>
</div>
<div className="bg-orange-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-orange-900 mb-4">
</h3>
<div className="space-y-3">
<div className="bg-white rounded-lg p-3 border-l-4 border-red-500">
<div className="flex justify-between items-center mb-1">
<span className="text-sm font-medium text-gray-800"></span>
<span className="text-xs text-red-600"></span>
</div>
<p className="text-xs text-gray-600">用户: test@example.com - 5</p>
</div>
<div className="bg-white rounded-lg p-3 border-l-4 border-yellow-500">
<div className="flex justify-between items-center mb-1">
<span className="text-sm font-medium text-gray-800"></span>
<span className="text-xs text-yellow-600"></span>
</div>
<p className="text-xs text-gray-600">用户: 李四 - 3</p>
</div>
<div className="bg-white rounded-lg p-3 border-l-4 border-blue-500">
<div className="flex justify-between items-center mb-1">
<span className="text-sm font-medium text-gray-800"></span>
<span className="text-xs text-blue-600"></span>
</div>
<p className="text-xs text-gray-600">用户: 王五 - 10</p>
</div>
</div>
</div>
</div>
</div>
<div className="mt-6 bg-yellow-50 rounded-lg p-6">
<h3 className="text-lg font-semibold text-yellow-900 mb-4">
🔍
</h3>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
<button className="px-4 py-2 bg-yellow-600 text-white rounded-md hover:bg-yellow-700 transition-colors">
</button>
<button className="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors">
使
</button>
<button className="px-4 py-2 bg-green-600 text-white rounded-md hover:bg-green-700 transition-colors">
</button>
</div>
</div>
</div>
</div>
)
}