From 53ea1e8395f6ec26b29fa84fec14b6b6bc50a8eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=AC=94=E8=AE=B0=E6=9C=AC=E9=87=8C=E7=9A=84=E6=B0=B8?= =?UTF-8?q?=E5=B9=B3?= Date: Thu, 10 Jul 2025 16:19:16 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=9C=AC=E6=AC=A1=E6=8F=90=E4=BA=A4?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=86=85=E5=AE=B9=E5=A6=82=E4=B8=8B=20?= =?UTF-8?q?=E6=9E=84=E5=BB=BA=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nkebao/src/components/FriendSelection.tsx | 548 +++++++++--------- .../traffic-distribution/NewDistribution.tsx | 175 +----- 2 files changed, 286 insertions(+), 437 deletions(-) diff --git a/nkebao/src/components/FriendSelection.tsx b/nkebao/src/components/FriendSelection.tsx index f18ec377..d35459cd 100644 --- a/nkebao/src/components/FriendSelection.tsx +++ b/nkebao/src/components/FriendSelection.tsx @@ -1,275 +1,275 @@ -import React, { useState, useEffect } from 'react'; -import { Search, X } from 'lucide-react'; -import { Button } from '@/components/ui/button'; -import { Input } from '@/components/ui/input'; -import { ScrollArea } from '@/components/ui/scroll-area'; -import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'; -import { get } from '@/api/request'; - -// 微信好友接口类型 -interface WechatFriend { - id: string; - nickname: string; - wechatId: string; - avatar: string; - customer: string; -} - -// 好友列表API响应类型 -interface FriendsResponse { - code: number; - msg: string; - data: { - list: Array<{ - id: number; - nickname: string; - wechatId: string; - avatar?: string; - customer?: string; - }>; - total: number; - page: number; - limit: number; - }; -} - -// 获取好友列表API函数 -const fetchFriendsList = async (page: number = 1, limit: number = 20, deviceIds: string[]): Promise => { - if (deviceIds.length === 0) { - return { - code: 200, - msg: 'success', - data: { - list: [], - total: 0, - page, - limit - } - }; - } - - const deviceIdsParam = deviceIds.join(','); - return get(`/v1/friend?page=${page}&limit=${limit}&deviceIds=${deviceIdsParam}`); -}; - -// 组件属性接口 -interface FriendSelectionProps { - selectedFriends: string[]; - onSelect: (friends: string[]) => void; - deviceIds: string[]; - placeholder?: string; - className?: string; -} - -export default function FriendSelection({ - selectedFriends, - onSelect, - deviceIds, - placeholder = "选择微信好友", - className = "" -}: FriendSelectionProps) { - const [dialogOpen, setDialogOpen] = useState(false); - const [friends, setFriends] = useState([]); - const [searchQuery, setSearchQuery] = useState(''); - const [currentPage, setCurrentPage] = useState(1); - const [totalPages, setTotalPages] = useState(1); - const [totalFriends, setTotalFriends] = useState(0); - const [loading, setLoading] = useState(false); - - // 当弹窗打开时获取好友列表 - useEffect(() => { - if (dialogOpen && deviceIds.length > 0) { - fetchFriends(currentPage); - } - }, [dialogOpen, currentPage, deviceIds]); - - // 当设备ID变化时,重置页码 - useEffect(() => { - if (deviceIds.length > 0) { - setCurrentPage(1); - } - }, [deviceIds]); - - // 获取好友列表API - const fetchFriends = async (page: number) => { - if (deviceIds.length === 0) return; - - setLoading(true); - try { - const res = await fetchFriendsList(page, 20, deviceIds); - - if (res && res.code === 200 && res.data) { - setFriends(res.data.list.map((friend) => ({ - id: friend.id?.toString() || '', - nickname: friend.nickname || '', - wechatId: friend.wechatId || '', - avatar: friend.avatar || '', - customer: friend.customer || '', - }))); - - setTotalFriends(res.data.total || 0); - setTotalPages(Math.ceil((res.data.total || 0) / 20)); - } - } catch (error) { - console.error('获取好友列表失败:', error); - } finally { - setLoading(false); - } - }; - - // 过滤好友 - const filteredFriends = friends.filter(friend => - friend.nickname.toLowerCase().includes(searchQuery.toLowerCase()) || - friend.wechatId.toLowerCase().includes(searchQuery.toLowerCase()) - ); - - // 处理好友选择 - const handleFriendToggle = (friendId: string) => { - if (selectedFriends.includes(friendId)) { - onSelect(selectedFriends.filter(id => id !== friendId)); - } else { - onSelect([...selectedFriends, friendId]); - } - }; - - // 获取显示文本 - const getDisplayText = () => { - if (selectedFriends.length === 0) return ''; - return `已选择 ${selectedFriends.length} 个好友`; - }; - - const handleConfirm = () => { - setDialogOpen(false); - }; - - return ( - <> - {/* 输入框 */} -
- - - - - - setDialogOpen(true)} - value={getDisplayText()} - /> -
- - {/* 微信好友选择弹窗 */} - - -
- 选择微信好友 - -
- setSearchQuery(e.target.value)} - className="pl-10 py-2 rounded-full border-gray-200" - /> - - -
-
- - - {loading ? ( -
-
加载中...
-
- ) : filteredFriends.length > 0 ? ( -
- {filteredFriends.map((friend) => ( - - ))} -
- ) : ( -
-
- {deviceIds.length === 0 ? '请先选择设备' : '没有找到好友'} -
-
- )} -
- -
-
- 总计 {totalFriends} 个好友 -
-
- - {currentPage} / {totalPages} - -
-
- -
- - -
-
-
- - ); +import React, { useState, useEffect } from 'react'; +import { Search, X } from 'lucide-react'; +import { Button } from '@/components/ui/button'; +import { Input } from '@/components/ui/input'; +import { ScrollArea } from '@/components/ui/scroll-area'; +import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'; +import { get } from '@/api/request'; + +// 微信好友接口类型 +interface WechatFriend { + id: string; + nickname: string; + wechatId: string; + avatar: string; + customer: string; +} + +// 好友列表API响应类型 +interface FriendsResponse { + code: number; + msg: string; + data: { + list: Array<{ + id: number; + nickname: string; + wechatId: string; + avatar?: string; + customer?: string; + }>; + total: number; + page: number; + limit: number; + }; +} + +// 获取好友列表API函数 +const fetchFriendsList = async (page: number = 1, limit: number = 20, deviceIds: string[]): Promise => { + if (deviceIds.length === 0) { + return { + code: 200, + msg: 'success', + data: { + list: [], + total: 0, + page, + limit + } + }; + } + + const deviceIdsParam = deviceIds.join(','); + return get(`/v1/friend?page=${page}&limit=${limit}&deviceIds=${deviceIdsParam}`); +}; + +// 组件属性接口 +interface FriendSelectionProps { + selectedFriends: string[]; + onSelect: (friends: string[]) => void; + deviceIds: string[]; + placeholder?: string; + className?: string; +} + +export default function FriendSelection({ + selectedFriends, + onSelect, + deviceIds, + placeholder = "选择微信好友", + className = "" +}: FriendSelectionProps) { + const [dialogOpen, setDialogOpen] = useState(false); + const [friends, setFriends] = useState([]); + const [searchQuery, setSearchQuery] = useState(''); + const [currentPage, setCurrentPage] = useState(1); + const [totalPages, setTotalPages] = useState(1); + const [totalFriends, setTotalFriends] = useState(0); + const [loading, setLoading] = useState(false); + + // 当弹窗打开时获取好友列表 + useEffect(() => { + if (dialogOpen && deviceIds.length > 0) { + fetchFriends(currentPage); + } + }, [dialogOpen, currentPage, deviceIds]); + + // 当设备ID变化时,重置页码 + useEffect(() => { + if (deviceIds.length > 0) { + setCurrentPage(1); + } + }, [deviceIds]); + + // 获取好友列表API + const fetchFriends = async (page: number) => { + if (deviceIds.length === 0) return; + + setLoading(true); + try { + const res = await fetchFriendsList(page, 20, deviceIds); + + if (res && res.code === 200 && res.data) { + setFriends(res.data.list.map((friend) => ({ + id: friend.id?.toString() || '', + nickname: friend.nickname || '', + wechatId: friend.wechatId || '', + avatar: friend.avatar || '', + customer: friend.customer || '', + }))); + + setTotalFriends(res.data.total || 0); + setTotalPages(Math.ceil((res.data.total || 0) / 20)); + } + } catch (error) { + console.error('获取好友列表失败:', error); + } finally { + setLoading(false); + } + }; + + // 过滤好友 + const filteredFriends = friends.filter(friend => + friend.nickname.toLowerCase().includes(searchQuery.toLowerCase()) || + friend.wechatId.toLowerCase().includes(searchQuery.toLowerCase()) + ); + + // 处理好友选择 + const handleFriendToggle = (friendId: string) => { + if (selectedFriends.includes(friendId)) { + onSelect(selectedFriends.filter(id => id !== friendId)); + } else { + onSelect([...selectedFriends, friendId]); + } + }; + + // 获取显示文本 + const getDisplayText = () => { + if (selectedFriends.length === 0) return ''; + return `已选择 ${selectedFriends.length} 个好友`; + }; + + const handleConfirm = () => { + setDialogOpen(false); + }; + + return ( + <> + {/* 输入框 */} +
+ + + + + + setDialogOpen(true)} + value={getDisplayText()} + /> +
+ + {/* 微信好友选择弹窗 */} + + +
+ 选择微信好友 + +
+ setSearchQuery(e.target.value)} + className="pl-10 py-2 rounded-full border-gray-200" + /> + + +
+
+ + + {loading ? ( +
+
加载中...
+
+ ) : filteredFriends.length > 0 ? ( +
+ {filteredFriends.map((friend) => ( + + ))} +
+ ) : ( +
+
+ {deviceIds.length === 0 ? '请先选择设备' : '没有找到好友'} +
+
+ )} +
+ +
+
+ 总计 {totalFriends} 个好友 +
+
+ + {currentPage} / {totalPages} + +
+
+ +
+ + +
+
+
+ + ); } \ No newline at end of file diff --git a/nkebao/src/pages/workspace/traffic-distribution/NewDistribution.tsx b/nkebao/src/pages/workspace/traffic-distribution/NewDistribution.tsx index 51993e6c..d08c074b 100644 --- a/nkebao/src/pages/workspace/traffic-distribution/NewDistribution.tsx +++ b/nkebao/src/pages/workspace/traffic-distribution/NewDistribution.tsx @@ -11,38 +11,15 @@ import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group'; -import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { Checkbox } from '@/components/ui/checkbox'; import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'; import Layout from '@/components/Layout'; import PageHeader from '@/components/PageHeader'; +import DeviceSelection from '@/components/DeviceSelection'; import { useToast } from '@/components/ui/toast'; import { fetchAccountList, Account } from '@/api/trafficDistribution'; import '@/components/Layout.css'; -// 移除原来的步骤指示器组件 -// function StepIndicator({ currentStep, steps }: { currentStep: number; steps: Step[] }) { -// return ( -//
-// {steps.map((step, index) => ( -//
-//
-// {React.cloneElement(step.icon as React.ReactElement, { className: "w-5 h-5" })} -//
-// {index < steps.length - 1 && ( -//
-// )} -//
-// ))} -//
-// ); -// } - interface BasicInfoData { name: string; distributionMethod: 'equal' | 'priority' | 'ratio'; @@ -55,7 +32,6 @@ interface BasicInfoData { interface TargetSettingsData { selectedDevices: string[]; - selectedCustomerServices: string[]; } interface TrafficPoolData { @@ -68,18 +44,6 @@ interface FormData { trafficPool: Partial; } -interface Device { - id: string; - name: string; - status: 'online' | 'offline'; -} - -interface CustomerService { - id: string; - name: string; - status: 'online' | 'offline'; -} - interface TrafficPool { id: string; name: string; @@ -367,7 +331,7 @@ export default function NewDistribution() { } }; - // 基本信息步骤组件 + // 基本信息步骤组件 const BasicInfoStep = ({ onNext, initialData = {} }: { onNext: (data: BasicInfoData) => void; initialData?: Partial }) => { const [formData, setFormData] = useState({ name: initialData.name || generateDefaultName(), @@ -579,50 +543,11 @@ export default function NewDistribution() { // 目标设置步骤组件 const TargetSettingsStep = ({ onNext, onBack, initialData = {} }: { onNext: (data: TargetSettingsData) => void; onBack: () => void; initialData?: Partial }) => { const [selectedDevices, setSelectedDevices] = useState(initialData.selectedDevices || []); - const [selectedCustomerServices, setSelectedCustomerServices] = useState(initialData.selectedCustomerServices || []); - const [searchTerm, setSearchTerm] = useState(""); - - // 模拟设备数据 - const devices: Device[] = [ - { id: "1", name: "设备 1", status: "online" }, - { id: "2", name: "设备 2", status: "online" }, - { id: "3", name: "设备 3", status: "offline" }, - { id: "4", name: "设备 4", status: "online" }, - { id: "5", name: "设备 5", status: "offline" }, - ]; - - // 模拟客服数据 - const customerServices: CustomerService[] = [ - { id: "1", name: "客服 A", status: "online" }, - { id: "2", name: "客服 B", status: "online" }, - { id: "3", name: "客服 C", status: "offline" }, - { id: "4", name: "客服 D", status: "online" }, - ]; - - const filteredDevices = devices.filter(device => - device.name.toLowerCase().includes(searchTerm.toLowerCase()) - ); - - const filteredCustomerServices = customerServices.filter(cs => - cs.name.toLowerCase().includes(searchTerm.toLowerCase()) - ); - - const toggleDevice = (id: string) => { - setSelectedDevices(prev => - prev.includes(id) ? prev.filter(deviceId => deviceId !== id) : [...prev, id] - ); - }; - - const toggleCustomerService = (id: string) => { - setSelectedCustomerServices(prev => - prev.includes(id) ? prev.filter(csId => csId !== id) : [...prev, id] - ); - }; const handleSubmit = () => { - if (selectedDevices.length === 0 && selectedCustomerServices.length === 0) { + if (selectedDevices.length === 0) { toast({ - title: "请选择至少一个设备或客服", + title: "请选择至少一个设备", variant: "destructive" }); return; @@ -630,102 +555,26 @@ export default function NewDistribution() { onNext({ selectedDevices, - selectedCustomerServices, }); }; return (

目标设置

- -
-
- - setSearchTerm(e.target.value)} - className="pl-10 h-12" - /> -
+ +
+
- - - 设备选择 - 客服选择 - - - -
- {filteredDevices.map(device => ( -
toggleDevice(device.id)} - > -
-
-
- - {device.name.substring(2, 3)} - -
-
-

{device.name}

-

- {device.status === "online" ? "在线" : "离线"} -

-
-
- toggleDevice(device.id)} - /> -
-
- ))} -
-
- - -
- {filteredCustomerServices.map(cs => ( -
toggleCustomerService(cs.id)} - > -
-
-
- - {cs.name.substring(2, 3)} - -
-
-

{cs.name}

-

- {cs.status === "online" ? "在线" : "离线"} -

-
-
- toggleCustomerService(cs.id)} - /> -
-
- ))} -
-
-
-
-