shebi xiufu
This commit is contained in:
@@ -16,7 +16,7 @@ import {
|
||||
DialogTrigger,
|
||||
} from "../ui/dialog"
|
||||
import { Plus, Filter, Download, MapPin, Calendar, Shield, ChevronLeft, ChevronRight } from "lucide-react"
|
||||
import { apiGet, apiPost } from "../../lib/services/api"
|
||||
import { apiGet, apiPost, apiPut } from "../../lib/services/api"
|
||||
|
||||
// 商户数据类型(根据新接口返回格式定义)
|
||||
interface ProvinceMerchant {
|
||||
@@ -70,6 +70,7 @@ export default function EquipmentPage() {
|
||||
const [searchTerm, setSearchTerm] = useState("")
|
||||
const [statusFilter, setStatusFilter] = useState("all")
|
||||
const [isAddEquipmentOpen, setIsAddEquipmentOpen] = useState(false)
|
||||
const [isEditEquipmentOpen, setIsEditEquipmentOpen] = useState(false)
|
||||
const [isSubmitting, setIsSubmitting] = useState(false)
|
||||
const [merchants, setMerchants] = useState<ProvinceMerchant[]>([])
|
||||
const [loadingMerchants, setLoadingMerchants] = useState(false)
|
||||
@@ -179,6 +180,84 @@ export default function EquipmentPage() {
|
||||
notes: "",
|
||||
})
|
||||
|
||||
const [editEquipment, setEditEquipment] = useState({
|
||||
id: "",
|
||||
name: "",
|
||||
type: "",
|
||||
model: "",
|
||||
merchantId: "",
|
||||
location: "",
|
||||
installDate: "",
|
||||
status: "normal",
|
||||
notes: "",
|
||||
})
|
||||
|
||||
// 打开编辑对话框
|
||||
const handleEditEquipment = (equipment: Equipment) => {
|
||||
setEditEquipment({
|
||||
id: equipment.id,
|
||||
name: equipment.equipmentName || "",
|
||||
type: equipment.equipmentType || "",
|
||||
model: equipment.equipmentModel || "",
|
||||
merchantId: equipment.merchantId || "",
|
||||
location: equipment.installationLocation || "",
|
||||
installDate: equipment.installationDate || "",
|
||||
status: equipment.status === "1" ? "normal" : equipment.status === "2" ? "expiring" : "expired",
|
||||
notes: equipment.remarks || "",
|
||||
})
|
||||
setIsEditEquipmentOpen(true)
|
||||
// 加载商户和设备类型数据
|
||||
if (merchants.length === 0) {
|
||||
fetchMerchants()
|
||||
}
|
||||
if (Object.keys(equipmentTypes).length === 0) {
|
||||
fetchEquipmentTypes()
|
||||
}
|
||||
}
|
||||
|
||||
// 提交编辑
|
||||
const handleUpdateEquipment = async () => {
|
||||
if (!editEquipment.name || !editEquipment.type || !editEquipment.merchantId) {
|
||||
alert('请填写必填信息')
|
||||
return
|
||||
}
|
||||
|
||||
setIsSubmitting(true)
|
||||
|
||||
try {
|
||||
const equipmentData = {
|
||||
id: editEquipment.id,
|
||||
equipmentName: editEquipment.name,
|
||||
equipmentType: editEquipment.type,
|
||||
equipmentModel: editEquipment.model,
|
||||
merchantId: editEquipment.merchantId,
|
||||
installationLocation: editEquipment.location,
|
||||
installationDate: editEquipment.installDate,
|
||||
status: editEquipment.status === 'normal' ? 1 : editEquipment.status === 'expiring' ? 2 : 3,
|
||||
remarks: editEquipment.notes,
|
||||
}
|
||||
|
||||
console.log("编辑设备:", equipmentData)
|
||||
|
||||
const result = await apiPut('/back/equipment/', equipmentData)
|
||||
|
||||
if (result.code === 200) {
|
||||
console.log('编辑设备成功:', result)
|
||||
alert('编辑设备成功!')
|
||||
setIsEditEquipmentOpen(false)
|
||||
fetchEquipmentList(pagination.pageNum, pagination.pageSize)
|
||||
} else {
|
||||
console.error('编辑设备失败:', result)
|
||||
alert('编辑设备失败:' + (result.msg || '未知错误'))
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('编辑设备请求失败:', error)
|
||||
alert('网络错误,请稍后重试')
|
||||
} finally {
|
||||
setIsSubmitting(false)
|
||||
}
|
||||
}
|
||||
|
||||
const handleAddEquipment = async () => {
|
||||
if (!newEquipment.name || !newEquipment.type || !newEquipment.merchantId) {
|
||||
alert('请填写必填信息')
|
||||
@@ -273,7 +352,17 @@ export default function EquipmentPage() {
|
||||
item.equipmentName.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||
merchantInfo.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||
merchantInfo.mall.toLowerCase().includes(searchTerm.toLowerCase())
|
||||
const matchesStatus = statusFilter === "all" || item.status === statusFilter
|
||||
|
||||
// 修正状态筛选逻辑
|
||||
let matchesStatus = true
|
||||
if (statusFilter === "1" || statusFilter === "normal") {
|
||||
matchesStatus = item.status === "1"
|
||||
} else if (statusFilter === "2" || statusFilter === "expiring") {
|
||||
matchesStatus = item.status === "2"
|
||||
} else if (statusFilter === "3" || statusFilter === "expired") {
|
||||
matchesStatus = item.status === "3"
|
||||
}
|
||||
|
||||
return matchesSearch && matchesStatus
|
||||
})
|
||||
|
||||
@@ -285,10 +374,18 @@ export default function EquipmentPage() {
|
||||
<p className="text-gray-600">管理所有消防设备的档案和状态</p>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<Button variant="outline">
|
||||
<Filter className="h-4 w-4 mr-2" />
|
||||
全部状态
|
||||
</Button>
|
||||
<Select value={statusFilter} onValueChange={setStatusFilter}>
|
||||
<SelectTrigger className="w-40">
|
||||
<Filter className="h-4 w-4 mr-2" />
|
||||
<SelectValue placeholder="筛选状态" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="all">全部状态</SelectItem>
|
||||
<SelectItem value="1">正常</SelectItem>
|
||||
<SelectItem value="2">即将到期</SelectItem>
|
||||
<SelectItem value="3">已到期</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<Button variant="outline">
|
||||
<Download className="h-4 w-4 mr-2" />
|
||||
导出数据
|
||||
@@ -441,6 +538,133 @@ export default function EquipmentPage() {
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
{/* 编辑设备对话框 */}
|
||||
<Dialog open={isEditEquipmentOpen} onOpenChange={setIsEditEquipmentOpen}>
|
||||
<DialogContent className="max-w-2xl">
|
||||
<DialogHeader>
|
||||
<DialogTitle>编辑设备</DialogTitle>
|
||||
<DialogDescription>修改设备基本信息和安装详情</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="edit-equipmentName">设备名称</Label>
|
||||
<Input
|
||||
id="edit-equipmentName"
|
||||
value={editEquipment.name}
|
||||
onChange={(e) => setEditEquipment({ ...editEquipment, name: e.target.value })}
|
||||
placeholder="请输入设备名称"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="edit-equipmentType">设备类型</Label>
|
||||
<Select
|
||||
value={editEquipment.type}
|
||||
onValueChange={(value) => setEditEquipment({ ...editEquipment, type: value })}
|
||||
disabled={loadingEquipmentTypes}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder={loadingEquipmentTypes ? "加载中..." : "选择设备类型"} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{Object.entries(equipmentTypes).map(([key, value]) => (
|
||||
<SelectItem key={key} value={key}>
|
||||
{value}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="edit-model">设备型号</Label>
|
||||
<Input
|
||||
id="edit-model"
|
||||
value={editEquipment.model}
|
||||
onChange={(e) => setEditEquipment({ ...editEquipment, model: e.target.value })}
|
||||
placeholder="请输入设备型号"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="edit-merchant">所属商户</Label>
|
||||
<Select
|
||||
value={editEquipment.merchantId}
|
||||
onValueChange={(value) => setEditEquipment({ ...editEquipment, merchantId: value })}
|
||||
disabled={loadingMerchants}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder={loadingMerchants ? "加载中..." : "选择商户"} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{merchants.map((merchant) => (
|
||||
<SelectItem key={merchant.id} value={merchant.merchantsId || merchant.id}>
|
||||
{merchant.merchantName}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="edit-location">安装位置</Label>
|
||||
<Input
|
||||
id="edit-location"
|
||||
value={editEquipment.location}
|
||||
onChange={(e) => setEditEquipment({ ...editEquipment, location: e.target.value })}
|
||||
placeholder="请输入安装位置"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="edit-installDate">安装日期</Label>
|
||||
<Input
|
||||
id="edit-installDate"
|
||||
type="date"
|
||||
value={editEquipment.installDate}
|
||||
onChange={(e) => setEditEquipment({ ...editEquipment, installDate: e.target.value })}
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="edit-status">设备状态</Label>
|
||||
<Select
|
||||
value={editEquipment.status}
|
||||
onValueChange={(value) => setEditEquipment({ ...editEquipment, status: value })}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="选择设备状态" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="normal">正常</SelectItem>
|
||||
<SelectItem value="expiring">即将到期</SelectItem>
|
||||
<SelectItem value="expired">已到期</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="col-span-2 space-y-2">
|
||||
<Label htmlFor="edit-notes">备注</Label>
|
||||
<Textarea
|
||||
id="edit-notes"
|
||||
value={editEquipment.notes}
|
||||
onChange={(e) => setEditEquipment({ ...editEquipment, notes: e.target.value })}
|
||||
placeholder="请输入备注信息"
|
||||
rows={3}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex justify-end space-x-2 mt-6">
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => setIsEditEquipmentOpen(false)}
|
||||
disabled={isSubmitting}
|
||||
>
|
||||
取消
|
||||
</Button>
|
||||
<Button
|
||||
onClick={handleUpdateEquipment}
|
||||
disabled={!editEquipment.name || !editEquipment.type || !editEquipment.merchantId || isSubmitting}
|
||||
>
|
||||
{isSubmitting ? "更新中..." : "更新设备"}
|
||||
</Button>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -454,6 +678,38 @@ export default function EquipmentPage() {
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
{/* 筛选区域 */}
|
||||
<div className="flex flex-col sm:flex-row gap-4 mb-6">
|
||||
<div className="flex-1">
|
||||
<div className="relative">
|
||||
<MapPin className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 h-4 w-4" />
|
||||
<Input
|
||||
placeholder="搜索设备名称、商户或商场..."
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
className="pl-10"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Select value={statusFilter} onValueChange={setStatusFilter}>
|
||||
<SelectTrigger className="w-full sm:w-40">
|
||||
<SelectValue placeholder="筛选状态" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="all">全部状态</SelectItem>
|
||||
<SelectItem value="1">正常</SelectItem>
|
||||
<SelectItem value="2">即将到期</SelectItem>
|
||||
<SelectItem value="3">已到期</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
<Button variant="outline">
|
||||
<Download className="h-4 w-4 mr-2" />
|
||||
导出
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="rounded-md border">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
@@ -526,9 +782,13 @@ export default function EquipmentPage() {
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<div className="flex items-center justify-center">
|
||||
<Button variant="ghost" size="sm">
|
||||
<span className="text-lg">⋯</span>
|
||||
<div className="flex items-center justify-center space-x-2">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => handleEditEquipment(item)}
|
||||
>
|
||||
编辑
|
||||
</Button>
|
||||
</div>
|
||||
</TableCell>
|
||||
|
Reference in New Issue
Block a user