更新关键词管理模块:调整关键词请求参数,优化关键词列表的获取逻辑,移除本地筛选功能,改为服务端搜索,提升代码可读性和用户体验。
This commit is contained in:
@@ -65,17 +65,17 @@ const NavCommon: React.FC<NavCommonProps> = ({ title = "触客宝" }) => {
|
||||
key: "userInfo",
|
||||
label: (
|
||||
<div style={{ fontWeight: "bold", color: "#188eee" }}>
|
||||
{user.username}({user.account})
|
||||
{user.account}
|
||||
</div>
|
||||
),
|
||||
},
|
||||
|
||||
{
|
||||
key: "profile",
|
||||
icon: <UserSwitchOutlined style={{ fontSize: 16 }} />,
|
||||
label: "个人资料",
|
||||
key: "settings",
|
||||
icon: <SettingOutlined style={{ fontSize: 16 }} />,
|
||||
label: "全局配置",
|
||||
onClick: () => {
|
||||
console.log("个人资料点击");
|
||||
// TODO: 跳转到个人资料页面
|
||||
navigate("/pc/commonConfig");
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -120,14 +120,14 @@ const NavCommon: React.FC<NavCommonProps> = ({ title = "触客宝" }) => {
|
||||
<BellOutlined style={{ fontSize: 20 }} />
|
||||
</Badge>
|
||||
</div>
|
||||
<Button
|
||||
{/* <Button
|
||||
onClick={() => {
|
||||
navigate("/pc/commonConfig");
|
||||
}}
|
||||
icon={<SettingOutlined />}
|
||||
>
|
||||
全局配置
|
||||
</Button>
|
||||
</Button> */}
|
||||
<Dropdown
|
||||
menu={{ items: userMenuItems }}
|
||||
placement="bottomRight"
|
||||
|
||||
@@ -136,7 +136,7 @@ export interface KeywordAddRequest {
|
||||
level: number; // 优先级
|
||||
replyType: number; // 回复类型:文本回复、模板回复
|
||||
status: string;
|
||||
materialId: number;
|
||||
metailGroups: any[];
|
||||
}
|
||||
|
||||
export interface KeywordUpdateRequest extends KeywordAddRequest {
|
||||
|
||||
@@ -15,7 +15,6 @@ import {
|
||||
} from "antd";
|
||||
import {
|
||||
SearchOutlined,
|
||||
FilterOutlined,
|
||||
FormOutlined,
|
||||
DeleteOutlined,
|
||||
} from "@ant-design/icons";
|
||||
@@ -38,7 +37,7 @@ interface KeywordItem {
|
||||
keywords: string;
|
||||
status: number;
|
||||
content: string;
|
||||
materialId: string;
|
||||
metailGroupsOptions: { title: string; id: number }[];
|
||||
level: number;
|
||||
}
|
||||
|
||||
@@ -56,6 +55,8 @@ const KeywordManagement = forwardRef<any, Record<string, never>>(
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
});
|
||||
// 已提交的搜索关键词(仅在点击搜索时更新,用于服务端查询)
|
||||
const [keywordQuery, setKeywordQuery] = useState<string>("");
|
||||
|
||||
//匹配类型
|
||||
const getMatchTypeText = (type: number) => {
|
||||
@@ -102,15 +103,16 @@ const KeywordManagement = forwardRef<any, Record<string, never>>(
|
||||
}
|
||||
};
|
||||
|
||||
// 获取关键词列表
|
||||
// 获取关键词列表(服务端搜索)
|
||||
const fetchKeywords = async (params?: KeywordListParams) => {
|
||||
try {
|
||||
setLoading(true);
|
||||
const requestParams = {
|
||||
page: pagination.current.toString(),
|
||||
limit: pagination.pageSize.toString(),
|
||||
keyword: keywordQuery || undefined,
|
||||
...params,
|
||||
};
|
||||
} as KeywordListParams;
|
||||
const response = await getKeywordList(requestParams);
|
||||
if (response) {
|
||||
setKeywordsList(response.list || []);
|
||||
@@ -175,20 +177,12 @@ const KeywordManagement = forwardRef<any, Record<string, never>>(
|
||||
}
|
||||
};
|
||||
|
||||
// 搜索和筛选功能
|
||||
const filteredKeywords = keywordsList.filter(item => {
|
||||
if (!searchValue) return true;
|
||||
return (
|
||||
item.title.toLowerCase().includes(searchValue.toLowerCase()) ||
|
||||
item.keywords.toLowerCase().includes(searchValue.toLowerCase()) ||
|
||||
item.content.toLowerCase().includes(searchValue.toLowerCase())
|
||||
);
|
||||
});
|
||||
// 移除本地筛选,改为服务端搜索,列表直接使用 keywordsList
|
||||
|
||||
// 搜索处理函数
|
||||
const handleSearch = (value: string) => {
|
||||
setKeywordQuery(value || "");
|
||||
setPagination(prev => ({ ...prev, current: 1 }));
|
||||
fetchKeywords({ keyword: value });
|
||||
};
|
||||
|
||||
// 分页处理函数
|
||||
@@ -200,10 +194,11 @@ const KeywordManagement = forwardRef<any, Record<string, never>>(
|
||||
}));
|
||||
};
|
||||
|
||||
// 组件挂载和分页变化时获取数据
|
||||
// 初始化与依赖变化时获取数据(依赖分页与搜索关键字)
|
||||
useEffect(() => {
|
||||
fetchKeywords();
|
||||
}, [pagination.current, pagination.pageSize]);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [pagination.current, pagination.pageSize, keywordQuery]);
|
||||
|
||||
return (
|
||||
<div className={styles.keywordContent}>
|
||||
@@ -216,16 +211,15 @@ const KeywordManagement = forwardRef<any, Record<string, never>>(
|
||||
style={{ width: 300 }}
|
||||
prefix={<SearchOutlined />}
|
||||
/>
|
||||
{/* <Button icon={<FilterOutlined />}>筛选</Button> */}
|
||||
</div>
|
||||
|
||||
<div className={styles.keywordList}>
|
||||
{loading ? (
|
||||
<div className={styles.loading}>加载中...</div>
|
||||
) : filteredKeywords.length === 0 ? (
|
||||
) : keywordsList.length === 0 ? (
|
||||
<div className={styles.empty}>暂无关键词数据</div>
|
||||
) : (
|
||||
filteredKeywords.map(item => (
|
||||
keywordsList.map(item => (
|
||||
<div key={item.id} className={styles.keywordItem}>
|
||||
<div className={styles.itemContent}>
|
||||
<div className={styles.leftSection}>
|
||||
@@ -234,7 +228,18 @@ const KeywordManagement = forwardRef<any, Record<string, never>>(
|
||||
<Tag color="default">{getMatchTypeText(item.type)}</Tag>
|
||||
<Tag color="default">{getPriorityText(item.level)}</Tag>
|
||||
</div>
|
||||
<div className={styles.description}>{item.content}</div>
|
||||
{item.content.length ? (
|
||||
<div className={styles.description}>{item.content}</div>
|
||||
) : (
|
||||
<div className={styles.description}>
|
||||
已选素材:
|
||||
{item.metailGroupsOptions.map(v => (
|
||||
<Tag color="success" key={v.id}>
|
||||
{v.title}
|
||||
</Tag>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
<div className={styles.footer}>
|
||||
<Tag color={getReplyTypeColor(item.replyType)}>
|
||||
{getReplyTypeText(item.replyType)}
|
||||
|
||||
@@ -28,6 +28,8 @@ const KeywordModal: React.FC<KeywordModalProps> = ({
|
||||
}) => {
|
||||
const [form] = Form.useForm();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const title = mode === "add" ? "添加关键词回复" : "编辑关键词回复";
|
||||
const [selectedOptions, setSelectedOptions] = useState<any[]>([]);
|
||||
|
||||
// 获取关键词详情
|
||||
const fetchKeywordDetails = useCallback(
|
||||
@@ -44,8 +46,9 @@ const KeywordModal: React.FC<KeywordModalProps> = ({
|
||||
level: keyword.level,
|
||||
replyType: keyword.replyType,
|
||||
status: keyword.status,
|
||||
materialId: keyword.materialId,
|
||||
metailGroups: keyword.metailGroups,
|
||||
});
|
||||
setSelectedOptions(keyword.metailGroupsOptions);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("获取关键词详情失败:", error);
|
||||
@@ -82,7 +85,7 @@ const KeywordModal: React.FC<KeywordModalProps> = ({
|
||||
level: values.level,
|
||||
replyType: values.replyType,
|
||||
status: values.status || "1",
|
||||
materialId: values.materialId,
|
||||
metailGroups: values.metailGroups,
|
||||
};
|
||||
|
||||
const response = await addKeyword(data);
|
||||
@@ -104,7 +107,7 @@ const KeywordModal: React.FC<KeywordModalProps> = ({
|
||||
level: values.level,
|
||||
replyType: values.replyType,
|
||||
status: values.status,
|
||||
materialId: values.materialId,
|
||||
metailGroups: values.metailGroups,
|
||||
};
|
||||
|
||||
const response = await updateKeyword(data);
|
||||
@@ -131,17 +134,15 @@ const KeywordModal: React.FC<KeywordModalProps> = ({
|
||||
onCancel();
|
||||
};
|
||||
|
||||
const title = mode === "add" ? "添加关键词回复" : "编辑关键词回复";
|
||||
const [selectedOptions, setSelectedOptions] = useState<any[]>([]);
|
||||
const handSelectMaterial = (options: any[]) => {
|
||||
if (options.length === 0) {
|
||||
form.setFieldsValue({
|
||||
materialId: null,
|
||||
metailGroups: [],
|
||||
});
|
||||
} else {
|
||||
// 在单选模式下,只取第一个选项的ID
|
||||
form.setFieldsValue({
|
||||
materialId: options[0].id,
|
||||
metailGroups: options.map(v => v.id),
|
||||
});
|
||||
}
|
||||
setSelectedOptions(options);
|
||||
@@ -222,7 +223,7 @@ const KeywordModal: React.FC<KeywordModalProps> = ({
|
||||
</Form.Item>
|
||||
) : (
|
||||
<Form.Item
|
||||
name="materialId"
|
||||
name="metailGroups"
|
||||
label="回复内容"
|
||||
rules={[{ required: true, message: "请输入回复内容" }]}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user