@@ -143,7 +143,7 @@ function lookupWordJisho(keyword) {
143143
144144// 初始化 Ollama
145145const app = express ( ) ;
146- const PORT = process . env . PORT || 3000 ;
146+ const PORT = process . env . PORT || 3456 ;
147147
148148// 中间件
149149app . use ( cors ( {
@@ -737,6 +737,70 @@ app.get('/api/verb-types', (req, res) => {
737737 } ) ;
738738} ) ;
739739
740+ // Dojo (动词变形道场) 题库 API
741+ app . get ( '/api/dojo-quiz' , ( req , res ) => {
742+ try {
743+ const limit = parseInt ( req . query . limit ) || 10 ;
744+ if ( ! tokenizer ) {
745+ return res . status ( 503 ) . json ( { error : 'Dictionary is initializing, please try again later.' } ) ;
746+ }
747+
748+ const forms = [
749+ { key : 'negative' , label : '否定式 (ない形)' } ,
750+ { key : 'polite' , label : '礼貌式 (ます形)' } ,
751+ { key : 'teForm' , label : 'て形' } ,
752+ { key : 'taForm' , label : '过去式 (た形)' } ,
753+ { key : 'potential' , label : '可能形' } ,
754+ { key : 'passive' , label : '被动形' } ,
755+ { key : 'causative' , label : '使役形' } ,
756+ { key : 'imperative' , label : '命令形' } ,
757+ { key : 'volitional' , label : '意向形' }
758+ ] ;
759+
760+ const questions = [ ] ;
761+ const usedVerbs = new Set ( ) ;
762+
763+ // 从 commonVerbs 中随机抽取
764+ while ( questions . length < limit && usedVerbs . size < commonVerbs . length ) {
765+ const randomIndex = Math . floor ( Math . random ( ) * commonVerbs . length ) ;
766+ const verbObj = commonVerbs [ randomIndex ] ;
767+
768+ if ( usedVerbs . has ( verbObj . kanji ) ) continue ;
769+ usedVerbs . add ( verbObj . kanji ) ;
770+
771+ // 解析动词类型
772+ const type = detectVerbType ( verbObj . kana ) ;
773+ if ( ! type ) continue ;
774+
775+ try {
776+ // 生成所有变形
777+ const result = conjugate ( verbObj . kana , type ) ;
778+
779+ // 随机挑一个考点
780+ const formObj = forms [ Math . floor ( Math . random ( ) * forms . length ) ] ;
781+ const answerKana = result [ formObj . key ] ;
782+
783+ if ( ! answerKana ) continue ;
784+
785+ questions . push ( {
786+ verb : verbObj . kanji ,
787+ kana : verbObj . kana ,
788+ meaning : verbObj . meaning ,
789+ formKey : formObj . key ,
790+ formLabel : formObj . label ,
791+ answer : answerKana
792+ } ) ;
793+ } catch ( e ) {
794+ // 忽略解析失败的动词
795+ }
796+ }
797+
798+ res . json ( questions ) ;
799+ } catch ( error ) {
800+ res . status ( 500 ) . json ( { error : error . message } ) ;
801+ }
802+ } ) ;
803+
740804// 启动服务器
741805app . listen ( PORT , ( ) => {
742806 console . log ( `Japanese Verb Master API running on port ${ PORT } ` ) ;
0 commit comments