@@ -294,6 +294,11 @@ export default function App() {
294294 // 全局警告弹窗状态
295295 const [ globalWarning , setGlobalWarning ] = useState ( null ) ;
296296
297+ // AI 解析弹窗相关状态
298+ const [ showAiModal , setShowAiModal ] = useState ( false ) ;
299+ const [ aiQuestionText , setAiQuestionText ] = useState ( '' ) ;
300+ const [ aiQuestionTitle , setAiQuestionTitle ] = useState ( '' ) ;
301+
297302 // 题库状态(从数据库加载)
298303 const [ MOCK_QUESTION_BANK , setMOCK_QUESTION_BANK ] = useState ( DEFAULT_QUESTION_BANK ) ;
299304 const [ isLoadingQuestions , setIsLoadingQuestions ] = useState ( false ) ;
@@ -849,6 +854,35 @@ export default function App() {
849854 } ;
850855 } , [ answeredIds , wrongQuestionIds ] ) ;
851856
857+ // --- AI 解析功能 ---
858+ const openAiAnalysis = ( question ) => {
859+ const title = question . question ;
860+ const text = `请帮我解析以下物联网题目:\n\n【题目】${ question . question } \n\n【选项】\n${ question . options . map ( ( o ) => `${ o . id } . ${ o . text } ` ) . join ( '\n' ) } \n\n请给出正确答案并详细解析。` ;
861+ setAiQuestionTitle ( title ) ;
862+ setAiQuestionText ( text ) ;
863+ setShowAiModal ( true ) ;
864+ } ;
865+
866+ const closeAiModal = ( ) => {
867+ setShowAiModal ( false ) ;
868+ setAiQuestionText ( '' ) ;
869+ setAiQuestionTitle ( '' ) ;
870+ } ;
871+
872+ const copyAiQuestion = ( ) => {
873+ navigator . clipboard . writeText ( aiQuestionText ) . then ( ( ) => {
874+ } ) . catch ( ( ) => {
875+ const textarea = document . createElement ( 'textarea' ) ;
876+ textarea . value = aiQuestionText ;
877+ textarea . style . position = 'fixed' ;
878+ textarea . style . opacity = '0' ;
879+ document . body . appendChild ( textarea ) ;
880+ textarea . select ( ) ;
881+ document . execCommand ( 'copy' ) ;
882+ document . body . removeChild ( textarea ) ;
883+ } ) ;
884+ } ;
885+
852886 // --- 组件视图 ---
853887
854888 const WelcomeView = ( ) => (
@@ -1012,13 +1046,22 @@ export default function App() {
10121046 </ span >
10131047 ) }
10141048 </ div >
1015- < button
1016- onClick = { ( ) => handleFeedback ( currentQ ) }
1017- className = "text-slate-400 hover:text-orange-500 transition-colors flex items-center gap-1 text-xs font-medium"
1018- title = "题目有误?点击反馈"
1019- >
1020- < Flag className = "w-4 h-4" /> 纠错
1021- </ button >
1049+ < div className = "flex items-center gap-2" >
1050+ < button
1051+ onClick = { ( ) => openAiAnalysis ( currentQ ) }
1052+ className = "ai-btn-glow text-indigo-500 hover:text-indigo-700 bg-indigo-50 hover:bg-indigo-100 transition-colors flex items-center gap-1 text-xs font-medium px-2.5 py-1.5 rounded-full"
1053+ title = "AI 智能解析本题"
1054+ >
1055+ < Sparkles className = "w-4 h-4" /> AI 解析
1056+ </ button >
1057+ < button
1058+ onClick = { ( ) => handleFeedback ( currentQ ) }
1059+ className = "text-slate-400 hover:text-orange-500 transition-colors flex items-center gap-1 text-xs font-medium"
1060+ title = "题目有误?点击反馈"
1061+ >
1062+ < Flag className = "w-4 h-4" /> 纠错
1063+ </ button >
1064+ </ div >
10221065 </ div >
10231066
10241067 < h2 className = "text-xl md:text-2xl font-bold text-slate-800 leading-relaxed mb-8" >
@@ -1269,7 +1312,10 @@ export default function App() {
12691312 </ div >
12701313 < div className = "bg-slate-50 p-3 rounded text-sm text-slate-600 flex justify-between items-start" >
12711314 < div > { q . explanation } </ div >
1272- < button onClick = { ( ) => handleFeedback ( q ) } className = "ml-4 text-slate-400 hover:text-orange-500 transition-colors" > < Flag className = "w-4 h-4" /> </ button >
1315+ < div className = "flex items-center gap-1 ml-4" >
1316+ < button onClick = { ( ) => openAiAnalysis ( q ) } className = "text-indigo-400 hover:text-indigo-600 transition-colors" title = "AI 解析" > < Sparkles className = "w-4 h-4" /> </ button >
1317+ < button onClick = { ( ) => handleFeedback ( q ) } className = "text-slate-400 hover:text-orange-500 transition-colors" > < Flag className = "w-4 h-4" /> </ button >
1318+ </ div >
12731319 </ div >
12741320 </ div >
12751321 )
@@ -1389,12 +1435,19 @@ export default function App() {
13891435 ) : (
13901436 < >
13911437 < div className = "mb-6" >
1392- < div className = "flex items-center gap-2 mb-4" >
1393- < span className = "bg-slate-100 text-slate-600 text-xs font-bold px-2 py-1 rounded uppercase tracking-wider" > { instantQuestion . category } </ span >
1394- { wrongQuestionIds . has ( instantQuestion . id ) && (
1395- < span className = "bg-red-50 text-red-600 text-xs font-bold px-2 py-1 rounded flex items-center" > < AlertTriangle className = "w-3 h-3 mr-1" /> 曾做错</ span >
1396- ) }
1397- </ div >
1438+ < div className = "flex items-center gap-2 mb-4" >
1439+ < span className = "bg-slate-100 text-slate-600 text-xs font-bold px-2 py-1 rounded uppercase tracking-wider" > { instantQuestion . category } </ span >
1440+ { wrongQuestionIds . has ( instantQuestion . id ) && (
1441+ < span className = "bg-red-50 text-red-600 text-xs font-bold px-2 py-1 rounded flex items-center" > < AlertTriangle className = "w-3 h-3 mr-1" /> 曾做错</ span >
1442+ ) }
1443+ < button
1444+ onClick = { ( ) => openAiAnalysis ( instantQuestion ) }
1445+ className = "ai-btn-glow text-indigo-500 hover:text-indigo-700 bg-indigo-50 hover:bg-indigo-100 transition-colors flex items-center gap-1 text-xs font-medium px-2.5 py-1.5 rounded-full ml-auto"
1446+ title = "AI 智能解析本题"
1447+ >
1448+ < Sparkles className = "w-3.5 h-3.5" /> AI 解析
1449+ </ button >
1450+ </ div >
13981451 < h3 className = "text-xl font-bold text-slate-800 leading-relaxed" > { instantQuestion . question } </ h3 >
13991452 </ div >
14001453
@@ -1525,6 +1578,58 @@ export default function App() {
15251578 </ div >
15261579 </ div >
15271580 ) }
1581+
1582+ { /* AI 解析弹窗 */ }
1583+ { showAiModal && (
1584+ < div className = "fixed inset-0 z-[110] flex items-center justify-center bg-black/60 backdrop-blur-sm" onClick = { closeAiModal } >
1585+ < div className = "bg-white w-full max-w-3xl mx-4 rounded-2xl shadow-2xl overflow-hidden ai-modal-enter max-h-[90vh] flex flex-col" onClick = { ( e ) => e . stopPropagation ( ) } >
1586+ < div className = "bg-gradient-to-r from-indigo-500 to-purple-600 p-4 flex justify-between items-center text-white shrink-0" >
1587+ < div className = "flex items-center space-x-2" >
1588+ < Sparkles className = "w-6 h-6" />
1589+ < span className = "font-bold text-lg" > AI 智能解析</ span >
1590+ </ div >
1591+ < button onClick = { closeAiModal } className = "text-white/80 hover:text-white transition-colors bg-white/10 rounded-full p-1" >
1592+ < X className = "w-5 h-5" />
1593+ </ button >
1594+ </ div >
1595+
1596+ < div className = "p-4 bg-indigo-50 border-b border-indigo-100 shrink-0" >
1597+ < p className = "text-sm text-slate-700 font-medium line-clamp-2" title = { aiQuestionTitle } > { aiQuestionTitle } </ p >
1598+ < button
1599+ onClick = { copyAiQuestion }
1600+ className = "mt-2 flex items-center gap-1 text-xs text-indigo-600 hover:text-indigo-800 bg-white px-3 py-1.5 rounded-full border border-indigo-200 hover:bg-indigo-100 transition-colors"
1601+ >
1602+ < svg className = "w-3.5 h-3.5" fill = "none" viewBox = "0 0 24 24" stroke = "currentColor" strokeWidth = "2" >
1603+ < rect x = "9" y = "9" width = "13" height = "13" rx = "2" ry = "2" />
1604+ < path d = "M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1" />
1605+ </ svg >
1606+ 复制题目文本
1607+ </ button >
1608+ </ div >
1609+
1610+ < div className = "flex-1 min-h-0" >
1611+ < iframe
1612+ src = "https://udify.app/chatbot/xg0maoDg7kzrcGT0"
1613+ style = { { width : '100%' , height : '100%' , minHeight : '420px' , border : 'none' } }
1614+ title = "AI 解析助手"
1615+ onLoad = { ( e ) => {
1616+ setTimeout ( ( ) => {
1617+ try {
1618+ e . target . contentWindow . postMessage ( {
1619+ type : 'dify-chatbot-send' ,
1620+ data : {
1621+ query : aiQuestionText ,
1622+ inputs : { }
1623+ }
1624+ } , 'https://udify.app' ) ;
1625+ } catch ( err ) { }
1626+ } , 800 ) ;
1627+ } }
1628+ />
1629+ </ div >
1630+ </ div >
1631+ </ div >
1632+ ) }
15281633 </ div >
15291634 ) ;
15301635}
0 commit comments