@@ -78,40 +78,115 @@ const markdownEditorStyles = `
7878 }
7979` ;
8080
81+ // 安全地将任何类型的值转换为字符串
82+ const safeToString = ( value : any ) : string => {
83+ if ( value === null || value === undefined ) {
84+ return '' ;
85+ }
86+ if ( typeof value === 'string' ) {
87+ return value ;
88+ }
89+ if ( typeof value === 'object' ) {
90+ try {
91+ // 尝试从对象中提取text属性或转换为JSON字符串
92+ if ( value . text && typeof value . text === 'string' ) {
93+ return value . text ;
94+ }
95+ if ( value . toString && value . toString ( ) !== '[object Object]' ) {
96+ return value . toString ( ) ;
97+ }
98+ return JSON . stringify ( value ) ;
99+ } catch ( e ) {
100+ console . error ( '无法将对象转换为字符串' , e ) ;
101+ return '' ;
102+ }
103+ }
104+ return String ( value ) ;
105+ } ;
106+
81107/**
82108 * 描述字段组件
83109 */
84110const DescriptionFields : React . FC < SectionProps > = ( { form } ) => {
85- const [ chineseMarkdown , setChineseMarkdown ] = useState < string > ( '' ) ;
86- const [ englishMarkdown , setEnglishMarkdown ] = useState < string > ( '' ) ;
111+ // 状态
87112 const [ markdownRenderer , setMarkdownRenderer ] = useState < any > ( {
88113 render : ( text : string ) => text
89114 } ) ;
115+
116+ // refs
90117 const styleRef = useRef < HTMLStyleElement | null > ( null ) ;
91- const isInitializedRef = useRef < boolean > ( false ) ;
118+ const editorChineseRef = useRef < MdEditor | null > ( null ) ;
119+ const editorEnglishRef = useRef < MdEditor | null > ( null ) ;
120+ const hasInitializedRef = useRef < boolean > ( false ) ;
92121
93- // 安全地将表单值转换为字符串
94- const ensureString = ( value : any ) : string => {
95- if ( value === null || value === undefined ) {
96- return '' ;
97- }
98- if ( typeof value === 'string' ) {
99- return value ;
100- }
101- if ( typeof value === 'object' ) {
122+ // 当本地存储里的值变化时,重新初始化编辑器内容
123+ useEffect ( ( ) => {
124+ // 监听存储变化
125+ const handleStorageChange = ( ) => {
126+ try {
127+ // 等待一个周期让React首先更新Form
128+ setTimeout ( ( ) => {
129+ // 从表单直接获取最新状态
130+ const chineseValue = form . getFieldValue ( 'descriptionMarkdown' ) ;
131+ const englishValue = form . getFieldValue ( 'descriptionMarkdownEn' ) ;
132+
133+ // 安全转换为字符串
134+ const chineseText = safeToString ( chineseValue ) ;
135+ const englishText = safeToString ( englishValue ) ;
136+
137+ // 直接更新编辑器内容
138+ if ( editorChineseRef . current ?. getMdElement ) {
139+ editorChineseRef . current . setText ( chineseText ) ;
140+ }
141+
142+ if ( editorEnglishRef . current ?. getMdElement ) {
143+ editorEnglishRef . current . setText ( englishText ) ;
144+ }
145+ } , 0 ) ;
146+ } catch ( err ) {
147+ console . error ( '处理存储变化时出错:' , err ) ;
148+ }
149+ } ;
150+
151+ window . addEventListener ( 'storage' , handleStorageChange ) ;
152+ return ( ) => {
153+ window . removeEventListener ( 'storage' , handleStorageChange ) ;
154+ } ;
155+ } , [ form ] ) ;
156+
157+ // 初始化编辑器内容
158+ useEffect ( ( ) => {
159+ if ( hasInitializedRef . current ) return ;
160+
161+ // 等待编辑器加载完成
162+ setTimeout ( ( ) => {
102163 try {
103- // 尝试从对象中提取text属性或转换为JSON字符串
104- if ( value . text && typeof value . text === 'string' ) {
105- return value . text ;
164+ // 获取表单中的字段值
165+ const chineseValue = form . getFieldValue ( 'descriptionMarkdown' ) ;
166+ const englishValue = form . getFieldValue ( 'descriptionMarkdownEn' ) ;
167+
168+ // 安全转换为字符串
169+ const chineseText = safeToString ( chineseValue ) ;
170+ const englishText = safeToString ( englishValue ) ;
171+
172+ // 更新编辑器内容
173+ if ( editorChineseRef . current ?. getMdElement ) {
174+ editorChineseRef . current . setText ( chineseText ) ;
175+ // 确保表单中也保存了正确的字符串
176+ form . setFieldsValue ( { descriptionMarkdown : chineseText } ) ;
106177 }
107- return JSON . stringify ( value ) ;
108- } catch ( e ) {
109- console . error ( '无法将对象转换为字符串' , e ) ;
110- return '' ;
178+
179+ if ( editorEnglishRef . current ?. getMdElement ) {
180+ editorEnglishRef . current . setText ( englishText ) ;
181+ form . setFieldsValue ( { descriptionMarkdownEn : englishText } ) ;
182+ }
183+
184+ hasInitializedRef . current = true ;
185+ } catch ( err ) {
186+ console . error ( '设置初始编辑器内容时出错:' , err ) ;
111187 }
112- }
113- return String ( value ) ;
114- } ;
188+ } , 300 ) ; // 延迟更久以确保编辑器已完全初始化
189+ } , [ form ] ) ;
115190
116191 // 处理图片上传
117192 const handleImageUpload = ( file : File ) : Promise < string > => {
@@ -130,13 +205,12 @@ const DescriptionFields: React.FC<SectionProps> = ({ form }) => {
130205
131206 // 处理中文描述变化
132207 const handleChineseEditorChange = ( { text } : { text : string } ) => {
133- setChineseMarkdown ( text ) ;
208+ // 确保更新的是字符串值
134209 form . setFieldsValue ( { descriptionMarkdown : text } ) ;
135210 } ;
136211
137212 // 处理英文描述变化
138213 const handleEnglishEditorChange = ( { text } : { text : string } ) => {
139- setEnglishMarkdown ( text ) ;
140214 form . setFieldsValue ( { descriptionMarkdownEn : text } ) ;
141215 } ;
142216
@@ -194,30 +268,7 @@ const DescriptionFields: React.FC<SectionProps> = ({ form }) => {
194268 }
195269 ` ;
196270
197- // 同步初始值到state
198- useEffect ( ( ) => {
199- if ( isInitializedRef . current ) return ;
200-
201- // 获取表单中的值并确保是字符串类型
202- const chnDesc = ensureString ( form . getFieldValue ( 'descriptionMarkdown' ) ) ;
203- const engDesc = ensureString ( form . getFieldValue ( 'descriptionMarkdownEn' ) ) ;
204-
205- // 设置到state中
206- setChineseMarkdown ( chnDesc ) ;
207- setEnglishMarkdown ( engDesc ) ;
208-
209- // 如果恢复的值不是字符串类型,纠正表单中的值
210- if ( typeof form . getFieldValue ( 'descriptionMarkdown' ) !== 'string' ) {
211- form . setFieldsValue ( { descriptionMarkdown : chnDesc } ) ;
212- }
213-
214- if ( typeof form . getFieldValue ( 'descriptionMarkdownEn' ) !== 'string' ) {
215- form . setFieldsValue ( { descriptionMarkdownEn : engDesc } ) ;
216- }
217-
218- isInitializedRef . current = true ;
219- } , [ form ] ) ;
220-
271+ // 初始化markdown-it和样式
221272 useEffect ( ( ) => {
222273 // 动态加载markdown-it库
223274 const script = document . createElement ( 'script' ) ;
@@ -260,10 +311,10 @@ const DescriptionFields: React.FC<SectionProps> = ({ form }) => {
260311 rules = { [ { required : true , message : '请输入中文描述' } ] }
261312 >
262313 < MdEditor
314+ ref = { editorChineseRef }
263315 style = { { height : '300px' } }
264316 renderHTML = { text => markdownRenderer . render ( text ) }
265317 onChange = { handleChineseEditorChange }
266- value = { chineseMarkdown }
267318 placeholder = "请使用Markdown格式输入题目描述,支持图片、代码块等。可以直接粘贴图片!"
268319 config = { editorConfig }
269320 onImageUpload = { handleImageUpload }
@@ -275,10 +326,10 @@ const DescriptionFields: React.FC<SectionProps> = ({ form }) => {
275326 label = "英文描述 (Markdown)"
276327 >
277328 < MdEditor
329+ ref = { editorEnglishRef }
278330 style = { { height : '300px' } }
279331 renderHTML = { text => markdownRenderer . render ( text ) }
280332 onChange = { handleEnglishEditorChange }
281- value = { englishMarkdown }
282333 placeholder = "请使用Markdown格式输入英文题目描述(可选),英文版将在用户切换语言时显示。可以直接粘贴图片!"
283334 config = { editorConfig }
284335 onImageUpload = { handleImageUpload }
0 commit comments