diff --git a/Cunkebao/src/pages/mobile/mine/wechat-accounts/detail/api.ts b/Cunkebao/src/pages/mobile/mine/wechat-accounts/detail/api.ts index 8c14f3e9..0165179a 100644 --- a/Cunkebao/src/pages/mobile/mine/wechat-accounts/detail/api.ts +++ b/Cunkebao/src/pages/mobile/mine/wechat-accounts/detail/api.ts @@ -55,6 +55,20 @@ export function transferWechatFriends(params: { return request("/v1/wechats/transfer-friends", params, "POST"); } +// 获取客服账号列表 +export function getKefuAccountsList() { + return request("/v1/kefu/accounts/list", {}, "GET"); +} + +// 转移好友到客服账号 +export function transferFriend(params: { + friendId: string; + toAccountId: string; + comment?: string; +}) { + return request("/v1/friend/transfer", params, "POST"); +} + // 导出朋友圈接口(直接下载文件) export async function exportWechatMoments(params: { wechatId: string; diff --git a/Cunkebao/src/pages/mobile/mine/wechat-accounts/detail/data.ts b/Cunkebao/src/pages/mobile/mine/wechat-accounts/detail/data.ts index 9245ba9f..6a374dba 100644 --- a/Cunkebao/src/pages/mobile/mine/wechat-accounts/detail/data.ts +++ b/Cunkebao/src/pages/mobile/mine/wechat-accounts/detail/data.ts @@ -102,9 +102,12 @@ export interface WechatAccountSummary { export interface Friend { id: string; + friendId?: string; avatar: string; nickname: string; wechatId: string; + accountUserName: string; + accountRealName: string; remark: string; addTime: string; lastInteraction: string; diff --git a/Cunkebao/src/pages/mobile/mine/wechat-accounts/detail/detail.module.scss b/Cunkebao/src/pages/mobile/mine/wechat-accounts/detail/detail.module.scss index 95c33d8a..41530573 100644 --- a/Cunkebao/src/pages/mobile/mine/wechat-accounts/detail/detail.module.scss +++ b/Cunkebao/src/pages/mobile/mine/wechat-accounts/detail/detail.module.scss @@ -684,99 +684,114 @@ .friend-card { display: flex; - align-items: center; - padding: 14px; + align-items: flex-start; + padding: 16px; background: #fff; border: 1px solid #f0f0f0; border-radius: 12px; - margin-bottom: 10px; + margin-bottom: 12px; gap: 12px; - transition: box-shadow 0.2s, border-color 0.2s; + transition: all 0.2s; + cursor: pointer; - &:hover { - border-color: #cfe2ff; - box-shadow: 0 6px 16px rgba(24, 144, 255, 0.15); + &:active { + background: #f8f9fa; + border-color: #1677ff; + transform: scale(0.98); } } .friend-avatar { - width: 48px; - height: 48px; + flex-shrink: 0; + width: 52px; + height: 52px; .adm-avatar { - width: 48px; - height: 48px; - border-radius: 50%; + width: 52px; + height: 52px; + border-radius: 50%; + border: 2px solid #f0f0f0; } } .friend-main { flex: 1; min-width: 0; - } - - .friend-name-row { - display: flex; - align-items: center; + display: flex; + flex-direction: column; gap: 8px; - margin-bottom: 4px; } - .friend-name { - font-size: 15px; + .friend-header { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + } + + .friend-name { + font-size: 16px; font-weight: 600; color: #111; + flex: 1; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .friend-value { flex-shrink: 0; + + .value-amount { + font-size: 15px; + font-weight: 600; + color: #fa541c; + white-space: nowrap; + } + } + + .friend-info { + display: flex; + flex-direction: column; + gap: 4px; + } + + .friend-info-item { + font-size: 13px; + color: #666; + display: flex; + align-items: center; + gap: 4px; + + .info-label { + color: #999; + flex-shrink: 0; + } + + .info-value { + color: #666; + flex: 1; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } } .friend-tags { display: flex; flex-wrap: wrap; - gap: 4px; - } + gap: 6px; + margin-top: 4px; + } .friend-tag { font-size: 11px; - padding: 2px 8px; - border-radius: 999px; - background: #f5f5f5; - color: #666; - } - - .friend-id-row { - font-size: 12px; - color: #999; - margin-bottom: 6px; - } - - .friend-status-row { - display: flex; - flex-wrap: wrap; - gap: 6px; - } - - .friend-status-chip { + padding: 4px 10px; + border-radius: 12px; background: #f0f7ff; color: #1677ff; - font-size: 11px; - padding: 2px 8px; - border-radius: 8px; - } - - .friend-value { - text-align: right; - - .value-label { - font-size: 11px; - color: #999; - margin-bottom: 4px; - } - - .value-amount { - font-size: 14px; - font-weight: 600; - color: #fa541c; - } + font-weight: 500; + white-space: nowrap; } } @@ -851,11 +866,98 @@ margin-top: 20px; } - .popup-footer { - margin-top: 24px; - padding-top: 16px; - border-top: 1px solid #f0f0f0; - } + .popup-footer { + margin-top: 24px; + padding-top: 16px; + border-top: 1px solid #f0f0f0; + } + + .friend-info-card { + display: flex; + align-items: center; + gap: 12px; + padding: 12px; + background: #f5f5f5; + border-radius: 8px; + + .friend-info-text { + flex: 1; + + .friend-info-name { + font-size: 14px; + font-weight: 500; + color: #333; + margin-bottom: 4px; + } + + .friend-info-id { + font-size: 12px; + color: #999; + } + } + } + + .loading-accounts, + .empty-accounts { + display: flex; + align-items: center; + justify-content: center; + padding: 20px; + color: #999; + font-size: 14px; + } + + .kefu-accounts-list { + display: flex; + flex-direction: column; + gap: 8px; + max-height: 300px; + overflow-y: auto; + + .kefu-account-item { + display: flex; + align-items: center; + justify-content: space-between; + padding: 12px; + border: 1px solid #e0e0e0; + border-radius: 8px; + cursor: pointer; + transition: all 0.2s; + background: white; + + &:hover { + border-color: #1677ff; + background: #f0f7ff; + } + + &.selected { + border-color: #1677ff; + background: #e6f4ff; + } + + .account-info { + flex: 1; + + .account-name { + font-size: 14px; + font-weight: 500; + color: #333; + margin-bottom: 4px; + } + + .account-id { + font-size: 12px; + color: #999; + } + } + + .selected-icon { + color: #1677ff; + font-size: 18px; + font-weight: bold; + } + } + } .export-form { margin-top: 20px; diff --git a/Cunkebao/src/pages/mobile/mine/wechat-accounts/detail/index.tsx b/Cunkebao/src/pages/mobile/mine/wechat-accounts/detail/index.tsx index 06609940..a985f182 100644 --- a/Cunkebao/src/pages/mobile/mine/wechat-accounts/detail/index.tsx +++ b/Cunkebao/src/pages/mobile/mine/wechat-accounts/detail/index.tsx @@ -14,7 +14,7 @@ import { DatePicker, InfiniteScroll, } from "antd-mobile"; -import { Input } from "antd"; +import { Input, Select } from "antd"; import NavCommon from "@/components/NavCommon"; import { SearchOutlined, @@ -34,6 +34,8 @@ import { getWechatAccountOverview, getWechatMoments, exportWechatMoments, + getKefuAccountsList, + transferFriend, } from "./api"; import DeviceSelection from "@/components/DeviceSelection"; import { DeviceSelectionItem } from "@/components/DeviceSelection/data"; @@ -84,6 +86,15 @@ const WechatAccountDetail: React.FC = () => { const [showEndTimePicker, setShowEndTimePicker] = useState(false); const [exportLoading, setExportLoading] = useState(false); + // 迁移好友相关状态 + const [showTransferFriendPopup, setShowTransferFriendPopup] = useState(false); + const [selectedFriend, setSelectedFriend] = useState(null); + const [kefuAccounts, setKefuAccounts] = useState([]); + const [selectedKefuAccountId, setSelectedKefuAccountId] = useState(""); + const [transferComment, setTransferComment] = useState(""); + const [transferFriendLoading, setTransferFriendLoading] = useState(false); + const [loadingKefuAccounts, setLoadingKefuAccounts] = useState(false); + // 获取基础信息 const fetchAccountInfo = useCallback(async () => { if (!id) return; @@ -237,9 +248,12 @@ const WechatAccountDetail: React.FC = () => { return { id: friend.id.toString(), + friendId: friend.friendId || friend.id?.toString() || "", avatar: friend.avatar || "/placeholder.svg", nickname: friend.nickname || "未知用户", wechatId: friend.wechatId || "", + accountUserName: friend.accountUserName || "", + accountRealName: friend.accountRealName || "", remark: friend.notes || "", addTime: friend.createTime || new Date().toISOString().split("T")[0], @@ -466,7 +480,66 @@ const WechatAccountDetail: React.FC = () => { }; const handleFriendClick = (friend: Friend) => { - navigate(`/mine/traffic-pool/detail/${friend.wechatId}/${friend.id}`); + setSelectedFriend(friend); + setShowTransferFriendPopup(true); + // 加载客服账号列表 + fetchKefuAccounts(); + }; + + // 获取客服账号列表 + const fetchKefuAccounts = useCallback(async () => { + setLoadingKefuAccounts(true); + try { + const response = await getKefuAccountsList(); + // 数据结构:{ code: 200, msg: "success", data: { total: 7, list: [...] } } + const accountsList = response?.data?.list || response?.list || (Array.isArray(response) ? response : []); + setKefuAccounts(accountsList); + } catch (error) { + console.error("获取客服账号列表失败:", error); + Toast.show({ + content: "获取客服账号列表失败", + position: "top", + }); + } finally { + setLoadingKefuAccounts(false); + } + }, []); + + // 确认转移好友 + const handleConfirmTransferFriend = async () => { + if (!selectedFriend) { + Toast.show({ content: "请选择好友", position: "top" }); + return; + } + if (!selectedKefuAccountId) { + Toast.show({ content: "请选择目标客服账号", position: "top" }); + return; + } + + setTransferFriendLoading(true); + try { + await transferFriend({ + friendId: selectedFriend.friendId || selectedFriend.id, + toAccountId: selectedKefuAccountId, + comment: transferComment || undefined, + }); + + Toast.show({ content: "转移成功", position: "top" }); + setShowTransferFriendPopup(false); + setSelectedFriend(null); + setSelectedKefuAccountId(""); + setTransferComment(""); + // 刷新好友列表 + fetchFriendsList(1, searchQuery, false); + } catch (error: any) { + console.error("转移好友失败:", error); + Toast.show({ + content: error?.message || "转移失败,请重试", + position: "top", + }); + } finally { + setTransferFriendLoading(false); + } }; const handleLoadMoreMoments = async () => { @@ -903,38 +976,53 @@ const WechatAccountDetail: React.FC = () => {
-
+
{friend.nickname || "未知好友"}
- +
+
+ {friend.valueFormatted + || (typeof friend.value === "number" + ? `¥${friend.value.toLocaleString()}` + : "¥3")} +
+
-
- ID: {friend.wechatId || "-"} -
-
- {friend.statusTags?.map((tag, idx) => ( - - {tag} - - ))} - {friend.remark && ( - - {friend.remark} +
+
+ 微信号: + + {friend.wechatId || "-"} +
+ {(friend.accountUserName || friend.accountRealName) && ( +
+ 归属: + + {friend.accountUserName || ""} + {friend.accountRealName && `(${friend.accountRealName})`} + +
)}
-
-
-
- {friend.valueFormatted - || (typeof friend.value === "number" - ? `¥${friend.value.toLocaleString()}` - : "估值 -")} -
+ {(friend.statusTags?.length > 0 || friend.remark) && ( +
+ {friend.statusTags?.map((tag, idx) => ( + + {tag} + + ))} + {friend.remark && ( + + {friend.remark} + + )} +
+ )}
))} @@ -1405,8 +1493,122 @@ const WechatAccountDetail: React.FC = () => {
- {/* 好友详情弹窗 */} - {/* Removed */} + {/* 迁移好友弹窗 */} + { + setShowTransferFriendPopup(false); + setSelectedFriend(null); + setSelectedKefuAccountId(""); + setTransferComment(""); + }} + bodyStyle={{ borderRadius: "16px 16px 0 0" }} + > +
+
+

迁移好友

+ +
+ +
+ {/* 好友信息 */} + {selectedFriend && ( +
+ +
+ +
+
+ {selectedFriend.nickname || "未知好友"} +
+
+ {selectedFriend.wechatId || "-"} +
+
+
+
+ )} + + {/* 选择客服账号 */} +
+ + {loadingKefuAccounts ? ( +
+ + 加载中... +
+ ) : kefuAccounts.length === 0 ? ( +
暂无客服账号
+ ) : ( + + )} +
+ + {/* 备注 */} +
+ + setTransferComment(e.target.value)} + allowClear + /> +
+
+ +
+ + +
+
+
); };