新建计划 - 获客场景

This commit is contained in:
柳清爽
2025-04-07 14:40:10 +08:00
parent 919317630e
commit 118c538e38

View File

@@ -19,6 +19,8 @@ import {
DialogFooter,
DialogDescription,
} from "@/components/ui/dialog"
import { fetchScenes } from "@/api/scenarios"
import type { SceneItem } from "@/api/scenarios"
// 调整场景顺序确保API获客在最后并且前三个是最常用的场景
const scenarios = [
@@ -108,6 +110,11 @@ const generatePosterMaterials = (): Material[] => {
}))
}
// 格式化场景名称,移除"获客"二字
function formatSceneName(name: string): string {
return name.replace(/获客/g, "");
}
export function BasicSettings({ formData, onChange, onNext }: BasicSettingsProps) {
const [isAccountDialogOpen, setIsAccountDialogOpen] = useState(false)
const [isMaterialDialogOpen, setIsMaterialDialogOpen] = useState(false)
@@ -123,6 +130,12 @@ export function BasicSettings({ formData, onChange, onNext }: BasicSettingsProps
const [selectedMaterials, setSelectedMaterials] = useState<Material[]>(
formData.materials?.length > 0 ? formData.materials : [],
)
// 添加场景列表状态
const [scenes, setScenes] = useState<SceneItem[]>([])
const [loadingScenes, setLoadingScenes] = useState(true)
const [sceneError, setSceneError] = useState<string | null>(null)
const [showAllScenarios, setShowAllScenarios] = useState(false)
const [isImportDialogOpen, setIsImportDialogOpen] = useState(false)
const [importedTags, setImportedTags] = useState<
@@ -142,6 +155,32 @@ export function BasicSettings({ formData, onChange, onNext }: BasicSettingsProps
questionExtraction: formData.phoneSettings?.questionExtraction ?? true,
})
// 加载场景列表
useEffect(() => {
const loadScenes = async () => {
try {
setLoadingScenes(true)
setSceneError(null)
const response = await fetchScenes({ limit: 30 })
if (response.code === 200 && response.data?.list) {
setScenes(response.data.list)
} else {
setSceneError(response.msg || "获取场景列表失败")
console.error("获取场景列表失败:", response.msg)
}
} catch (err) {
console.error("获取场景列表失败:", err)
setSceneError("获取场景列表失败,请稍后重试")
} finally {
setLoadingScenes(false)
}
}
loadScenes()
}, [])
// 初始化时,如果没有选择场景,默认选择海报获客
useEffect(() => {
if (!formData.scenario) {
@@ -158,16 +197,50 @@ export function BasicSettings({ formData, onChange, onNext }: BasicSettingsProps
}
}, [formData, onChange])
// 处理从API获取的场景选择
const handleSceneSelect = (scene: SceneItem) => {
// 更新formData中的场景相关数据
const formattedName = formatSceneName(scene.name);
onChange({
...formData,
sceneId: scene.id,
sceneName: scene.name,
scenario: getLocalScenarioType(scene.name), // 基于名称推断本地场景类型
});
// 如果是电话场景,自动设置计划名称
if (scene.name.includes("电话")) {
const today = new Date().toLocaleDateString("zh-CN").replace(/\//g, "");
onChange({ ...formData, planName: `${formattedName}${today}` });
}
}
// 处理本地场景选择
const handleScenarioSelect = (scenarioId: string) => {
onChange({ ...formData, scenario: scenarioId })
// 如果选择了电话获客,自动更新计划名称
if (scenarioId === "phone") {
const today = new Date().toLocaleDateString("zh-CN").replace(/\//g, "")
onChange({ ...formData, planName: `电话获客${today}` })
onChange({ ...formData, planName: `电话${today}` })
}
}
// 根据场景名称推断本地场景类型
const getLocalScenarioType = (name: string): string => {
if (name.includes("海报")) return "haibao";
if (name.includes("订单")) return "order";
if (name.includes("抖音")) return "douyin";
if (name.includes("小红书")) return "xiaohongshu";
if (name.includes("电话")) return "phone";
if (name.includes("公众号")) return "gongzhonghao";
if (name.includes("微信群")) return "weixinqun";
if (name.includes("付款码")) return "payment";
if (name.includes("API")) return "api";
return "haibao"; // 默认返回海报获客类型
}
const handleAccountSelect = (account: Account) => {
const updatedAccounts = [...selectedAccounts, account]
setSelectedAccounts(updatedAccounts)
@@ -258,22 +331,49 @@ export function BasicSettings({ formData, onChange, onNext }: BasicSettingsProps
<div className="space-y-6">
<div>
<Label className="text-base mb-4 block"></Label>
{/* 场景按钮阵列 */}
<div className="grid grid-cols-3 gap-2">
{displayedScenarios.map((scenario) => (
<button
key={scenario.id}
className={`p-2 rounded-lg text-center transition-all ${
formData.scenario === scenario.id
? "bg-blue-100 text-blue-600 font-medium"
: "bg-gray-50 text-gray-600 hover:bg-gray-100"
}`}
onClick={() => handleScenarioSelect(scenario.id)}
>
{scenario.name.replace("获客", "")}
</button>
))}
{loadingScenes ? (
// 加载中状态
Array.from({ length: 6 }).map((_, index) => (
<div key={index} className="h-10 w-full rounded-lg bg-gray-200 animate-pulse"></div>
))
) : sceneError || scenes.length === 0 ? (
// 加载失败或无数据时显示本地场景
displayedScenarios.map((scenario) => (
<button
key={scenario.id}
className={`p-2 rounded-lg text-center transition-all ${
formData.scenario === scenario.id
? "bg-blue-100 text-blue-600 font-medium"
: "bg-gray-50 text-gray-600 hover:bg-gray-100"
}`}
onClick={() => handleScenarioSelect(scenario.id)}
>
{formatSceneName(scenario.name)}
</button>
))
) : (
// 从API获取的场景列表
scenes.map((scene) => (
<button
key={scene.id}
className={`p-2 rounded-lg text-center transition-all ${
formData.sceneId === scene.id
? "bg-blue-100 text-blue-600 font-medium"
: "bg-gray-50 text-gray-600 hover:bg-gray-100"
}`}
onClick={() => handleSceneSelect(scene)}
>
{formatSceneName(scene.name)}
</button>
))
)}
</div>
{!showAllScenarios && (
{/* 展开更多按钮 - 仅当显示本地场景且未展开全部时显示 */}
{(!loadingScenes && (sceneError || scenes.length === 0) && !showAllScenarios) && (
<Button variant="ghost" className="mt-2 w-full text-blue-600" onClick={() => setShowAllScenarios(true)}>
<ChevronDown className="ml-2 h-4 w-4" />
</Button>