| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853 |
- import React, { useState } from 'react';
- import { Plus, Search, Edit2, Trash2, MoreVertical, Package, Key, Lock, Briefcase, QrCode, MapPin } from 'lucide-react';
- import { Button } from 'antd';
- import { Button as UIButton } from './ui/button';
- import PadLockManagement from './PadLockManagement';
- import HardwareLockCabinetManagement from './lockCabinet/HardwareLockCabinetManagement';
- interface TableRow {
- id: number;
- [key: string]: any;
- }
- interface HardwareManagementProps {
- subMenu: string;
- }
- export default function HardwareManagement({ subMenu }: HardwareManagementProps) {
- // 如果是挂锁,使用专门的挂锁管理组件
- // subMenu 可能是 '挂锁'、'padlock' 或 'lock'
- if (subMenu === '挂锁' || subMenu === 'padlock' || subMenu === 'lock') {
- return <PadLockManagement subMenu={subMenu} />;
- }
- const [searchTerm, setSearchTerm] = useState('');
- const [showAddModal, setShowAddModal] = useState(false);
- const [editingItem, setEditingItem] = useState<TableRow | null>(null);
- // 机柜数据
- const cabinetData: TableRow[] = [
- {
- id: 1,
- code: 'CAB-001',
- name: '1号配电柜',
- location: 'A区-1层',
- type: '配电柜',
- voltage: '380V',
- capacity: '200A',
- status: '运行中',
- lockCount: 8,
- manufacturer: '施耐德',
- installDate: '2024-01-15',
- lastCheck: '2025-12-01'
- },
- {
- id: 2,
- code: 'CAB-002',
- name: '2号配电柜',
- location: 'A区-2层',
- type: '配电柜',
- voltage: '380V',
- capacity: '150A',
- status: '维护中',
- lockCount: 6,
- manufacturer: 'ABB',
- installDate: '2024-02-20',
- lastCheck: '2025-11-28'
- },
- {
- id: 3,
- code: 'CAB-003',
- name: '变压器柜A',
- location: 'B区-地下室',
- type: '变压器柜',
- voltage: '10kV',
- capacity: '1000kVA',
- status: '运行中',
- lockCount: 12,
- manufacturer: '西门子',
- installDate: '2024-01-10',
- lastCheck: '2025-12-03'
- },
- {
- id: 4,
- code: 'CAB-004',
- name: '控制柜C1',
- location: 'C区-3层',
- type: '控制柜',
- voltage: '220V',
- capacity: '50A',
- status: '运行中',
- lockCount: 4,
- manufacturer: '正泰',
- installDate: '2024-03-05',
- lastCheck: '2025-11-25'
- },
- ];
- // 钥匙数据
- const keyData: TableRow[] = [
- {
- id: 1,
- code: 'KEY-001',
- name: '1号配电柜主钥匙',
- type: '主钥匙',
- cabinet: '1号配电柜',
- holder: '张三',
- department: '运维部',
- status: '在用',
- borrowDate: '2025-12-01',
- returnDate: '-',
- remark: '日常巡检使用'
- },
- {
- id: 2,
- code: 'KEY-002',
- name: '1号配电柜备用钥匙',
- type: '备用钥匙',
- cabinet: '1号配电柜',
- holder: '钥匙柜',
- department: '安全部',
- status: '库存',
- borrowDate: '-',
- returnDate: '-',
- remark: '应急备用'
- },
- {
- id: 3,
- code: 'KEY-003',
- name: '变压器柜A钥匙',
- type: '主钥匙',
- cabinet: '变压器柜A',
- holder: '李四',
- department: '技术部',
- status: '在用',
- borrowDate: '2025-12-03',
- returnDate: '-',
- remark: '设备检修'
- },
- {
- id: 4,
- code: 'KEY-004',
- name: '控制柜C1钥匙',
- type: '主钥匙',
- cabinet: '控制柜C1',
- holder: '钥匙柜',
- department: '安全部',
- status: '库存',
- borrowDate: '-',
- returnDate: '-',
- remark: ''
- },
- ];
- // 挂锁数据
- const padlockData: TableRow[] = [
- {
- id: 1,
- code: 'LOCK-001',
- name: '红色安全挂锁-001',
- type: '安全挂锁',
- color: '红色',
- keyCode: 'K001',
- owner: '张三',
- department: '运维部',
- status: '使用中',
- location: '1号配电柜',
- lockDate: '2025-12-01 09:00',
- remark: '隔离作业中'
- },
- {
- id: 2,
- code: 'LOCK-002',
- name: '蓝色安全挂锁-002',
- type: '安全挂锁',
- color: '蓝色',
- keyCode: 'K002',
- owner: '李四',
- department: '技术部',
- status: '使用中',
- location: '变压器柜A',
- lockDate: '2025-12-03 08:30',
- remark: '维修作业'
- },
- {
- id: 3,
- code: 'LOCK-003',
- name: '黄色安全挂锁-003',
- type: '安全挂锁',
- color: '黄色',
- keyCode: 'K003',
- owner: '王五',
- department: '安全部',
- status: '空闲',
- location: '工具柜',
- lockDate: '-',
- remark: ''
- },
- {
- id: 4,
- code: 'LOCK-004',
- name: '绿色安全挂锁-004',
- type: '安全挂锁',
- color: '绿色',
- keyCode: 'K004',
- owner: '赵六',
- department: '运维部',
- status: '空闲',
- location: '工具柜',
- lockDate: '-',
- remark: ''
- },
- ];
- // 便携式数据
- const portableData: TableRow[] = [
- {
- id: 1,
- code: 'PORT-001',
- name: '便携式接地线-A组',
- type: '接地线',
- model: 'JDX-10',
- specification: '10kV/50mm²',
- quantity: 3,
- holder: '张三',
- department: '运维部',
- status: '使用中',
- borrowDate: '2025-12-01',
- returnDate: '-',
- location: 'B区变压器',
- remark: '定期检修使用'
- },
- {
- id: 2,
- code: 'PORT-002',
- name: '验电器-B',
- type: '验电器',
- model: 'YDQ-10',
- specification: '10kV',
- quantity: 2,
- holder: '李四',
- department: '技术部',
- status: '使用中',
- borrowDate: '2025-12-03',
- returnDate: '-',
- location: 'B区变压器',
- remark: '配合接地线使用'
- },
- {
- id: 3,
- code: 'PORT-003',
- name: '绝缘手套-C组',
- type: '绝缘防护',
- model: 'JYT-500',
- specification: '500V',
- quantity: 5,
- holder: '工具库',
- department: '安全部',
- status: '库存',
- borrowDate: '-',
- returnDate: '-',
- location: '安全工具柜',
- remark: '每月检测'
- },
- {
- id: 4,
- code: 'PORT-004',
- name: '便携式接地线-D组',
- type: '接地线',
- model: 'JDX-35',
- specification: '35kV/70mm²',
- quantity: 3,
- holder: '工具库',
- department: '安全部',
- status: '库存',
- borrowDate: '-',
- returnDate: '-',
- location: '安全工具柜',
- remark: ''
- },
- ];
- // 机柜管理使用专用组件
- // subMenu 可能是 '机柜'、'cabinet' 或 'hwcabinet'
- if (subMenu === '机柜' || subMenu === 'cabinet' || subMenu === 'hwcabinet') {
- console.log('HardwareManagement: 渲染机柜管理组件,subMenu:', subMenu);
- return <HardwareLockCabinetManagement key="hardware-lock-cabinet-management" />;
- }
- // 根据当前子菜单获取数据和列配置
- const getTableConfig = () => {
- if (subMenu === '钥匙') {
- return {
- data: keyData,
- columns: [
- { key: 'code', label: '编号', width: '10%' },
- { key: 'name', label: '名称', width: '15%' },
- { key: 'type', label: '类型', width: '10%' },
- { key: 'cabinet', label: '对应机柜', width: '12%' },
- { key: 'holder', label: '持有人', width: '10%' },
- { key: 'department', label: '部门', width: '10%' },
- { key: 'status', label: '状态', width: '8%' },
- { key: 'borrowDate', label: '借出日期', width: '12%' },
- { key: 'remark', label: '备注', width: '13%' },
- ],
- };
- } else if (subMenu === '挂锁') {
- return {
- data: padlockData,
- columns: [
- { key: 'code', label: '编号', width: '10%' },
- { key: 'name', label: '名称', width: '15%' },
- { key: 'color', label: '颜色', width: '8%' },
- { key: 'owner', label: '所有人', width: '10%' },
- { key: 'department', label: '部门', width: '10%' },
- { key: 'status', label: '状态', width: '8%' },
- { key: 'location', label: '当前位置', width: '12%' },
- { key: 'lockDate', label: '上锁时间', width: '15%' },
- { key: 'remark', label: '备注', width: '12%' },
- ],
- };
- } else if (subMenu === '便携式') {
- return {
- data: portableData,
- columns: [
- { key: 'code', label: '编号', width: '10%' },
- { key: 'name', label: '名称', width: '15%' },
- { key: 'type', label: '类型', width: '10%' },
- { key: 'specification', label: '规格', width: '10%' },
- { key: 'quantity', label: '数量', width: '6%' },
- { key: 'holder', label: '持有人', width: '10%' },
- { key: 'status', label: '状态', width: '8%' },
- { key: 'location', label: '位置', width: '12%' },
- { key: 'borrowDate', label: '借出日期', width: '10%' },
- { key: 'remark', label: '备注', width: '9%' },
- ],
- };
- }
- return { data: [], columns: [] };
- };
- const { data, columns } = getTableConfig();
- // 过滤数据
- const filteredData = data.filter((item) =>
- Object.values(item).some((value) =>
- String(value).toLowerCase().includes(searchTerm.toLowerCase())
- )
- );
- const handleDelete = (id: number) => {
- if (confirm('确定要删除这条数据吗?')) {
- console.log('删除:', id);
- }
- };
- const handleEdit = (item: TableRow) => {
- setEditingItem(item);
- setShowAddModal(true);
- };
- // 获取表单字段
- const getFormFields = () => {
- if (subMenu === '机柜') {
- return (
- <div className="grid grid-cols-2 gap-4">
- <div>
- <label className="block text-sm text-gray-700 mb-2">编号 *</label>
- <input
- type="text"
- className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl outline-none focus:border-blue-400 focus:ring-4 focus:ring-blue-100 transition-all text-sm"
- placeholder="请输入编号"
- defaultValue={editingItem?.code || ''}
- />
- </div>
- <div>
- <label className="block text-sm text-gray-700 mb-2">名称 *</label>
- <input
- type="text"
- className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl outline-none focus:border-blue-400 focus:ring-4 focus:ring-blue-100 transition-all text-sm"
- placeholder="请输入名称"
- defaultValue={editingItem?.name || ''}
- />
- </div>
- <div>
- <label className="block text-sm text-gray-700 mb-2">位置 *</label>
- <input
- type="text"
- className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl outline-none focus:border-blue-400 focus:ring-4 focus:ring-blue-100 transition-all text-sm"
- placeholder="请输入位置"
- defaultValue={editingItem?.location || ''}
- />
- </div>
- <div>
- <label className="block text-sm text-gray-700 mb-2">类型 *</label>
- <select className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl outline-none focus:border-blue-400 focus:ring-4 focus:ring-blue-100 transition-all text-sm">
- <option value="">请选择</option>
- <option value="配电柜">配电柜</option>
- <option value="变压器柜">变压器柜</option>
- <option value="控制柜">控制柜</option>
- </select>
- </div>
- <div>
- <label className="block text-sm text-gray-700 mb-2">电压</label>
- <input
- type="text"
- className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl outline-none focus:border-blue-400 focus:ring-4 focus:ring-blue-100 transition-all text-sm"
- placeholder="请输入电压"
- defaultValue={editingItem?.voltage || ''}
- />
- </div>
- <div>
- <label className="block text-sm text-gray-700 mb-2">容量</label>
- <input
- type="text"
- className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl outline-none focus:border-blue-400 focus:ring-4 focus:ring-blue-100 transition-all text-sm"
- placeholder="请输入容量"
- defaultValue={editingItem?.capacity || ''}
- />
- </div>
- <div>
- <label className="block text-sm text-gray-700 mb-2">锁点数</label>
- <input
- type="number"
- className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl outline-none focus:border-blue-400 focus:ring-4 focus:ring-blue-100 transition-all text-sm"
- placeholder="请输入锁点数"
- defaultValue={editingItem?.lockCount || ''}
- />
- </div>
- <div>
- <label className="block text-sm text-gray-700 mb-2">厂商</label>
- <input
- type="text"
- className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl outline-none focus:border-blue-400 focus:ring-4 focus:ring-blue-100 transition-all text-sm"
- placeholder="请输入厂商"
- defaultValue={editingItem?.manufacturer || ''}
- />
- </div>
- <div className="col-span-2">
- <label className="block text-sm text-gray-700 mb-2">备注</label>
- <textarea
- rows={3}
- className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl outline-none focus:border-blue-400 focus:ring-4 focus:ring-blue-100 transition-all text-sm resize-none"
- placeholder="请输入备注"
- ></textarea>
- </div>
- </div>
- );
- } else if (subMenu === '钥匙') {
- return (
- <div className="grid grid-cols-2 gap-4">
- <div>
- <label className="block text-sm text-gray-700 mb-2">编号 *</label>
- <input
- type="text"
- className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl outline-none focus:border-blue-400 focus:ring-4 focus:ring-blue-100 transition-all text-sm"
- placeholder="请输入编号"
- defaultValue={editingItem?.code || ''}
- />
- </div>
- <div>
- <label className="block text-sm text-gray-700 mb-2">名称 *</label>
- <input
- type="text"
- className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl outline-none focus:border-blue-400 focus:ring-4 focus:ring-blue-100 transition-all text-sm"
- placeholder="请输入名称"
- defaultValue={editingItem?.name || ''}
- />
- </div>
- <div>
- <label className="block text-sm text-gray-700 mb-2">类型 *</label>
- <select className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl outline-none focus:border-blue-400 focus:ring-4 focus:ring-blue-100 transition-all text-sm">
- <option value="">请选择</option>
- <option value="主钥匙">主钥匙</option>
- <option value="备用钥匙">备用钥匙</option>
- </select>
- </div>
- <div>
- <label className="block text-sm text-gray-700 mb-2">对应机柜 *</label>
- <select className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl outline-none focus:border-blue-400 focus:ring-4 focus:ring-blue-100 transition-all text-sm">
- <option value="">请选择</option>
- <option value="1号配电柜">1号配电柜</option>
- <option value="2号配电柜">2号配电柜</option>
- <option value="变压器柜A">变压器柜A</option>
- </select>
- </div>
- <div>
- <label className="block text-sm text-gray-700 mb-2">持有人</label>
- <input
- type="text"
- className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl outline-none focus:border-blue-400 focus:ring-4 focus:ring-blue-100 transition-all text-sm"
- placeholder="请输入持有人"
- defaultValue={editingItem?.holder || ''}
- />
- </div>
- <div>
- <label className="block text-sm text-gray-700 mb-2">部门</label>
- <select className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl outline-none focus:border-blue-400 focus:ring-4 focus:ring-blue-100 transition-all text-sm">
- <option value="">请选择</option>
- <option value="运维部">运维部</option>
- <option value="技术部">技术部</option>
- <option value="安全部">安全部</option>
- </select>
- </div>
- <div className="col-span-2">
- <label className="block text-sm text-gray-700 mb-2">备注</label>
- <textarea
- rows={3}
- className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl outline-none focus:border-blue-400 focus:ring-4 focus:ring-blue-100 transition-all text-sm resize-none"
- placeholder="请输入备注"
- defaultValue={editingItem?.remark || ''}
- ></textarea>
- </div>
- </div>
- );
- } else if (subMenu === '挂锁') {
- return (
- <div className="grid grid-cols-2 gap-4">
- <div>
- <label className="block text-sm text-gray-700 mb-2">编号 *</label>
- <input
- type="text"
- className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl outline-none focus:border-blue-400 focus:ring-4 focus:ring-blue-100 transition-all text-sm"
- placeholder="请输入编号"
- defaultValue={editingItem?.code || ''}
- />
- </div>
- <div>
- <label className="block text-sm text-gray-700 mb-2">名称 *</label>
- <input
- type="text"
- className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl outline-none focus:border-blue-400 focus:ring-4 focus:ring-blue-100 transition-all text-sm"
- placeholder="请输入名称"
- defaultValue={editingItem?.name || ''}
- />
- </div>
- <div>
- <label className="block text-sm text-gray-700 mb-2">颜色 *</label>
- <select className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl outline-none focus:border-blue-400 focus:ring-4 focus:ring-blue-100 transition-all text-sm">
- <option value="">请选择</option>
- <option value="红色">红色</option>
- <option value="蓝色">蓝色</option>
- <option value="黄色">黄色</option>
- <option value="绿色">绿色</option>
- </select>
- </div>
- <div>
- <label className="block text-sm text-gray-700 mb-2">钥匙编号</label>
- <input
- type="text"
- className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl outline-none focus:border-blue-400 focus:ring-4 focus:ring-blue-100 transition-all text-sm"
- placeholder="请输入钥匙编号"
- defaultValue={editingItem?.keyCode || ''}
- />
- </div>
- <div>
- <label className="block text-sm text-gray-700 mb-2">所有人 *</label>
- <input
- type="text"
- className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl outline-none focus:border-blue-400 focus:ring-4 focus:ring-blue-100 transition-all text-sm"
- placeholder="请输入所有人"
- defaultValue={editingItem?.owner || ''}
- />
- </div>
- <div>
- <label className="block text-sm text-gray-700 mb-2">部门 *</label>
- <select className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl outline-none focus:border-blue-400 focus:ring-4 focus:ring-blue-100 transition-all text-sm">
- <option value="">请选择</option>
- <option value="运维部">运维部</option>
- <option value="技术部">技术部</option>
- <option value="安全部">安全部</option>
- </select>
- </div>
- <div className="col-span-2">
- <label className="block text-sm text-gray-700 mb-2">备注</label>
- <textarea
- rows={3}
- className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl outline-none focus:border-blue-400 focus:ring-4 focus:ring-blue-100 transition-all text-sm resize-none"
- placeholder="请输入备注"
- defaultValue={editingItem?.remark || ''}
- ></textarea>
- </div>
- </div>
- );
- } else if (subMenu === '便携式') {
- return (
- <div className="grid grid-cols-2 gap-4">
- <div>
- <label className="block text-sm text-gray-700 mb-2">编号 *</label>
- <input
- type="text"
- className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl outline-none focus:border-blue-400 focus:ring-4 focus:ring-blue-100 transition-all text-sm"
- placeholder="请输入编号"
- defaultValue={editingItem?.code || ''}
- />
- </div>
- <div>
- <label className="block text-sm text-gray-700 mb-2">名称 *</label>
- <input
- type="text"
- className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl outline-none focus:border-blue-400 focus:ring-4 focus:ring-blue-100 transition-all text-sm"
- placeholder="请输入名称"
- defaultValue={editingItem?.name || ''}
- />
- </div>
- <div>
- <label className="block text-sm text-gray-700 mb-2">类型 *</label>
- <select className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl outline-none focus:border-blue-400 focus:ring-4 focus:ring-blue-100 transition-all text-sm">
- <option value="">请选择</option>
- <option value="接地线">接地线</option>
- <option value="验电器">验电器</option>
- <option value="绝缘防护">绝缘防护</option>
- </select>
- </div>
- <div>
- <label className="block text-sm text-gray-700 mb-2">型号</label>
- <input
- type="text"
- className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl outline-none focus:border-blue-400 focus:ring-4 focus:ring-blue-100 transition-all text-sm"
- placeholder="请输入型号"
- defaultValue={editingItem?.model || ''}
- />
- </div>
- <div>
- <label className="block text-sm text-gray-700 mb-2">规格</label>
- <input
- type="text"
- className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl outline-none focus:border-blue-400 focus:ring-4 focus:ring-blue-100 transition-all text-sm"
- placeholder="请输入规格"
- defaultValue={editingItem?.specification || ''}
- />
- </div>
- <div>
- <label className="block text-sm text-gray-700 mb-2">数量</label>
- <input
- type="number"
- className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl outline-none focus:border-blue-400 focus:ring-4 focus:ring-blue-100 transition-all text-sm"
- placeholder="请输入数量"
- defaultValue={editingItem?.quantity || ''}
- />
- </div>
- <div className="col-span-2">
- <label className="block text-sm text-gray-700 mb-2">备注</label>
- <textarea
- rows={3}
- className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl outline-none focus:border-blue-400 focus:ring-4 focus:ring-blue-100 transition-all text-sm resize-none"
- placeholder="请输入备注"
- defaultValue={editingItem?.remark || ''}
- ></textarea>
- </div>
- </div>
- );
- }
- return null;
- };
- return (
- <div className="space-y-6">
- {/* 表格容器 - 合并工具栏和列表 */}
- <div className="bg-white rounded-2xl border border-gray-200/50 shadow-sm overflow-hidden">
- {/* 工具栏 */}
- <div className="p-4 border-b border-gray-200/50">
- <div className="flex items-center justify-between">
- <div className="relative w-80">
- <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-gray-400" />
- <input
- type="text"
- placeholder={`搜索${subMenu}...`}
- value={searchTerm}
- onChange={(e) => setSearchTerm(e.target.value)}
- className="w-full h-10 pl-10 pr-4 bg-gray-50 border border-gray-200 rounded-xl outline-none focus:border-blue-400 focus:ring-4 focus:ring-blue-100 transition-all text-sm"
- />
- </div>
- <button
- onClick={() => {
- setEditingItem(null);
- setShowAddModal(true);
- }}
- className="flex items-center gap-2 px-4 py-2.5 bg-gradient-to-r from-blue-500 to-blue-600 text-white rounded-xl hover:shadow-lg hover:shadow-blue-400/40 transition-all duration-300"
- >
- <Plus className="w-4 h-4" strokeWidth={2.5} />
- <span className="text-sm">新增{subMenu}</span>
- </button>
- </div>
- </div>
- {/* 表格 */}
- <div className="overflow-x-auto">
- <table className="w-full">
- <thead>
- <tr className="bg-gradient-to-r from-gray-50 to-gray-100/50 border-b border-gray-200">
- <th className="px-6 py-4 text-left text-xs text-gray-600 uppercase tracking-wider" style={{ width: '5%' }}>
- 序号
- </th>
- {columns.map((column) => (
- <th
- key={column.key}
- className="px-6 py-4 text-left text-xs text-gray-600 uppercase tracking-wider"
- style={{ width: column.width }}
- >
- {column.label}
- </th>
- ))}
- <th className="px-6 py-4 text-center text-xs text-gray-600 uppercase tracking-wider" style={{ width: '10%' }}>
- 操作
- </th>
- </tr>
- </thead>
- <tbody className="divide-y divide-gray-100">
- {filteredData.map((row, index) => (
- <tr
- key={row.id}
- className="hover:bg-blue-50/30 transition-colors"
- >
- <td className="px-6 py-4 text-sm text-gray-900">
- {index + 1}
- </td>
- {columns.map((column) => (
- <td key={column.key} className="px-6 py-4 text-sm text-gray-900">
- {column.key === 'status' ? (
- <span
- className={`inline-flex px-3 py-1 rounded-lg text-xs ${
- row[column.key] === '运行中' || row[column.key] === '在用' || row[column.key] === '使用中'
- ? 'bg-green-100 text-green-700'
- : row[column.key] === '维护中'
- ? 'bg-orange-100 text-orange-700'
- : row[column.key] === '库存' || row[column.key] === '空闲'
- ? 'bg-blue-100 text-blue-700'
- : 'bg-gray-100 text-gray-700'
- }`}
- >
- {row[column.key]}
- </span>
- ) : column.key === 'color' ? (
- <div className="flex items-center gap-2">
- <div
- className={`w-4 h-4 rounded-full border border-gray-300 ${
- row[column.key] === '红色' ? 'bg-red-500' :
- row[column.key] === '蓝色' ? 'bg-blue-500' :
- row[column.key] === '黄色' ? 'bg-yellow-500' :
- row[column.key] === '绿色' ? 'bg-green-500' :
- 'bg-gray-500'
- }`}
- ></div>
- <span>{row[column.key]}</span>
- </div>
- ) : (
- row[column.key]
- )}
- </td>
- ))}
- <td className="px-6 py-4">
- <div className="flex items-center justify-center gap-2">
- <UIButton
- variant="ghost"
- size="sm"
- onClick={() => handleEdit(row)}
- className="h-8 px-2"
- >
- <Edit2 className="w-4 h-4" />
- <span className="ml-1">编辑</span>
- </UIButton>
- <UIButton
- variant="ghost"
- size="sm"
- onClick={() => handleDelete(row.id)}
- className="h-8 px-2 text-red-600 hover:text-red-700"
- >
- <Trash2 className="w-4 h-4" />
- <span className="ml-1">删除</span>
- </UIButton>
- <UIButton
- variant="ghost"
- size="sm"
- className="h-8 px-2"
- >
- <MoreVertical className="w-4 h-4" />
- <span className="ml-1">更多</span>
- </UIButton>
- </div>
- </td>
- </tr>
- ))}
- </tbody>
- </table>
- </div>
- </div>
- {/* 分页 */}
- {filteredData.length > 0 && (
- <div className="bg-white rounded-lg border border-gray-200 px-6 py-4">
- <div className="flex items-center justify-between">
- <div className="text-sm text-gray-600">
- 共 <span className="text-blue-600 font-medium">{filteredData.length}</span> 条记录
- </div>
- <div className="flex gap-2">
- <Button
- disabled={true}
- >
- 上一页
- </Button>
- <span className="px-4 py-2 text-sm text-gray-600 flex items-center">
- 1 / 1
- </span>
- <Button
- disabled={true}
- >
- 下一页
- </Button>
- </div>
- </div>
- </div>
- )}
- {/* 新增/编辑弹窗 */}
- {showAddModal && (
- <div className="fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50 animate-in fade-in duration-200">
- <div className="bg-white rounded-2xl shadow-2xl w-full max-w-3xl mx-4 max-h-[90vh] overflow-y-auto animate-in zoom-in duration-200">
- {/* 弹窗标题 */}
- <div className="px-6 py-4 border-b border-gray-200 flex items-center justify-between sticky top-0 bg-white z-10">
- <h3 className="text-lg text-gray-900">
- {editingItem ? `编辑${subMenu}` : `新增${subMenu}`}
- </h3>
- <button
- onClick={() => setShowAddModal(false)}
- className="p-2 hover:bg-gray-100 rounded-lg transition-colors"
- >
- <svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
- <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
- </svg>
- </button>
- </div>
- {/* 弹窗内容 */}
- <div className="px-6 py-6">
- {getFormFields()}
- </div>
- {/* 弹窗底部 */}
- <div className="px-6 py-4 bg-gray-50/50 border-t border-gray-200 flex justify-end gap-3 rounded-b-2xl">
- <button
- onClick={() => setShowAddModal(false)}
- className="px-5 py-2.5 text-sm text-gray-600 bg-white border border-gray-200 rounded-xl hover:bg-gray-50 transition-colors"
- >
- 取消
- </button>
- <button
- onClick={() => {
- console.log('保存:', editingItem);
- setShowAddModal(false);
- }}
- className="px-5 py-2.5 text-sm text-white bg-gradient-to-r from-blue-500 to-blue-600 rounded-xl hover:shadow-lg hover:shadow-blue-400/40 transition-all"
- >
- {editingItem ? '保存修改' : '确定'}
- </button>
- </div>
- </div>
- </div>
- )}
- </div>
- );
- }
|