0&&n.push({type:`text`,value:`
`}),n}function A4e(e){let t=0,n=e.charCodeAt(t);for(;n===9||n===32;)t++,n=e.charCodeAt(t);return e.slice(t)}function j4e(e,t){let n=T4e(e,t),r=n.one(e,void 0),i=F2e(n),a=Array.isArray(r)?{type:`root`,children:r}:r||{type:`root`,children:[]};return i&&(`children`in a,a.children.push({type:`text`,value:`
-`},i)),a}function M4e(e,t){return e&&`run`in e?async function(n,r){let i=j4e(n,{file:r,...t});await e.run(i,r)}:function(n,r){return j4e(n,{file:r,...e||t})}}function N4e(e){if(e)throw e}var P4e=o(((e,t)=>{var n=Object.prototype.hasOwnProperty,r=Object.prototype.toString,i=Object.defineProperty,a=Object.getOwnPropertyDescriptor,o=function(e){return typeof Array.isArray==`function`?Array.isArray(e):r.call(e)===`[object Array]`},s=function(e){if(!e||r.call(e)!==`[object Object]`)return!1;var t=n.call(e,`constructor`),i=e.constructor&&e.constructor.prototype&&n.call(e.constructor.prototype,`isPrototypeOf`);if(e.constructor&&!t&&!i)return!1;for(var a in e);return a===void 0||n.call(e,a)},c=function(e,t){i&&t.name===`__proto__`?i(e,t.name,{enumerable:!0,configurable:!0,value:t.newValue,writable:!0}):e[t.name]=t.newValue},l=function(e,t){if(t===`__proto__`){if(!n.call(e,t))return;if(a)return a(e,t).value}return e[t]};t.exports=function e(){var t,n,r,i,a,u,d=arguments[0],f=1,p=arguments.length,m=!1;for(typeof d==`boolean`&&(m=d,d=arguments[1]||{},f=2),(d==null||typeof d!=`object`&&typeof d!=`function`)&&(d={});ft.length,o;r&&t.push(i);try{o=e.apply(this,t)}catch(e){let t=e;if(r&&n)throw t;return i(t)}r||(o&&o.then&&typeof o.then==`function`?o.then(a,i):o instanceof Error?i(o):a(o))}function i(e,...r){n||(n=!0,t(e,...r))}function a(e){i(null,e)}}var V9={basename:L4e,dirname:R4e,extname:z4e,join:B4e,sep:`/`};function L4e(e,t){if(t!==void 0&&typeof t!=`string`)throw TypeError(`"ext" argument must be a string`);H9(e);let n=0,r=-1,i=e.length,a;if(t===void 0||t.length===0||t.length>e.length){for(;i--;)if(e.codePointAt(i)===47){if(a){n=i+1;break}}else r<0&&(a=!0,r=i+1);return r<0?``:e.slice(n,r)}if(t===e)return``;let o=-1,s=t.length-1;for(;i--;)if(e.codePointAt(i)===47){if(a){n=i+1;break}}else o<0&&(a=!0,o=i+1),s>-1&&(e.codePointAt(i)===t.codePointAt(s--)?s<0&&(r=i):(s=-1,r=o));return n===r?r=o:r<0&&(r=e.length),e.slice(n,r)}function R4e(e){if(H9(e),e.length===0)return`.`;let t=-1,n=e.length,r;for(;--n;)if(e.codePointAt(n)===47){if(r){t=n;break}}else r||=!0;return t<0?e.codePointAt(0)===47?`/`:`.`:t===1&&e.codePointAt(0)===47?`//`:e.slice(0,t)}function z4e(e){H9(e);let t=e.length,n=-1,r=0,i=-1,a=0,o;for(;t--;){let s=e.codePointAt(t);if(s===47){if(o){r=t+1;break}continue}n<0&&(o=!0,n=t+1),s===46?i<0?i=t:a!==1&&(a=1):i>-1&&(a=-1)}return i<0||n<0||a===0||a===1&&i===n-1&&i===r+1?``:e.slice(i,n)}function B4e(...e){let t=-1,n;for(;++t0&&e.codePointAt(e.length-1)===47&&(n+=`/`),t?`/`+n:n}function H4e(e,t){let n=``,r=0,i=-1,a=0,o=-1,s,c;for(;++o<=e.length;){if(o2){if(c=n.lastIndexOf(`/`),c!==n.length-1){c<0?(n=``,r=0):(n=n.slice(0,c),r=n.length-1-n.lastIndexOf(`/`)),i=o,a=0;continue}}else if(n.length>0){n=``,r=0,i=o,a=0;continue}}t&&(n=n.length>0?n+`/..`:`..`,r=2)}else n.length>0?n+=`/`+e.slice(i+1,o):n=e.slice(i+1,o),r=o-i-1;i=o,a=0}else s===46&&a>-1?a++:a=-1}return n}function H9(e){if(typeof e!=`string`)throw TypeError(`Path must be a string. Received `+JSON.stringify(e))}var U4e={cwd:W4e};function W4e(){return`/`}function U9(e){return!!(typeof e==`object`&&e&&`href`in e&&e.href&&`protocol`in e&&e.protocol&&e.auth===void 0)}function G4e(e){if(typeof e==`string`)e=new URL(e);else if(!U9(e)){let t=TypeError('The "path" argument must be of type string or an instance of URL. Received `'+e+"`");throw t.code=`ERR_INVALID_ARG_TYPE`,t}if(e.protocol!==`file:`){let e=TypeError(`The URL must be of scheme file`);throw e.code=`ERR_INVALID_URL_SCHEME`,e}return K4e(e)}function K4e(e){if(e.hostname!==``){let e=TypeError(`File URL host must be "localhost" or empty on darwin`);throw e.code=`ERR_INVALID_FILE_URL_HOST`,e}let t=e.pathname,n=-1;for(;++n0){let[r,...a]=t,o=n[i][1];B9(o)&&B9(r)&&(r=(0,q9.default)(!0,o,r)),n[i]=[e,r,...a]}}}}().freeze();function J9(e,t){if(typeof t!=`function`)throw TypeError("Cannot `"+e+"` without `parser`")}function Y9(e,t){if(typeof t!=`function`)throw TypeError("Cannot `"+e+"` without `compiler`")}function X9(e,t){if(t)throw Error("Cannot call `"+e+"` on a frozen processor.\nCreate a new processor first, by calling it: use `processor()` instead of `processor`.")}function $4e(e){if(!B9(e)||typeof e.type!=`string`)throw TypeError("Expected node, got `"+e+"`")}function e3e(e,t,n){if(!n)throw Error("`"+e+"` finished async. Use `"+t+"` instead")}function Z9(e){return t3e(e)?e:new q4e(e)}function t3e(e){return!!(e&&typeof e==`object`&&`message`in e&&`messages`in e)}function n3e(e){return typeof e==`string`||r3e(e)}function r3e(e){return!!(e&&typeof e==`object`&&`byteLength`in e&&`byteOffset`in e)}var i3e=[],a3e={allowDangerousHtml:!0},o3e=/^(https?|ircs?|mailto|xmpp)$/i,s3e=[{from:`astPlugins`,id:`remove-buggy-html-in-markdown-parser`},{from:`allowDangerousHtml`,id:`remove-buggy-html-in-markdown-parser`},{from:`allowNode`,id:`replace-allownode-allowedtypes-and-disallowedtypes`,to:`allowElement`},{from:`allowedTypes`,id:`replace-allownode-allowedtypes-and-disallowedtypes`,to:`allowedElements`},{from:`className`,id:`remove-classname`},{from:`disallowedTypes`,id:`replace-allownode-allowedtypes-and-disallowedtypes`,to:`disallowedElements`},{from:`escapeHtml`,id:`remove-buggy-html-in-markdown-parser`},{from:`includeElementIndex`,id:`#remove-includeelementindex`},{from:`includeNodeIndex`,id:`change-includenodeindex-to-includeelementindex`},{from:`linkTarget`,id:`remove-linktarget`},{from:`plugins`,id:`change-plugins-to-remarkplugins`,to:`remarkPlugins`},{from:`rawSourcePos`,id:`#remove-rawsourcepos`},{from:`renderers`,id:`change-renderers-to-components`,to:`components`},{from:`source`,id:`change-source-to-children`,to:`children`},{from:`sourcePos`,id:`#remove-sourcepos`},{from:`transformImageUri`,id:`#add-urltransform`,to:`urlTransform`},{from:`transformLinkUri`,id:`#add-urltransform`,to:`urlTransform`}];function c3e(e){let t=l3e(e),n=u3e(e);return d3e(t.runSync(t.parse(n),n),e)}function l3e(e){let t=e.rehypePlugins||i3e,n=e.remarkPlugins||i3e,r=e.remarkRehypeOptions?{...e.remarkRehypeOptions,...a3e}:a3e;return Q4e().use(w2e).use(n).use(M4e,r).use(t)}function u3e(e){let t=e.children||``,n=new q4e;return typeof t==`string`?n.value=t:``+t,n}function d3e(e,t){let n=t.allowedElements,r=t.allowElement,i=t.components,a=t.disallowedElements,o=t.skipHtml,s=t.unwrapDisallowed,c=t.urlTransform||f3e;for(let e of s3e)Object.hasOwn(t,e.from)&&``+e.from+(e.to?"use `"+e.to+"` instead":`remove it`)+e.id;return K2e(e,l),k$e(e,{Fragment:Y.Fragment,components:i,ignoreInvalidStyle:!0,jsx:Y.jsx,jsxs:Y.jsxs,passKeys:!0,passNode:!0});function l(e,t,i){if(e.type===`raw`&&i&&typeof t==`number`)return o?i.children.splice(t,1):i.children[t]={type:`text`,value:e.value},t;if(e.type===`element`){let t;for(t in s9)if(Object.hasOwn(s9,t)&&Object.hasOwn(e.properties,t)){let n=e.properties[t],r=s9[t];(r===null||r.includes(e.tagName))&&(e.properties[t]=c(String(n||``),t,e))}}if(e.type===`element`){let o=n?!n.includes(e.tagName):a?a.includes(e.tagName):!1;if(!o&&r&&typeof t==`number`&&(o=!r(e,t,i)),o&&i&&typeof t==`number`)return s&&e.children?i.children.splice(t,1,...e.children):i.children.splice(t,1),t}}}function f3e(e){let t=e.indexOf(`:`),n=e.indexOf(`?`),r=e.indexOf(`#`),i=e.indexOf(`/`);return t===-1||i!==-1&&t>i||n!==-1&&t>n||r!==-1&&t>r||o3e.test(e.slice(0,t))?e:``}function p3e({questionId:e,open:t,onClose:n,onUpdated:r,onDeleted:i}){let[a,o]=(0,h.useState)(null),[s,c]=(0,h.useState)(!1),[l,u]=(0,h.useState)(``),[d,f]=(0,h.useState)(``),[p,m]=(0,h.useState)(``),[g,_]=(0,h.useState)(`annotated`),[v,y]=(0,h.useState)(!1),[b,x]=(0,h.useState)(!1),[S,C]=(0,h.useState)(!1),w=async()=>{c(!0);try{let{data:t}=await hk.get(e);o(t),u(t.question_text||``),f(t.solution_approach||``),m(t.solution_text||``),_(t.has_annotated_image?`annotated`:`original`)}finally{c(!1)}};return(0,h.useEffect)(()=>{t&&e&&w()},[t,e]),(0,h.useEffect)(()=>{if(!t||!a||!P7(a))return;let n=window.setInterval(async()=>{try{let{data:t}=await hk.get(e);o(t),u(t.question_text||``),f(t.solution_approach||``),m(t.solution_text||``),t.has_annotated_image&&_(`annotated`),P7(t)||r()}catch{}},4e3);return()=>window.clearInterval(n)},[t,e,a?.status,a?.question_text,a?.error_message]),(0,Y.jsx)(yx,{title:a?`${a.subject_name}${a.category===`olympiad`?` · 奥数`:``} · 详情`:`详情`,open:t,onCancel:n,width:`90%`,style:{maxWidth:960},footer:(0,Y.jsxs)(Py,{wrap:!0,children:[(0,Y.jsx)(xx,{title:`确定删除该题?`,onConfirm:async()=>{C(!0);try{await hk.remove(e),rx.success(`已删除`),i?.(),n()}catch{rx.error(`删除失败`)}finally{C(!1)}},children:(0,Y.jsx)(_p,{danger:!0,loading:S,children:`删除`})}),(0,Y.jsx)(_p,{onClick:async()=>{await hk.retryOcr(e),rx.info(`已重新识别并标注,请稍后刷新`),r(),n()},children:`重新识别标注`}),(0,Y.jsx)(_p,{loading:b,onClick:async()=>{x(!0);try{let{data:t}=await hk.regenerate(e);o(t),u(t.question_text||``),f(t.solution_approach||``),m(t.solution_text||``),rx.success(`解题思路已重新生成`),r()}catch{rx.error(`生成失败,请检查 AI 模型配置`)}finally{x(!1)}},children:`重新生成思路`}),(0,Y.jsx)(_p,{type:`primary`,loading:v,onClick:async()=>{y(!0);try{await hk.update(e,{question_text:l,solution_approach:d,solution_text:p}),rx.success(`已保存`),r()}finally{y(!1)}},children:`保存编辑`})]}),children:(0,Y.jsx)(TS,{spinning:s,children:a&&(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsxs)(Py,{wrap:!0,style:{marginBottom:8},children:[(0,Y.jsxs)(rE.Text,{type:`secondary`,children:[`状态:`,jk[a.status]]}),a.has_annotated_image&&!a.error_message&&(0,Y.jsx)(rE.Text,{type:`danger`,children:`红色框为自动标注的错误位置`})]}),a.error_message&&(0,Y.jsx)(Rc,{message:`处理失败`,description:a.error_message,type:`error`,showIcon:!0,style:{marginBottom:12}}),a.status===`pending`&&!a.error_message&&(0,Y.jsx)(Rc,{message:F7(a),type:`info`,showIcon:!0,style:{marginBottom:12}}),a.status===`ocr_done`&&!a.question_text&&!a.error_message&&(0,Y.jsx)(Rc,{message:F7(a),type:`info`,showIcon:!0,style:{marginBottom:12}}),(a.solution_approach||a.solution_text)&&(0,Y.jsx)(Rc,{message:`AI 识别与标注,请核对后再使用`,type:`warning`,showIcon:!0,style:{margin:`12px 0`}}),(0,Y.jsxs)(Dle,{gutter:16,style:{marginTop:12},children:[(0,Y.jsxs)(bg,{xs:24,md:10,children:[a.has_annotated_image&&(0,Y.jsx)(Ble,{block:!0,style:{marginBottom:8},value:g,onChange:e=>_(e),options:[{label:`标注图`,value:`annotated`},{label:`原图`,value:`original`}]}),(0,Y.jsx)(I7,{questionId:a.id,variant:g,alt:`原题`,style:{width:`100%`,borderRadius:8,border:`1px solid #f0f0f0`}}),a.ocr_raw_text&&(0,Y.jsxs)(`div`,{style:{marginTop:12},children:[(0,Y.jsx)(rE.Text,{strong:!0,children:`OCR 原文`}),(0,Y.jsx)(`pre`,{style:{background:`#fafafa`,padding:8,fontSize:12,maxHeight:150,overflow:`auto`,whiteSpace:`pre-wrap`},children:a.ocr_raw_text})]})]}),(0,Y.jsxs)(bg,{xs:24,md:14,children:[(0,Y.jsx)(rE.Text,{strong:!0,children:`识别题目(可编辑)`}),(0,Y.jsx)(ib.TextArea,{rows:5,value:l,onChange:e=>u(e.target.value),style:{marginTop:8,marginBottom:16}}),(0,Y.jsx)(rE.Text,{strong:!0,children:`解题思路`}),(0,Y.jsx)(ib.TextArea,{rows:4,value:d,onChange:e=>f(e.target.value),placeholder:`识别完成后自动生成,类似作业帮「解题思路」`,style:{marginTop:8,marginBottom:16}}),d&&(0,Y.jsxs)(`div`,{style:{background:`#e6f4ff`,padding:12,borderRadius:8,marginBottom:16,border:`1px solid #91caff`},children:[(0,Y.jsx)(rE.Text,{type:`secondary`,style:{fontSize:12},children:`思路预览`}),(0,Y.jsx)(c3e,{children:d})]}),(0,Y.jsx)(rE.Text,{strong:!0,children:`详细解答`}),(0,Y.jsx)(ib.TextArea,{rows:8,value:p,onChange:e=>m(e.target.value),style:{marginTop:8,marginBottom:12}}),p&&(0,Y.jsxs)(`div`,{style:{background:`#fafafa`,padding:12,borderRadius:8},children:[(0,Y.jsx)(rE.Text,{type:`secondary`,style:{fontSize:12},children:`解答预览`}),(0,Y.jsx)(c3e,{children:p})]})]})]})]})})})}function m3e(e){return e.error_message?{tone:`error`,text:e.error_message}:P7(e)?{tone:`pending`,text:F7(e)}:{tone:`normal`,text:e.question_text||e.ocr_raw_text||jk[e.status]}}function h3e({items:e,selectedId:t,onSelect:n,onRefresh:r,emptyText:i=`暂无记录`,pollWhenProcessing:a=!0}){let o=a&&e.some(P7);(0,h.useEffect)(()=>{if(!o)return;let e=window.setInterval(()=>r(),4e3);return()=>window.clearInterval(e)},[o,r]);let s=async e=>{try{await hk.remove(e),rx.success(`已删除`),t===e&&n(null),r()}catch{rx.error(`删除失败`)}};return(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(`div`,{className:`wq-grid`,children:e.map(e=>{let t=m3e(e);return(0,Y.jsxs)(`div`,{className:`wq-card`,children:[(0,Y.jsxs)(`div`,{className:`wq-card-click`,onClick:()=>n(e.id),children:[(0,Y.jsx)(I7,{questionId:e.id,variant:`annotated`,alt:`题目`,className:`wq-card-img`}),(0,Y.jsxs)(`div`,{className:`wq-card-body`,children:[(0,Y.jsxs)(Py,{size:4,wrap:!0,children:[(0,Y.jsx)(rE.Text,{strong:!0,children:e.subject_name}),e.category===`olympiad`&&(0,Y.jsx)(PT,{color:`gold`,children:`奥数`}),(0,Y.jsx)(PT,{color:e.error_message||e.status===`failed`?`error`:P7(e)?`processing`:`default`,children:e.error_message?`失败`:jk[e.status]})]}),(0,Y.jsx)(rE.Paragraph,{ellipsis:{rows:3},style:{margin:`8px 0 0`,fontSize:13,color:t.tone===`error`?`#ff4d4f`:t.tone===`pending`?`#1677ff`:void 0},children:t.text})]})]}),(0,Y.jsx)(`div`,{className:`wq-card-actions`,children:(0,Y.jsx)(xx,{title:`确定删除该题?`,onConfirm:()=>s(e.id),children:(0,Y.jsx)(_p,{type:`text`,danger:!0,size:`small`,icon:(0,Y.jsx)(bE,{}),onClick:e=>e.stopPropagation(),children:`删除`})})})]},e.id)})}),e.length===0&&(0,Y.jsx)(rE.Text,{type:`secondary`,children:i}),t&&(0,Y.jsx)(p3e,{questionId:t,open:!!t,onClose:()=>n(null),onUpdated:r,onDeleted:()=>{n(null),r()}})]})}function g3e({studentId:e,subjects:t,category:n,onUploaded:r}){let i=n===`olympiad`,a=(0,h.useMemo)(()=>i?t.filter(e=>e.name===`数学`):t,[t,i]),[o,s]=(0,h.useState)(),[c,l]=(0,h.useState)(!1),u=(0,h.useRef)(null);(0,h.useEffect)(()=>{a.length&&s(a[0].id)},[a]);let d=async t=>{if(!o){rx.warning(i?`未找到数学科目`:`请选择科目`);return}l(!0);try{await hk.upload(e,o,t,n),rx.success(`上传成功,正在识别并生成解法…`),r()}catch{rx.error(`上传失败`)}finally{l(!1)}},f=async e=>(await d(e),!1);return(0,Y.jsxs)(Py,{direction:`vertical`,size:`middle`,style:{width:`100%`,marginBottom:16},children:[i?(0,Y.jsx)(rE.Text,{children:`科目:数学(奥数区仅支持数学)`}):(0,Y.jsx)(gS,{style:{width:`100%`,maxWidth:200},placeholder:`选择科目`,value:o,onChange:s,options:a.map(e=>({value:e.id,label:e.name}))}),(0,Y.jsxs)(Py,{wrap:!0,className:`upload-actions`,children:[(0,Y.jsx)(FE,{beforeUpload:f,showUploadList:!1,accept:`image/*`,children:(0,Y.jsx)(_p,{icon:(0,Y.jsx)(pE,{}),loading:c,type:`primary`,size:`large`,children:`相册选图`})}),(0,Y.jsx)(_p,{icon:(0,Y.jsx)(bxe,{}),loading:c,size:`large`,onClick:()=>u.current?.click(),children:`拍照上传`}),(0,Y.jsx)(`input`,{ref:u,type:`file`,accept:`image/*`,capture:`environment`,style:{display:`none`},onChange:async e=>{let t=e.target.files?.[0];e.target.value=``,t&&await d(t)}}),!i&&(0,Y.jsx)(FE,{beforeUpload:f,showUploadList:!1,accept:`image/*`,children:(0,Y.jsx)(_p,{icon:(0,Y.jsx)(Oxe,{}),loading:c,size:`large`,children:`上传图片`})})]}),i&&(0,Y.jsx)(`span`,{style:{color:`#666`,fontSize:13},children:`奥数区仅数学,按学生学段(初中/高中)生成解题思路,严禁超纲`})]})}function _3e({subjectId:e,onSubjectChange:t,search:n,onSearchChange:r,onRefresh:i,subjects:a,hideSubjectFilter:o}){return(0,Y.jsxs)(Py,{wrap:!0,style:{marginBottom:16,width:`100%`},children:[!o&&(0,Y.jsx)(gS,{allowClear:!0,style:{width:`100%`,maxWidth:140},placeholder:`全部科目`,value:e,onChange:t,options:a.map(e=>({value:e.id,label:e.name}))}),(0,Y.jsx)(ib.Search,{placeholder:`搜索题目/解法`,value:n,onChange:e=>r(e.target.value),onSearch:()=>i(),style:{width:`100%`,maxWidth:260},allowClear:!0}),(0,Y.jsx)(_p,{icon:(0,Y.jsx)(Txe,{}),onClick:i,children:`刷新`})]})}var Q9={junior_high:`初中`,senior_high:`高中`},v3e={junior_high:[`初一`,`初二`,`初三`],senior_high:[`高一`,`高二`,`高三`]};function y3e(e){let t=[Q9[e.school_level],e.grade,e.class_name].filter(Boolean);return t.length?t.join(` · `):`未设置学段年级`}var b3e=[`scores`,`overview`,`trend`,`wrong`,`olympiad`];function x3e(){let{id:e}=X_e(),[t,n]=tye(),r=t.get(`tab`),i=b3e.includes(r)?r:`scores`,[a,o]=(0,h.useState)(null),[s,c]=(0,h.useState)([]),[l,u]=(0,h.useState)([]),[d,f]=(0,h.useState)(null),[p,m]=(0,h.useState)(),[g,_]=(0,h.useState)([]),[v,y]=(0,h.useState)([]),[b,x]=(0,h.useState)(),[S,C]=(0,h.useState)(``),[w,T]=(0,h.useState)(``),[E,D]=(0,h.useState)(null),[O,k]=(0,h.useState)(null),[A,j]=(0,h.useState)(!0),M=(0,h.useMemo)(()=>s.find(e=>e.name===`数学`),[s]),N=Object.fromEntries(s.map(e=>[e.id,e.name])),P=(0,h.useCallback)(async()=>{if(!e)return;let{data:t}=await mk.list(e);u(t)},[e]),F=(0,h.useCallback)(async()=>{if(!e||!p)return;let{data:t}=await mk.trend(e,p);f(t)},[e,p]),I=(0,h.useCallback)(async()=>{if(!e)return;let{data:t}=await hk.list(e,{subject_id:b,q:S||void 0,category:`regular`});_(t)},[e,b,S]),L=(0,h.useCallback)(async()=>{if(!e)return;let{data:t}=await hk.list(e,{subject_id:M?.id,q:w||void 0,category:`olympiad`});y(t)},[e,M?.id,w]);(0,h.useEffect)(()=>{if(!e)return;let t=!1;return(async()=>{j(!0);try{let[n,r]=await Promise.all([pk.get(e),mxe.list()]);if(t)return;o(n.data),c(r.data),r.data.length&&m(r.data[0].id);let i=await mk.list(e);t||u(i.data)}finally{t||j(!1)}})(),()=>{t=!0}},[e]),(0,h.useEffect)(()=>{I()},[I]),(0,h.useEffect)(()=>{L()},[L]),(0,h.useEffect)(()=>{F()},[F]);let R=e=>{n({tab:e},{replace:!0})},z=async()=>{if(e)try{let{data:t}=await mk.exportCsv(e),n=URL.createObjectURL(t),r=document.createElement(`a`);r.href=n,r.download=`${a?.name||`student`}_scores.csv`,r.click(),URL.revokeObjectURL(n)}catch{rx.error(`导出失败`)}};if(A)return(0,Y.jsx)(`div`,{style:{textAlign:`center`,padding:80},children:(0,Y.jsx)(TS,{size:`large`})});if(!a)return(0,Y.jsx)(rE.Text,{children:`学生不存在`});let B=Q9[a.school_level];return(0,Y.jsxs)(`div`,{className:`page-container`,children:[(0,Y.jsxs)(Py,{className:`page-header`,wrap:!0,children:[(0,Y.jsx)(RD,{to:`/`,children:(0,Y.jsx)(_p,{icon:(0,Y.jsx)(vxe,{}),children:`返回`})}),(0,Y.jsx)(rE.Title,{level:4,style:{margin:0},children:a.name}),(0,Y.jsx)(PT,{color:a.school_level===`senior_high`?`purple`:`blue`,children:B}),(0,Y.jsx)(rE.Text,{type:`secondary`,children:y3e(a)}),(0,Y.jsx)(_p,{icon:(0,Y.jsx)(SE,{}),onClick:z,children:`导出 CSV`})]}),(0,Y.jsx)(sg,{className:`student-tabs`,activeKey:i,onChange:R,destroyInactiveTabPane:!1,items:[{key:`scores`,label:`成绩录入`,children:(0,Y.jsx)(Mxe,{studentId:e,subjects:s,exams:l,onRefresh:P})},{key:`overview`,label:`成绩总览`,children:(0,Y.jsx)(Nxe,{exams:l,subjectNames:N})},{key:`trend`,label:`分科曲线`,children:(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(gS,{style:{width:`100%`,maxWidth:160,marginBottom:16},value:p,onChange:m,options:s.map(e=>({value:e.id,label:e.name}))}),d&&(0,Y.jsx)(BQe,{points:d.points,subjectName:d.subject_name,threshold:d.threshold})]})},{key:`wrong`,label:`错题库`,children:(0,Y.jsxs)(`div`,{children:[(0,Y.jsxs)(rE.Paragraph,{type:`secondary`,style:{marginBottom:12},children:[`上传后自动标注错误位置(红框),并生成解题思路,按`,B,`课内标准解题`]}),(0,Y.jsx)(g3e,{studentId:e,subjects:s,category:`regular`,onUploaded:I}),(0,Y.jsx)(_3e,{subjectId:b,onSubjectChange:x,search:S,onSearchChange:C,onRefresh:I,subjects:s}),(0,Y.jsx)(h3e,{items:g,selectedId:E,onSelect:D,onRefresh:I,emptyText:`暂无错题`})]})},{key:`olympiad`,label:`奥数区`,children:(0,Y.jsxs)(`div`,{children:[(0,Y.jsxs)(rE.Paragraph,{type:`secondary`,style:{marginBottom:12},children:[B,`数学奥数,严格限制在`,B,`奥数培优范围内,禁止超纲`]}),(0,Y.jsx)(g3e,{studentId:e,subjects:s,category:`olympiad`,onUploaded:L}),(0,Y.jsx)(_3e,{search:w,onSearchChange:T,onRefresh:L,subjects:s,hideSubjectFilter:!0}),(0,Y.jsx)(h3e,{items:v,selectedId:O,onSelect:k,onRefresh:L,emptyText:`暂无奥数题`})]})}]})]})}function S3e(){let{user:e,logout:t}=_k(),[n,r]=(0,h.useState)([]),[i,a]=(0,h.useState)(!0),[o,s]=(0,h.useState)(!1),[c]=ky.useForm(),l=ky.useWatch(`school_level`,c),u=async()=>{a(!0);try{let{data:e}=await pk.list();r(e)}finally{a(!1)}};return(0,h.useEffect)(()=>{u()},[]),(0,Y.jsxs)(`div`,{className:`page-container`,children:[(0,Y.jsxs)(`div`,{style:{display:`flex`,justifyContent:`space-between`,alignItems:`center`,marginBottom:24,flexWrap:`wrap`,gap:12},children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(rE.Title,{level:3,style:{margin:0},children:`学生档案`}),(0,Y.jsxs)(rE.Text,{type:`secondary`,children:[`欢迎,`,e?.username]})]}),(0,Y.jsxs)(Py,{wrap:!0,children:[e?.is_superuser&&(0,Y.jsx)(RD,{to:`/settings`,children:(0,Y.jsx)(_p,{icon:(0,Y.jsx)(Tk,{}),children:`系统设置`})}),(0,Y.jsx)(_p,{type:`primary`,icon:(0,Y.jsx)(Nm,{}),onClick:()=>{c.setFieldsValue({school_level:`junior_high`,grade:void 0}),s(!0)},children:`添加学生`}),(0,Y.jsx)(_p,{icon:(0,Y.jsx)(Cxe,{}),onClick:t,children:`退出`})]})]}),(0,Y.jsx)(TS,{spinning:i,children:(0,Y.jsxs)(Dle,{gutter:[16,16],children:[n.map(e=>(0,Y.jsx)(bg,{xs:24,sm:12,md:8,children:(0,Y.jsx)(RD,{to:`/students/${e.id}`,style:{textDecoration:`none`},children:(0,Y.jsx)(lg,{hoverable:!0,children:(0,Y.jsxs)(Py,{align:`start`,children:[(0,Y.jsx)(Ok,{style:{fontSize:24,color:`#1677ff`}}),(0,Y.jsxs)(`div`,{children:[(0,Y.jsxs)(Py,{size:4,children:[(0,Y.jsx)(rE.Text,{strong:!0,children:e.name}),(0,Y.jsx)(PT,{color:e.school_level===`senior_high`?`purple`:`blue`,children:Q9[e.school_level]})]}),(0,Y.jsx)(`br`,{}),(0,Y.jsx)(rE.Text,{type:`secondary`,style:{fontSize:12},children:y3e(e)})]})]})})})},e.id)),!i&&n.length===0&&(0,Y.jsx)(bg,{span:24,children:(0,Y.jsx)(lg,{children:(0,Y.jsx)(rE.Text,{type:`secondary`,children:`暂无学生,点击「添加学生」开始`})})})]})}),(0,Y.jsx)(yx,{title:`添加学生`,open:o,onCancel:()=>s(!1),onOk:async()=>{let e=await c.validateFields();await pk.create(e),rx.success(`学生已添加`),s(!1),c.resetFields(),u()},destroyOnHidden:!0,children:(0,Y.jsxs)(ky,{form:c,layout:`vertical`,initialValues:{school_level:`junior_high`},children:[(0,Y.jsx)(ky.Item,{name:`name`,label:`姓名`,rules:[{required:!0}],children:(0,Y.jsx)(ib,{})}),(0,Y.jsx)(ky.Item,{name:`school_level`,label:`学段`,rules:[{required:!0}],children:(0,Y.jsx)(gS,{options:Object.entries(Q9).map(([e,t])=>({value:e,label:t})),onChange:()=>c.setFieldValue(`grade`,void 0)})}),(0,Y.jsx)(ky.Item,{name:`grade`,label:`年级`,children:(0,Y.jsx)(gS,{allowClear:!0,placeholder:l===`senior_high`?`如:高一`:`如:初二`,options:(v3e[l||`junior_high`]||[]).map(e=>({value:e,label:e}))})}),(0,Y.jsx)(ky.Item,{name:`class_name`,label:`班级`,children:(0,Y.jsx)(ib,{placeholder:`如:3班`})})]})})]})}function $9({children:e}){let{user:t,loading:n}=_k();return n?null:t?(0,Y.jsx)(Y.Fragment,{children:e}):(0,Y.jsx)(wD,{to:`/login`,replace:!0})}function C3e(){return(0,Y.jsxs)(gve,{children:[(0,Y.jsx)(TD,{path:`/login`,element:(0,Y.jsx)(Axe,{})}),(0,Y.jsx)(TD,{path:`/`,element:(0,Y.jsx)($9,{children:(0,Y.jsx)(S3e,{})})}),(0,Y.jsx)(TD,{path:`/students/:id`,element:(0,Y.jsx)($9,{children:(0,Y.jsx)(x3e,{})})}),(0,Y.jsx)(TD,{path:`/settings`,element:(0,Y.jsx)($9,{children:(0,Y.jsx)(jxe,{})})}),(0,Y.jsx)(TD,{path:`*`,element:(0,Y.jsx)(wD,{to:`/`,replace:!0})})]})}(0,vn.createRoot)(document.getElementById(`root`)).render((0,Y.jsx)(h.StrictMode,{children:(0,Y.jsx)(Uu,{locale:fxe.default,children:(0,Y.jsx)(qve,{children:(0,Y.jsx)(gxe,{children:(0,Y.jsx)(C3e,{})})})})}));
\ No newline at end of file
+`},i)),a}function M4e(e,t){return e&&`run`in e?async function(n,r){let i=j4e(n,{file:r,...t});await e.run(i,r)}:function(n,r){return j4e(n,{file:r,...e||t})}}function N4e(e){if(e)throw e}var P4e=o(((e,t)=>{var n=Object.prototype.hasOwnProperty,r=Object.prototype.toString,i=Object.defineProperty,a=Object.getOwnPropertyDescriptor,o=function(e){return typeof Array.isArray==`function`?Array.isArray(e):r.call(e)===`[object Array]`},s=function(e){if(!e||r.call(e)!==`[object Object]`)return!1;var t=n.call(e,`constructor`),i=e.constructor&&e.constructor.prototype&&n.call(e.constructor.prototype,`isPrototypeOf`);if(e.constructor&&!t&&!i)return!1;for(var a in e);return a===void 0||n.call(e,a)},c=function(e,t){i&&t.name===`__proto__`?i(e,t.name,{enumerable:!0,configurable:!0,value:t.newValue,writable:!0}):e[t.name]=t.newValue},l=function(e,t){if(t===`__proto__`){if(!n.call(e,t))return;if(a)return a(e,t).value}return e[t]};t.exports=function e(){var t,n,r,i,a,u,d=arguments[0],f=1,p=arguments.length,m=!1;for(typeof d==`boolean`&&(m=d,d=arguments[1]||{},f=2),(d==null||typeof d!=`object`&&typeof d!=`function`)&&(d={});ft.length,o;r&&t.push(i);try{o=e.apply(this,t)}catch(e){let t=e;if(r&&n)throw t;return i(t)}r||(o&&o.then&&typeof o.then==`function`?o.then(a,i):o instanceof Error?i(o):a(o))}function i(e,...r){n||(n=!0,t(e,...r))}function a(e){i(null,e)}}var V9={basename:L4e,dirname:R4e,extname:z4e,join:B4e,sep:`/`};function L4e(e,t){if(t!==void 0&&typeof t!=`string`)throw TypeError(`"ext" argument must be a string`);H9(e);let n=0,r=-1,i=e.length,a;if(t===void 0||t.length===0||t.length>e.length){for(;i--;)if(e.codePointAt(i)===47){if(a){n=i+1;break}}else r<0&&(a=!0,r=i+1);return r<0?``:e.slice(n,r)}if(t===e)return``;let o=-1,s=t.length-1;for(;i--;)if(e.codePointAt(i)===47){if(a){n=i+1;break}}else o<0&&(a=!0,o=i+1),s>-1&&(e.codePointAt(i)===t.codePointAt(s--)?s<0&&(r=i):(s=-1,r=o));return n===r?r=o:r<0&&(r=e.length),e.slice(n,r)}function R4e(e){if(H9(e),e.length===0)return`.`;let t=-1,n=e.length,r;for(;--n;)if(e.codePointAt(n)===47){if(r){t=n;break}}else r||=!0;return t<0?e.codePointAt(0)===47?`/`:`.`:t===1&&e.codePointAt(0)===47?`//`:e.slice(0,t)}function z4e(e){H9(e);let t=e.length,n=-1,r=0,i=-1,a=0,o;for(;t--;){let s=e.codePointAt(t);if(s===47){if(o){r=t+1;break}continue}n<0&&(o=!0,n=t+1),s===46?i<0?i=t:a!==1&&(a=1):i>-1&&(a=-1)}return i<0||n<0||a===0||a===1&&i===n-1&&i===r+1?``:e.slice(i,n)}function B4e(...e){let t=-1,n;for(;++t0&&e.codePointAt(e.length-1)===47&&(n+=`/`),t?`/`+n:n}function H4e(e,t){let n=``,r=0,i=-1,a=0,o=-1,s,c;for(;++o<=e.length;){if(o2){if(c=n.lastIndexOf(`/`),c!==n.length-1){c<0?(n=``,r=0):(n=n.slice(0,c),r=n.length-1-n.lastIndexOf(`/`)),i=o,a=0;continue}}else if(n.length>0){n=``,r=0,i=o,a=0;continue}}t&&(n=n.length>0?n+`/..`:`..`,r=2)}else n.length>0?n+=`/`+e.slice(i+1,o):n=e.slice(i+1,o),r=o-i-1;i=o,a=0}else s===46&&a>-1?a++:a=-1}return n}function H9(e){if(typeof e!=`string`)throw TypeError(`Path must be a string. Received `+JSON.stringify(e))}var U4e={cwd:W4e};function W4e(){return`/`}function U9(e){return!!(typeof e==`object`&&e&&`href`in e&&e.href&&`protocol`in e&&e.protocol&&e.auth===void 0)}function G4e(e){if(typeof e==`string`)e=new URL(e);else if(!U9(e)){let t=TypeError('The "path" argument must be of type string or an instance of URL. Received `'+e+"`");throw t.code=`ERR_INVALID_ARG_TYPE`,t}if(e.protocol!==`file:`){let e=TypeError(`The URL must be of scheme file`);throw e.code=`ERR_INVALID_URL_SCHEME`,e}return K4e(e)}function K4e(e){if(e.hostname!==``){let e=TypeError(`File URL host must be "localhost" or empty on darwin`);throw e.code=`ERR_INVALID_FILE_URL_HOST`,e}let t=e.pathname,n=-1;for(;++n0){let[r,...a]=t,o=n[i][1];B9(o)&&B9(r)&&(r=(0,q9.default)(!0,o,r)),n[i]=[e,r,...a]}}}}().freeze();function J9(e,t){if(typeof t!=`function`)throw TypeError("Cannot `"+e+"` without `parser`")}function Y9(e,t){if(typeof t!=`function`)throw TypeError("Cannot `"+e+"` without `compiler`")}function X9(e,t){if(t)throw Error("Cannot call `"+e+"` on a frozen processor.\nCreate a new processor first, by calling it: use `processor()` instead of `processor`.")}function $4e(e){if(!B9(e)||typeof e.type!=`string`)throw TypeError("Expected node, got `"+e+"`")}function e3e(e,t,n){if(!n)throw Error("`"+e+"` finished async. Use `"+t+"` instead")}function Z9(e){return t3e(e)?e:new q4e(e)}function t3e(e){return!!(e&&typeof e==`object`&&`message`in e&&`messages`in e)}function n3e(e){return typeof e==`string`||r3e(e)}function r3e(e){return!!(e&&typeof e==`object`&&`byteLength`in e&&`byteOffset`in e)}var i3e=[],a3e={allowDangerousHtml:!0},o3e=/^(https?|ircs?|mailto|xmpp)$/i,s3e=[{from:`astPlugins`,id:`remove-buggy-html-in-markdown-parser`},{from:`allowDangerousHtml`,id:`remove-buggy-html-in-markdown-parser`},{from:`allowNode`,id:`replace-allownode-allowedtypes-and-disallowedtypes`,to:`allowElement`},{from:`allowedTypes`,id:`replace-allownode-allowedtypes-and-disallowedtypes`,to:`allowedElements`},{from:`className`,id:`remove-classname`},{from:`disallowedTypes`,id:`replace-allownode-allowedtypes-and-disallowedtypes`,to:`disallowedElements`},{from:`escapeHtml`,id:`remove-buggy-html-in-markdown-parser`},{from:`includeElementIndex`,id:`#remove-includeelementindex`},{from:`includeNodeIndex`,id:`change-includenodeindex-to-includeelementindex`},{from:`linkTarget`,id:`remove-linktarget`},{from:`plugins`,id:`change-plugins-to-remarkplugins`,to:`remarkPlugins`},{from:`rawSourcePos`,id:`#remove-rawsourcepos`},{from:`renderers`,id:`change-renderers-to-components`,to:`components`},{from:`source`,id:`change-source-to-children`,to:`children`},{from:`sourcePos`,id:`#remove-sourcepos`},{from:`transformImageUri`,id:`#add-urltransform`,to:`urlTransform`},{from:`transformLinkUri`,id:`#add-urltransform`,to:`urlTransform`}];function c3e(e){let t=l3e(e),n=u3e(e);return d3e(t.runSync(t.parse(n),n),e)}function l3e(e){let t=e.rehypePlugins||i3e,n=e.remarkPlugins||i3e,r=e.remarkRehypeOptions?{...e.remarkRehypeOptions,...a3e}:a3e;return Q4e().use(w2e).use(n).use(M4e,r).use(t)}function u3e(e){let t=e.children||``,n=new q4e;return typeof t==`string`?n.value=t:``+t,n}function d3e(e,t){let n=t.allowedElements,r=t.allowElement,i=t.components,a=t.disallowedElements,o=t.skipHtml,s=t.unwrapDisallowed,c=t.urlTransform||f3e;for(let e of s3e)Object.hasOwn(t,e.from)&&``+e.from+(e.to?"use `"+e.to+"` instead":`remove it`)+e.id;return K2e(e,l),k$e(e,{Fragment:Y.Fragment,components:i,ignoreInvalidStyle:!0,jsx:Y.jsx,jsxs:Y.jsxs,passKeys:!0,passNode:!0});function l(e,t,i){if(e.type===`raw`&&i&&typeof t==`number`)return o?i.children.splice(t,1):i.children[t]={type:`text`,value:e.value},t;if(e.type===`element`){let t;for(t in s9)if(Object.hasOwn(s9,t)&&Object.hasOwn(e.properties,t)){let n=e.properties[t],r=s9[t];(r===null||r.includes(e.tagName))&&(e.properties[t]=c(String(n||``),t,e))}}if(e.type===`element`){let o=n?!n.includes(e.tagName):a?a.includes(e.tagName):!1;if(!o&&r&&typeof t==`number`&&(o=!r(e,t,i)),o&&i&&typeof t==`number`)return s&&e.children?i.children.splice(t,1,...e.children):i.children.splice(t,1),t}}}function f3e(e){let t=e.indexOf(`:`),n=e.indexOf(`?`),r=e.indexOf(`#`),i=e.indexOf(`/`);return t===-1||i!==-1&&t>i||n!==-1&&t>n||r!==-1&&t>r||o3e.test(e.slice(0,t))?e:``}function p3e({questionId:e,open:t,onClose:n,onUpdated:r,onDeleted:i}){let[a,o]=(0,h.useState)(null),[s,c]=(0,h.useState)(!1),[l,u]=(0,h.useState)(``),[d,f]=(0,h.useState)(``),[p,m]=(0,h.useState)(``),[g,_]=(0,h.useState)(`annotated`),[v,y]=(0,h.useState)(!1),[b,x]=(0,h.useState)(!1),[S,C]=(0,h.useState)(!1),w=async()=>{c(!0);try{let{data:t}=await hk.get(e);o(t),u(t.question_text||t.ocr_raw_text||``),f(t.solution_approach||``),m(t.solution_text||``),_(t.has_annotated_image?`annotated`:`original`)}finally{c(!1)}};return(0,h.useEffect)(()=>{t&&e&&w()},[t,e]),(0,h.useEffect)(()=>{if(!t||!a||!P7(a))return;let n=window.setInterval(async()=>{try{let{data:t}=await hk.get(e);o(t),u(t.question_text||t.ocr_raw_text||``),f(t.solution_approach||``),m(t.solution_text||``),t.has_annotated_image&&_(`annotated`),P7(t)||r()}catch{}},4e3);return()=>window.clearInterval(n)},[t,e,a?.status,a?.question_text,a?.error_message]),(0,Y.jsx)(yx,{title:a?`${a.subject_name}${a.category===`olympiad`?` · 奥数`:``} · 详情`:`详情`,open:t,onCancel:n,width:`90%`,style:{maxWidth:960},footer:(0,Y.jsxs)(Py,{wrap:!0,children:[(0,Y.jsx)(xx,{title:`确定删除该题?`,onConfirm:async()=>{C(!0);try{await hk.remove(e),rx.success(`已删除`),i?.(),n()}catch{rx.error(`删除失败`)}finally{C(!1)}},children:(0,Y.jsx)(_p,{danger:!0,loading:S,children:`删除`})}),(0,Y.jsx)(_p,{onClick:async()=>{await hk.retryOcr(e),rx.info(`已重新识别并标注,请稍后刷新`),r(),n()},children:`重新识别标注`}),(0,Y.jsx)(_p,{loading:b,onClick:async()=>{x(!0);try{let{data:t}=await hk.regenerate(e);o(t),u(t.question_text||t.ocr_raw_text||``),f(t.solution_approach||``),m(t.solution_text||``),rx.success(`解题思路已重新生成`),r()}catch{rx.error(`生成失败,请检查 AI 模型配置`)}finally{x(!1)}},children:`重新生成思路`}),(0,Y.jsx)(_p,{type:`primary`,loading:v,onClick:async()=>{y(!0);try{await hk.update(e,{question_text:l,solution_approach:d,solution_text:p}),rx.success(`已保存`),r()}finally{y(!1)}},children:`保存编辑`})]}),children:(0,Y.jsx)(TS,{spinning:s,children:a&&(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsxs)(Py,{wrap:!0,style:{marginBottom:8},children:[(0,Y.jsxs)(rE.Text,{type:`secondary`,children:[`状态:`,jk[a.status]]}),a.has_annotated_image&&!a.error_message&&(0,Y.jsx)(rE.Text,{type:`danger`,children:`红色框为自动标注的错误位置`})]}),a.error_message&&(0,Y.jsx)(Rc,{message:`处理失败`,description:a.error_message,type:`error`,showIcon:!0,style:{marginBottom:12}}),a.status===`pending`&&!a.error_message&&(0,Y.jsx)(Rc,{message:F7(a),type:`info`,showIcon:!0,style:{marginBottom:12}}),a.status===`ocr_done`&&!a.question_text&&!a.error_message&&(0,Y.jsx)(Rc,{message:F7(a),type:`info`,showIcon:!0,style:{marginBottom:12}}),(a.solution_approach||a.solution_text)&&(0,Y.jsx)(Rc,{message:`AI 识别与标注,请核对后再使用`,type:`warning`,showIcon:!0,style:{margin:`12px 0`}}),(0,Y.jsxs)(Dle,{gutter:16,style:{marginTop:12},children:[(0,Y.jsxs)(bg,{xs:24,md:10,children:[a.has_annotated_image&&(0,Y.jsx)(Ble,{block:!0,style:{marginBottom:8},value:g,onChange:e=>_(e),options:[{label:`标注图`,value:`annotated`},{label:`原图`,value:`original`}]}),(0,Y.jsx)(I7,{questionId:a.id,variant:g,alt:`原题`,style:{width:`100%`,borderRadius:8,border:`1px solid #f0f0f0`}}),a.ocr_raw_text&&(0,Y.jsxs)(`div`,{style:{marginTop:12},children:[(0,Y.jsx)(rE.Text,{strong:!0,children:`OCR 原文`}),(0,Y.jsx)(`pre`,{style:{background:`#fafafa`,padding:8,fontSize:12,maxHeight:150,overflow:`auto`,whiteSpace:`pre-wrap`},children:a.ocr_raw_text})]})]}),(0,Y.jsxs)(bg,{xs:24,md:14,children:[(0,Y.jsx)(rE.Text,{strong:!0,children:`识别题目(可编辑)`}),(0,Y.jsx)(ib.TextArea,{rows:5,value:l,onChange:e=>u(e.target.value),style:{marginTop:8,marginBottom:16}}),(0,Y.jsx)(rE.Text,{strong:!0,children:`解题思路`}),(0,Y.jsx)(ib.TextArea,{rows:4,value:d,onChange:e=>f(e.target.value),placeholder:`识别完成后自动生成,类似作业帮「解题思路」`,style:{marginTop:8,marginBottom:16}}),d&&(0,Y.jsxs)(`div`,{style:{background:`#e6f4ff`,padding:12,borderRadius:8,marginBottom:16,border:`1px solid #91caff`},children:[(0,Y.jsx)(rE.Text,{type:`secondary`,style:{fontSize:12},children:`思路预览`}),(0,Y.jsx)(c3e,{children:d})]}),(0,Y.jsx)(rE.Text,{strong:!0,children:`详细解答`}),(0,Y.jsx)(ib.TextArea,{rows:8,value:p,onChange:e=>m(e.target.value),style:{marginTop:8,marginBottom:12}}),p&&(0,Y.jsxs)(`div`,{style:{background:`#fafafa`,padding:12,borderRadius:8},children:[(0,Y.jsx)(rE.Text,{type:`secondary`,style:{fontSize:12},children:`解答预览`}),(0,Y.jsx)(c3e,{children:p})]})]})]})]})})})}function m3e(e){return e.error_message?{tone:`error`,text:e.error_message}:P7(e)?{tone:`pending`,text:F7(e)}:{tone:`normal`,text:e.question_text||e.ocr_raw_text||jk[e.status]}}function h3e({items:e,selectedId:t,onSelect:n,onRefresh:r,emptyText:i=`暂无记录`,pollWhenProcessing:a=!0}){let o=a&&e.some(P7);(0,h.useEffect)(()=>{if(!o)return;let e=window.setInterval(()=>r(),4e3);return()=>window.clearInterval(e)},[o,r]);let s=async e=>{try{await hk.remove(e),rx.success(`已删除`),t===e&&n(null),r()}catch{rx.error(`删除失败`)}};return(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(`div`,{className:`wq-grid`,children:e.map(e=>{let t=m3e(e);return(0,Y.jsxs)(`div`,{className:`wq-card`,children:[(0,Y.jsxs)(`div`,{className:`wq-card-click`,onClick:()=>n(e.id),children:[(0,Y.jsx)(I7,{questionId:e.id,variant:`annotated`,alt:`题目`,className:`wq-card-img`}),(0,Y.jsxs)(`div`,{className:`wq-card-body`,children:[(0,Y.jsxs)(Py,{size:4,wrap:!0,children:[(0,Y.jsx)(rE.Text,{strong:!0,children:e.subject_name}),e.category===`olympiad`&&(0,Y.jsx)(PT,{color:`gold`,children:`奥数`}),(0,Y.jsx)(PT,{color:e.error_message||e.status===`failed`?`error`:P7(e)?`processing`:`default`,children:e.error_message?`失败`:jk[e.status]})]}),(0,Y.jsx)(rE.Paragraph,{ellipsis:{rows:3},style:{margin:`8px 0 0`,fontSize:13,color:t.tone===`error`?`#ff4d4f`:t.tone===`pending`?`#1677ff`:void 0},children:t.text})]})]}),(0,Y.jsx)(`div`,{className:`wq-card-actions`,children:(0,Y.jsx)(xx,{title:`确定删除该题?`,onConfirm:()=>s(e.id),children:(0,Y.jsx)(_p,{type:`text`,danger:!0,size:`small`,icon:(0,Y.jsx)(bE,{}),onClick:e=>e.stopPropagation(),children:`删除`})})})]},e.id)})}),e.length===0&&(0,Y.jsx)(rE.Text,{type:`secondary`,children:i}),t&&(0,Y.jsx)(p3e,{questionId:t,open:!!t,onClose:()=>n(null),onUpdated:r,onDeleted:()=>{n(null),r()}})]})}function g3e({studentId:e,subjects:t,category:n,onUploaded:r}){let i=n===`olympiad`,a=(0,h.useMemo)(()=>i?t.filter(e=>e.name===`数学`):t,[t,i]),[o,s]=(0,h.useState)(),[c,l]=(0,h.useState)(!1),u=(0,h.useRef)(null);(0,h.useEffect)(()=>{a.length&&s(a[0].id)},[a]);let d=async t=>{if(!o){rx.warning(i?`未找到数学科目`:`请选择科目`);return}l(!0);try{await hk.upload(e,o,t,n),rx.success(`上传成功,正在识别并生成解法…`),r()}catch{rx.error(`上传失败`)}finally{l(!1)}},f=async e=>(await d(e),!1);return(0,Y.jsxs)(Py,{direction:`vertical`,size:`middle`,style:{width:`100%`,marginBottom:16},children:[i?(0,Y.jsx)(rE.Text,{children:`科目:数学(奥数区仅支持数学)`}):(0,Y.jsx)(gS,{style:{width:`100%`,maxWidth:200},placeholder:`选择科目`,value:o,onChange:s,options:a.map(e=>({value:e.id,label:e.name}))}),(0,Y.jsxs)(Py,{wrap:!0,className:`upload-actions`,children:[(0,Y.jsx)(FE,{beforeUpload:f,showUploadList:!1,accept:`image/*`,children:(0,Y.jsx)(_p,{icon:(0,Y.jsx)(pE,{}),loading:c,type:`primary`,size:`large`,children:`相册选图`})}),(0,Y.jsx)(_p,{icon:(0,Y.jsx)(bxe,{}),loading:c,size:`large`,onClick:()=>u.current?.click(),children:`拍照上传`}),(0,Y.jsx)(`input`,{ref:u,type:`file`,accept:`image/*`,capture:`environment`,style:{display:`none`},onChange:async e=>{let t=e.target.files?.[0];e.target.value=``,t&&await d(t)}}),!i&&(0,Y.jsx)(FE,{beforeUpload:f,showUploadList:!1,accept:`image/*`,children:(0,Y.jsx)(_p,{icon:(0,Y.jsx)(Oxe,{}),loading:c,size:`large`,children:`上传图片`})})]}),i&&(0,Y.jsx)(`span`,{style:{color:`#666`,fontSize:13},children:`奥数区仅数学,按学生学段(初中/高中)生成解题思路,严禁超纲`})]})}function _3e({subjectId:e,onSubjectChange:t,search:n,onSearchChange:r,onRefresh:i,subjects:a,hideSubjectFilter:o}){return(0,Y.jsxs)(Py,{wrap:!0,style:{marginBottom:16,width:`100%`},children:[!o&&(0,Y.jsx)(gS,{allowClear:!0,style:{width:`100%`,maxWidth:140},placeholder:`全部科目`,value:e,onChange:t,options:a.map(e=>({value:e.id,label:e.name}))}),(0,Y.jsx)(ib.Search,{placeholder:`搜索题目/解法`,value:n,onChange:e=>r(e.target.value),onSearch:()=>i(),style:{width:`100%`,maxWidth:260},allowClear:!0}),(0,Y.jsx)(_p,{icon:(0,Y.jsx)(Txe,{}),onClick:i,children:`刷新`})]})}var Q9={junior_high:`初中`,senior_high:`高中`},v3e={junior_high:[`初一`,`初二`,`初三`],senior_high:[`高一`,`高二`,`高三`]};function y3e(e){let t=[Q9[e.school_level],e.grade,e.class_name].filter(Boolean);return t.length?t.join(` · `):`未设置学段年级`}var b3e=[`scores`,`overview`,`trend`,`wrong`,`olympiad`];function x3e(){let{id:e}=X_e(),[t,n]=tye(),r=t.get(`tab`),i=b3e.includes(r)?r:`scores`,[a,o]=(0,h.useState)(null),[s,c]=(0,h.useState)([]),[l,u]=(0,h.useState)([]),[d,f]=(0,h.useState)(null),[p,m]=(0,h.useState)(),[g,_]=(0,h.useState)([]),[v,y]=(0,h.useState)([]),[b,x]=(0,h.useState)(),[S,C]=(0,h.useState)(``),[w,T]=(0,h.useState)(``),[E,D]=(0,h.useState)(null),[O,k]=(0,h.useState)(null),[A,j]=(0,h.useState)(!0),M=(0,h.useMemo)(()=>s.find(e=>e.name===`数学`),[s]),N=Object.fromEntries(s.map(e=>[e.id,e.name])),P=(0,h.useCallback)(async()=>{if(!e)return;let{data:t}=await mk.list(e);u(t)},[e]),F=(0,h.useCallback)(async()=>{if(!e||!p)return;let{data:t}=await mk.trend(e,p);f(t)},[e,p]),I=(0,h.useCallback)(async()=>{if(!e)return;let{data:t}=await hk.list(e,{subject_id:b,q:S||void 0,category:`regular`});_(t)},[e,b,S]),L=(0,h.useCallback)(async()=>{if(!e)return;let{data:t}=await hk.list(e,{subject_id:M?.id,q:w||void 0,category:`olympiad`});y(t)},[e,M?.id,w]);(0,h.useEffect)(()=>{if(!e)return;let t=!1;return(async()=>{j(!0);try{let[n,r]=await Promise.all([pk.get(e),mxe.list()]);if(t)return;o(n.data),c(r.data),r.data.length&&m(r.data[0].id);let i=await mk.list(e);t||u(i.data)}finally{t||j(!1)}})(),()=>{t=!0}},[e]),(0,h.useEffect)(()=>{I()},[I]),(0,h.useEffect)(()=>{L()},[L]),(0,h.useEffect)(()=>{F()},[F]);let R=e=>{n({tab:e},{replace:!0})},z=async()=>{if(e)try{let{data:t}=await mk.exportCsv(e),n=URL.createObjectURL(t),r=document.createElement(`a`);r.href=n,r.download=`${a?.name||`student`}_scores.csv`,r.click(),URL.revokeObjectURL(n)}catch{rx.error(`导出失败`)}};if(A)return(0,Y.jsx)(`div`,{style:{textAlign:`center`,padding:80},children:(0,Y.jsx)(TS,{size:`large`})});if(!a)return(0,Y.jsx)(rE.Text,{children:`学生不存在`});let B=Q9[a.school_level];return(0,Y.jsxs)(`div`,{className:`page-container`,children:[(0,Y.jsxs)(Py,{className:`page-header`,wrap:!0,children:[(0,Y.jsx)(RD,{to:`/`,children:(0,Y.jsx)(_p,{icon:(0,Y.jsx)(vxe,{}),children:`返回`})}),(0,Y.jsx)(rE.Title,{level:4,style:{margin:0},children:a.name}),(0,Y.jsx)(PT,{color:a.school_level===`senior_high`?`purple`:`blue`,children:B}),(0,Y.jsx)(rE.Text,{type:`secondary`,children:y3e(a)}),(0,Y.jsx)(_p,{icon:(0,Y.jsx)(SE,{}),onClick:z,children:`导出 CSV`})]}),(0,Y.jsx)(sg,{className:`student-tabs`,activeKey:i,onChange:R,destroyInactiveTabPane:!1,items:[{key:`scores`,label:`成绩录入`,children:(0,Y.jsx)(Mxe,{studentId:e,subjects:s,exams:l,onRefresh:P})},{key:`overview`,label:`成绩总览`,children:(0,Y.jsx)(Nxe,{exams:l,subjectNames:N})},{key:`trend`,label:`分科曲线`,children:(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(gS,{style:{width:`100%`,maxWidth:160,marginBottom:16},value:p,onChange:m,options:s.map(e=>({value:e.id,label:e.name}))}),d&&(0,Y.jsx)(BQe,{points:d.points,subjectName:d.subject_name,threshold:d.threshold})]})},{key:`wrong`,label:`错题库`,children:(0,Y.jsxs)(`div`,{children:[(0,Y.jsxs)(rE.Paragraph,{type:`secondary`,style:{marginBottom:12},children:[`上传后自动标注错误位置(红框),并生成解题思路,按`,B,`课内标准解题`]}),(0,Y.jsx)(g3e,{studentId:e,subjects:s,category:`regular`,onUploaded:I}),(0,Y.jsx)(_3e,{subjectId:b,onSubjectChange:x,search:S,onSearchChange:C,onRefresh:I,subjects:s}),(0,Y.jsx)(h3e,{items:g,selectedId:E,onSelect:D,onRefresh:I,emptyText:`暂无错题`})]})},{key:`olympiad`,label:`奥数区`,children:(0,Y.jsxs)(`div`,{children:[(0,Y.jsxs)(rE.Paragraph,{type:`secondary`,style:{marginBottom:12},children:[B,`数学奥数,严格限制在`,B,`奥数培优范围内,禁止超纲`]}),(0,Y.jsx)(g3e,{studentId:e,subjects:s,category:`olympiad`,onUploaded:L}),(0,Y.jsx)(_3e,{search:w,onSearchChange:T,onRefresh:L,subjects:s,hideSubjectFilter:!0}),(0,Y.jsx)(h3e,{items:v,selectedId:O,onSelect:k,onRefresh:L,emptyText:`暂无奥数题`})]})}]})]})}function S3e(){let{user:e,logout:t}=_k(),[n,r]=(0,h.useState)([]),[i,a]=(0,h.useState)(!0),[o,s]=(0,h.useState)(!1),[c]=ky.useForm(),l=ky.useWatch(`school_level`,c),u=async()=>{a(!0);try{let{data:e}=await pk.list();r(e)}finally{a(!1)}};return(0,h.useEffect)(()=>{u()},[]),(0,Y.jsxs)(`div`,{className:`page-container`,children:[(0,Y.jsxs)(`div`,{style:{display:`flex`,justifyContent:`space-between`,alignItems:`center`,marginBottom:24,flexWrap:`wrap`,gap:12},children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(rE.Title,{level:3,style:{margin:0},children:`学生档案`}),(0,Y.jsxs)(rE.Text,{type:`secondary`,children:[`欢迎,`,e?.username]})]}),(0,Y.jsxs)(Py,{wrap:!0,children:[e?.is_superuser&&(0,Y.jsx)(RD,{to:`/settings`,children:(0,Y.jsx)(_p,{icon:(0,Y.jsx)(Tk,{}),children:`系统设置`})}),(0,Y.jsx)(_p,{type:`primary`,icon:(0,Y.jsx)(Nm,{}),onClick:()=>{c.setFieldsValue({school_level:`junior_high`,grade:void 0}),s(!0)},children:`添加学生`}),(0,Y.jsx)(_p,{icon:(0,Y.jsx)(Cxe,{}),onClick:t,children:`退出`})]})]}),(0,Y.jsx)(TS,{spinning:i,children:(0,Y.jsxs)(Dle,{gutter:[16,16],children:[n.map(e=>(0,Y.jsx)(bg,{xs:24,sm:12,md:8,children:(0,Y.jsx)(RD,{to:`/students/${e.id}`,style:{textDecoration:`none`},children:(0,Y.jsx)(lg,{hoverable:!0,children:(0,Y.jsxs)(Py,{align:`start`,children:[(0,Y.jsx)(Ok,{style:{fontSize:24,color:`#1677ff`}}),(0,Y.jsxs)(`div`,{children:[(0,Y.jsxs)(Py,{size:4,children:[(0,Y.jsx)(rE.Text,{strong:!0,children:e.name}),(0,Y.jsx)(PT,{color:e.school_level===`senior_high`?`purple`:`blue`,children:Q9[e.school_level]})]}),(0,Y.jsx)(`br`,{}),(0,Y.jsx)(rE.Text,{type:`secondary`,style:{fontSize:12},children:y3e(e)})]})]})})})},e.id)),!i&&n.length===0&&(0,Y.jsx)(bg,{span:24,children:(0,Y.jsx)(lg,{children:(0,Y.jsx)(rE.Text,{type:`secondary`,children:`暂无学生,点击「添加学生」开始`})})})]})}),(0,Y.jsx)(yx,{title:`添加学生`,open:o,onCancel:()=>s(!1),onOk:async()=>{let e=await c.validateFields();await pk.create(e),rx.success(`学生已添加`),s(!1),c.resetFields(),u()},destroyOnHidden:!0,children:(0,Y.jsxs)(ky,{form:c,layout:`vertical`,initialValues:{school_level:`junior_high`},children:[(0,Y.jsx)(ky.Item,{name:`name`,label:`姓名`,rules:[{required:!0}],children:(0,Y.jsx)(ib,{})}),(0,Y.jsx)(ky.Item,{name:`school_level`,label:`学段`,rules:[{required:!0}],children:(0,Y.jsx)(gS,{options:Object.entries(Q9).map(([e,t])=>({value:e,label:t})),onChange:()=>c.setFieldValue(`grade`,void 0)})}),(0,Y.jsx)(ky.Item,{name:`grade`,label:`年级`,children:(0,Y.jsx)(gS,{allowClear:!0,placeholder:l===`senior_high`?`如:高一`:`如:初二`,options:(v3e[l||`junior_high`]||[]).map(e=>({value:e,label:e}))})}),(0,Y.jsx)(ky.Item,{name:`class_name`,label:`班级`,children:(0,Y.jsx)(ib,{placeholder:`如:3班`})})]})})]})}function $9({children:e}){let{user:t,loading:n}=_k();return n?null:t?(0,Y.jsx)(Y.Fragment,{children:e}):(0,Y.jsx)(wD,{to:`/login`,replace:!0})}function C3e(){return(0,Y.jsxs)(gve,{children:[(0,Y.jsx)(TD,{path:`/login`,element:(0,Y.jsx)(Axe,{})}),(0,Y.jsx)(TD,{path:`/`,element:(0,Y.jsx)($9,{children:(0,Y.jsx)(S3e,{})})}),(0,Y.jsx)(TD,{path:`/students/:id`,element:(0,Y.jsx)($9,{children:(0,Y.jsx)(x3e,{})})}),(0,Y.jsx)(TD,{path:`/settings`,element:(0,Y.jsx)($9,{children:(0,Y.jsx)(jxe,{})})}),(0,Y.jsx)(TD,{path:`*`,element:(0,Y.jsx)(wD,{to:`/`,replace:!0})})]})}(0,vn.createRoot)(document.getElementById(`root`)).render((0,Y.jsx)(h.StrictMode,{children:(0,Y.jsx)(Uu,{locale:fxe.default,children:(0,Y.jsx)(qve,{children:(0,Y.jsx)(gxe,{children:(0,Y.jsx)(C3e,{})})})})}));
\ No newline at end of file
diff --git a/frontend/dist/index.html b/frontend/dist/index.html
index f2de863..23adb99 100644
--- a/frontend/dist/index.html
+++ b/frontend/dist/index.html
@@ -9,7 +9,7 @@
中学成绩档案
-
+
diff --git a/frontend/src/pages/WrongQuestionDetail.tsx b/frontend/src/pages/WrongQuestionDetail.tsx
index 8df7858..38f05c4 100644
--- a/frontend/src/pages/WrongQuestionDetail.tsx
+++ b/frontend/src/pages/WrongQuestionDetail.tsx
@@ -37,7 +37,7 @@ export default function WrongQuestionDetail({
try {
const { data } = await wrongQuestionApi.get(questionId)
setWq(data)
- setQuestionText(data.question_text || '')
+ setQuestionText(data.question_text || data.ocr_raw_text || '')
setApproachText(data.solution_approach || '')
setSolutionText(data.solution_text || '')
setImageMode(data.has_annotated_image ? 'annotated' : 'original')
@@ -56,7 +56,7 @@ export default function WrongQuestionDetail({
try {
const { data } = await wrongQuestionApi.get(questionId)
setWq(data)
- setQuestionText(data.question_text || '')
+ setQuestionText(data.question_text || data.ocr_raw_text || '')
setApproachText(data.solution_approach || '')
setSolutionText(data.solution_text || '')
if (data.has_annotated_image) setImageMode('annotated')
@@ -88,7 +88,7 @@ export default function WrongQuestionDetail({
try {
const { data } = await wrongQuestionApi.regenerate(questionId)
setWq(data)
- setQuestionText(data.question_text || '')
+ setQuestionText(data.question_text || data.ocr_raw_text || '')
setApproachText(data.solution_approach || '')
setSolutionText(data.solution_text || '')
message.success('解题思路已重新生成')
diff --git a/frontend/src/utils/wqProcessing.ts b/frontend/src/utils/wqProcessing.ts
index 6b1b726..0ea319d 100644
--- a/frontend/src/utils/wqProcessing.ts
+++ b/frontend/src/utils/wqProcessing.ts
@@ -9,10 +9,10 @@ export function isWrongQuestionProcessing(wq: WrongQuestion): boolean {
export function processingHint(wq: WrongQuestion): string {
if (wq.status === 'pending') {
- return '正在 OCR 识别(首次约 1–5 分钟,请稍候)…'
+ return '正在识别文字(约 10–30 秒)…'
}
if (wq.status === 'ocr_done') {
- return '正在标注错题并生成解题思路…'
+ return '正在标注错题并生成解题思路(约 30–90 秒)…'
}
return '正在识别、标注并生成解题思路…'
}