通过添加AI重写功能增强StepSendMessage组件。为AI重写引入新的状态管理,为内容修改实现新的AiRewrite方法,并更新AI操作按钮的样式。通过加载指示符和验证消息改善用户体验。
This commit is contained in:
@@ -273,6 +273,16 @@
|
||||
.aiRewriteInput {
|
||||
max-width: 240px;
|
||||
}
|
||||
|
||||
.aiRewriteActions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.aiRewriteButton {
|
||||
min-width: 96px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,12 @@ import {
|
||||
Switch,
|
||||
message as antdMessage,
|
||||
} from "antd";
|
||||
import { CopyOutlined, DeleteOutlined, PlusOutlined } from "@ant-design/icons";
|
||||
import {
|
||||
CopyOutlined,
|
||||
DeleteOutlined,
|
||||
PlusOutlined,
|
||||
ReloadOutlined,
|
||||
} from "@ant-design/icons";
|
||||
import type { CheckboxChangeEvent } from "antd/es/checkbox";
|
||||
|
||||
import styles from "./index.module.scss";
|
||||
@@ -21,6 +26,7 @@ import type { ContentItem } from "@/components/ContentSelection/data";
|
||||
import {
|
||||
createContentLibrary,
|
||||
deleteContentLibrary,
|
||||
aiEditContent,
|
||||
type CreateContentLibraryParams,
|
||||
} from "./api";
|
||||
|
||||
@@ -80,6 +86,7 @@ const StepSendMessage: React.FC<StepSendMessageProps> = ({
|
||||
onSelectedContentLibrariesChange,
|
||||
}) => {
|
||||
const [savingScriptGroup, setSavingScriptGroup] = useState(false);
|
||||
const [aiRewriting, setAiRewriting] = useState(false);
|
||||
const [deletingGroupIds, setDeletingGroupIds] = useState<string[]>([]);
|
||||
|
||||
const handleAddMessage = useCallback(
|
||||
@@ -172,6 +179,99 @@ const StepSendMessage: React.FC<StepSendMessageProps> = ({
|
||||
savingScriptGroup,
|
||||
]);
|
||||
|
||||
const handleAiRewrite = useCallback(async () => {
|
||||
if (!aiRewriteEnabled) {
|
||||
antdMessage.warning("请先开启AI智能话术改写");
|
||||
return;
|
||||
}
|
||||
const trimmedPrompt = aiPrompt.trim();
|
||||
const originalContent = messageContent;
|
||||
const trimmedContent = originalContent.trim();
|
||||
if (!trimmedPrompt) {
|
||||
antdMessage.warning("请输入改写提示词");
|
||||
return;
|
||||
}
|
||||
if (!trimmedContent) {
|
||||
antdMessage.warning("请输入需要改写的内容");
|
||||
return;
|
||||
}
|
||||
if (aiRewriting) {
|
||||
return;
|
||||
}
|
||||
let hideLoading: ReturnType<typeof antdMessage.loading> | undefined;
|
||||
try {
|
||||
setAiRewriting(true);
|
||||
hideLoading = antdMessage.loading("AI正在改写话术...", 0);
|
||||
const response = await aiEditContent({
|
||||
aiPrompt: trimmedPrompt,
|
||||
content: originalContent,
|
||||
});
|
||||
hideLoading?.();
|
||||
const normalizedResponse = response as {
|
||||
content?: string;
|
||||
contentAfter?: string;
|
||||
contentFront?: string;
|
||||
data?:
|
||||
| string
|
||||
| {
|
||||
content?: string;
|
||||
contentAfter?: string;
|
||||
contentFront?: string;
|
||||
};
|
||||
result?: string;
|
||||
};
|
||||
const dataField = normalizedResponse?.data;
|
||||
const dataContent =
|
||||
typeof dataField === "string"
|
||||
? dataField
|
||||
: (dataField?.content ?? undefined);
|
||||
const dataContentAfter =
|
||||
typeof dataField === "string" ? undefined : dataField?.contentAfter;
|
||||
const dataContentFront =
|
||||
typeof dataField === "string" ? undefined : dataField?.contentFront;
|
||||
|
||||
const primaryAfter =
|
||||
normalizedResponse?.contentAfter ?? dataContentAfter ?? undefined;
|
||||
const primaryFront =
|
||||
normalizedResponse?.contentFront ?? dataContentFront ?? undefined;
|
||||
|
||||
let rewrittenContent = "";
|
||||
if (typeof response === "string") {
|
||||
rewrittenContent = response;
|
||||
} else if (primaryAfter) {
|
||||
rewrittenContent = primaryFront
|
||||
? `${primaryFront}\n${primaryAfter}`
|
||||
: primaryAfter;
|
||||
} else if (typeof normalizedResponse?.content === "string") {
|
||||
rewrittenContent = normalizedResponse.content;
|
||||
} else if (typeof dataContent === "string") {
|
||||
rewrittenContent = dataContent;
|
||||
} else if (typeof normalizedResponse?.result === "string") {
|
||||
rewrittenContent = normalizedResponse.result;
|
||||
} else if (primaryFront) {
|
||||
rewrittenContent = primaryFront;
|
||||
}
|
||||
if (!rewrittenContent || typeof rewrittenContent !== "string") {
|
||||
antdMessage.error("AI改写失败,请稍后重试");
|
||||
return;
|
||||
}
|
||||
onMessageContentChange(rewrittenContent.trim());
|
||||
antdMessage.success("AI改写完成,请确认内容");
|
||||
} catch (error) {
|
||||
hideLoading?.();
|
||||
console.error("AI改写失败:", error);
|
||||
antdMessage.error("AI改写失败,请稍后重试");
|
||||
} finally {
|
||||
setAiRewriting(false);
|
||||
}
|
||||
}, [
|
||||
aiPrompt,
|
||||
aiRewriting,
|
||||
aiRewriteEnabled,
|
||||
messageContent,
|
||||
onMessageContentChange,
|
||||
]);
|
||||
|
||||
const handleApplyGroup = useCallback(
|
||||
(group: ScriptGroup) => {
|
||||
onCurrentScriptMessagesChange(group.messages);
|
||||
@@ -389,13 +489,24 @@ const StepSendMessage: React.FC<StepSendMessageProps> = ({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
type="primary"
|
||||
icon={<PlusOutlined />}
|
||||
onClick={() => handleAddMessage(undefined, true)}
|
||||
>
|
||||
添加
|
||||
</Button>
|
||||
<div className={styles.aiRewriteActions}>
|
||||
<Button
|
||||
icon={<ReloadOutlined />}
|
||||
onClick={handleAiRewrite}
|
||||
disabled={!aiRewriteEnabled}
|
||||
loading={aiRewriting}
|
||||
className={styles.aiRewriteButton}
|
||||
>
|
||||
AI改写
|
||||
</Button>
|
||||
<Button
|
||||
type="primary"
|
||||
icon={<PlusOutlined />}
|
||||
onClick={() => handleAddMessage(undefined, true)}
|
||||
>
|
||||
添加
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user