正在显示
7 个修改的文件
包含
283 行增加
和
179 行删除
@@ -452,45 +452,6 @@ export function BgPanel(props: PanelProps) { | @@ -452,45 +452,6 @@ export function BgPanel(props: PanelProps) { | ||
452 | 452 | ||
453 | return ( | 453 | return ( |
454 | <> | 454 | <> |
455 | - <ControlParamItem title={Locale.BgRemoval.subTitle}> | ||
456 | - <div className={styles["ai-models"]}> | ||
457 | - <IconButton | ||
458 | - text={Locale.BgRemoval.generateImg} | ||
459 | - type="primary" | ||
460 | - shadow | ||
461 | - onClick={handleGenerateImg} | ||
462 | - disabled={isLoading} | ||
463 | - /> | ||
464 | - <IconButton | ||
465 | - text={Locale.BgRemoval.bgRemoveBtn} | ||
466 | - type="primary" | ||
467 | - shadow | ||
468 | - onClick={() => handleProcessImage("visual/segmentation")} | ||
469 | - disabled={isLoading} | ||
470 | - /> | ||
471 | - <IconButton | ||
472 | - text={Locale.BgRemoval.downloadImg} | ||
473 | - type="primary" | ||
474 | - shadow | ||
475 | - onClick={handleDownload} | ||
476 | - disabled={!previewUrl} | ||
477 | - /> | ||
478 | - <IconButton | ||
479 | - text={Locale.BgRemoval.generateBg} | ||
480 | - type="primary" | ||
481 | - shadow | ||
482 | - onClick={() => handleProcessImage("visual/r-background")} | ||
483 | - disabled={isLoading} | ||
484 | - /> | ||
485 | - <IconButton | ||
486 | - text={Locale.BgRemoval.generateBg} | ||
487 | - type="primary" | ||
488 | - shadow | ||
489 | - onClick={() => console.log(Path.BgRemoval)} | ||
490 | - disabled={isLoading} | ||
491 | - /> | ||
492 | - </div> | ||
493 | - </ControlParamItem> | ||
494 | <ControlParamItem title={Locale.BgRemoval.promptTitle} required={true}> | 455 | <ControlParamItem title={Locale.BgRemoval.promptTitle} required={true}> |
495 | <div className={styles["prompt"]}> | 456 | <div className={styles["prompt"]}> |
496 | <textarea | 457 | <textarea |
@@ -528,6 +489,38 @@ export function BgPanel(props: PanelProps) { | @@ -528,6 +489,38 @@ export function BgPanel(props: PanelProps) { | ||
528 | /> | 489 | /> |
529 | )} | 490 | )} |
530 | </ControlParamItem> | 491 | </ControlParamItem> |
492 | + <ControlParamItem title={Locale.BgRemoval.subTitle}> | ||
493 | + <div className={styles["ai-models"]}> | ||
494 | + <IconButton | ||
495 | + text={Locale.BgRemoval.generateImg} | ||
496 | + type="primary" | ||
497 | + shadow | ||
498 | + onClick={handleGenerateImg} | ||
499 | + disabled={isLoading} | ||
500 | + /> | ||
501 | + <IconButton | ||
502 | + text={Locale.BgRemoval.bgRemoveBtn} | ||
503 | + type="primary" | ||
504 | + shadow | ||
505 | + onClick={() => handleProcessImage("visual/segmentation")} | ||
506 | + disabled={isLoading} | ||
507 | + /> | ||
508 | + <IconButton | ||
509 | + text={Locale.BgRemoval.downloadImg} | ||
510 | + type="primary" | ||
511 | + shadow | ||
512 | + onClick={handleDownload} | ||
513 | + disabled={!previewUrl} | ||
514 | + /> | ||
515 | + <IconButton | ||
516 | + text={Locale.BgRemoval.generateBg} | ||
517 | + type="primary" | ||
518 | + shadow | ||
519 | + onClick={() => handleProcessImage("visual/r-background")} | ||
520 | + disabled={isLoading} | ||
521 | + /> | ||
522 | + </div> | ||
523 | + </ControlParamItem> | ||
531 | </> | 524 | </> |
532 | ); | 525 | ); |
533 | } | 526 | } |
@@ -102,7 +102,7 @@ export function MindPage() { | @@ -102,7 +102,7 @@ export function MindPage() { | ||
102 | if (!content) return; | 102 | if (!content) return; |
103 | setIsLoading(true); | 103 | setIsLoading(true); |
104 | try { | 104 | try { |
105 | - const response = await chatStore.getMindData(newMessages, "gpt-4o-mini"); | 105 | + const response = await chatStore.sendContext(newMessages, "gpt-4o-mini"); |
106 | const cleanedContent = response.replace(/^```json|```$/g, ""); | 106 | const cleanedContent = response.replace(/^```json|```$/g, ""); |
107 | const parsedData: MindElixirData = JSON.parse(cleanedContent); | 107 | const parsedData: MindElixirData = JSON.parse(cleanedContent); |
108 | // 增强校验逻辑 | 108 | // 增强校验逻辑 |
@@ -115,7 +115,6 @@ export function MindPage() { | @@ -115,7 +115,6 @@ export function MindPage() { | ||
115 | setData(parsedData); | 115 | setData(parsedData); |
116 | navigate(Path.Mind, { replace: true, state: { msg: null } }); | 116 | navigate(Path.Mind, { replace: true, state: { msg: null } }); |
117 | } catch (error) { | 117 | } catch (error) { |
118 | - console.log(error); | ||
119 | message.error("请求失败,请重试"); | 118 | message.error("请求失败,请重试"); |
120 | } finally { | 119 | } finally { |
121 | setIsLoading(false); // 确保关闭加载状态 | 120 | setIsLoading(false); // 确保关闭加载状态 |
app/components/writing/menuData.ts
0 → 100644
1 | +export const maxWord = 5000; | ||
2 | +export const minWord = 200; | ||
3 | + | ||
4 | +export const rewriteItems = [ | ||
5 | + "全文润色", | ||
6 | + "全文缩写", | ||
7 | + "全文扩写", | ||
8 | + "语气更专业", | ||
9 | + "语气更口语化", | ||
10 | + "语气更易读", | ||
11 | + "语气更含蓄", | ||
12 | + "语气更学术化", | ||
13 | + "语气更有文采", | ||
14 | + "语气更有网感", | ||
15 | +]; | ||
16 | + | ||
17 | +export const mergedData = [ | ||
18 | + { | ||
19 | + title: "写作用途", | ||
20 | + required: true, | ||
21 | + type: "select", | ||
22 | + default: "公司官网", | ||
23 | + options: [ | ||
24 | + { name: "公司官网", value: "100%" }, | ||
25 | + { name: "小红书", value: "400px" }, | ||
26 | + { name: "微信公众号", value: "300px" }, | ||
27 | + { name: "今日头条", value: "500px" }, | ||
28 | + ], | ||
29 | + }, | ||
30 | + { | ||
31 | + title: "图片模式", | ||
32 | + type: "select", | ||
33 | + required: false, | ||
34 | + default: "免费配图", | ||
35 | + options: [ | ||
36 | + { name: "免费配图", value: "free" }, | ||
37 | + { name: "收费配图", value: "paid" }, | ||
38 | + ], | ||
39 | + }, | ||
40 | + { | ||
41 | + title: "写作风格", | ||
42 | + type: "select", | ||
43 | + required: false, | ||
44 | + default: "专业", | ||
45 | + options: [ | ||
46 | + { name: "专业", value: "professional" }, | ||
47 | + { name: "活泼", value: "lively" }, | ||
48 | + { name: "严谨", value: "strict" }, | ||
49 | + ], | ||
50 | + }, | ||
51 | + { | ||
52 | + title: "写作语言", | ||
53 | + type: "select", | ||
54 | + required: false, | ||
55 | + default: "中文", | ||
56 | + options: [ | ||
57 | + { name: "中文", value: "Chinese" }, | ||
58 | + { name: "英文", value: "English" }, | ||
59 | + { name: "法文", value: "French" }, | ||
60 | + { name: "德文", value: "German" }, | ||
61 | + ], | ||
62 | + }, | ||
63 | + { | ||
64 | + title: "写作类型", | ||
65 | + type: "select", | ||
66 | + required: false, | ||
67 | + default: "产品推广文案", | ||
68 | + options: [ | ||
69 | + { name: "产品推广文案", value: "promotion" }, | ||
70 | + { name: "品牌宣传文案", value: "propagandize" }, | ||
71 | + { name: "产品说明书", value: "instructionBook" }, | ||
72 | + { name: "产品介绍", value: "introduce" }, | ||
73 | + ], | ||
74 | + }, | ||
75 | + { | ||
76 | + title: "是否图文", | ||
77 | + type: "select", | ||
78 | + required: false, | ||
79 | + default: "是", | ||
80 | + options: [ | ||
81 | + { name: "是", value: "true" }, | ||
82 | + { name: "否", value: "false" }, | ||
83 | + ], | ||
84 | + }, | ||
85 | +]; | ||
86 | + | ||
87 | +// 20250408新增写作风格选项映射 | ||
88 | +export const getWritingStyleOptions = (purpose: string) => { | ||
89 | + switch (purpose) { | ||
90 | + case "公司官网": | ||
91 | + return [ | ||
92 | + { name: "专业", value: "professional" }, | ||
93 | + { name: "活泼", value: "lively" }, | ||
94 | + { name: "严谨", value: "strict" }, | ||
95 | + ]; | ||
96 | + case "小红书": | ||
97 | + return [ | ||
98 | + { name: "俏皮", value: "playful" }, | ||
99 | + { name: "幽默", value: "humorous" }, | ||
100 | + ]; | ||
101 | + case "微信公众号": | ||
102 | + return [ | ||
103 | + { name: "夸张", value: "exaggerated" }, | ||
104 | + { name: "可爱", value: "cute" }, | ||
105 | + ]; | ||
106 | + case "今日头条": | ||
107 | + return [ | ||
108 | + { name: "丰满", value: "full" }, | ||
109 | + { name: "可爱", value: "cute" }, | ||
110 | + { name: "健康", value: "healthy" }, | ||
111 | + ]; | ||
112 | + default: | ||
113 | + return [ | ||
114 | + { name: "专业", value: "professional" }, | ||
115 | + { name: "活泼", value: "lively" }, | ||
116 | + { name: "严谨", value: "strict" }, | ||
117 | + ]; | ||
118 | + } | ||
119 | +}; | ||
120 | + | ||
121 | +export interface writeMessage { | ||
122 | + role: string; | ||
123 | + content: string; | ||
124 | +} | ||
125 | + | ||
126 | +export interface WritePanelProps { | ||
127 | + htmlCode: string; | ||
128 | + setHtmlCode: React.Dispatch<React.SetStateAction<string>>; | ||
129 | + loading: boolean; | ||
130 | + setLoading: React.Dispatch<React.SetStateAction<boolean>>; | ||
131 | + setWidth: React.Dispatch<React.SetStateAction<string>>; | ||
132 | + setHtmlheader: React.Dispatch<React.SetStateAction<string>>; | ||
133 | +} |
@@ -3,7 +3,7 @@ import { ControlParamItem } from "../sd"; | @@ -3,7 +3,7 @@ import { ControlParamItem } from "../sd"; | ||
3 | import { SideBarTail } from "@/app/components/sidebar"; | 3 | import { SideBarTail } from "@/app/components/sidebar"; |
4 | import { useState } from "react"; | 4 | import { useState } from "react"; |
5 | import { IconButton } from "../button"; | 5 | import { IconButton } from "../button"; |
6 | -import { message } from "antd"; | 6 | +import { message as msgModal } from "antd"; |
7 | import { useChatStore } from "@/app/store"; | 7 | import { useChatStore } from "@/app/store"; |
8 | import { getWrtingPrompt } from "@/app/utils/prompt"; | 8 | import { getWrtingPrompt } from "@/app/utils/prompt"; |
9 | import type { writePromptParam } from "@/app/types/prompt"; | 9 | import type { writePromptParam } from "@/app/types/prompt"; |
@@ -11,119 +11,15 @@ import { processChatFile } from "@/app/utils/fileUtil"; | @@ -11,119 +11,15 @@ import { processChatFile } from "@/app/utils/fileUtil"; | ||
11 | import Locale from "@/app/locales"; | 11 | import Locale from "@/app/locales"; |
12 | import styles from "./wrtie-panel.module.scss"; | 12 | import styles from "./wrtie-panel.module.scss"; |
13 | import DeleteIcon from "@/app/icons/delete.svg"; | 13 | import DeleteIcon from "@/app/icons/delete.svg"; |
14 | +import { | ||
15 | + getWritingStyleOptions, | ||
16 | + maxWord, | ||
17 | + mergedData, | ||
18 | + minWord, | ||
19 | + writeMessage, | ||
20 | + WritePanelProps, | ||
21 | +} from "./menuData"; | ||
14 | 22 | ||
15 | -export const mergedData = [ | ||
16 | - { | ||
17 | - title: "写作用途", | ||
18 | - required: true, | ||
19 | - type: "select", | ||
20 | - default: "公司官网", | ||
21 | - options: [ | ||
22 | - { name: "公司官网", value: "100%" }, | ||
23 | - { name: "小红书", value: "400px" }, | ||
24 | - { name: "微信公众号", value: "300px" }, | ||
25 | - { name: "今日头条", value: "500px" }, | ||
26 | - ], | ||
27 | - }, | ||
28 | - { | ||
29 | - title: "图片模式", | ||
30 | - type: "select", | ||
31 | - required: false, | ||
32 | - default: "免费配图", | ||
33 | - options: [ | ||
34 | - { name: "免费配图", value: "free" }, | ||
35 | - { name: "收费配图", value: "paid" }, | ||
36 | - ], | ||
37 | - }, | ||
38 | - { | ||
39 | - title: "写作风格", | ||
40 | - type: "select", | ||
41 | - required: false, | ||
42 | - default: "专业", | ||
43 | - options: [ | ||
44 | - { name: "专业", value: "professional" }, | ||
45 | - { name: "活泼", value: "lively" }, | ||
46 | - { name: "严谨", value: "strict" }, | ||
47 | - ], | ||
48 | - }, | ||
49 | - { | ||
50 | - title: "写作语言", | ||
51 | - type: "select", | ||
52 | - required: false, | ||
53 | - default: "中文", | ||
54 | - options: [ | ||
55 | - { name: "中文", value: "Chinese" }, | ||
56 | - { name: "英文", value: "English" }, | ||
57 | - { name: "法文", value: "French" }, | ||
58 | - { name: "德文", value: "German" }, | ||
59 | - ], | ||
60 | - }, | ||
61 | - { | ||
62 | - title: "写作类型", | ||
63 | - type: "select", | ||
64 | - required: false, | ||
65 | - default: "产品推广文案", | ||
66 | - options: [ | ||
67 | - { name: "产品推广文案", value: "promotion" }, | ||
68 | - { name: "品牌宣传文案", value: "propagandize" }, | ||
69 | - { name: "产品说明书", value: "instructionBook" }, | ||
70 | - { name: "产品介绍", value: "introduce" }, | ||
71 | - ], | ||
72 | - }, | ||
73 | - { | ||
74 | - title: "是否图文", | ||
75 | - type: "select", | ||
76 | - required: false, | ||
77 | - default: "是", | ||
78 | - options: [ | ||
79 | - { name: "是", value: "true" }, | ||
80 | - { name: "否", value: "false" }, | ||
81 | - ], | ||
82 | - }, | ||
83 | -]; | ||
84 | - | ||
85 | -// 20250408新增写作风格选项映射 | ||
86 | -const getWritingStyleOptions = (purpose: string) => { | ||
87 | - switch (purpose) { | ||
88 | - case "公司官网": | ||
89 | - return [ | ||
90 | - { name: "专业", value: "professional" }, | ||
91 | - { name: "活泼", value: "lively" }, | ||
92 | - { name: "严谨", value: "strict" }, | ||
93 | - ]; | ||
94 | - case "小红书": | ||
95 | - return [ | ||
96 | - { name: "俏皮", value: "playful" }, | ||
97 | - { name: "幽默", value: "humorous" }, | ||
98 | - ]; | ||
99 | - case "微信公众号": | ||
100 | - return [ | ||
101 | - { name: "夸张", value: "exaggerated" }, | ||
102 | - { name: "可爱", value: "cute" }, | ||
103 | - ]; | ||
104 | - case "今日头条": | ||
105 | - return [ | ||
106 | - { name: "丰满", value: "full" }, | ||
107 | - { name: "可爱", value: "cute" }, | ||
108 | - { name: "健康", value: "healthy" }, | ||
109 | - ]; | ||
110 | - default: | ||
111 | - return [ | ||
112 | - { name: "专业", value: "professional" }, | ||
113 | - { name: "活泼", value: "lively" }, | ||
114 | - { name: "严谨", value: "strict" }, | ||
115 | - ]; | ||
116 | - } | ||
117 | -}; | ||
118 | - | ||
119 | -export interface WritePanelProps { | ||
120 | - htmlCode: string; | ||
121 | - setHtmlCode: React.Dispatch<React.SetStateAction<string>>; | ||
122 | - loading: boolean; | ||
123 | - setLoading: React.Dispatch<React.SetStateAction<boolean>>; | ||
124 | - setWidth: React.Dispatch<React.SetStateAction<string>>; | ||
125 | - setHtmlheader: React.Dispatch<React.SetStateAction<string>>; | ||
126 | -} | ||
127 | export function WritingPanel(props: WritePanelProps) { | 23 | export function WritingPanel(props: WritePanelProps) { |
128 | const { | 24 | const { |
129 | htmlCode, | 25 | htmlCode, |
@@ -147,6 +43,7 @@ export function WritingPanel(props: WritePanelProps) { | @@ -147,6 +43,7 @@ export function WritingPanel(props: WritePanelProps) { | ||
147 | 43 | ||
148 | const [fileData, setFileData] = useState(""); | 44 | const [fileData, setFileData] = useState(""); |
149 | const [fileName, setFileName] = useState(""); | 45 | const [fileName, setFileName] = useState(""); |
46 | + const messages: writeMessage[] = []; | ||
150 | 47 | ||
151 | // 生成动态数据 | 48 | // 生成动态数据 |
152 | const dynamicMergedData = mergedData.map((item) => { | 49 | const dynamicMergedData = mergedData.map((item) => { |
@@ -214,14 +111,14 @@ export function WritingPanel(props: WritePanelProps) { | @@ -214,14 +111,14 @@ export function WritingPanel(props: WritePanelProps) { | ||
214 | 111 | ||
215 | setFileName(name); | 112 | setFileName(name); |
216 | } catch { | 113 | } catch { |
217 | - message.error(Locale.ComError.UploadErr); | 114 | + msgModal.error(Locale.ComError.UploadErr); |
218 | } | 115 | } |
219 | }; | 116 | }; |
220 | 117 | ||
221 | // 提交表单时的处理函数 | 118 | // 提交表单时的处理函数 |
222 | const handleSubmit = async () => { | 119 | const handleSubmit = async () => { |
223 | if (!prompt.trim()) { | 120 | if (!prompt.trim()) { |
224 | - return message.error("请输入提示词"); | 121 | + return msgModal.error("请输入提示词"); |
225 | } | 122 | } |
226 | try { | 123 | try { |
227 | const param: writePromptParam = { | 124 | const param: writePromptParam = { |
@@ -237,7 +134,13 @@ export function WritingPanel(props: WritePanelProps) { | @@ -237,7 +134,13 @@ export function WritingPanel(props: WritePanelProps) { | ||
237 | const input = getWrtingPrompt(param); | 134 | const input = getWrtingPrompt(param); |
238 | setLoading(true); | 135 | setLoading(true); |
239 | console.log("------------------------" + input); | 136 | console.log("------------------------" + input); |
240 | - const response = await chatStore.directLlmInvoke(input, "gpt-4o-mini"); | 137 | + |
138 | + messages.push({ role: "user", content: input }); | ||
139 | + | ||
140 | + const response = await chatStore.sendContext(messages, "gpt-4o-mini"); | ||
141 | + | ||
142 | + messages.push({ role: "assistant", content: response }); | ||
143 | + | ||
241 | let cleanedContent = response.startsWith("```html") | 144 | let cleanedContent = response.startsWith("```html") |
242 | ? response.substring(8) | 145 | ? response.substring(8) |
243 | : response; | 146 | : response; |
@@ -256,9 +159,11 @@ export function WritingPanel(props: WritePanelProps) { | @@ -256,9 +159,11 @@ export function WritingPanel(props: WritePanelProps) { | ||
256 | setHtmlheader(contentUpToBody); //保存html头部 | 159 | setHtmlheader(contentUpToBody); //保存html头部 |
257 | } | 160 | } |
258 | localStorage.setItem("htmlCode", cleanedContent); | 161 | localStorage.setItem("htmlCode", cleanedContent); |
162 | + | ||
163 | + localStorage.setItem("aiWrite", JSON.stringify(messages)); | ||
259 | setHtmlCode(cleanedContent); | 164 | setHtmlCode(cleanedContent); |
260 | } catch (error) { | 165 | } catch (error) { |
261 | - message.error("生成失败,请重试"); | 166 | + msgModal.error("生成失败,请重试"); |
262 | } finally { | 167 | } finally { |
263 | setLoading(false); | 168 | setLoading(false); |
264 | } | 169 | } |
@@ -319,9 +224,9 @@ export function WritingPanel(props: WritePanelProps) { | @@ -319,9 +224,9 @@ export function WritingPanel(props: WritePanelProps) { | ||
319 | <input | 224 | <input |
320 | aria-label="写作字数" | 225 | aria-label="写作字数" |
321 | type="number" | 226 | type="number" |
322 | - placeholder="200" | ||
323 | - min="200" | ||
324 | - max="5000" | 227 | + placeholder={String(minWord)} |
228 | + min={minWord} | ||
229 | + max={maxWord} | ||
325 | value={writingCount} | 230 | value={writingCount} |
326 | onChange={handleInputChange} | 231 | onChange={handleInputChange} |
327 | /> | 232 | /> |
@@ -39,14 +39,14 @@ import PptIcon from "@/app/icons/ppt.svg"; | @@ -39,14 +39,14 @@ import PptIcon from "@/app/icons/ppt.svg"; | ||
39 | import PdfIcon from "@/app/icons/pdf.svg"; | 39 | import PdfIcon from "@/app/icons/pdf.svg"; |
40 | import HtmlIcon from "@/app/icons/HTML.svg"; | 40 | import HtmlIcon from "@/app/icons/HTML.svg"; |
41 | 41 | ||
42 | -import { message } from "antd"; | 42 | +import { Button, Dropdown, MenuProps, message as msgModal, Space } from "antd"; |
43 | import { HTMLPreview } from "../artifacts"; | 43 | import { HTMLPreview } from "../artifacts"; |
44 | import { getMindPrompt, getWrtingPrompt } from "@/app/utils/prompt"; | 44 | import { getMindPrompt, getWrtingPrompt } from "@/app/utils/prompt"; |
45 | import { htmlToPdf2 } from "@/app/utils/fileExport/toPdf"; | 45 | import { htmlToPdf2 } from "@/app/utils/fileExport/toPdf"; |
46 | import { hasTable, htmlToExcel } from "@/app/utils/fileExport/export2Excel"; | 46 | import { hasTable, htmlToExcel } from "@/app/utils/fileExport/export2Excel"; |
47 | import { writePromptParam } from "@/app/types/prompt"; | 47 | import { writePromptParam } from "@/app/types/prompt"; |
48 | -import { mergedData } from "./writie-panel"; | ||
49 | import dynamic from "next/dynamic"; | 48 | import dynamic from "next/dynamic"; |
49 | +import { rewriteItems, mergedData } from "./menuData"; | ||
50 | 50 | ||
51 | const EditorComponent = dynamic( | 51 | const EditorComponent = dynamic( |
52 | async () => (await import("./editor")).EditorComponent, | 52 | async () => (await import("./editor")).EditorComponent, |
@@ -75,6 +75,23 @@ export function WritingPage() { | @@ -75,6 +75,23 @@ export function WritingPage() { | ||
75 | const query = useLocation(); //获取路由参数 | 75 | const query = useLocation(); //获取路由参数 |
76 | let { msg, writeMessage } = query.state || {}; //获取路由参数 | 76 | let { msg, writeMessage } = query.state || {}; //获取路由参数 |
77 | 77 | ||
78 | + const items: MenuProps["items"] = rewriteItems.map((item, index) => ({ | ||
79 | + key: (index + 1).toString(), | ||
80 | + label: ( | ||
81 | + <a | ||
82 | + target="_blank" | ||
83 | + rel="noopener noreferrer" | ||
84 | + href="#" | ||
85 | + onClick={(e) => { | ||
86 | + e.preventDefault(); // 阻止默认行为 | ||
87 | + rewrite(item); // 调用 rewrite 函数并传递菜单项文本 | ||
88 | + }} | ||
89 | + > | ||
90 | + {item} | ||
91 | + </a> | ||
92 | + ), | ||
93 | + })); | ||
94 | + | ||
78 | useEffect(() => { | 95 | useEffect(() => { |
79 | if (!msg) { | 96 | if (!msg) { |
80 | return; | 97 | return; |
@@ -121,7 +138,7 @@ export function WritingPage() { | @@ -121,7 +138,7 @@ export function WritingPage() { | ||
121 | localStorage.setItem("htmlCode", cleanedContent); | 138 | localStorage.setItem("htmlCode", cleanedContent); |
122 | setHtmlCode(cleanedContent); | 139 | setHtmlCode(cleanedContent); |
123 | } catch (error) { | 140 | } catch (error) { |
124 | - message.error("生成失败,请重试"); | 141 | + msgModal.error("生成失败,请重试"); |
125 | } finally { | 142 | } finally { |
126 | setLoading(false); | 143 | setLoading(false); |
127 | } | 144 | } |
@@ -159,11 +176,9 @@ export function WritingPage() { | @@ -159,11 +176,9 @@ export function WritingPage() { | ||
159 | const blob = new Blob([htmlCode], { type: "text/html" }); | 176 | const blob = new Blob([htmlCode], { type: "text/html" }); |
160 | const clipboardItem = new ClipboardItem({ "text/html": blob }); | 177 | const clipboardItem = new ClipboardItem({ "text/html": blob }); |
161 | await navigator.clipboard.write([clipboardItem]); | 178 | await navigator.clipboard.write([clipboardItem]); |
162 | - message.success("复制成功!"); | 179 | + msgModal.success("复制成功!"); |
163 | } catch (error) { | 180 | } catch (error) { |
164 | - console.log(error); | ||
165 | - | ||
166 | - message.error("复制失败"); | 181 | + msgModal.error("复制失败"); |
167 | } | 182 | } |
168 | }; | 183 | }; |
169 | //跳转到ppt页面 | 184 | //跳转到ppt页面 |
@@ -211,12 +226,67 @@ export function WritingPage() { | @@ -211,12 +226,67 @@ export function WritingPage() { | ||
211 | a.download = fileName; | 226 | a.download = fileName; |
212 | a.click(); | 227 | a.click(); |
213 | URL.revokeObjectURL(url); | 228 | URL.revokeObjectURL(url); |
214 | - message.success("导出成功"); | 229 | + msgModal.success("导出成功"); |
215 | } catch (error) { | 230 | } catch (error) { |
216 | - message.error("导出失败"); | 231 | + msgModal.error("导出失败"); |
217 | } | 232 | } |
218 | }, [wrapContentInDivWithWidth]); | 233 | }, [wrapContentInDivWithWidth]); |
219 | 234 | ||
235 | + async function rewrite(msg: string) { | ||
236 | + const messagesStr = localStorage.getItem("aiWrite"); | ||
237 | + if (!messagesStr) return; | ||
238 | + | ||
239 | + let messages: any; | ||
240 | + try { | ||
241 | + messages = JSON.parse(messagesStr); | ||
242 | + } catch (error) { | ||
243 | + return; | ||
244 | + } | ||
245 | + | ||
246 | + // 检查是否是数组且包含合法 message 对象 | ||
247 | + if (!Array.isArray(messages)) return; | ||
248 | + if ( | ||
249 | + !messages.every( | ||
250 | + (m) => | ||
251 | + typeof m === "object" && | ||
252 | + m !== null && | ||
253 | + "role" in m && | ||
254 | + "content" in m && | ||
255 | + typeof m.role === "string" && | ||
256 | + typeof m.content === "string", | ||
257 | + ) | ||
258 | + ) | ||
259 | + return; | ||
260 | + try { | ||
261 | + setLoading(true); | ||
262 | + const response = await chatStore.sendContext(messages, "gpt-4o-mini"); | ||
263 | + messages.push({ role: "assistant", content: response }); | ||
264 | + | ||
265 | + let cleanedContent = response.startsWith("```html") | ||
266 | + ? response.substring(8) | ||
267 | + : response; | ||
268 | + if (cleanedContent.endsWith("```")) { | ||
269 | + cleanedContent = cleanedContent.substring(0, cleanedContent.length - 4); | ||
270 | + } | ||
271 | + | ||
272 | + const bodyTagRegex = /<body[^>]*>/i; | ||
273 | + const bodyTagMatch = cleanedContent.match(bodyTagRegex); | ||
274 | + if (bodyTagMatch?.index !== undefined) { | ||
275 | + setHtmlheader( | ||
276 | + cleanedContent.slice(0, bodyTagMatch.index + bodyTagMatch[0].length), | ||
277 | + ); | ||
278 | + } | ||
279 | + | ||
280 | + localStorage.setItem("htmlCode", cleanedContent); | ||
281 | + localStorage.setItem("aiWrite", JSON.stringify(messages)); | ||
282 | + setHtmlCode(cleanedContent); | ||
283 | + } catch (error) { | ||
284 | + msgModal.error("重写失败,请重试"); | ||
285 | + } finally { | ||
286 | + setLoading(false); | ||
287 | + } | ||
288 | + } | ||
289 | + | ||
220 | useEffect(() => { | 290 | useEffect(() => { |
221 | localStorage.setItem("htmlCode", htmlCode); | 291 | localStorage.setItem("htmlCode", htmlCode); |
222 | }, [htmlCode]); | 292 | }, [htmlCode]); |
@@ -257,12 +327,18 @@ export function WritingPage() { | @@ -257,12 +327,18 @@ export function WritingPage() { | ||
257 | <div className={chatStyles["chat-message-actions"]}> | 327 | <div className={chatStyles["chat-message-actions"]}> |
258 | {htmlCode && ( | 328 | {htmlCode && ( |
259 | <div className={chatStyles["chat-input-actions"]}> | 329 | <div className={chatStyles["chat-input-actions"]}> |
260 | - <ChatAction | ||
261 | - text={Locale.Chat.Actions.ReWrite} | ||
262 | - icon={<ReloadIcon />} | ||
263 | - onClick={() => {}} | ||
264 | - disabled={isEdit} | ||
265 | - /> | 330 | + <Dropdown |
331 | + menu={{ items }} | ||
332 | + placement="bottom" | ||
333 | + arrow={{ pointAtCenter: true }} | ||
334 | + > | ||
335 | + <Button> | ||
336 | + <Space> | ||
337 | + <ReloadIcon /> | ||
338 | + {Locale.Chat.Actions.ReWrite} | ||
339 | + </Space> | ||
340 | + </Button> | ||
341 | + </Dropdown> | ||
266 | <ChatAction | 342 | <ChatAction |
267 | text={Locale.Chat.Actions.Copy} | 343 | text={Locale.Chat.Actions.Copy} |
268 | icon={<CopyIcon />} | 344 | icon={<CopyIcon />} |
@@ -895,7 +895,7 @@ export const useChatStore = createPersistStore( | @@ -895,7 +895,7 @@ export const useChatStore = createPersistStore( | ||
895 | }); | 895 | }); |
896 | }, | 896 | }, |
897 | 897 | ||
898 | - async getMindData( | 898 | + async sendContext( |
899 | messages: Array<{ role: string; content: string }>, | 899 | messages: Array<{ role: string; content: string }>, |
900 | model: string, | 900 | model: string, |
901 | ): Promise<string> { | 901 | ): Promise<string> { |
@@ -12,8 +12,6 @@ export function getWrtingPrompt(param: writePromptParam): string { | @@ -12,8 +12,6 @@ export function getWrtingPrompt(param: writePromptParam): string { | ||
12 | writingCount, | 12 | writingCount, |
13 | fileData, | 13 | fileData, |
14 | } = param; | 14 | } = param; |
15 | - console.log("********************", fileData); | ||
16 | - console.log("**********************", prompt); | ||
17 | 15 | ||
18 | // 根据用途调整文案类型描述 | 16 | // 根据用途调整文案类型描述 |
19 | const purposeMap: Record<string, string> = { | 17 | const purposeMap: Record<string, string> = { |
-
请 注册 或 登录 后发表评论