From 9835b6332cf7d2ce8584b5f1609a3e89035706db Mon Sep 17 00:00:00 2001
From: 刘帅 <rr.iii@qq.com>
Date: 星期一, 14 九月 2026 10:08:06 +0800
Subject: [PATCH] 机器人设置页面调整
---
management/src/pages/settings/outboundRobotSetting/index.jsx | 106 +++++++++++++++++++++++++++++++++-
management/src/pages/settings/outboundRobotSetting/style.less | 19 ++++++
2 files changed, 120 insertions(+), 5 deletions(-)
diff --git a/management/src/pages/settings/outboundRobotSetting/index.jsx b/management/src/pages/settings/outboundRobotSetting/index.jsx
index 71a26af..62b42ca 100644
--- a/management/src/pages/settings/outboundRobotSetting/index.jsx
+++ b/management/src/pages/settings/outboundRobotSetting/index.jsx
@@ -1,6 +1,8 @@
+import { allAreaList } from '@/utils/area';
+import { PlusOutlined } from '@ant-design/icons';
import { PageContainer } from '@ant-design/pro-components';
-import { Button, Empty, message, Select, Spin } from 'antd';
-import { useEffect, useState } from 'react';
+import { Button, Cascader, Empty, message, Select, Spin, Tag } from 'antd';
+import { useEffect, useMemo, useState } from 'react';
import { getList, update } from './service';
import styles from './style.less';
@@ -12,14 +14,47 @@
.filter(Number.isFinite)
: [];
+const commaTextToArray = (value) =>
+ value
+ ? String(value)
+ .split(',')
+ .map((item) => item.trim())
+ .filter(Boolean)
+ : [];
+
const arraysEqual = (a = [], b = []) =>
a.length === b.length && [...a].sort().join(',') === [...b].sort().join(',');
+const buildAreaOptions = () => {
+ const codeMap = {};
+ const options = (allAreaList || []).map((provinceItem) => {
+ codeMap[provinceItem.value] = provinceItem.province;
+ return {
+ label: provinceItem.province,
+ value: provinceItem.value,
+ children: (provinceItem.data || []).map((cityItem) => {
+ codeMap[cityItem.value] = cityItem.city;
+ return {
+ label: cityItem.city,
+ value: cityItem.value,
+ children: (cityItem.dataList || []).map((areaItem) => {
+ codeMap[areaItem.value] = areaItem.area;
+ return { label: areaItem.area, value: areaItem.value };
+ }),
+ };
+ }),
+ };
+ });
+ return { options, codeMap };
+};
+
export default function OutboundRobotSetting() {
+ const { options: areaOptions, codeMap } = useMemo(() => buildAreaOptions(), []);
const [loading, setLoading] = useState(false);
const [saving, setSaving] = useState(false);
const [robotList, setRobotList] = useState([]);
const [siteOptions, setSiteOptions] = useState([]);
+ const [draftArea, setDraftArea] = useState({});
const [originList, setOriginList] = useState([]);
const loadList = async () => {
@@ -30,6 +65,7 @@
const list = (res?.data?.robotSettings || []).map((item) => ({
...item,
siteIds: commaTextToNumberArray(item.siteIds),
+ dialAreaCodes: commaTextToArray(item.dialAreaCodes),
}));
setSiteOptions(
(res?.data?.sites || []).map((item) => ({ label: item.siteName, value: item.id })),
@@ -39,6 +75,7 @@
list.map((item) => ({
id: item.id,
siteIds: [...item.siteIds],
+ dialAreaCodes: [...item.dialAreaCodes],
})),
);
} else {
@@ -59,13 +96,44 @@
);
};
+ const setAreaValue = (id, value) => {
+ setDraftArea((prev) => ({ ...prev, [id]: value }));
+ };
+
+ const addArea = (id) => {
+ const selectedPath = draftArea[id];
+ const code = Array.isArray(selectedPath) ? selectedPath[selectedPath.length - 1] : selectedPath;
+ if (!code) return;
+
+ setRobotList((prev) =>
+ prev.map((item) => {
+ if (item.id !== id || item.dialAreaCodes.includes(code)) return item;
+ return { ...item, dialAreaCodes: [...item.dialAreaCodes, code] };
+ }),
+ );
+ setDraftArea((prev) => ({ ...prev, [id]: undefined }));
+ };
+
+ const removeArea = (id, code) => {
+ setRobotList((prev) =>
+ prev.map((item) =>
+ item.id === id
+ ? { ...item, dialAreaCodes: item.dialAreaCodes.filter((itemCode) => itemCode !== code) }
+ : item,
+ ),
+ );
+ };
+
const save = async () => {
const changedList = robotList.filter((item) => {
const origin = originList.find((originItem) => originItem.id === item.id);
if (!origin) {
return true;
}
- return !arraysEqual(origin.siteIds, item.siteIds);
+ return (
+ !arraysEqual(origin.siteIds, item.siteIds) ||
+ !arraysEqual(origin.dialAreaCodes, item.dialAreaCodes)
+ );
});
if (changedList.length === 0) {
@@ -79,6 +147,7 @@
const res = await update({
id: item.id,
siteIds: item.siteIds || [],
+ dialAreaCodes: item.dialAreaCodes || [],
});
if (String(res?.code) !== '200') {
message.error(res?.msg || `机器人 ${item.robotNumber || item.id} 保存失败`);
@@ -97,8 +166,8 @@
<Spin spinning={loading}>
<div className={styles.page}>
<div className={styles.header}>
- <div className={styles.title}>机器人可外呼站点设置</div>
- <div className={styles.subTitle}>按订单所属站点配置机器人可外呼范围</div>
+ <div className={styles.title}>机器人外呼设置</div>
+ <div className={styles.subTitle}>按订单所属站点和拨打区域配置机器人外呼范围</div>
</div>
{robotList.length === 0 && !loading ? <Empty description="暂无配置" /> : null}
@@ -131,6 +200,33 @@
/>
</div>
</div>
+
+ <div className={styles.fieldRow}>
+ <div className={styles.label}>拨打区域</div>
+ <div className={styles.value}>
+ <div className={styles.tags}>
+ {item.dialAreaCodes.map((code) => (
+ <Tag key={code} closable onClose={() => removeArea(item.id, code)}>
+ {codeMap[code] || code}
+ </Tag>
+ ))}
+ </div>
+ <div className={styles.areaRow}>
+ <Cascader
+ className={styles.cascader}
+ value={draftArea[item.id]}
+ options={areaOptions}
+ placeholder="请选择省 / 市 / 区"
+ changeOnSelect
+ expandTrigger="hover"
+ onChange={(value) => setAreaValue(item.id, value)}
+ />
+ <Button icon={<PlusOutlined />} onClick={() => addArea(item.id)}>
+ 添加
+ </Button>
+ </div>
+ </div>
+ </div>
</section>
))}
diff --git a/management/src/pages/settings/outboundRobotSetting/style.less b/management/src/pages/settings/outboundRobotSetting/style.less
index 2f331cd..e2d3962 100644
--- a/management/src/pages/settings/outboundRobotSetting/style.less
+++ b/management/src/pages/settings/outboundRobotSetting/style.less
@@ -72,6 +72,25 @@
width: min(520px, 100%);
}
+.tags {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ min-height: 32px;
+ margin-bottom: 10px;
+}
+
+.areaRow {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 10px;
+ align-items: center;
+}
+
+.cascader {
+ width: min(420px, 100%);
+}
+
.footer {
display: flex;
justify-content: flex-start;
--
Gitblit v1.7.1