From c76c6e65ea96efd6d424aa1b4467e8dd9a4ea90e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9F=B3=E6=B8=85=E7=88=BD?= Date: Mon, 7 Apr 2025 15:09:07 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=BB=BA=E8=8E=B7=E5=AE=A2=E8=AE=A1?= =?UTF-8?q?=E5=88=92=20-=20=E8=AE=BE=E5=A4=87=E9=80=89=E6=8B=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plans/new/steps/FriendRequestSettings.tsx | 141 +++++++--- Server/application/plan/controller/Tag.php | 247 ------------------ Server/application/plan/model/Tag.php | 125 --------- Server/application/plan/route.php | 5 - 4 files changed, 108 insertions(+), 410 deletions(-) delete mode 100644 Server/application/plan/controller/Tag.php delete mode 100644 Server/application/plan/model/Tag.php diff --git a/Cunkebao/app/plans/new/steps/FriendRequestSettings.tsx b/Cunkebao/app/plans/new/steps/FriendRequestSettings.tsx index 763f725b..c63eba71 100755 --- a/Cunkebao/app/plans/new/steps/FriendRequestSettings.tsx +++ b/Cunkebao/app/plans/new/steps/FriendRequestSettings.tsx @@ -5,13 +5,15 @@ import { Card } from "@/components/ui/card" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" -import { HelpCircle, MessageSquare, AlertCircle } from "lucide-react" +import { HelpCircle, MessageSquare, AlertCircle, RefreshCw } from "lucide-react" import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog" import { Alert, AlertDescription } from "@/components/ui/alert" import { ChevronsUpDown } from "lucide-react" import { Checkbox } from "@/components/ui/checkbox" +import { fetchDeviceList } from "@/api/devices" +import type { ServerDevice } from "@/types/device" interface FriendRequestSettingsProps { formData: any @@ -36,20 +38,15 @@ const remarkTypes = [ { value: "source", label: "来源" }, ] -// 模拟设备数据 -const mockDevices = [ - { id: "1", name: "iPhone 13 Pro", status: "online" }, - { id: "2", name: "Xiaomi 12", status: "online" }, - { id: "3", name: "Huawei P40", status: "offline" }, - { id: "4", name: "OPPO Find X3", status: "online" }, - { id: "5", name: "Samsung S21", status: "online" }, -] - export function FriendRequestSettings({ formData, onChange, onNext, onPrev }: FriendRequestSettingsProps) { const [isTemplateDialogOpen, setIsTemplateDialogOpen] = useState(false) const [hasWarnings, setHasWarnings] = useState(false) const [isDeviceSelectorOpen, setIsDeviceSelectorOpen] = useState(false) - const [selectedDevices, setSelectedDevices] = useState(formData.selectedDevices || []) + const [selectedDevices, setSelectedDevices] = useState(formData.selectedDevices || []) + const [devices, setDevices] = useState([]) + const [loadingDevices, setLoadingDevices] = useState(false) + const [deviceError, setDeviceError] = useState(null) + const [searchKeyword, setSearchKeyword] = useState("") // 获取场景标题 const getScenarioTitle = () => { @@ -67,6 +64,33 @@ export function FriendRequestSettings({ formData, onChange, onNext, onPrev }: Fr } } + // 加载设备列表 + const loadDevices = async () => { + try { + setLoadingDevices(true) + setDeviceError(null) + + const response = await fetchDeviceList(1, 100, searchKeyword) + + if (response.code === 200 && response.data?.list) { + setDevices(response.data.list) + } else { + setDeviceError(response.msg || "获取设备列表失败") + console.error("获取设备列表失败:", response.msg) + } + } catch (err) { + console.error("获取设备列表失败:", err) + setDeviceError("获取设备列表失败,请稍后重试") + } finally { + setLoadingDevices(false) + } + } + + // 初始化时加载设备列表 + useEffect(() => { + loadDevices() + }, []) + // 使用useEffect设置默认值 useEffect(() => { if (!formData.greeting) { @@ -96,7 +120,7 @@ export function FriendRequestSettings({ formData, onChange, onNext, onPrev }: Fr onNext() } - const toggleDeviceSelection = (device: any) => { + const toggleDeviceSelection = (device: ServerDevice) => { const isSelected = selectedDevices.some((d) => d.id === device.id) let newSelectedDevices @@ -110,6 +134,11 @@ export function FriendRequestSettings({ formData, onChange, onNext, onPrev }: Fr onChange({ ...formData, selectedDevices: newSelectedDevices }) } + // 根据关键词搜索设备 + const handleSearch = () => { + loadDevices() + } + return (
@@ -128,31 +157,77 @@ export function FriendRequestSettings({ formData, onChange, onNext, onPrev }: Fr {isDeviceSelectorOpen && (
- -
- {mockDevices.map((device) => ( -
toggleDeviceSelection(device)} - > -
- d.id === device.id)} - onCheckedChange={() => toggleDeviceSelection(device)} - /> - {device.name} -
- - {device.status === "online" ? "在线" : "离线"} - -
- ))} +
+ setSearchKeyword(e.target.value)} + onKeyDown={(e) => e.key === 'Enter' && handleSearch()} + /> +
+ + {loadingDevices ? ( +
+
+
+ ) : deviceError ? ( +
+ {deviceError} + +
+ ) : devices.length === 0 ? ( +
+ 没有找到设备 +
+ ) : ( +
+ {devices.map((device) => ( +
toggleDeviceSelection(device)} + > +
+ d.id === device.id)} + onCheckedChange={() => toggleDeviceSelection(device)} + /> + {device.memo} +
+ + {device.alive === 1 ? "在线" : "离线"} + +
+ ))} +
+ )}
)}
+ + {selectedDevices.length > 0 && ( +
+ {selectedDevices.map((device) => ( +
+ {device.memo} + +
+ ))} +
+ )}
@@ -239,7 +314,7 @@ export function FriendRequestSettings({ formData, onChange, onNext, onPrev }: Fr
{hasWarnings && ( - + 您有未完成的设置项,建议完善后再进入下一步。 diff --git a/Server/application/plan/controller/Tag.php b/Server/application/plan/controller/Tag.php deleted file mode 100644 index 12a0ff8d..00000000 --- a/Server/application/plan/controller/Tag.php +++ /dev/null @@ -1,247 +0,0 @@ - 200, - 'msg' => '获取成功', - 'data' => $tags - ]); - } - - /** - * 创建标签 - * - * @return \think\response\Json - */ - public function save() - { - $data = Request::post(); - - // 数据验证 - if (empty($data['name']) || empty($data['type'])) { - return json([ - 'code' => 400, - 'msg' => '缺少必要参数' - ]); - } - - try { - // 创建或获取标签 - $tagId = TagModel::getOrCreate($data['name'], $data['type']); - - return json([ - 'code' => 200, - 'msg' => '创建成功', - 'data' => $tagId - ]); - - } catch (\Exception $e) { - Log::error('创建标签异常', [ - 'data' => $data, - 'error' => $e->getMessage(), - 'trace' => $e->getTraceAsString() - ]); - - return json([ - 'code' => 500, - 'msg' => '创建失败:' . $e->getMessage() - ]); - } - } - - /** - * 批量创建标签 - * - * @return \think\response\Json - */ - public function batchCreate() - { - $data = Request::post(); - - // 数据验证 - if (empty($data['names']) || empty($data['type'])) { - return json([ - 'code' => 400, - 'msg' => '缺少必要参数' - ]); - } - - // 检查名称数组 - if (!is_array($data['names'])) { - return json([ - 'code' => 400, - 'msg' => '标签名称必须是数组' - ]); - } - - try { - $result = []; - - // 批量处理标签 - foreach ($data['names'] as $name) { - $name = trim($name); - if (empty($name)) continue; - - $tagId = TagModel::getOrCreate($name, $data['type']); - $result[] = [ - 'id' => $tagId, - 'name' => $name, - 'type' => $data['type'] - ]; - } - - return json([ - 'code' => 200, - 'msg' => '创建成功', - 'data' => $result - ]); - - } catch (\Exception $e) { - Log::error('批量创建标签异常', [ - 'data' => $data, - 'error' => $e->getMessage(), - 'trace' => $e->getTraceAsString() - ]); - - return json([ - 'code' => 500, - 'msg' => '创建失败:' . $e->getMessage() - ]); - } - } - - /** - * 更新标签 - * - * @param int $id - * @return \think\response\Json - */ - public function update($id) - { - $data = Request::put(); - - // 检查标签是否存在 - $tag = TagModel::get($id); - if (!$tag) { - return json([ - 'code' => 404, - 'msg' => '标签不存在' - ]); - } - - // 准备更新数据 - $updateData = []; - - // 只允许更新特定字段 - $allowedFields = ['name', 'status']; - foreach ($allowedFields as $field) { - if (isset($data[$field])) { - $updateData[$field] = $data[$field]; - } - } - - // 更新标签 - $tag->save($updateData); - - // 如果更新了标签名称,且该标签有使用次数,则增加计数 - if (isset($updateData['name']) && $updateData['name'] != $tag->name && $tag->count > 0) { - $tag->updateCount(1); - } - - return json([ - 'code' => 200, - 'msg' => '更新成功' - ]); - } - - /** - * 删除标签 - * - * @param int $id - * @return \think\response\Json - */ - public function delete($id) - { - // 检查标签是否存在 - $tag = TagModel::get($id); - if (!$tag) { - return json([ - 'code' => 404, - 'msg' => '标签不存在' - ]); - } - - // 更新状态为删除 - $tag->save([ - 'status' => 0 - ]); - - return json([ - 'code' => 200, - 'msg' => '删除成功' - ]); - } - - /** - * 获取标签名称 - * - * @return \think\response\Json - */ - public function getNames() - { - $ids = Request::param('ids'); - - // 验证参数 - if (empty($ids)) { - return json([ - 'code' => 400, - 'msg' => '缺少标签ID参数' - ]); - } - - // 处理参数 - if (is_string($ids)) { - $ids = explode(',', $ids); - } - - // 获取标签名称 - $names = TagModel::getTagNames($ids); - - return json([ - 'code' => 200, - 'msg' => '获取成功', - 'data' => $names - ]); - } -} \ No newline at end of file diff --git a/Server/application/plan/model/Tag.php b/Server/application/plan/model/Tag.php deleted file mode 100644 index 01813874..00000000 --- a/Server/application/plan/model/Tag.php +++ /dev/null @@ -1,125 +0,0 @@ - 'integer', - 'count' => 'integer', - 'status' => 'integer', - 'createTime' => 'integer', - 'updateTime' => 'integer' - ]; - - /** - * 获取或创建标签 - * @param string $name 标签名 - * @param string $type 标签类型 - * @param string $color 标签颜色 - * @return int 标签ID - */ - public static function getOrCreate($name, $type = 'traffic', $color = '') - { - $tag = self::where([ - ['name', '=', $name], - ['type', '=', $type] - ])->find(); - - if ($tag) { - return $tag['id']; - } else { - $model = new self(); - $model->save([ - 'name' => $name, - 'type' => $type, - 'color' => $color ?: self::getRandomColor(), - 'count' => 0, - 'status' => 1 - ]); - return $model->id; - } - } - - /** - * 更新标签使用次数 - * @param int $id 标签ID - * @param int $increment 增量 - * @return bool 更新结果 - */ - public static function updateCount($id, $increment = 1) - { - return self::where('id', $id)->inc('count', $increment)->update(); - } - - /** - * 获取标签列表 - * @param string $type 标签类型 - * @param array $where 额外条件 - * @return array 标签列表 - */ - public static function getTagsByType($type = 'traffic', $where = []) - { - $conditions = array_merge([ - ['type', '=', $type], - ['status', '=', 1] - ], $where); - - return self::where($conditions) - ->order('count DESC, id DESC') - ->select(); - } - - /** - * 根据ID获取标签名称 - * @param array $ids 标签ID数组 - * @return array 标签名称数组 - */ - public static function getTagNames($ids) - { - if (empty($ids)) { - return []; - } - - $tagIds = is_array($ids) ? $ids : explode(',', $ids); - - $tags = self::where('id', 'in', $tagIds)->column('name'); - - return $tags; - } - - /** - * 获取随机颜色 - * @return string 颜色代码 - */ - private static function getRandomColor() - { - $colors = [ - '#f44336', '#e91e63', '#9c27b0', '#673ab7', '#3f51b5', - '#2196f3', '#03a9f4', '#00bcd4', '#009688', '#4caf50', - '#8bc34a', '#cddc39', '#ffeb3b', '#ffc107', '#ff9800', - '#ff5722', '#795548', '#9e9e9e', '#607d8b' - ]; - - return $colors[array_rand($colors)]; - } -} \ No newline at end of file diff --git a/Server/application/plan/route.php b/Server/application/plan/route.php index 0b3964d5..f4c271ad 100644 --- a/Server/application/plan/route.php +++ b/Server/application/plan/route.php @@ -19,11 +19,6 @@ Route::group('api/plan', function () { Route::get('traffic/stats', 'plan/Traffic/sourceStats'); Route::post('traffic/import', 'plan/Traffic/importTraffic'); Route::post('traffic/external', 'plan/Traffic/handleExternalTraffic'); - - // 标签相关路由 - Route::resource('tags', 'plan/Tag'); - Route::post('tags/batch', 'plan/Tag/batchCreate'); - Route::get('tags/names', 'plan/Tag/getNames'); }); // 返回空数组,避免路由注册冲突