二手回收后台,师傅端,用户端
刘帅
2026-09-14 9835b6332cf7d2ce8584b5f1609a3e89035706db
机器人设置页面调整
2个文件已修改
125 ■■■■■ 已修改文件
management/src/pages/settings/outboundRobotSetting/index.jsx 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
management/src/pages/settings/outboundRobotSetting/style.less 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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>
          ))}
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;