// aislop-ignore-file: duplicate-block -- 床位/柜子表格声明结构相似且字段不同,渲染逻辑已共享 EditableRoomCell import React from 'react'; import { Button, Drawer, InputNumber, Popconfirm, Space, Table, Tabs, Tag, } from 'antd'; import { PlusOutlined } from '@ant-design/icons'; import PermissionButton from '../../components/PermissionButton'; import { QueryErrorState } from '../../components/QueryState'; import { BED_STATUS_MAP, BED_STATUS_OPTIONS, EditableRoomCell, statusMap, type BedItem, type LockerItem, } from './RoomColumns'; export interface RoomDrawerProps { open: boolean; room: any; beds: BedItem[]; lockers: LockerItem[]; bedsError: boolean; lockersError: boolean; onRetryBeds: () => void; onRetryLockers: () => void; canEditRooms: boolean; remainingBedSlots: number; defaultBatchBedCount: number; onClose: () => void; onAddBed: () => void; onBatchBeds: (count: number) => void; onEditBed: (record: BedItem) => void; onDeleteBed: (id: number) => void; onSaveBedCell: (record: BedItem, field: string, value: unknown) => void; onAddLocker: () => void; onBatchLockers: (count: number) => void; onEditLocker: (record: LockerItem) => void; onDeleteLocker: (id: number) => void; onSaveLockerCell: (record: LockerItem, field: string, value: unknown) => void; } export const RoomDrawer: React.FC = ({ open, room, beds, lockers, bedsError, lockersError, onRetryBeds, onRetryLockers, canEditRooms, remainingBedSlots, defaultBatchBedCount, onClose, onAddBed, onBatchBeds, onEditBed, onDeleteBed, onSaveBedCell, onAddLocker, onBatchLockers, onEditLocker, onDeleteLocker, onSaveLockerCell, }) => { const roomItemActions = (kind: 'bed' | 'locker') => (r: any) => { const isBed = kind === 'bed'; const handleDelete = isBed ? onDeleteBed : onDeleteLocker; const handleEdit = isBed ? onEditBed : onEditLocker; return ( handleEdit(r)} > 编辑 {r.status !== 'occupied' && canEditRooms && ( handleDelete(r.id)}> )} ); }; return (
房间号: {room.roomNumber}
楼栋: {room.building || '-'}
楼层: {room.floor ?? '-'}
类型: {room.roomType || '-'}
额定人数: {room.capacity}
租赁类别: {room.rentalCategory === 'long' ? '长租' : '短租'}
月租金: {room.monthlyRate ? `¥${room.monthlyRate}` : '-'}
状态: {statusMap[room.status]?.text}
), }, { key: 'beds', label: `床位管理 (${beds.length})`, children: bedsError ? ( ) : (
{canEditRooms ? (
0 ? '批量生成床位' : '床位已达到额定人数'} description={ remainingBedSlots > 0 ? ( ) : ( '如需增加床位,请先调整宿舍额定人数' ) } onConfirm={() => { const input = document.getElementById( 'batch-bed-count', ) as HTMLInputElement; onBatchBeds( input ? parseInt(input.value) || defaultBatchBedCount : defaultBatchBedCount, ); }} okText="生成" disabled={room?.status === 'archived' || remainingBedSlots === 0} >
) : null} ( {v} ), }, { title: '状态', dataIndex: 'status', width: 80, render: (s: string, r: BedItem) => ( {BED_STATUS_MAP[s]?.text || s} ), }, { title: '备注', dataIndex: 'notes', render: (v: string, r: BedItem) => ( {v || '-'} ), }, { title: '操作', width: 120, render: roomItemActions('bed'), }, ]} /> ), }, { key: 'lockers', label: `柜子管理 (${lockers.length})`, children: lockersError ? ( ) : (
{canEditRooms ? (
} onConfirm={() => { const input = document.getElementById( 'batch-locker-count', ) as HTMLInputElement; onBatchLockers(input ? parseInt(input.value) || 4 : 4); }} okText="生成" disabled={room?.status === 'archived'} >
) : null}
( {v} ), }, { title: '状态', dataIndex: 'status', width: 80, render: (s: string, r: LockerItem) => ( {BED_STATUS_MAP[s]?.text || s} ), }, { title: '备注', dataIndex: 'notes', render: (v: string, r: LockerItem) => ( {v || '-'} ), }, { title: '操作', width: 120, render: roomItemActions('locker'), }, ]} /> ), }, ]} /> ); };