diff --git a/nkebao/.env.development b/nkebao/.env.development index 05c62ec4..f37023e8 100644 --- a/nkebao/.env.development +++ b/nkebao/.env.development @@ -1,5 +1,5 @@ # 基础环境变量示例 -# VITE_API_BASE_URL=http://www.yishi.com +VITE_API_BASE_URL=http://www.yishi.com VITE_API_BASE_URL=https://ckbapi.quwanzhi.com VITE_APP_TITLE=Nkebao Base diff --git a/nkebao/src/api/devices.ts b/nkebao/src/api/devices.ts new file mode 100644 index 00000000..b39c7683 --- /dev/null +++ b/nkebao/src/api/devices.ts @@ -0,0 +1,44 @@ +import request from "./request"; + +// 获取设备列表 +export const fetchDeviceList = (params: { + page?: number; + limit?: number; + keyword?: string; +}) => request("/v1/devices", params, "GET"); + +// 获取设备详情 +export const fetchDeviceDetail = (id: string | number) => + request(`/v1/devices/${id}`); + +// 获取设备关联微信账号 +export const fetchDeviceRelatedAccounts = (id: string | number) => + request(`/v1/wechats/related-device/${id}`); + +// 获取设备操作日志 +export const fetchDeviceHandleLogs = ( + id: string | number, + page = 1, + limit = 10 +) => request(`/v1/devices/${id}/handle-logs`, { page, limit }, "GET"); + +// 更新设备任务配置 +export const updateDeviceTaskConfig = (config: { + deviceId: string | number; + autoAddFriend?: boolean; + autoReply?: boolean; + momentsSync?: boolean; + aiChat?: boolean; +}) => request("/v1/devices/task-config", config, "POST"); + +// 删除设备 +export const deleteDevice = (id: number) => + request(`/v1/devices/${id}`, undefined, "DELETE"); + +// 获取设备二维码 +export const fetchDeviceQRCode = (accountId: string) => + request("/v1/api/device/add", { accountId }, "POST"); + +// 通过IMEI添加设备 +export const addDeviceByImei = (imei: string, name: string) => + request("/v1/api/device/add-by-imei", { imei, name }, "POST"); diff --git a/nkebao/src/components/FriendSelection/index.module.scss b/nkebao/src/components/FriendSelection/index.module.scss index 0c82db96..663353e8 100644 --- a/nkebao/src/components/FriendSelection/index.module.scss +++ b/nkebao/src/components/FriendSelection/index.module.scss @@ -205,13 +205,21 @@ } .popupFooter { - border-top: 1px solid #f0f0f0; - padding: 16px; display: flex; align-items: center; justify-content: space-between; + padding: 16px; + border-top: 1px solid #f0f0f0; background: #fff; } +.selectedCount { + font-size: 14px; + color: #888; +} +.footerBtnGroup { + display: flex; + gap: 12px; +} .cancelBtn { padding: 0 24px; border-radius: 24px; diff --git a/nkebao/src/components/FriendSelection/index.tsx b/nkebao/src/components/FriendSelection/index.tsx index d67aa0ff..51598c53 100644 --- a/nkebao/src/components/FriendSelection/index.tsx +++ b/nkebao/src/components/FriendSelection/index.tsx @@ -1,11 +1,7 @@ import React, { useState, useEffect } from "react"; -import { - SearchOutlined, - CloseOutlined, - LeftOutlined, - RightOutlined, -} from "@ant-design/icons"; -import { Input, Button, Popup, Toast } from "antd-mobile"; +import { SearchOutlined, DeleteOutlined } from "@ant-design/icons"; +import { Popup, Toast } from "antd-mobile"; +import { Button, Input } from "antd"; import { getFriendList } from "./api"; import style from "./index.module.scss"; @@ -29,6 +25,11 @@ interface FriendSelectionProps { className?: string; visible?: boolean; // 新增 onVisibleChange?: (visible: boolean) => void; // 新增 + selectedListMaxHeight?: number; + showInput?: boolean; + showSelectedList?: boolean; + readonly?: boolean; + onConfirm?: (selectedIds: string[], selectedItems: WechatFriend[]) => void; // 新增 } export default function FriendSelection({ @@ -41,6 +42,11 @@ export default function FriendSelection({ className = "", visible, onVisibleChange, + selectedListMaxHeight = 300, + showInput = true, + showSelectedList = true, + readonly = false, + onConfirm, }: FriendSelectionProps) { const [popupVisible, setPopupVisible] = useState(false); const [friends, setFriends] = useState([]); @@ -59,6 +65,7 @@ export default function FriendSelection({ // 打开弹窗并请求第一页好友 const openPopup = () => { + if (readonly) return; setCurrentPage(1); setSearchQuery(""); setRealVisible(true); @@ -152,8 +159,23 @@ export default function FriendSelection({ return `已选择 ${selectedFriends.length} 个好友`; }; + // 获取已选好友详细信息 + const selectedFriendObjs = selectedFriends + .map((id) => friends.find((f) => f.id === id)) + .filter(Boolean) as WechatFriend[]; + + // 删除已选好友 + const handleRemoveFriend = (id: string) => { + if (readonly) return; + onSelect(selectedFriends.filter((f) => f !== id)); + }; + + // 确认按钮逻辑 const handleConfirm = () => { - setPopupVisible(false); + setRealVisible(false); + if (onConfirm) { + onConfirm(selectedFriends, selectedFriendObjs); + } }; // 清空搜索 @@ -166,35 +188,85 @@ export default function FriendSelection({ return ( <> {/* 输入框 */} -
- - - - - - -
- - {/* 微信好友选择弹窗 */} + {showInput && ( +
+ } + allowClear={!readonly} + size="large" + readOnly={readonly} + disabled={readonly} + style={ + readonly ? { background: "#f5f5f5", cursor: "not-allowed" } : {} + } + /> +
+ )} + {/* 已选好友列表窗口 */} + {showSelectedList && selectedFriendObjs.length > 0 && ( +
+ {selectedFriendObjs.map((friend) => ( +
+
+ {friend.nickname || friend.wechatId || friend.id} +
+ {!readonly && ( +
+ ))} +
+ )} + {/* 弹窗 */} setRealVisible(false)} position="bottom" bodyStyle={{ height: "100vh" }} @@ -206,23 +278,33 @@ export default function FriendSelection({ setSearchQuery(val)} - className={style.searchInput} + onChange={(e) => setSearchQuery(e.target.value)} + disabled={readonly} + prefix={} + allowClear + size="large" /> - - {searchQuery && ( + {searchQuery && !readonly && ( + style={{ + color: "#ff4d4f", + border: "none", + background: "none", + minWidth: 24, + height: 24, + display: "flex", + alignItems: "center", + justifyContent: "center", + }} + /> )} -
{loading ? (
@@ -234,7 +316,7 @@ export default function FriendSelection({