好友转移
This commit is contained in:
@@ -55,6 +55,20 @@ export function transferWechatFriends(params: {
|
|||||||
return request("/v1/wechats/transfer-friends", params, "POST");
|
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: {
|
export async function exportWechatMoments(params: {
|
||||||
wechatId: string;
|
wechatId: string;
|
||||||
|
|||||||
@@ -102,9 +102,12 @@ export interface WechatAccountSummary {
|
|||||||
|
|
||||||
export interface Friend {
|
export interface Friend {
|
||||||
id: string;
|
id: string;
|
||||||
|
friendId?: string;
|
||||||
avatar: string;
|
avatar: string;
|
||||||
nickname: string;
|
nickname: string;
|
||||||
wechatId: string;
|
wechatId: string;
|
||||||
|
accountUserName: string;
|
||||||
|
accountRealName: string;
|
||||||
remark: string;
|
remark: string;
|
||||||
addTime: string;
|
addTime: string;
|
||||||
lastInteraction: string;
|
lastInteraction: string;
|
||||||
|
|||||||
@@ -684,99 +684,114 @@
|
|||||||
|
|
||||||
.friend-card {
|
.friend-card {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: flex-start;
|
||||||
padding: 14px;
|
padding: 16px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
border: 1px solid #f0f0f0;
|
border: 1px solid #f0f0f0;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 12px;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
transition: box-shadow 0.2s, border-color 0.2s;
|
transition: all 0.2s;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
&:hover {
|
&:active {
|
||||||
border-color: #cfe2ff;
|
background: #f8f9fa;
|
||||||
box-shadow: 0 6px 16px rgba(24, 144, 255, 0.15);
|
border-color: #1677ff;
|
||||||
|
transform: scale(0.98);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.friend-avatar {
|
.friend-avatar {
|
||||||
width: 48px;
|
flex-shrink: 0;
|
||||||
height: 48px;
|
width: 52px;
|
||||||
|
height: 52px;
|
||||||
|
|
||||||
.adm-avatar {
|
.adm-avatar {
|
||||||
width: 48px;
|
width: 52px;
|
||||||
height: 48px;
|
height: 52px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
|
border: 2px solid #f0f0f0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.friend-main {
|
.friend-main {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
.friend-name-row {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
margin-bottom: 4px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.friend-name {
|
.friend-header {
|
||||||
font-size: 15px;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.friend-name {
|
||||||
|
font-size: 16px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #111;
|
color: #111;
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.friend-value {
|
||||||
flex-shrink: 0;
|
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 {
|
.friend-tags {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 4px;
|
gap: 6px;
|
||||||
}
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
.friend-tag {
|
.friend-tag {
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
padding: 2px 8px;
|
padding: 4px 10px;
|
||||||
border-radius: 999px;
|
border-radius: 12px;
|
||||||
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 {
|
|
||||||
background: #f0f7ff;
|
background: #f0f7ff;
|
||||||
color: #1677ff;
|
color: #1677ff;
|
||||||
font-size: 11px;
|
font-weight: 500;
|
||||||
padding: 2px 8px;
|
white-space: nowrap;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -851,11 +866,98 @@
|
|||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.popup-footer {
|
.popup-footer {
|
||||||
margin-top: 24px;
|
margin-top: 24px;
|
||||||
padding-top: 16px;
|
padding-top: 16px;
|
||||||
border-top: 1px solid #f0f0f0;
|
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 {
|
.export-form {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import {
|
|||||||
DatePicker,
|
DatePicker,
|
||||||
InfiniteScroll,
|
InfiniteScroll,
|
||||||
} from "antd-mobile";
|
} from "antd-mobile";
|
||||||
import { Input } from "antd";
|
import { Input, Select } from "antd";
|
||||||
import NavCommon from "@/components/NavCommon";
|
import NavCommon from "@/components/NavCommon";
|
||||||
import {
|
import {
|
||||||
SearchOutlined,
|
SearchOutlined,
|
||||||
@@ -34,6 +34,8 @@ import {
|
|||||||
getWechatAccountOverview,
|
getWechatAccountOverview,
|
||||||
getWechatMoments,
|
getWechatMoments,
|
||||||
exportWechatMoments,
|
exportWechatMoments,
|
||||||
|
getKefuAccountsList,
|
||||||
|
transferFriend,
|
||||||
} from "./api";
|
} from "./api";
|
||||||
import DeviceSelection from "@/components/DeviceSelection";
|
import DeviceSelection from "@/components/DeviceSelection";
|
||||||
import { DeviceSelectionItem } from "@/components/DeviceSelection/data";
|
import { DeviceSelectionItem } from "@/components/DeviceSelection/data";
|
||||||
@@ -84,6 +86,15 @@ const WechatAccountDetail: React.FC = () => {
|
|||||||
const [showEndTimePicker, setShowEndTimePicker] = useState(false);
|
const [showEndTimePicker, setShowEndTimePicker] = useState(false);
|
||||||
const [exportLoading, setExportLoading] = useState(false);
|
const [exportLoading, setExportLoading] = useState(false);
|
||||||
|
|
||||||
|
// 迁移好友相关状态
|
||||||
|
const [showTransferFriendPopup, setShowTransferFriendPopup] = useState(false);
|
||||||
|
const [selectedFriend, setSelectedFriend] = useState<Friend | null>(null);
|
||||||
|
const [kefuAccounts, setKefuAccounts] = useState<any[]>([]);
|
||||||
|
const [selectedKefuAccountId, setSelectedKefuAccountId] = useState<string>("");
|
||||||
|
const [transferComment, setTransferComment] = useState<string>("");
|
||||||
|
const [transferFriendLoading, setTransferFriendLoading] = useState(false);
|
||||||
|
const [loadingKefuAccounts, setLoadingKefuAccounts] = useState(false);
|
||||||
|
|
||||||
// 获取基础信息
|
// 获取基础信息
|
||||||
const fetchAccountInfo = useCallback(async () => {
|
const fetchAccountInfo = useCallback(async () => {
|
||||||
if (!id) return;
|
if (!id) return;
|
||||||
@@ -237,9 +248,12 @@ const WechatAccountDetail: React.FC = () => {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
id: friend.id.toString(),
|
id: friend.id.toString(),
|
||||||
|
friendId: friend.friendId || friend.id?.toString() || "",
|
||||||
avatar: friend.avatar || "/placeholder.svg",
|
avatar: friend.avatar || "/placeholder.svg",
|
||||||
nickname: friend.nickname || "未知用户",
|
nickname: friend.nickname || "未知用户",
|
||||||
wechatId: friend.wechatId || "",
|
wechatId: friend.wechatId || "",
|
||||||
|
accountUserName: friend.accountUserName || "",
|
||||||
|
accountRealName: friend.accountRealName || "",
|
||||||
remark: friend.notes || "",
|
remark: friend.notes || "",
|
||||||
addTime:
|
addTime:
|
||||||
friend.createTime || new Date().toISOString().split("T")[0],
|
friend.createTime || new Date().toISOString().split("T")[0],
|
||||||
@@ -466,7 +480,66 @@ const WechatAccountDetail: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleFriendClick = (friend: Friend) => {
|
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 () => {
|
const handleLoadMoreMoments = async () => {
|
||||||
@@ -903,38 +976,53 @@ const WechatAccountDetail: React.FC = () => {
|
|||||||
<Avatar src={friend.avatar} />
|
<Avatar src={friend.avatar} />
|
||||||
</div>
|
</div>
|
||||||
<div className={style["friend-main"]}>
|
<div className={style["friend-main"]}>
|
||||||
<div className={style["friend-name-row"]}>
|
<div className={style["friend-header"]}>
|
||||||
<div className={style["friend-name"]}>
|
<div className={style["friend-name"]}>
|
||||||
{friend.nickname || "未知好友"}
|
{friend.nickname || "未知好友"}
|
||||||
</div>
|
</div>
|
||||||
|
<div className={style["friend-value"]}>
|
||||||
|
<div className={style["value-amount"]}>
|
||||||
|
{friend.valueFormatted
|
||||||
|
|| (typeof friend.value === "number"
|
||||||
|
? `¥${friend.value.toLocaleString()}`
|
||||||
|
: "¥3")}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={style["friend-id-row"]}>
|
<div className={style["friend-info"]}>
|
||||||
ID: {friend.wechatId || "-"}
|
<div className={style["friend-info-item"]}>
|
||||||
</div>
|
<span className={style["info-label"]}>微信号:</span>
|
||||||
<div className={style["friend-status-row"]}>
|
<span className={style["info-value"]}>
|
||||||
{friend.statusTags?.map((tag, idx) => (
|
{friend.wechatId || "-"}
|
||||||
<span
|
|
||||||
key={idx}
|
|
||||||
className={style["friend-status-chip"]}
|
|
||||||
>
|
|
||||||
{tag}
|
|
||||||
</span>
|
|
||||||
))}
|
|
||||||
{friend.remark && (
|
|
||||||
<span className={style["friend-status-chip"]}>
|
|
||||||
{friend.remark}
|
|
||||||
</span>
|
</span>
|
||||||
|
</div>
|
||||||
|
{(friend.accountUserName || friend.accountRealName) && (
|
||||||
|
<div className={style["friend-info-item"]}>
|
||||||
|
<span className={style["info-label"]}>归属:</span>
|
||||||
|
<span className={style["info-value"]}>
|
||||||
|
{friend.accountUserName || ""}
|
||||||
|
{friend.accountRealName && `(${friend.accountRealName})`}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{(friend.statusTags?.length > 0 || friend.remark) && (
|
||||||
<div className={style["friend-value"]}>
|
<div className={style["friend-tags"]}>
|
||||||
<div className={style["value-amount"]}>
|
{friend.statusTags?.map((tag, idx) => (
|
||||||
{friend.valueFormatted
|
<span
|
||||||
|| (typeof friend.value === "number"
|
key={idx}
|
||||||
? `¥${friend.value.toLocaleString()}`
|
className={style["friend-tag"]}
|
||||||
: "估值 -")}
|
>
|
||||||
</div>
|
{tag}
|
||||||
|
</span>
|
||||||
|
))}
|
||||||
|
{friend.remark && (
|
||||||
|
<span className={style["friend-tag"]}>
|
||||||
|
{friend.remark}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
@@ -1405,8 +1493,122 @@ const WechatAccountDetail: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
</Popup>
|
</Popup>
|
||||||
|
|
||||||
{/* 好友详情弹窗 */}
|
{/* 迁移好友弹窗 */}
|
||||||
{/* Removed */}
|
<Popup
|
||||||
|
visible={showTransferFriendPopup}
|
||||||
|
onMaskClick={() => {
|
||||||
|
setShowTransferFriendPopup(false);
|
||||||
|
setSelectedFriend(null);
|
||||||
|
setSelectedKefuAccountId("");
|
||||||
|
setTransferComment("");
|
||||||
|
}}
|
||||||
|
bodyStyle={{ borderRadius: "16px 16px 0 0" }}
|
||||||
|
>
|
||||||
|
<div className={style["popup-content"]}>
|
||||||
|
<div className={style["popup-header"]}>
|
||||||
|
<h3>迁移好友</h3>
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
fill="outline"
|
||||||
|
onClick={() => {
|
||||||
|
setShowTransferFriendPopup(false);
|
||||||
|
setSelectedFriend(null);
|
||||||
|
setSelectedKefuAccountId("");
|
||||||
|
setTransferComment("");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
关闭
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={style["export-form"]}>
|
||||||
|
{/* 好友信息 */}
|
||||||
|
{selectedFriend && (
|
||||||
|
<div className={style["form-item"]}>
|
||||||
|
<label>好友信息</label>
|
||||||
|
<div className={style["friend-info-card"]}>
|
||||||
|
<Avatar src={selectedFriend.avatar} style={{ width: 40, height: 40 }} />
|
||||||
|
<div className={style["friend-info-text"]}>
|
||||||
|
<div className={style["friend-info-name"]}>
|
||||||
|
{selectedFriend.nickname || "未知好友"}
|
||||||
|
</div>
|
||||||
|
<div className={style["friend-info-id"]}>
|
||||||
|
{selectedFriend.wechatId || "-"}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* 选择客服账号 */}
|
||||||
|
<div className={style["form-item"]}>
|
||||||
|
<label>选择客服账号</label>
|
||||||
|
{loadingKefuAccounts ? (
|
||||||
|
<div className={style["loading-accounts"]}>
|
||||||
|
<SpinLoading color="primary" style={{ fontSize: 16 }} />
|
||||||
|
<span style={{ marginLeft: 8 }}>加载中...</span>
|
||||||
|
</div>
|
||||||
|
) : kefuAccounts.length === 0 ? (
|
||||||
|
<div className={style["empty-accounts"]}>暂无客服账号</div>
|
||||||
|
) : (
|
||||||
|
<Select
|
||||||
|
placeholder="请选择客服账号"
|
||||||
|
value={selectedKefuAccountId || undefined}
|
||||||
|
onChange={(value: string) => setSelectedKefuAccountId(value)}
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
allowClear
|
||||||
|
>
|
||||||
|
{kefuAccounts.map((account: any) => {
|
||||||
|
const displayName = `${account.userName || ""}(${account.realName || ""})`;
|
||||||
|
return (
|
||||||
|
<Select.Option key={account.id} value={String(account.id)}>
|
||||||
|
{displayName}
|
||||||
|
</Select.Option>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Select>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 备注 */}
|
||||||
|
<div className={style["form-item"]}>
|
||||||
|
<label>备注(可选)</label>
|
||||||
|
<Input
|
||||||
|
placeholder="请输入备注信息"
|
||||||
|
value={transferComment}
|
||||||
|
onChange={e => setTransferComment(e.target.value)}
|
||||||
|
allowClear
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={style["popup-footer"]}>
|
||||||
|
<Button
|
||||||
|
block
|
||||||
|
color="primary"
|
||||||
|
onClick={handleConfirmTransferFriend}
|
||||||
|
loading={transferFriendLoading}
|
||||||
|
disabled={transferFriendLoading || !selectedKefuAccountId}
|
||||||
|
>
|
||||||
|
{transferFriendLoading ? "转移中..." : "确认转移"}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
block
|
||||||
|
color="danger"
|
||||||
|
fill="outline"
|
||||||
|
onClick={() => {
|
||||||
|
setShowTransferFriendPopup(false);
|
||||||
|
setSelectedFriend(null);
|
||||||
|
setSelectedKefuAccountId("");
|
||||||
|
setTransferComment("");
|
||||||
|
}}
|
||||||
|
style={{ marginTop: 12 }}
|
||||||
|
>
|
||||||
|
取消
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Popup>
|
||||||
</Layout>
|
</Layout>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user