From 9c33603c04983f8e60cf31d6d0a717f54074fc5f Mon Sep 17 00:00:00 2001 From: wong <106998207@qq.com> Date: Thu, 17 Apr 2025 17:18:35 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96=E6=8F=90?= =?UTF-8?q?=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/device-selection-dialog.tsx | 9 +- .../components/device-selection-dialog.tsx | 234 ++++---- .../api/controller/WebSocketController.php | 6 +- .../device/GetDeviceListV1Controller.php | 5 +- Server/application/store/config/route.php | 7 + .../store/controller/StatisticsController.php | 97 ++-- .../controller/SystemConfigController.php | 93 ++- .../store/controller/VendorController.php | 534 ++++++++++++++++++ .../controller/VendorOrderController.php | 229 ++++++++ .../application/store/model/VendorModel.php | 34 ++ .../store/model/VendorOrderModel.php | 45 ++ .../store/model/VendorPackageModel.php | 50 ++ .../store/model/VendorProjectModel.php | 33 ++ Store_vue/api/modules/supply.js | 41 ++ Store_vue/components/PackageDetail.vue | 15 +- Store_vue/components/SideMenu.vue | 14 +- Store_vue/components/SupplyChainPurchase.vue | 339 ++++++----- Store_vue/components/SupplyItemDetail.vue | 341 ++++++++--- Store_vue/components/TrafficPurchase.vue | 11 - 19 files changed, 1657 insertions(+), 480 deletions(-) create mode 100644 Server/application/store/controller/VendorController.php create mode 100644 Server/application/store/controller/VendorOrderController.php create mode 100644 Server/application/store/model/VendorModel.php create mode 100644 Server/application/store/model/VendorOrderModel.php create mode 100644 Server/application/store/model/VendorPackageModel.php create mode 100644 Server/application/store/model/VendorProjectModel.php create mode 100644 Store_vue/api/modules/supply.js diff --git a/Cunkebao/app/workspace/auto-like/components/device-selection-dialog.tsx b/Cunkebao/app/workspace/auto-like/components/device-selection-dialog.tsx index cf66849f..25a23f7a 100644 --- a/Cunkebao/app/workspace/auto-like/components/device-selection-dialog.tsx +++ b/Cunkebao/app/workspace/auto-like/components/device-selection-dialog.tsx @@ -60,11 +60,12 @@ export function DeviceSelectionDialog({ open, onOpenChange, selectedDevices, onS if (response.code === 200 && response.data.list) { const transformedDevices: Device[] = response.data.list.map(device => ({ id: device.id, - name: device.memo || device.imei || '', + name: device.memo || '设备_' + device.id, imei: device.imei || '', - wxid: device.wechatId || '', + wxid: device.alias || device.wechatId || '', status: device.alive === 1 ? "online" : "offline", - totalFriend: device.totalFriend || 0 + totalFriend: device.totalFriend || 0, + nickname: device.nickname || '' })) setDevices(transformedDevices) } else { @@ -175,7 +176,7 @@ export function DeviceSelectionDialog({ open, onOpenChange, selectedDevices, onS
IMEI: {device.imei || '--'}
-
微信号: {device.wxid || '--'}
+
微信号: {device.wxid || '--'}({device.nickname || ''})
diff --git a/Cunkebao/app/workspace/moments-sync/components/device-selection-dialog.tsx b/Cunkebao/app/workspace/moments-sync/components/device-selection-dialog.tsx index a17158e3..25a23f7a 100644 --- a/Cunkebao/app/workspace/moments-sync/components/device-selection-dialog.tsx +++ b/Cunkebao/app/workspace/moments-sync/components/device-selection-dialog.tsx @@ -1,51 +1,58 @@ "use client" import { useState, useEffect } from "react" -import { Search, RefreshCw, Loader2 } from "lucide-react" import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog" import { Input } from "@/components/ui/input" import { Button } from "@/components/ui/button" -import { ScrollArea } from "@/components/ui/scroll-area" -import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" -import { Checkbox } from "@/components/ui/checkbox" -import { Label } from "@/components/ui/label" import { Badge } from "@/components/ui/badge" +import { Search, RefreshCw, Loader2 } from "lucide-react" +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" +import { ScrollArea } from "@/components/ui/scroll-area" +import { Checkbox } from "@/components/ui/checkbox" import { api } from "@/lib/api" import { showToast } from "@/lib/toast" +interface ServerDevice { + id: number + imei: string + memo: string + wechatId: string + alive: number + totalFriend: number +} + interface Device { - id: string + id: number name: string imei: string - wechatId: string - memo?: string - alive: number - usedInPlans: number - lastActiveTime: string + wxid: string + status: "online" | "offline" + totalFriend: number } interface DeviceSelectionDialogProps { open: boolean onOpenChange: (open: boolean) => void - selectedDevices: string[] - onSelect: (devices: string[]) => void + selectedDevices: number[] + onSelect: (devices: number[]) => void } -export function DeviceSelectionDialog({ - open, - onOpenChange, - selectedDevices, - onSelect, -}: DeviceSelectionDialogProps) { +export function DeviceSelectionDialog({ open, onOpenChange, selectedDevices, onSelect }: DeviceSelectionDialogProps) { const [searchQuery, setSearchQuery] = useState("") const [statusFilter, setStatusFilter] = useState("all") - const [loading, setLoading] = useState(false) const [devices, setDevices] = useState([]) - const [tempSelected, setTempSelected] = useState([]) + const [loading, setLoading] = useState(false) + const [tempSelectedDevices, setTempSelectedDevices] = useState(selectedDevices) + + useEffect(() => { + if (open) { + setTempSelectedDevices(selectedDevices) + fetchDevices() + } + }, [open, selectedDevices]) - // 获取设备列表 const fetchDevices = async () => { - setLoading(true) + const loadingToast = showToast("正在加载设备列表...", "loading", true); try { setLoading(true) const response = await api.get<{code: number, msg: string, data: {list: ServerDevice[], total: number}}>('/v1/devices?page=1&limit=100') @@ -53,86 +60,78 @@ export function DeviceSelectionDialog({ if (response.code === 200 && response.data.list) { const transformedDevices: Device[] = response.data.list.map(device => ({ id: device.id, - name: device.memo || "未命名设备", + name: device.memo || '设备_' + device.id, imei: device.imei || '', - wxid: device.wechatId || '', + wxid: device.alias || device.wechatId || '', status: device.alive === 1 ? "online" : "offline", - totalFriend: device.totalFriend || 0 + totalFriend: device.totalFriend || 0, + nickname: device.nickname || '' })) setDevices(transformedDevices) } else { showToast(response.msg || "获取设备列表失败", "error") } } catch (error: any) { - console.error("获取设备列表失败:", error) + console.error('获取设备列表失败:', error) showToast(error?.message || "请检查网络连接", "error") } finally { + loadingToast.remove(); setLoading(false) } } - useEffect(() => { - if (open) { - fetchDevices() - setTempSelected(selectedDevices) - } - }, [open, searchQuery, selectedDevices]) - const handleRefresh = () => { fetchDevices() } - const filteredDevices = devices.filter(device => { - const matchesSearch = !searchQuery || - device.name.toLowerCase().includes(searchQuery.toLowerCase()) || - device.imei.toLowerCase().includes(searchQuery.toLowerCase()) || - device.wechatId.toLowerCase().includes(searchQuery.toLowerCase()) - - const matchesStatus = statusFilter === "all" || - (statusFilter === "online" && device.alive === 1) || - (statusFilter === "offline" && device.alive === 0) + const handleDeviceToggle = (deviceId: number, checked: boolean) => { + if (checked) { + setTempSelectedDevices(prev => [...prev, deviceId]) + } else { + setTempSelectedDevices(prev => prev.filter(id => id !== deviceId)) + } + } + + const handleConfirm = () => { + onSelect(tempSelectedDevices) + onOpenChange(false) + } + + const handleCancel = () => { + setTempSelectedDevices(selectedDevices) + onOpenChange(false) + } + + const filteredDevices = devices.filter((device) => { + const searchLower = searchQuery.toLowerCase() + const matchesSearch = + (device.name || '').toLowerCase().includes(searchLower) || + (device.imei || '').toLowerCase().includes(searchLower) || + (device.wxid || '').toLowerCase().includes(searchLower) + + const matchesStatus = + statusFilter === "all" || + (statusFilter === "online" && device.status === "online") || + (statusFilter === "offline" && device.status === "offline") return matchesSearch && matchesStatus }) - const handleDialogOpenChange = (open: boolean) => { - if (!open) { - setTempSelected(selectedDevices) - } - onOpenChange(open) - } - - const handleSelectAll = () => { - if (tempSelected.length === filteredDevices.length) { - setTempSelected([]) - } else { - setTempSelected(filteredDevices.map(device => device.id)) - } - } - - const handleDeviceToggle = (deviceId: string) => { - setTempSelected(prev => - prev.includes(deviceId) - ? prev.filter(id => id !== deviceId) - : [...prev, deviceId] - ) - } - return ( - - + + 选择设备 -
+
setSearchQuery(e.target.value)} + className="pl-9" />