shebi xiufu

This commit is contained in:
menxipeng
2025-10-19 14:07:19 +08:00
parent 6cb2164dbe
commit 2f2cf47c6f

View File

@@ -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">
<Select value={statusFilter} onValueChange={setStatusFilter}>
<SelectTrigger className="w-40">
<Filter className="h-4 w-4 mr-2" />
</Button>
<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>