更新接待設置功能:修改API請求路徑以支持新的流量池設置,新增批量設置功能並優化用戶界面,添加空狀態提示以提升用戶體驗。
This commit is contained in:
@@ -1,9 +1,13 @@
|
|||||||
import request from "@/api/request";
|
import request from "@/api/request";
|
||||||
|
|
||||||
export const getAiSettings = () => {
|
export const getAiSettings = () => {
|
||||||
return request("/v1/kefu/ai/settings/get", "GET");
|
return request("/v1/kefu/ai/friend/get", "GET");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const setAiSettings = (data: any) => {
|
export const setAiSettings = (params: {
|
||||||
return request("/v1/kefu/ai/settings/set", "POST", data);
|
isUpdata: string;
|
||||||
|
packageId: string[];
|
||||||
|
type: number;
|
||||||
|
}) => {
|
||||||
|
return request("/v1/kefu/ai/friend/setAll", params, "POST");
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -62,6 +62,26 @@
|
|||||||
color: #586069;
|
color: #586069;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.emptyState {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 200px;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
.emptyText {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #999;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emptyDesc {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 响应式设计
|
// 响应式设计
|
||||||
|
|||||||
@@ -1,21 +1,110 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { Card, Select, Button, Space, Tag, List } from "antd";
|
import { Card, Select, Button, Space, Tag, List, message, Modal } from "antd";
|
||||||
import { DatabaseOutlined } from "@ant-design/icons";
|
import { DatabaseOutlined, ExclamationCircleOutlined } from "@ant-design/icons";
|
||||||
|
import PoolSelection from "@/components/PoolSelection";
|
||||||
|
import { PoolSelectionItem } from "@/components/PoolSelection/data";
|
||||||
|
import { setAiSettings } from "./api";
|
||||||
import styles from "./index.module.scss";
|
import styles from "./index.module.scss";
|
||||||
|
|
||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
|
|
||||||
const ReceptionSettings: React.FC = () => {
|
const ReceptionSettings: React.FC = () => {
|
||||||
const [pool, setPool] = useState<string | undefined>();
|
const [selectedPools, setSelectedPools] = useState<PoolSelectionItem[]>([]);
|
||||||
const [mode, setMode] = useState<string>("人工接待");
|
const [mode, setMode] = useState<number>(0);
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
const pools = ["官网咨询", "朋友推荐", "展会获客"];
|
|
||||||
const typeOptions = [
|
const typeOptions = [
|
||||||
{ value: 0, label: "人工接待" },
|
{ value: 0, label: "人工接待" },
|
||||||
{ value: 1, label: "AI辅助" },
|
{ value: 1, label: "AI辅助" },
|
||||||
{ value: 2, label: "AI接管" },
|
{ value: 2, label: "AI接管" },
|
||||||
];
|
];
|
||||||
const [currentConfig, setCurrentConfig] = useState<number | null>(null);
|
|
||||||
|
// 处理流量池选择
|
||||||
|
const handlePoolSelect = (pools: PoolSelectionItem[]) => {
|
||||||
|
setSelectedPools(pools);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 处理接待模式选择
|
||||||
|
const handleModeChange = (value: number) => {
|
||||||
|
setMode(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 处理批量设置
|
||||||
|
const handleBatchSet = async () => {
|
||||||
|
if (selectedPools.length === 0) {
|
||||||
|
message.warning("请先选择流量池");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectedModeLabel =
|
||||||
|
typeOptions.find(opt => opt.value === mode)?.label || "人工接待";
|
||||||
|
const poolNames = selectedPools
|
||||||
|
.map(pool => pool.name || pool.nickname)
|
||||||
|
.join("、");
|
||||||
|
|
||||||
|
Modal.confirm({
|
||||||
|
title: "确认批量设置",
|
||||||
|
icon: <ExclamationCircleOutlined />,
|
||||||
|
content: (
|
||||||
|
<div>
|
||||||
|
<p>您即将对以下流量池进行批量设置:</p>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
margin: "12px 0",
|
||||||
|
padding: "8px 12px",
|
||||||
|
background: "#f5f5f5",
|
||||||
|
borderRadius: "4px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<strong>流量池:</strong>
|
||||||
|
{poolNames}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
margin: "12px 0",
|
||||||
|
padding: "8px 12px",
|
||||||
|
background: "#f5f5f5",
|
||||||
|
borderRadius: "4px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<strong>接待模式:</strong>
|
||||||
|
{selectedModeLabel}
|
||||||
|
</div>
|
||||||
|
<p style={{ color: "#ff4d4f", marginTop: "12px" }}>
|
||||||
|
此操作将影响 {selectedPools.length}{" "}
|
||||||
|
个流量池的接待设置,确定要继续吗?
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
okText: "确认设置",
|
||||||
|
cancelText: "取消",
|
||||||
|
okType: "primary",
|
||||||
|
onOk: async () => {
|
||||||
|
setLoading(true);
|
||||||
|
try {
|
||||||
|
const packageIds = selectedPools.map(pool => pool.id);
|
||||||
|
const params = {
|
||||||
|
isUpdata: "1", // 1表示更新,0表示新增
|
||||||
|
packageId: packageIds,
|
||||||
|
type: mode,
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await setAiSettings(params);
|
||||||
|
if (response) {
|
||||||
|
message.success(
|
||||||
|
`成功为 ${selectedPools.length} 个流量池设置接待模式为"${selectedModeLabel}"`,
|
||||||
|
);
|
||||||
|
// 可以在这里刷新流量池状态列表
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("批量设置失败:", error);
|
||||||
|
message.error("批量设置失败,请重试");
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
@@ -34,25 +123,20 @@ const ReceptionSettings: React.FC = () => {
|
|||||||
|
|
||||||
<div className={styles.formItem}>
|
<div className={styles.formItem}>
|
||||||
<div className={styles.label}>选择流量池</div>
|
<div className={styles.label}>选择流量池</div>
|
||||||
<Select
|
<PoolSelection
|
||||||
|
selectedOptions={selectedPools}
|
||||||
|
onSelect={handlePoolSelect}
|
||||||
placeholder="请选择流量池"
|
placeholder="请选择流量池"
|
||||||
value={pool}
|
showSelectedList={true}
|
||||||
onChange={setPool}
|
selectedListMaxHeight={200}
|
||||||
style={{ width: "100%" }}
|
/>
|
||||||
>
|
|
||||||
{pools.map(p => (
|
|
||||||
<Option key={p} value={p}>
|
|
||||||
{p}
|
|
||||||
</Option>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={styles.formItem}>
|
<div className={styles.formItem}>
|
||||||
<div className={styles.label}>接待模式</div>
|
<div className={styles.label}>接待模式</div>
|
||||||
<Select
|
<Select
|
||||||
value={mode}
|
value={mode}
|
||||||
onChange={setCurrentConfig}
|
onChange={handleModeChange}
|
||||||
style={{ width: "100%" }}
|
style={{ width: "100%" }}
|
||||||
>
|
>
|
||||||
{typeOptions.map(option => (
|
{typeOptions.map(option => (
|
||||||
@@ -62,8 +146,14 @@ const ReceptionSettings: React.FC = () => {
|
|||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
{JSON.stringify(currentConfig)}
|
|
||||||
<Button type="primary" block className={styles.primaryBtn}>
|
<Button
|
||||||
|
type="primary"
|
||||||
|
block
|
||||||
|
className={styles.primaryBtn}
|
||||||
|
onClick={handleBatchSet}
|
||||||
|
loading={loading}
|
||||||
|
>
|
||||||
批量设置
|
批量设置
|
||||||
</Button>
|
</Button>
|
||||||
</Card>
|
</Card>
|
||||||
@@ -78,33 +168,31 @@ const ReceptionSettings: React.FC = () => {
|
|||||||
</Space>
|
</Space>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<List
|
{selectedPools.length > 0 ? (
|
||||||
itemLayout="horizontal"
|
<List
|
||||||
dataSource={pools}
|
itemLayout="horizontal"
|
||||||
renderItem={(item, index) => (
|
dataSource={selectedPools}
|
||||||
<List.Item>
|
renderItem={item => (
|
||||||
<List.Item.Meta
|
<List.Item>
|
||||||
title={item}
|
<List.Item.Meta
|
||||||
description={`${Math.floor(Math.random() * 300) + 50} 个客户`}
|
title={item.name || item.nickname}
|
||||||
/>
|
description={`${item.num || 0} 个客户`}
|
||||||
<Tag
|
/>
|
||||||
color={
|
<Tag color="blue">
|
||||||
index % 3 === 0
|
{typeOptions.find(opt => opt.value === mode)?.label ||
|
||||||
? "blue"
|
"人工接待"}
|
||||||
: index % 3 === 1
|
</Tag>
|
||||||
? "orange"
|
</List.Item>
|
||||||
: "green"
|
)}
|
||||||
}
|
/>
|
||||||
>
|
) : (
|
||||||
{index % 3 === 0
|
<div className={styles.emptyState}>
|
||||||
? "AI辅助"
|
<div className={styles.emptyText}>请先选择流量池</div>
|
||||||
: index % 3 === 1
|
<div className={styles.emptyDesc}>
|
||||||
? "人工接待"
|
选择流量池后将显示其状态信息
|
||||||
: "AI接管"}
|
</div>
|
||||||
</Tag>
|
</div>
|
||||||
</List.Item>
|
)}
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user