新增自定義標籤功能,更新表單數據結構以支持自定義標籤選項,並優化相關邏輯以提升用戶體驗。

This commit is contained in:
超级老白兔
2025-08-12 16:12:37 +08:00
parent 9170857d8a
commit 2693e573f6
3 changed files with 68 additions and 20 deletions

View File

@@ -24,11 +24,13 @@ export interface FormData {
posters: any[]; // 后续可替换为具体Poster类型
device: string[];
customTags: string[];
customTagsOptions: string[];
deveiceGroups: string[];
deveiceGroupsOptions: DeviceSelectionItem[];
wechatGroups: string[];
wechatGroupsOptions: GroupSelectionItem[];
messagePlans: any[];
[key: string]: any;
}
export const defFormData: FormData = {
name: "",
@@ -46,6 +48,7 @@ export const defFormData: FormData = {
posters: [],
device: [],
customTags: [],
customTagsOptions: [],
messagePlans: [],
deveiceGroups: [],
deveiceGroupsOptions: [],

View File

@@ -1,7 +1,6 @@
import { useState, useEffect } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { message, Button, Space } from "antd";
import { ArrowLeftOutlined, ArrowRightOutlined } from "@ant-design/icons";
import NavCommon from "@/components/NavCommon";
import BasicSettings from "./steps/BasicSettings";
import FriendRequestSettings from "./steps/FriendRequestSettings";
@@ -53,6 +52,9 @@ export default function NewPlan() {
...prev,
name: detail.name ?? "",
scenario: Number(detail.scenario) || 1,
scenarioTags: detail.scenarioTags ?? [],
customTags: detail.customTags ?? [],
customTagsOptions: detail.customTags ?? [],
posters: detail.posters ?? [],
device: detail.device ?? [],
remarkType: detail.remarkType ?? "phone",

View File

@@ -38,7 +38,6 @@ const generatePosterMaterials = (): Material[] => {
};
const BasicSettings: React.FC<BasicSettingsProps> = ({
isEdit,
formData,
onChange,
sceneList,
@@ -52,14 +51,16 @@ const BasicSettings: React.FC<BasicSettingsProps> = ({
// 自定义标签相关状态
const [customTagInput, setCustomTagInput] = useState("");
const [customTags, setCustomTags] = useState<string[]>(
formData.customTags || [],
const [customTagsOptions, setCustomTagsOptions] = useState<string[]>(
formData.customTagsOptions || [],
);
const [tips, setTips] = useState(formData.tips || "");
const [selectedScenarioTags, setSelectedScenarioTags] = useState(
formData.scenarioTags || [],
);
const [selectedCustomTags, setSelectedCustomTags] = useState(
formData.customTags || [],
);
// 电话获客相关状态
const [phoneSettings, setPhoneSettings] = useState({
autoAdd: formData.phoneSettings?.autoAdd ?? true,
@@ -81,6 +82,17 @@ const BasicSettings: React.FC<BasicSettingsProps> = ({
}
}, [formData, onChange]);
// 监听 formData 变化,同步自定义标签和获客标签状态
useEffect(() => {
setCustomTagsOptions(formData.customTagsOptions || []);
setSelectedCustomTags(formData.customTags || []);
}, [formData.customTagsOptions, formData.customTags]);
// 监听获客标签变化
useEffect(() => {
setSelectedScenarioTags(formData.scenarioTags || []);
}, [formData.scenarioTags]);
useEffect(() => {
setTips(formData.tips || "");
}, [formData.tips]);
@@ -99,32 +111,58 @@ const BasicSettings: React.FC<BasicSettingsProps> = ({
onChange({ ...formData, scenarioTags: newTags });
};
const handleCustomTagToggle = (tag: string) => {
const newTags = selectedCustomTags.includes(tag)
? selectedCustomTags.filter((t: string) => t !== tag)
: [...selectedCustomTags, tag];
setSelectedCustomTags(newTags);
onChange({ ...formData, customTags: newTags });
};
// 添加自定义标签
const handleAddCustomTag = () => {
if (!customTagInput.trim()) return;
const newTag = customTagInput.trim();
const updatedCustomTags = [...customTags, newTag];
setCustomTags(updatedCustomTags);
// 已存在则忽略
if (customTagsOptions.includes(newTag)) {
// 若未选中则顺便选中
const maybeSelected = selectedCustomTags.includes(newTag)
? selectedCustomTags
: [...selectedCustomTags, newTag];
setSelectedCustomTags(maybeSelected);
onChange({ ...formData, customTags: maybeSelected });
setCustomTagInput("");
return;
}
const updatedOptions = [...customTagsOptions, newTag];
const updatedSelected = [...selectedCustomTags, newTag];
setCustomTagsOptions(updatedOptions);
setSelectedCustomTags(updatedSelected);
setCustomTagInput("");
onChange({ ...formData, customTags: updatedCustomTags });
onChange({
...formData,
customTagsOptions: updatedOptions,
customTags: updatedSelected,
});
};
// 删除自定义标签
const handleRemoveCustomTag = (tagName: string) => {
const updatedCustomTags = customTags.filter(
const updatedOptions = customTagsOptions.filter(
(tag: string) => tag !== tagName,
);
setCustomTags(updatedCustomTags);
onChange({ ...formData, customTags: updatedCustomTags });
// 同时从选中标签中移除
const updatedSelectedTags = selectedScenarioTags.filter(
setCustomTagsOptions(updatedOptions);
// 同时从选中的自定义标签中移除
const updatedSelectedCustom = selectedCustomTags.filter(
(t: string) => t !== tagName,
);
setSelectedScenarioTags(updatedSelectedTags);
setSelectedCustomTags(updatedSelectedCustom);
onChange({
...formData,
scenarioTags: updatedSelectedTags,
customTags: updatedCustomTags,
customTagsOptions: updatedOptions,
customTags: updatedSelectedCustom,
});
};
@@ -248,11 +286,11 @@ const BasicSettings: React.FC<BasicSettingsProps> = ({
</Tag>
))}
{/* 自定义标签 */}
{customTags.map((tag: string) => (
{customTagsOptions.map((tag: string) => (
<Tag
key={tag}
color={selectedScenarioTags.includes(tag) ? "blue" : "default"}
onClick={() => handleScenarioTagToggle(tag)}
color={selectedCustomTags.includes(tag) ? "blue" : "default"}
onClick={() => handleCustomTagToggle(tag)}
closable
onClose={() => handleRemoveCustomTag(tag)}
className={styles["basic-tag-item"]}
@@ -268,9 +306,14 @@ const BasicSettings: React.FC<BasicSettingsProps> = ({
type="text"
value={customTagInput}
onChange={e => setCustomTagInput(e.target.value)}
onPressEnter={handleAddCustomTag}
placeholder="添加自定义标签"
/>
<Button type="primary" onClick={handleAddCustomTag}>
<Button
type="primary"
onClick={handleAddCustomTag}
disabled={!customTagInput.trim()}
>
</Button>
</div>