print_index.js 248 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040
  1. var env = (function (defaultEnv) {
  2. var isProduction = ~location.href.indexOf('zhixinhuixue')
  3. var isLocal = ~location.href.indexOf('localhost') || ~location.href.indexOf('192.168')
  4. if (isLocal) return defaultEnv
  5. if (isProduction) return 'online'
  6. return 'testing'
  7. })('localxx')
  8. //环境配置
  9. var envConfig = envConfigs[env]
  10. //登陆态'/username/pc002/time/1567499908/sig/7d9ca3d40b7422b759ce9a7e08b2de20/sessionid/session_93482f6cf1c865b7a2e2793c66f2c595'
  11. var loginStatus = envConfig.loginStatus
  12. //当前环境域名'http://192.168.1.51/index.php'
  13. var domain = envConfig.domain + "/index.php"
  14. //当前环境转pdf所需css 相对路径
  15. var printCssPath = envConfig.printCssPath
  16. //当前环境转pdf所要请求的域
  17. var printPdfIp = envConfig.printPdfIp
  18. var editorIndexLi = 1
  19. var editorIndexUp = ''
  20. var isShowPreview = -1
  21. var isShowEdit = -1
  22. Print = {
  23. apis: {
  24. //获取答题卡信息
  25. getTopicsDetailAPi: domain + '/print/getPaperWithTopicsDetails' + loginStatus,
  26. //保存答题卡信息
  27. saveTopicsDetailsApi: domain + '/print/saveCardOnline' + loginStatus,
  28. //保存为pdf
  29. htmlToPdfApi: domain + '/print/htmlToPdf' + loginStatus,
  30. //上传图片===富文本编辑试题的时候需要
  31. uploadFileApi: domain + '/online/uploadFile' + loginStatus,
  32. //考试学生重置接口
  33. /**
  34. schoolId
  35. examGroupId
  36. 两个参数
  37. */
  38. resetExamStudentApi: domain + '/rest/answer_card_online/resetStudentStatus' + loginStatus,
  39. //下载pdf
  40. downPdfApi: domain + '/print/downOnlinePdf' + loginStatus,
  41. downOnlinePdfApi: domain + '/third/download' + loginStatus,
  42. getPdfApi: '//' + printPdfIp + '/getPdf',
  43. // getOnlinePdf
  44. getOnlinePdfApi: domain + '/third/getOnlinePdf' + loginStatus,
  45. delPdfApi: '//' + printPdfIp + '/delPdf',
  46. //直接下载node服务器上的pdf 模版
  47. //192.168.1.84:8001/download/
  48. downloadPdfUrl: '//' + printPdfIp + '/download/',
  49. batchGeneratePdfApi: '//' + printPdfIp + '/batchGeneratePdf',
  50. //latex 转 公式图片
  51. getMathtexApi: domain + '/print/ajaxGetMathtex' + loginStatus,
  52. //保存全学科试卷信息
  53. saveAllSubjectInfoApi: domain + '/third/createThirdOnline' + loginStatus,
  54. //保存为我的模版信息
  55. saveTemplateByOnlineApi: domain + '/third/saveTemplateByOnline' + loginStatus,
  56. //获取模版
  57. getTplListApi: domain + '/third/tplList' + loginStatus,
  58. //第三方创建答题卡的时候获取准考证配置信息
  59. getExamNumberConfigApi: domain + '/third/getCardStatusByGrade' + loginStatus
  60. },
  61. init: function (config) {
  62. this.modal = hgc_modal
  63. //是否第一次进入页面
  64. this.firstEnterPage = true
  65. //需要同时保存用来记忆布局的有:纸张规格,纸张方向,是否有装订线,考号配置(填涂考号or条形码,是否使用二维码)
  66. this.paper = 'A3'
  67. this.direction = 'horizontal'
  68. //装订线
  69. this.hasBindingLine = false
  70. //信息栏
  71. this.hasPaperMsg = true
  72. //考号配置
  73. this.examNumberConfig = {
  74. //条形码
  75. barCode: true,
  76. //准考证号
  77. ticketNumber: true
  78. }
  79. this.cardStatus = 0,
  80. //考号配置
  81. this.examInfoConfig = {
  82. //时间
  83. wpTimes: true,
  84. //满分
  85. fullScore: true,
  86. //命卷人
  87. wpAuthor: true,
  88. //审核人
  89. wpReviewer: true
  90. }
  91. this.examInfoConfigText = {
  92. //时间
  93. wpTimes: '',
  94. //满分
  95. fullScore: '',
  96. //命卷人
  97. wpAuthor: '',
  98. //审核人
  99. wpReviewer: ''
  100. }
  101. //是否使用二维码
  102. this.useQrCode = false
  103. this.config = simpleCopy(config[this.paper])
  104. this.configOrigin = simpleCopy(this.config)
  105. //分栏
  106. this.columns = 2
  107. //页面页码计算
  108. //当前分页
  109. this.currentPage = 1
  110. //总分页
  111. this.totalPage = 1
  112. //当前纸张-包括正反两面 ceil(totalPage/(column*2))
  113. this.currentPaper = 0
  114. //当前纸张正面1正面2 反面1 反面2
  115. this.currentPaperPage = 0
  116. //初始化页面数据
  117. /**
  118. * 核心功能模块盒模型设计
  119. */
  120. //解答区域--最小高度
  121. this.moduleMinHeight = 10
  122. //解答区域--默认高度
  123. this.moduleDefaultHeihgt = 54
  124. //解答区域--左右内边距之和
  125. this.modulePaddingSide = 20
  126. //解答区域--上内边距
  127. this.modulePaddingTop = 42
  128. //解答区域--下内边距
  129. this.modulePaddingBottom = 12
  130. this.modulePadding = this.modulePaddingTop + this.modulePaddingBottom
  131. //每个分页答题区域的--上下内边距
  132. this.pagePadding = 50
  133. //这个答题区域布局外边距
  134. this.layoutPadding = 20
  135. //每页的左右间距
  136. this.pagePaddingSide = 30
  137. //用于页面 mm 和 px 之间单位转换
  138. //96dpi 打印出来300dpi纸张上面的的比例
  139. this.dpiRadio = 1
  140. this.unitConversion = new UnitConversion()
  141. this.pageHeight = this.unitConversion.mmConversionPx(this.config.height)
  142. this.pageWidth = this.unitConversion.mmConversionPx(this.config.width)
  143. //富文本编辑 ==>> 全局富文本编辑构造函数
  144. this.EDITOR = window.wangEditor
  145. //富文本菜单配置文件
  146. this.EDITOR_CONFIG = [
  147. 'underline', // 下划线
  148. 'justify', // 对齐方式
  149. 'image', // 插入图片
  150. 'table', // 表格
  151. 'undo', // 撤销
  152. 'redo', // 重复
  153. 'lineheight',
  154. 'Hline',
  155. 'formula'
  156. ]
  157. this.EDITOR_CONFIG_ZW = [
  158. 'underline', // 下划线
  159. 'justify', // 对齐方式
  160. 'image', // 插入图片
  161. 'table', // 表格
  162. 'undo', // 撤销
  163. 'redo', // 重复
  164. 'lineheight',
  165. 'composition',
  166. 'Hline',
  167. 'formula'
  168. ]
  169. //题型配置 不定向选择 判断 作文 定位点c++
  170. this.questionTypeMapForPhp = {
  171. //0单选
  172. singleSelect: 0,
  173. //8多选
  174. moreSelect: 8,
  175. //填空
  176. fillInBlank: 3,
  177. //解答
  178. answer: 1,
  179. //选做
  180. chooseAnswer: 2,
  181. //必做题
  182. mustAnswer: 27,
  183. //不定项
  184. uncertainOption: 5
  185. }
  186. //类型 1 单选 2 多选 5 填空 7 解答 17 选做 11不定项 php
  187. this.questionTypeMapForC = {
  188. 1: 'singleSelect',
  189. 2: 'moreSelect',
  190. 11: 'uncertainOption',
  191. 5: 'fillInBlank',
  192. 7: 'shortAnswer',
  193. 27: 'mustAnswer',
  194. 17: 'chooseAnswer',
  195. '7c': 'composition'
  196. }
  197. //题型名称映射
  198. this.questionNameMap = {
  199. singleSelect: '单选题',
  200. moreSelect: '多选题',
  201. fillInBlank: '填空题',
  202. shortAnswer: '解答题',
  203. chooseAnswer: '选做题',
  204. uncertainOption: '不定项',
  205. mustAnswer: '必做题',
  206. composition: '作文'
  207. }
  208. //题型数据存储
  209. this.questionMap = []
  210. if (isNewBuild) {
  211. this.subjectId = subjectId
  212. } else {
  213. //全局groupId
  214. this.examGroupId = examGroupId || 0
  215. this.examIds = examIds
  216. this.schoolId = schoolId
  217. }
  218. //如果是创建考试,则唯一标识符 自定义,用来创建考试页面下载答题卡
  219. this.identifier = isNewBuild ? _symbolId() : self.examGroupId
  220. //当前区域定位信息,用来简单判断两次保存是否有改动,来防止重复提交数据
  221. this.saveLocationPosition = {}
  222. //首次保存
  223. this.alreadySave = false
  224. //当前答题卡模块是否在编辑状态--是否可以 编辑当前答题卡模板
  225. /**
  226. * 刚进页面
  227. * 1如果是之前没有保存,就属于编辑状态
  228. * 2如果之前有保存过,就属于保存在状态(页面所有操作按钮不可操作,需要点击编辑才可操作)
  229. * 页面中
  230. * 1如果点击了保存,就是保存状态
  231. */
  232. this.isCanEditCard = true
  233. //是否已经有打印的班级
  234. this.printClassStatus = false
  235. //题卡合一 的type值
  236. this.subjectCardToOneType = 1
  237. //是否需要题卡合一
  238. this.isSubjectInfoToCard = false
  239. //替换富文本没用内容
  240. this.replaceEditorRegexp = /(<p><br><\/p>)|(<div><br><\/div>)/g
  241. //所有打分框的分值上线标准
  242. this.answerScoreLimitKeyArr = [15, 16, 29, 49, 69]
  243. this.initDom()
  244. //初始化打印面积
  245. this.initPageStyle()
  246. //初始化页面渲染
  247. this.initPage()
  248. //解答题图片移动
  249. this.shortAnswerImgPositionChange()
  250. },
  251. tpls: PRINT_TPL,
  252. initPageStyle: function () {
  253. var self = this
  254. var $headEL = $('head')
  255. var $styleTag = $('#pageSizeStyle')
  256. self.pageHeight = self.unitConversion.mmConversionPx(self.config.height)
  257. self.pageWidth = self.unitConversion.mmConversionPx(self.config.width)
  258. if ($styleTag.length) $styleTag.remove()
  259. var initPrintPageStyle = self.tpls.printPageStyle.substitute({
  260. pageWidth: self.pageWidth / self.columns,
  261. pageHeight: self.pageHeight
  262. })
  263. $headEL.append(initPrintPageStyle)
  264. },
  265. /**
  266. * 初始化打印区域宽高 mm 转 px
  267. * 纸张方向,纸张大小,纸张分栏
  268. * 默认A3 两栏
  269. */
  270. initPrintContentArea: function () {
  271. var self = this
  272. self.initPageStyle()
  273. //列举属于小版面的配置,统一使用小版面的布局
  274. var isHorizontal = self.direction === 'horizontal'
  275. var isLayoutWhite = ~[
  276. 'A3-3',
  277. 'A4-2',
  278. 'A4-3',
  279. '8Ks-3',
  280. '8Kb-3',
  281. '16K-2',
  282. '16K-3'
  283. ].indexOf(self.paper + '-' + self.columns)
  284. var isSmallLayout = isHorizontal && isLayoutWhite
  285. self.$firstPageContent[isSmallLayout ? 'addClass' : 'removeClass'](
  286. 'smallLayout'
  287. )
  288. //判断第一页有没有题型模块,如果第一页没有题型模块,则直接跳到第二页做题型重排处理
  289. var hasSurplus = false
  290. var $secondPage = self.$firstPageContent.find('.examNumberLayout').next()
  291. var $secondPageFirstModule = $secondPage.find('.module').eq(0)
  292. var secondPageFirstModuleType = $secondPage
  293. .find('.answerModule')
  294. .eq(0)
  295. .attr('data-type')
  296. if (
  297. !$secondPage.length ||
  298. !$secondPageFirstModule.length ||
  299. !secondPageFirstModuleType
  300. ) {
  301. hasSurplus = true
  302. } else {
  303. var curpageSurplusHeight = self.getCurPageSurplusHeight(
  304. self.$firstPageContent
  305. )
  306. var nextPageFirstModuleHeight = self.getNextPageFirstModuleHeight(
  307. $secondPageFirstModule,
  308. secondPageFirstModuleType
  309. )
  310. hasSurplus = curpageSurplusHeight > nextPageFirstModuleHeight
  311. }
  312. self.changePrintArea(
  313. hasSurplus ? self.$firstPageContent : self.$firstPageContent.next()
  314. )
  315. self.editNoScoringWidth()
  316. },
  317. //render page
  318. initPage: function () {
  319. var self = this
  320. isShowPreview = window.location.href.indexOf('isPreview')
  321. isShowEdit = window.location.href.indexOf('isEdit')
  322. $('#hgc_print').height($(window).height())
  323. if (isNewBuild) {
  324. $('.switch_ewm').hide()
  325. self.initPageForNewBuild()
  326. } else {
  327. self.getTopicDetails()
  328. }
  329. if (isShowPreview > -1) {
  330. setTimeout(function () {
  331. self.previewPrintDiv('printcontent')
  332. }, 200)
  333. }
  334. if (isShowEdit > -1) {
  335. setTimeout(function () {
  336. self.isCanEditCard = false
  337. self.changeCardEditStatus()
  338. }, 200)
  339. }
  340. if(localStorage.examStatus && isShowEdit > -1){
  341. let examStatus = JSON.parse(localStorage.getItem('examStatus'));
  342. if(examStatus==2){
  343. $('#saveBtn').unbind();
  344. $('#saveBtn').addClass('disabled')
  345. }
  346. }
  347. },
  348. //创建答题卡部分-----------------------------------
  349. //get buildQuestions
  350. getBuildQuestions: function () {
  351. var self = this
  352. // 当前的数据包
  353. // var originQuestions = localStorage.getItem('buildQuestions')
  354. var localSavePrintInfo = localStorage.getItem('savePrintInfo')
  355. var localBuildQuestions = localSavePrintInfo ? JSON.parse(localSavePrintInfo) : {}
  356. var buildQuestions = localBuildQuestions.position ? self.reTopicNum(localBuildQuestions.position.buildQuestions) : {}
  357. // var buildQuestions = originQuestions ? JSON.parse(originQuestions) : {}
  358. if (isShowPreview > -1) {
  359. buildQuestions = JSON.parse(localStorage.getItem('previewBuildQuestions'))
  360. }
  361. if(localBuildQuestions.position){
  362. self.rePagesId(localBuildQuestions.position.pages)
  363. self.reQuestionInfoNum(localBuildQuestions.question_info.content)
  364. }
  365. self.questionMap = buildQuestions
  366. self.setBuildQuestions()
  367. return buildQuestions
  368. },
  369. reTopicNum: function(data){
  370. jQuery.each(data, function (i, bigTopicData){
  371. jQuery.each(bigTopicData.questions, function (i, minTopicData){
  372. minTopicData.questionNum = minTopicData.alias
  373. })
  374. jQuery.each(bigTopicData.pages, function (i, pages){
  375. jQuery.each(pages, function (i, pages){
  376. pages.questionNum = pages.alias
  377. })
  378. })
  379. })
  380. return data
  381. },
  382. rePagesId: function(data){
  383. jQuery.each(data, function (i, page){
  384. jQuery.each(page.questions, function (i, minTopicData){
  385. minTopicData.id = minTopicData.name
  386. })
  387. })
  388. },
  389. reQuestionInfoNum: function(data){
  390. jQuery.each(data, function (i, minTopicData){
  391. minTopicData.questionNum = minTopicData.alias
  392. })
  393. },
  394. setBuildQuestions: function () {
  395. localStorage.setItem('buildQuestions', JSON.stringify(this.questionMap))
  396. },
  397. //获取记忆配置信息
  398. getMemoryPosition: function () {
  399. var self = this
  400. var originPosition = JSON.parse(localStorage.getItem('position'))
  401. var savePrintInfoData = JSON.parse(localStorage.getItem('savePrintInfo'))
  402. savePrintInfoData = savePrintInfoData ? savePrintInfoData : {}
  403. originPosition = originPosition ? originPosition : savePrintInfoData.position
  404. var position = originPosition ? originPosition : {}
  405. return position
  406. },
  407. initPageForNewBuild: function () {
  408. var self = this
  409. localStorage.removeItem('position');
  410. localStorage.removeItem('buildQuestions');
  411. $('#addQustionBtn').show()
  412. self.getExamNumConfig()
  413. // 当前的数据包
  414. var buildQuestions = self.getBuildQuestions()
  415. if ($.isEmptyObject(buildQuestions)) {
  416. $('.addTips').show();
  417. } else {
  418. $('.addTips').hide();
  419. }
  420. /**
  421. * //如果是创建考试,则唯一标识符 自定义,用来创建考试页面下载答题卡
  422. var identifier = isNewBuild?_symbolId():self.examGroupId;
  423. */
  424. //先进行配置话记忆 --- 正常流式布局 --- 然后记忆布局
  425. var res = self.getMemoryPosition()
  426. // if (Object.keys(buildQuestions).length) {
  427. // //初始化内容区域,所有的pages 归1
  428. // self.renderSubjectInfo(
  429. // self.renderSubjectDataFormatForNewCard(buildQuestions)
  430. // )
  431. // //重新定义超出部分布局
  432. // self.changePrintArea(self.$firstPageContent)
  433. // }
  434. self.bindEvent()
  435. self.initEvent()
  436. if (Object.keys(res).length) {
  437. self.memoryLayout(res)
  438. }
  439. if (Object.keys(buildQuestions).length) {
  440. //初始化内容区域,所有的pages 归1
  441. self.renderSubjectInfo(
  442. self.renderSubjectDataFormatForNewCard(buildQuestions)
  443. )
  444. //重新定义超出部分布局
  445. self.changePrintArea(self.$firstPageContent)
  446. }
  447. if (Object.keys(res).length) {
  448. self.memoryLayout(res)
  449. }
  450. },
  451. reInitPageForNewBuild: function () {
  452. var self = this
  453. // $('#addQustionBtn').show()
  454. // self.getExamNumConfig()
  455. // 当前的数据包
  456. var buildQuestions = self.questionMap
  457. /**
  458. * //如果是创建考试,则唯一标识符 自定义,用来创建考试页面下载答题卡
  459. var identifier = isNewBuild?_symbolId():self.examGroupId;
  460. */
  461. // printcontent
  462. $('#printcontent').find('.pageContent').each(function (index) {
  463. if (index === 0) {
  464. $(this).find('.dtk-content').find('.answerModule').remove();
  465. } else {
  466. $(this).remove();
  467. }
  468. })
  469. self.totalPage = 1
  470. $(".pageContent .totalPage").html(self.totalPage)
  471. // 试题删除后 隐藏右边操作栏试题显示
  472. if ($('.answerModule').length > 0) {
  473. $('#subjectList').html(listHtml)
  474. } else {
  475. $('#subjectList').html('')
  476. }
  477. //先进行配置话记忆 --- 正常流式布局 --- 然后记忆布局
  478. var res = self.getMemoryPosition()
  479. if (Object.keys(buildQuestions).length) {
  480. //初始化内容区域,所有的pages 归1
  481. self.renderSubjectInfo(
  482. self.renderSubjectDataFormatForNewCard(buildQuestions)
  483. )
  484. //重新定义超出部分布局
  485. self.changePrintArea(self.$firstPageContent)
  486. }
  487. // self.bindEvent()
  488. // self.initEvent()
  489. if (Object.keys(res).length) {
  490. self.memoryLayout(res)
  491. }
  492. },
  493. getExamNumConfig: function () {
  494. var self = this
  495. $.post(
  496. self.apis.getExamNumberConfigApi, {
  497. grade: localStorage.getItem('grade')
  498. },
  499. function (res) {
  500. var result = JSON.parse(res)
  501. if (result.success === 1) {
  502. //初始化默认title
  503. var savePrintInfoData = JSON.parse(localStorage.getItem('savePrintInfo'))
  504. var testFormData = JSON.parse(localStorage.getItem('testFormData'))
  505. var paperName = ''
  506. self.cardStatus = result.data.card_status
  507. if (savePrintInfoData != null) {
  508. paperName = savePrintInfoData.title
  509. if (paperName == undefined) {
  510. paperName = testFormData ? testFormData.examName : ''
  511. }
  512. } else {
  513. paperName = testFormData ? testFormData.examName : ''
  514. }
  515. self.renderExamBaseInfo({
  516. school_card_length: +result.data.card_length,
  517. school_card_status: 1,
  518. paperName: paperName,
  519. wpTimes: 90,
  520. fullScore: '',
  521. wpAuthor: '',
  522. wpReviewer: '',
  523. })
  524. self.editNoticeDetail(self.useQrCode,result.data.card_status)
  525. }
  526. }
  527. )
  528. },
  529. editNoticeDetail: function (qrStatus,cardStatus) {
  530. let noticeDetailMsgBoxXT =
  531. '<p>1、考生务必正确书写班级、姓名,请填涂系统准考证号。</p>' +
  532. '<p>2、考生务必用2B铅笔填涂。</p>' +
  533. '<p>3、考生务必在答题卡指定位置作答,并保持卷面整洁。</p>' +
  534. '<p>4、如需要条形码,则考生务必要在指定位置正确贴好条形码。</p>' +
  535. '<p>5、教师务必使用红笔阅卷。</p>';
  536. let noticeDetailMsgBoxXX =
  537. '<p>1、考生务必正确书写班级、姓名,请填涂学校准考证号。</p>' +
  538. '<p>2、考生务必用2B铅笔填涂。</p>' +
  539. '<p>3、考生务必在答题卡指定位置作答,并保持卷面整洁。</p>' +
  540. '<p>4、如需要条形码,则考生务必要在指定位置正确贴好条形码。</p>' +
  541. '<p>5、教师务必使用红笔阅卷。</p>';
  542. let noticeDetailMsgBoxQR =
  543. '<p>1、考生务必用2B铅笔填涂。</p>' +
  544. '<p>2、考生务必在答题卡指定位置作答,并保持卷面整洁。</p>' +
  545. '<p>3、如需要条形码,则考生务必要在指定位置正确贴好条形码。</p>' +
  546. '<p>4、教师务必使用红笔阅卷。</p>';
  547. if(qrStatus){
  548. $('#noticeDetailMsgBox').html(noticeDetailMsgBoxQR)
  549. } else {
  550. $('#noticeDetailMsgBox').html(cardStatus==0 ? noticeDetailMsgBoxXT : noticeDetailMsgBoxXX)
  551. }
  552. },
  553. //创建答题卡部分-----------------------------------
  554. getTopicDetails: function () {
  555. var self = this
  556. //如果之前保存过,则需要记忆之前的答题卡排版
  557. $.post(
  558. self.apis.getTopicsDetailAPi, {
  559. examGroupId: self.examGroupId
  560. },
  561. function (res) {
  562. res = JSON.parse(res)
  563. if (res.success) {
  564. //判断是否已经保存过,如果已经保存过,需要记忆布局
  565. self.alreadySave = res.position ? true : false
  566. //判断是否题卡合一
  567. self.isSubjectInfoToCard =
  568. res.paperTplType == self.subjectCardToOneType
  569. if (self.alreadySave) {
  570. var memoryPosition = JSON.parse(res.position)
  571. self.saveLocationPosition = res.position
  572. self.memoryColumns = memoryPosition.columns
  573. self.isCanEditCard = false
  574. //是否已经有打印班级
  575. self.printClassStatus = res.printClassStatus
  576. self.initPrintContentArea()
  577. self.renderPage(res, memoryPosition)
  578. self.memoryLayout(memoryPosition)
  579. self.changeCardEditStatus()
  580. } else {
  581. self.isCanEditCard = true
  582. self.renderPage(res)
  583. self.changeCardEditStatus()
  584. }
  585. } else {
  586. hgc_layer.msg('获取试卷题目信息失败')
  587. }
  588. }
  589. )
  590. },
  591. /*
  592. --------------------------------------------------------------------------------------------------------------------
  593. 初始页面布局功能开始
  594. ---------------------------------------------------------------------------------------------------------------------
  595. */
  596. renderPage: function (renderJSON, memoryPosition) {
  597. var self = this
  598. memoryPosition = memoryPosition || null
  599. self.renderExamBaseInfo(renderJSON.object)
  600. //格式化题型题号信息 -- 可重复执行
  601. self.renderSubjectInfo(
  602. self.renderSubjectDataFormat(renderJSON.object.questions),
  603. memoryPosition
  604. )
  605. if (!self.alreadySave) {
  606. //重新定义超出部分布局
  607. self.changePrintArea(self.$firstPageContent)
  608. }
  609. self.bindEvent()
  610. self.initEvent()
  611. },
  612. //渲染答题卡基本信息 准考证号、名称、考试时间等
  613. renderExamBaseInfo: function (examInfo) {
  614. var self = this
  615. //答题卡题目类型
  616. self.$dtkName.val(examInfo.paperName)
  617. // var examInfoHtml = self.tpls.examInfoTpl.substitute(examInfo)
  618. // $('#examInfo').html(examInfoHtml)
  619. // self.examInfoConfigText.wpTimes = examInfo.wpTimes
  620. // self.examInfoConfigText.fullScore = examInfo.fullScore
  621. // self.examInfoConfigText.wpAuthor = examInfo.wpAuthor
  622. // self.examInfoConfigText.wpReviewer = examInfo.wpReviewer
  623. let examInfoConfigText = {
  624. wpTimes: examInfo.wpTimes,
  625. fullScore: examInfo.fullScore,
  626. wpAuthor: examInfo.wpAuthor,
  627. wpReviewer: examInfo.wpReviewer
  628. }
  629. self.examInfoConfigText = examInfoConfigText
  630. self.showExamInfoHtml()
  631. //准考证号信息
  632. self.renderExamNumberInfo(examInfo)
  633. },
  634. //准考证号信息
  635. renderExamNumberInfo: function (examInfo) {
  636. var self = this
  637. //准考证号类型 1学校准考证 0系统准考证
  638. self.school_card_status = examInfo.school_card_status
  639. //准考证号长度
  640. var school_card_length = examInfo.school_card_length
  641. var examNumberHtml = ''
  642. var examNumberForOnlyCodeHtml = ''
  643. for (var colIndex = 0; colIndex < school_card_length; colIndex++) {
  644. examNumberHtml += self.tpls.examNumberItemTpl
  645. examNumberForOnlyCodeHtml += '<span></span>'
  646. }
  647. $('#hgc_examNumber .ticketNumber').html(examNumberHtml)
  648. $('#hgc_examNumberForOnlyBarcode .ticketNumber p').html(
  649. examNumberForOnlyCodeHtml
  650. )
  651. },
  652. renderSubjectDataFormat: function (questions) {
  653. var self = this
  654. //大题分类
  655. var curGuid = ''
  656. var questionClassify = {}
  657. self.questionMap = questionClassify
  658. questions.forEach(function (question, index) {
  659. var curType = self.questionTypeMapForC[question.questionTypeId]
  660. var prevIndex = index - 1
  661. var prevQuestionTypeId = questions[prevIndex] ?
  662. questions[prevIndex].questionTypeId :
  663. ''
  664. var prevType = prevQuestionTypeId ?
  665. self.questionTypeMapForC[prevQuestionTypeId] :
  666. ''
  667. //如果之前的题型type和现在的题型type不一样,新建一个key做大题类型
  668. if (prevType !== curType) {
  669. curGuid = guid()
  670. questionClassify[curGuid] = {
  671. questions: [question]
  672. }
  673. } else {
  674. questionClassify[curGuid].questions.push(question)
  675. }
  676. })
  677. var titleTPls = {
  678. singleSelect: '、选择题<span>(本大题共{subjectCount}小题,{subjectPointText}共{totalPoint}分。在每小题给出的四个选项中,只有一项是符合题目要求的。把答案填涂在答题卡上。)</span>',
  679. moreSelect: '、多选题<span>(本大题共{subjectCount}小题,{subjectPointText}共{totalPoint}分。在每小题给出的四个选项中,有两项及以上是符合题目要求的。把答案填涂在答题卡上。)</span>',
  680. fillInBlank: '、填空题<span>(本大题共{subjectCount}小题,{subjectPointText}共{totalPoint}分。把答案填写在答题卡相应的题号后的横线上。)</span>',
  681. shortAnswer: '、解答题<span>(本大题共{subjectCount}小题,{subjectPointText}共{totalPoint}分。解答写出相应的文字说明、证明过程或演算步骤。)</span>',
  682. chooseAnswer: '、选做题<span>(本题包括{chooseOption}{chooseOptionLength}小题,请选定其中{chooseCount}小题,并在相应的答题区域内作答,请用2B铅笔涂黑(示例:■)。若多做,则按作答的前一小题评分。解答应写出文字说明、证明过程或演算步骤。)</span><div class="originSubjectInfo">{chooseSubjectContent}</div>',
  683. mustAnswer: '、必做题<span>(本大题共{subjectCount}小题,{subjectPointText}共{totalPoint}分。解答写出相应的文字说明、证明过程或演算步骤。)</span>'
  684. //一、选做题( 本题包括A、B两小题,请选定其中一小题,并在相应的答题区域内作答,请用2B铅笔涂黑(示例:■)。若多做,则按作答的前一小题评分。解答应写出文字说明、证明过程或演算步骤。)
  685. }
  686. var objectiveTitleTpl = {
  687. singleSelect: '、选择题题文',
  688. moreSelect: '、多选题题文',
  689. fillInBlank: '、填空题题文'
  690. }
  691. //填空题,选择题超出控制数据
  692. var numberIndex = 0
  693. for (var uid in questionClassify) {
  694. var questionClassifyItem = questionClassify[uid]
  695. //题型单个大题下面所有小题
  696. var questionClassifyItemQuestions = questionClassifyItem.questions
  697. var typeId = questionClassifyItem.questions[0].questionTypeId
  698. var type = self.questionTypeMapForC[typeId]
  699. questionClassifyItem.questionType = typeId
  700. numberIndex++
  701. var titleFormatData = {}
  702. var isChooseAnswer = type === 'chooseAnswer'
  703. var isMoreSelect = type === 'moreSelect'
  704. //选做题题干信息
  705. var chooseSubjectContent = ''
  706. //选做题标题特殊对待
  707. if (isChooseAnswer) {
  708. var chooseOptionLength = SectionToChinese(
  709. questionClassifyItemQuestions.length
  710. )
  711. var chooseOption = questionClassifyItemQuestions
  712. .map(function (questionItem, index) {
  713. chooseSubjectContent +=
  714. '<div class="questionItemBody"><b>' +
  715. questionItem.questionNum +
  716. '、</b>' +
  717. questionItem.queBody +
  718. '</div>'
  719. return String.fromCharCode(65 + index)
  720. }, [])
  721. .join(',')
  722. var chooseCount = SectionToChinese(
  723. questionClassifyItemQuestions[0].required
  724. )
  725. titleFormatData = {
  726. chooseOption: chooseOption,
  727. chooseCount: chooseCount === '二' ? '两' : chooseCount,
  728. chooseOptionLength: chooseOptionLength === '二' ? '两' : chooseOptionLength
  729. }
  730. } else {
  731. var subjectCount = questionClassifyItemQuestions.length
  732. var subjectPoint = questionClassifyItemQuestions[0].fullScore
  733. var totalPoint = 0
  734. var isSameScore = questionClassifyItemQuestions.every(function (item) {
  735. return item.fullScore === subjectPoint
  736. })
  737. var subjectPointText = ''
  738. if (isSameScore) {
  739. subjectPointText = '每小题{subjectPoint}分,'.substitute({
  740. subjectPoint: subjectPoint
  741. })
  742. totalPoint = subjectPoint * subjectCount
  743. } else {
  744. subjectPointText = questionClassifyItemQuestions.reduce(
  745. (total, cur) => {
  746. total += '第{questionNum}题{fullScore}分,'.substitute(cur)
  747. totalPoint += cur.fullScore
  748. return total
  749. },
  750. ''
  751. )
  752. }
  753. titleFormatData = {
  754. subjectCount: subjectCount,
  755. subjectPoint: subjectPoint,
  756. totalPoint: totalPoint,
  757. subjectPointText: subjectPointText
  758. }
  759. }
  760. //如果需要题卡合一的话
  761. //选做题的题干信息不可编辑
  762. if (self.isSubjectInfoToCard && isChooseAnswer) {
  763. titleFormatData.chooseSubjectContent =
  764. '<div class="originSubjectInfo">' + chooseSubjectContent + '</div>'
  765. }
  766. //试卷大题默认title 如果是接口传入,则使用接口传入的字段
  767. questionClassifyItem.bigTitle =
  768. SectionToChinese(numberIndex) +
  769. titleTPls[type].substitute(titleFormatData)
  770. //题干信息title---只针对客观题
  771. if (objectiveTitleTpl[type]) {
  772. questionClassifyItem.objectiveTitle =
  773. '<h3>' +
  774. SectionToChinese(numberIndex) +
  775. objectiveTitleTpl[type] +
  776. '</h3>'
  777. }
  778. questionClassifyItem.pages = {
  779. page1: simpleCopy(questionClassifyItemQuestions),
  780. page2: []
  781. }
  782. }
  783. return questionClassify
  784. },
  785. //所有的pages 数据归1
  786. renderSubjectDataFormatForNewCard: function (buildQuestions) {
  787. var self = this
  788. for (var modelId in buildQuestions) {
  789. var buildQuestionsItem = buildQuestions[modelId]
  790. var allPageData = []
  791. for (var page in buildQuestionsItem.pages) {
  792. allPageData = allPageData.concat(buildQuestionsItem.pages[page])
  793. }
  794. buildQuestionsItem.pages = {
  795. page1: allPageData,
  796. page2: []
  797. }
  798. }
  799. return buildQuestions
  800. },
  801. titleHtml: function (title) {
  802. var self = this
  803. return title ? self.tpls.moduleTitleTpl.substitute({
  804. title: title
  805. }) : ''
  806. },
  807. //渲染答题卡题目题型信息
  808. renderSubjectInfo: function (questionClassify, memoryPosition) {
  809. var self = this
  810. //渲染右侧操作栏 题目列表信息 -- 可重复执行
  811. self.renderSubjectListInfo(questionClassify)
  812. //保存题目定位点的时候 获取 题目数量 分数 等信息 -- 可重复执行
  813. self.getSaveSubjectInfo(questionClassify)
  814. //批量渲染所有题型模块
  815. if (!self.firstEnterPage) return
  816. var dtkContentEl = $('.dtk-content')
  817. for (var uid in questionClassify) {
  818. var questionClassifyItem = questionClassify[uid]
  819. var questionType = questionClassifyItem.questionType
  820. var subjectType = self.questionTypeMapForC[questionType]
  821. questionClassifyItem.modelId = uid
  822. if (subjectType === 'shortAnswer' && !isNewBuild) {
  823. //或者一开始进来就是题卡合一
  824. if (!self.alreadySave && self.isSubjectInfoToCard) {
  825. self.renderObjective()
  826. //有记忆的时候先渲染题卡合一,主要是缓存原题干信息内容
  827. } else if (
  828. memoryPosition &&
  829. memoryPosition.stemInfo &&
  830. memoryPosition.stemInfo.length
  831. ) {
  832. self.renderObjective()
  833. }
  834. }
  835. self[subjectType + 'Render'](questionClassifyItem, dtkContentEl)
  836. }
  837. },
  838. //右侧题目列表模块-布局
  839. renderSubjectListInfo: function (questionClassify) {
  840. var self = this
  841. var listItemTpl =
  842. '<div class="paper selOptions"><span class="name ">{name}</span><div class="content_wrap">{quantityList}</div></div>'
  843. var listItemNoTpl =
  844. '<div class="content s_num">{quantityStart}~{quantityEnd}</div>'
  845. var listItemNoXzTpl =
  846. '<div class="content s_num">{quantityStart}</div>'
  847. var listHtml = ''
  848. for (var uid in questionClassify) {
  849. let questions = questionClassify[uid].questions
  850. let configData = questionClassify[uid].commonFields
  851. if (!questions[0]) continue
  852. let listItemNoHtml = ''
  853. jQuery.each(configData.questionTypeArr, function (i, configItem) {
  854. let Start = configItem.startNo
  855. let End = configItem.endNo
  856. if (configData.questionType == 17) {
  857. listItemNoHtml += listItemNoXzTpl.substitute({
  858. quantityStart: Start
  859. })
  860. } else {
  861. listItemNoHtml += listItemNoTpl.substitute({
  862. quantityStart: Start,
  863. quantityEnd: End
  864. })
  865. }
  866. });
  867. let questionType = questionClassify[uid].questionType
  868. if (questionType == 7) {
  869. questionType = questionClassify[uid].markQuestionType
  870. }
  871. listHtml += listItemTpl.substitute({
  872. name: self.questionNameMap[self.questionTypeMapForC[questionType]],
  873. quantityList: listItemNoHtml
  874. })
  875. }
  876. $('#subjectList').html(listHtml)
  877. },
  878. /**
  879. —————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  880. 客观题题干内容渲染 开始 —————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  881. */
  882. renderObjective: function (cb) {
  883. var self = this
  884. questionClassify = self.questionMap
  885. self.originStemInfos = []
  886. //,'shortAnswer','chooseAnswer','mustAnswer'
  887. var quesTypeOrder = ['fillInBlank', 'moreSelect', 'singleSelect']
  888. function getDataFromSubjectType(subjectType) {
  889. var subjectData
  890. for (var uid in questionClassify) {
  891. var questionType = questionClassify[uid].questionType
  892. if (self.questionTypeMapForC[questionType] === subjectType) {
  893. subjectData = questionClassify[uid].pages
  894. break
  895. }
  896. }
  897. return subjectData
  898. }
  899. //判断第一次出现的分页
  900. var lastPageIndex
  901. var lastPageType
  902. quesTypeOrder.forEach(function (type) {
  903. if (lastPageType) return
  904. var subjectData = getDataFromSubjectType(type)
  905. if (subjectData) {
  906. var pageIndex = Object.keys(subjectData).length
  907. function getLastPageIndex() {
  908. var pageData = subjectData['page' + pageIndex]
  909. if (pageData && pageData.length) {
  910. lastPageIndex = pageIndex
  911. lastPageType = type
  912. } else {
  913. pageIndex--
  914. getLastPageIndex()
  915. }
  916. }
  917. getLastPageIndex()
  918. }
  919. })
  920. //找到最后一个分页处理
  921. var $afterPage = $('.pageContent').eq(lastPageIndex - 1)
  922. var $afterContent = $afterPage.children('.dtk-content')
  923. var $afterModule
  924. //根据type 来判断题干信息该放在哪个元素后面
  925. if (lastPageType === 'fillInBlank') {
  926. $afterModule = $afterContent.children('.completion-topic')
  927. } else if (lastPageType === 'moreSelect') {
  928. $afterModule = $afterContent.children('.moreSelect')
  929. } else if (lastPageType === 'singleSelect') {
  930. $afterModule = $afterContent.children('.single-select:last()')
  931. }
  932. quesTypeOrder.forEach(function (quesType) {
  933. //找到对应的模块,所有的主观题的题干信息
  934. var quesTypeData
  935. for (var modelId in questionClassify) {
  936. var questionClassItem = questionClassify[modelId]
  937. var typeId = questionClassItem.questionType
  938. var type = self.questionTypeMapForC[typeId]
  939. if (type === quesType) {
  940. quesTypeData = questionClassItem
  941. break
  942. }
  943. }
  944. if (quesTypeData.questions && quesTypeData.questions.length) {
  945. self[quesType + 'StemRender'](quesTypeData, $afterModule)
  946. }
  947. })
  948. //图片加载时间
  949. self.judegeImgsLoaded('.objectiveItem')
  950. cb && cb($afterPage)
  951. },
  952. //公式自带的行内样式转换mm
  953. changeUnitForFormulaPic: function (parent, type) {
  954. var self = this
  955. parent = parent || $('.answerModule')
  956. parent.find('img').each(function () {
  957. var oh = $(this).attr('height')
  958. var ow = $(this).attr('width')
  959. if (!/^\d+$/.test(oh) || !/^\d+$/.test(ow)) return
  960. var widthMatch = $(this)[0].outerHTML.match(/width="(\d{1,3})"/) || [0, 0]
  961. var heightMatch = $(this)[0].outerHTML.match(/height="(\d{1,3})"/) || [
  962. 0,
  963. 0
  964. ]
  965. var pxWidth = +widthMatch[1]
  966. var pxHeight = +heightMatch[1]
  967. if (!pxWidth && !pxHeight) return
  968. //给你图片最大宽度的阀值
  969. var isMaxWidth = pxWidth > 430
  970. var mmWidth = self.unitConversion.pxConversionMm(pxWidth) + 'mm'
  971. var mmHeight =
  972. type === 'origin' || !isMaxWidth
  973. ? self.unitConversion.pxConversionMm(pxHeight) + 'mm'
  974. : 'auto'
  975. var originStyle = $(this).attr('style') || ''
  976. $(this).attr(
  977. 'style',
  978. originStyle +
  979. ';width:' +
  980. mmWidth +
  981. ';height:' +
  982. mmHeight +
  983. ';max-width:100%;'
  984. )
  985. })
  986. },
  987. queBodyRegExp: /^<p([^<]*)>/,
  988. singleSelectStemRender: function (questionClassItem, $afterModule) {
  989. var self = this
  990. var htmls = questionClassItem.objectiveTitle
  991. var data = questionClassItem.questions
  992. var stemInfos = []
  993. data.forEach(function (item) {
  994. //一排排列几个
  995. //0一排一个 1一排4个 2一排两个',
  996. var columnNumber =
  997. typeof item.listType === 'number'
  998. ? !item.listType
  999. ? 1
  1000. : item.listType === 1
  1001. ? 4
  1002. : 2
  1003. : ''
  1004. var columnClass = columnNumber ? 'column-' + columnNumber : ''
  1005. var content = item.queBody.replace(
  1006. self.queBodyRegExp,
  1007. '<p' + RegExp.$1 + '><span>' + item.questionNum + '、</span>'
  1008. )
  1009. var optionsHtml =
  1010. '<div class="optionObjectiveWrap clearfix ' + columnClass + '">'
  1011. item.queOptions.forEach(function (option, index) {
  1012. optionsHtml +=
  1013. '<div class="optionItemObjective fl"><p>' +
  1014. String.fromCharCode(65 + index) +
  1015. '.</p>' +
  1016. option.content +
  1017. '</div>'
  1018. })
  1019. optionsHtml += '</div>'
  1020. var stemItemHtml = self.tpls.objectiveItemTpl.substitute({
  1021. content: content,
  1022. options: optionsHtml
  1023. })
  1024. //如果是题卡合一并且是保存状态的时候 才会保存原题信息
  1025. if (self.isSubjectInfoToCard) {
  1026. stemInfos.push(encodeURIComponent(stemItemHtml))
  1027. }
  1028. htmls += stemItemHtml
  1029. })
  1030. self.originStemInfos = stemInfos.concat(self.originStemInfos)
  1031. htmls = self.tpls.objectiveWrapTpl.substitute({
  1032. editModule: htmls
  1033. })
  1034. $afterModule.after(htmls)
  1035. },
  1036. moreSelectStemRender: function (questionClassItem, $afterModule) {
  1037. var self = this
  1038. var htmls = questionClassItem.objectiveTitle
  1039. var data = questionClassItem.questions
  1040. var stemInfos = []
  1041. data.forEach(function (item) {
  1042. var columnNumber =
  1043. typeof item.listType === 'number'
  1044. ? !item.listType
  1045. ? 1
  1046. : item.listType === 1
  1047. ? 4
  1048. : 2
  1049. : ''
  1050. var columnClass = columnNumber ? 'column-' + columnNumber : ''
  1051. var content = item.queBody.replace(
  1052. self.queBodyRegExp,
  1053. '<p' + RegExp.$1 + '><span>' + item.questionNum + '、</span>'
  1054. )
  1055. var optionsHtml =
  1056. '<div class="optionObjectiveWrap clearfix ' + columnClass + '">'
  1057. item.queOptions.forEach(function (option, index) {
  1058. optionsHtml +=
  1059. '<div class="optionItemObjective fl"><p>' +
  1060. String.fromCharCode(65 + index) +
  1061. '.</p>' +
  1062. option.content +
  1063. '</div>'
  1064. })
  1065. optionsHtml += '</div>'
  1066. var stemItemHtml = self.tpls.objectiveItemTpl.substitute({
  1067. content: content,
  1068. options: optionsHtml
  1069. })
  1070. //如果是题卡合一并且是保存状态的时候 才会保存原题信息
  1071. if (self.isSubjectInfoToCard) {
  1072. stemInfos.push(encodeURIComponent(stemItemHtml))
  1073. }
  1074. htmls += stemItemHtml
  1075. })
  1076. self.originStemInfos = stemInfos.concat(self.originStemInfos)
  1077. htmls = self.tpls.objectiveWrapTpl.substitute({
  1078. editModule: htmls
  1079. })
  1080. $afterModule.after(htmls)
  1081. },
  1082. fillInBlankStemRender: function (questionClassItem, $afterModule) {
  1083. var self = this
  1084. var htmls = questionClassItem.objectiveTitle
  1085. var data = questionClassItem.questions
  1086. var stemInfos = []
  1087. data.forEach(function (item) {
  1088. var content = item.queBody.replace(
  1089. self.queBodyRegExp,
  1090. '<p' + RegExp.$1 + '><span>' + item.questionNum + '、</span>'
  1091. )
  1092. var stemItemHtml = self.tpls.objectiveItemTpl.substitute({
  1093. content: content
  1094. })
  1095. //如果是题卡合一并且是保存状态的时候 才会保存原题信息
  1096. if (self.isSubjectInfoToCard) {
  1097. stemInfos.push(encodeURIComponent(stemItemHtml))
  1098. }
  1099. htmls += stemItemHtml
  1100. })
  1101. htmls = self.tpls.objectiveWrapTpl.substitute({
  1102. editModule: htmls
  1103. })
  1104. self.originStemInfos = stemInfos.concat(self.originStemInfos)
  1105. $afterModule.after(htmls)
  1106. },
  1107. /**
  1108. * —————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  1109. 主观题题干内容渲染 结束 —————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  1110. */
  1111. getSingleSelectHtml: function (datas, type) {
  1112. var self = this
  1113. //判断是否多选
  1114. var isMoreSelect = type === 'more'
  1115. var moreSelectClass = isMoreSelect ? 'more-option' : ''
  1116. var singleSelectHtml = ''
  1117. var singleColHtml = ''
  1118. datas.forEach(function (singleItem, index) {
  1119. var singleContent = ''
  1120. for (var i = 0; i < singleItem.optionCount; i++) {
  1121. var option = String.fromCharCode(65 + i)
  1122. singleContent += '<span data-option="{option}">[<i>{option}</i>]</span>'.substitute(
  1123. { option: option }
  1124. )
  1125. }
  1126. singleColHtml += self.tpls.singleSelectOptionTpl.substitute({
  1127. _index: ++index,
  1128. singleContent: singleContent,
  1129. questionNum: singleItem.questionNum,
  1130. answer: singleItem.answer,
  1131. alias: singleItem.alias
  1132. })
  1133. if (!(index % 5)) {
  1134. singleSelectHtml +=
  1135. '<ul class="single-option ' +
  1136. moreSelectClass +
  1137. ' clearfix">' +
  1138. singleColHtml +
  1139. '</ul>'
  1140. singleColHtml = ''
  1141. }
  1142. })
  1143. singleSelectHtml +=
  1144. !datas.length % 5
  1145. ? ''
  1146. : '<ul class="single-option ' +
  1147. moreSelectClass +
  1148. ' clearfix">' +
  1149. singleColHtml +
  1150. '</ul>'
  1151. return singleSelectHtml
  1152. },
  1153. /**
  1154. * @param {多选 or 单选} title
  1155. * @param {选择题布局方向} direction
  1156. * @param {选择题内容} selectContent
  1157. */
  1158. getSelectRenderContent: function (data) {
  1159. //selectContent, title, direction,hasTitle
  1160. var self = this
  1161. data.settingBtn =
  1162. typeof data.settingBtn === 'boolean' ? data.settingBtn : true
  1163. /**
  1164. * vertical 竖向布局
  1165. * horizontal 横向布局
  1166. */
  1167. var direction = data.direction || 'vertical'
  1168. var hasTitle = typeof data.hasTitle === 'undefined' ? true : data.hasTitle
  1169. var SingleSelectModuleHtml = self.tpls.selectTpl.substitute({
  1170. title: hasTitle ? self.titleHtml(data.bigTitle) : '',
  1171. direction: direction,
  1172. moduleType: data.moduleType,
  1173. selectContent: data.selectContent,
  1174. modelId: data.modelId,
  1175. settingBtn: data.settingBtn
  1176. ? '<div class="settingBtn" data-type="{moduleType}"></div>'.substitute({
  1177. moduleType: data.title
  1178. })
  1179. : ''
  1180. })
  1181. return SingleSelectModuleHtml
  1182. },
  1183. //单选题--布局
  1184. // {
  1185. // bigTitle:'',
  1186. // question:[]
  1187. // }
  1188. getDirection: function (direction) {
  1189. if (typeof direction === 'number') {
  1190. return direction ? 'vertical' : 'horizontal'
  1191. } else {
  1192. return direction ? direction : 'vertical'
  1193. }
  1194. },
  1195. singleSelectRender: function (questionModelData, appendEl, replaceEl) {
  1196. var self = this
  1197. var datas = questionModelData.questions
  1198. var modelId = questionModelData.modelId
  1199. var direction = self.getDirection(questionModelData.direction)
  1200. var singleSelectHtml = self.getSingleSelectHtml(datas, 'single')
  1201. //selectContent, title, direction,hasTitle
  1202. var SingleSelectModuleHtml = self.getSelectRenderContent({
  1203. selectContent: singleSelectHtml,
  1204. moduleType: 'singleSelect',
  1205. bigTitle: questionModelData.bigTitle,
  1206. modelId: modelId,
  1207. direction: direction
  1208. })
  1209. if (replaceEl) {
  1210. replaceEl[0].outerHTML = SingleSelectModuleHtml
  1211. var $settingBtn = self.getSettingBtn(modelId)
  1212. self.selectStyleChange($settingBtn, direction)
  1213. } else {
  1214. appendEl.append(SingleSelectModuleHtml)
  1215. }
  1216. },
  1217. //多选题--布局
  1218. moreSelectRender: function (questionModelData, appendEl, replaceEl) {
  1219. var self = this
  1220. var datas = questionModelData.questions
  1221. var modelId = questionModelData.modelId
  1222. var direction = self.getDirection(questionModelData.direction)
  1223. //获取选项html
  1224. var singleSelectHtml = self.getSingleSelectHtml(datas, 'more')
  1225. //获取整个选择题区域模块html
  1226. //selectContent, title, direction,hasTitle
  1227. var SingleSelectModuleHtml = self.getSelectRenderContent({
  1228. selectContent: singleSelectHtml,
  1229. moduleType: 'moreSelect',
  1230. bigTitle: questionModelData.bigTitle,
  1231. modelId: modelId,
  1232. direction: direction
  1233. })
  1234. if (replaceEl) {
  1235. replaceEl[0].outerHTML = SingleSelectModuleHtml
  1236. var $settingBtn = self.getSettingBtn(modelId)
  1237. self.selectStyleChange($settingBtn, direction)
  1238. } else {
  1239. appendEl.append(SingleSelectModuleHtml)
  1240. }
  1241. },
  1242. //不定项--布局
  1243. uncertainOptionRender: function (questionModelData, appendEl, replaceEl) {
  1244. var self = this
  1245. var datas = questionModelData.questions
  1246. var modelId = questionModelData.modelId
  1247. var direction = self.getDirection(questionModelData.direction)
  1248. //获取选项html
  1249. var singleSelectHtml = self.getSingleSelectHtml(datas, 'more')
  1250. //获取整个选择题区域模块html
  1251. //selectContent, title, direction,hasTitle
  1252. var SingleSelectModuleHtml = self.getSelectRenderContent({
  1253. selectContent: singleSelectHtml,
  1254. moduleType: 'uncertainOption',
  1255. bigTitle: questionModelData.bigTitle,
  1256. modelId: modelId,
  1257. direction: direction
  1258. })
  1259. if (replaceEl) {
  1260. replaceEl[0].outerHTML = SingleSelectModuleHtml
  1261. var $settingBtn = self.getSettingBtn(modelId)
  1262. self.selectStyleChange($settingBtn, direction)
  1263. } else {
  1264. appendEl.append(SingleSelectModuleHtml)
  1265. }
  1266. },
  1267. getFillInBlankHtml: function (datas) {
  1268. var self = this
  1269. var fillInBlankHtml = ''
  1270. var getScoreHtml = function (scoreStyle) {
  1271. if (!scoreStyle) return '<i></i>'
  1272. return scoreStyle.split('/').reduce(function (total, score) {
  1273. total += '<i>' + score + '</i>'
  1274. return total
  1275. }, '')
  1276. }
  1277. datas.forEach(function (fillInBlankItem) {
  1278. fillInBlankItem.scoreStyle = fillInBlankItem.scoreStyle || ''
  1279. fillInBlankItem.scoreHtml = getScoreHtml(fillInBlankItem.scoreStyle)
  1280. fillInBlankHtml += self.tpls.fillInBlankItemTpl.substitute(
  1281. fillInBlankItem
  1282. )
  1283. })
  1284. return fillInBlankHtml
  1285. },
  1286. getFillInBlankRenderContent: function (
  1287. fillInBlankHtml,
  1288. title,
  1289. scoreStyle,
  1290. modelId,
  1291. rowLineHeight,
  1292. columns
  1293. ) {
  1294. var self = this
  1295. title = title || ''
  1296. var fillInBlankModuleHtml = self.tpls.fillInBlankTpl.substitute({
  1297. fillInBlankContent: fillInBlankHtml,
  1298. scoreStyle: scoreStyle,
  1299. title: title,
  1300. modelId: modelId,
  1301. rowLineHeight,
  1302. columns
  1303. })
  1304. return fillInBlankModuleHtml
  1305. },
  1306. //填空题--布局
  1307. formatRenderDataForFillInBlank: function (datas, scoreStyle) {
  1308. var renderData = JSON.parse(JSON.stringify(datas))
  1309. return renderData.map(function (item) {
  1310. item.scoreStyle = scoreStyle
  1311. return item
  1312. })
  1313. },
  1314. fillInBlankRender: function (questionModelData, appendEl, replaceEl) {
  1315. var self = this
  1316. var datas = questionModelData.questions
  1317. var bigTitle = questionModelData.bigTitle
  1318. var modelId = questionModelData.modelId
  1319. var column = questionModelData.columns || 1
  1320. var rowLinHeight = questionModelData.rowLineHeight || 40
  1321. var scoreStyle = questionModelData.scoreStyle || ''
  1322. var renderData = self.formatRenderDataForFillInBlank(datas, scoreStyle)
  1323. var fillInBlankHtml = self.getFillInBlankHtml(renderData)
  1324. var fillInBlankModuleHtml = self.getFillInBlankRenderContent(
  1325. fillInBlankHtml,
  1326. self.titleHtml(bigTitle),
  1327. scoreStyle,
  1328. modelId,
  1329. rowLinHeight,
  1330. column
  1331. )
  1332. if (replaceEl) {
  1333. replaceEl[0].outerHTML = fillInBlankModuleHtml
  1334. var $settingBtn = self.getSettingBtn(modelId)
  1335. self.fillInBlankStyleChange($settingBtn, column, rowLinHeight, scoreStyle)
  1336. } else {
  1337. appendEl.append(fillInBlankModuleHtml)
  1338. }
  1339. },
  1340. //重新渲染填空题
  1341. reRenderFillInBlank: function (modelId) {
  1342. var self = this
  1343. var pageIndex = 1
  1344. while (self.questionMap[modelId]['page' + pageIndex]) {
  1345. var pageFillInBlank = self.questionMap[modelId]['page' + pageIndex]
  1346. var scoreStyle = self.questionMap[modelId].scoreStyle || ''
  1347. if (!pageFillInBlank.length) {
  1348. pageIndex++
  1349. continue
  1350. }
  1351. var $curPage = $('#printcontent .pageContent').eq(pageIndex - 1)
  1352. var $pageFillInBlank = null
  1353. $curPage.find('.completion-topic').each(function () {
  1354. var findModelId = $(this).attr('data-modelId')
  1355. if (modelId === findModelId) {
  1356. $pageFillInBlank = $(this).find('.subjectCol')
  1357. }
  1358. })
  1359. $pageFillInBlank
  1360. .attr('data-scorestyle', scoreStyle)
  1361. .html(self.getFillInBlankHtml(pageFillInBlank))
  1362. pageIndex++
  1363. }
  1364. },
  1365. //解答题获取最小可选分值
  1366. getAnswerMinScoreLimit: function (limit) {
  1367. var self = this
  1368. var minLimit = 16
  1369. for (var i = 0, item; (item = self.answerScoreLimitKeyArr[i++]);) {
  1370. if (item >= limit) {
  1371. minLimit = item
  1372. break
  1373. }
  1374. }
  1375. return minLimit
  1376. },
  1377. //解答题--布局
  1378. shortAnswerRender: function (questionModelData, appendEl, replaceEl) {
  1379. var self = this
  1380. var shortAnswerTpl = self.tpls.shortAnswerItemTpl
  1381. var shortAnswerHtml = ''
  1382. var datas = questionModelData.questions
  1383. datas.forEach(function (shortAnswerItem) {
  1384. shortAnswerItem.editorContentHeight = shortAnswerItem.editorContentHeight
  1385. ? shortAnswerItem.editorContentHeight
  1386. : self.moduleDefaultHeihgt
  1387. //scorelimitkey 15 16 29 49 isHalf 是否有半分的概念
  1388. var minLimit = self.getAnswerMinScoreLimit(shortAnswerItem.fullScore)
  1389. if (Number(shortAnswerItem.fullScore) < questionModelData.dialogData.scoreLimit) {
  1390. minLimit = questionModelData.dialogData.scoreLimit
  1391. }
  1392. shortAnswerItem.scoreColumnHtml = self.generateScoreBox(minLimit, questionModelData.isAddHalf, shortAnswerItem.fullScore)
  1393. shortAnswerItem.scoreLimit = minLimit
  1394. shortAnswerHtml += shortAnswerTpl.substitute(shortAnswerItem)
  1395. //保存原题信息
  1396. self.editorAreaOriginContent[shortAnswerItem.questionNum] =
  1397. shortAnswerItem.queBody || ''
  1398. })
  1399. var shortAnswerModuleHtml = self.tpls.shortAnswerTpl.substitute({
  1400. shortAnswerContent: shortAnswerHtml,
  1401. title: questionModelData.bigTitle,
  1402. modelId: questionModelData.modelId
  1403. })
  1404. if (replaceEl) {
  1405. replaceEl[0].outerHTML = shortAnswerModuleHtml
  1406. } else {
  1407. appendEl.append(shortAnswerModuleHtml)
  1408. }
  1409. //初始化解答题富文本插件
  1410. datas.forEach(function (item) {
  1411. var questionNum = item.questionNum
  1412. var answerContent = ''
  1413. let topicType = item.questionTypeId
  1414. if (topicType == 7) {
  1415. topicType = item.markQuestionType
  1416. }
  1417. //题卡合一渲染原题信息
  1418. if (!self.alreadySave && self.isSubjectInfoToCard) {
  1419. answerContent = self.editorAreaOriginContent[questionNum]
  1420. }
  1421. // self.createShortAnswer(questionNum, answerContent)
  1422. self.createShortAnswer(item.topicEditorIndex, answerContent, topicType)
  1423. })
  1424. },
  1425. //选做题--布局
  1426. chooseAnswerRender: function (questionModelData, appendEl, replaceEl) {
  1427. var self = this
  1428. var chooseAnswerTpl = self.tpls.chooseAnswerItemTpl
  1429. var editorCreateIds = []
  1430. var datas = questionModelData.questions
  1431. var bigTigle = questionModelData.bigTitle
  1432. var modelId = questionModelData.modelId
  1433. //m 选 n 的n
  1434. var requiredCount = datas[0].required || 1
  1435. var chooseAnswerHtml = ''
  1436. //外显题号
  1437. var questionNumShow = 0
  1438. for (var i = 0; i < requiredCount; i++) {
  1439. var selOptionHtml = ''
  1440. var startChooseNumber = 0
  1441. var titleNumber = ''
  1442. var fullScore = 16
  1443. datas.forEach(function (item, index) {
  1444. if (index === i) {
  1445. if (!questionNumShow)
  1446. questionNumShow = item.topicNo
  1447. // item.questionNum + '~' + (+item.questionNum + datas.length - 1)
  1448. startChooseNumber = item.questionNum
  1449. editorCreateIds.push(item.questionNum)
  1450. self.editorAreaOriginContent[item.questionNum] = item.queBody || ''
  1451. fullScore = item.fullScore
  1452. }
  1453. // titleNumber += item.questionNum + ','
  1454. titleNumber = item.topicNo
  1455. selOptionHtml += '<span data-titleNumber="{titleNumber}" data-option="[{char}]">[{char}]</span>'.substitute(
  1456. {
  1457. char: String.fromCharCode(65 + index),
  1458. titleNumber: item.questionNum
  1459. }
  1460. )
  1461. })
  1462. var minLimit = self.getAnswerMinScoreLimit(fullScore)
  1463. if (Number(datas[0].fullScore) < questionModelData.dialogData.scoreLimit) {
  1464. minLimit = questionModelData.dialogData.scoreLimit
  1465. }
  1466. var scoreColumnHtml = self.generateScoreBox(minLimit, questionModelData.isAddHalf, datas[0].fullScore)
  1467. chooseAnswerHtml += chooseAnswerTpl.substitute({
  1468. questionNum: startChooseNumber,
  1469. questionNumShow: questionNumShow,
  1470. //4,5,6,
  1471. // titleNumber: titleNumber.substring(0, titleNumber.length - 1),
  1472. titleNumber: titleNumber,
  1473. selOptionHtml: selOptionHtml,
  1474. scoreColumnHtml: scoreColumnHtml,
  1475. editorContentHeight: self.moduleDefaultHeihgt,
  1476. scoreLimit: minLimit,
  1477. fullScore:datas[0].fullScore
  1478. })
  1479. }
  1480. //先渲染多选题
  1481. //选做题题干信息单独处理
  1482. var chooseAddTitle = ''
  1483. var hasObjective = self.chooseAnswerObjective && !self.alreadySave
  1484. if (hasObjective) {
  1485. chooseAddTitle = self.chooseAnswerObjective
  1486. }
  1487. var chooseAnswerModuleHtml = self.tpls.chooseAnswerTpl.substitute({
  1488. chooseAnswerContent: chooseAnswerHtml,
  1489. title: bigTigle,
  1490. modelId: modelId
  1491. })
  1492. if (replaceEl) {
  1493. replaceEl[0].outerHTML = chooseAnswerModuleHtml
  1494. } else {
  1495. appendEl.append(chooseAnswerModuleHtml)
  1496. }
  1497. //如果有题干信息
  1498. if (hasObjective) {
  1499. self.judegeImgsLoaded(
  1500. '.answerModule[data-type="chooseAnswer"] .originSubjectInfo'
  1501. )
  1502. }
  1503. editorCreateIds.forEach(function (editorId) {
  1504. self.createShortAnswer(editorId)
  1505. })
  1506. },
  1507. //必做题--布局
  1508. mustAnswerRender: function (datas, appendEl, replaceEl) {
  1509. var self = this
  1510. var shortAnswerTpl = self.tpls.shortAnswerItemTpl
  1511. var shortAnswerHtml = ''
  1512. datas.forEach(function (shortAnswerItem) {
  1513. shortAnswerItem.editorContentHeight = shortAnswerItem.editorContentHeight
  1514. ? shortAnswerItem.editorContentHeight
  1515. : self.moduleDefaultHeihgt
  1516. var minLimit = self.getAnswerMinScoreLimit(shortAnswerItem.fullScore)
  1517. shortAnswerItem.scoreColumnHtml = self.generateScoreBox(minLimit, false)
  1518. shortAnswerItem.scoreLimit = minLimit
  1519. shortAnswerHtml += shortAnswerTpl.substitute(shortAnswerItem)
  1520. //保存原题信息
  1521. self.editorAreaOriginContent[shortAnswerItem.questionNum] =
  1522. shortAnswerItem.queBody || ''
  1523. })
  1524. var shortAnswerModuleHtml = self.tpls.shortAnswerTpl.substitute({
  1525. shortAnswerContent: shortAnswerHtml,
  1526. title: questionModelData.bigTigle,
  1527. modelId: questionModelData.modelId
  1528. })
  1529. if (replaceEl) {
  1530. replaceEl[0].outerHTML = shortAnswerModuleHtml
  1531. } else {
  1532. appendEl.append(shortAnswerModuleHtml)
  1533. }
  1534. //初始化解答题富文本插件
  1535. datas.forEach(function (item) {
  1536. var questionNum = item.questionNum
  1537. var answerContent = ''
  1538. if (!self.alreadySave && self.isSubjectInfoToCard) {
  1539. answerContent = self.editorAreaOriginContent[questionNum]
  1540. }
  1541. self.createShortAnswer(questionNum, answerContent)
  1542. })
  1543. },
  1544. /*--------------------------------------------------------------------------------------------------------------------
  1545. 初始页面布局功能结束
  1546. -----------------------------------------------------------------------------------------------------------------------*/
  1547. /*--------------------------------------------------------------------------------------------------------------------------------
  1548. 记忆布局功能开始
  1549. ------------------------------------------------------------------------------------------------------------------------------------*/
  1550. memoryLayout: function (res) {
  1551. var self = this
  1552. var formatData = self.memoryDataFormat(res)
  1553. var shortAnswerData = formatData.shortAnswerData
  1554. // 先控制是否有装订线,纸张大小,方向,分栏,装订线考号
  1555. //{paper,direction,hasBindingLine,examNumberConfig:{barCode,ticketNumber},useQrCode}
  1556. self.memoryHasBindLine(res.hasBindingLine)
  1557. self.memoryPaperDirectColumn(res.paper, res.direction, res.columns)
  1558. //记忆布局--考号配置
  1559. self.memoryExamNumberConfig(res.examNumberConfig, res.useQrCode)
  1560. // 信息栏
  1561. self.memoryHasPaperMsgConfig(res)
  1562. //如果不是创建答题卡
  1563. if (!isNewBuild) {
  1564. //记忆布局--选择题选项排列方向设置
  1565. var singleSelectData = formatData.singleSelectData
  1566. var moreSelectData = formatData.moreSelectData
  1567. var fillInBlankData = formatData.fillInBlankData
  1568. if (singleSelectData.length) {
  1569. self.memorySelectData(singleSelectData[0].direction, 'singleSelect')
  1570. }
  1571. if (moreSelectData.length) {
  1572. self.memorySelectData(moreSelectData[0].direction, 'moreSelect')
  1573. }
  1574. if (fillInBlankData.length) {
  1575. self.memoryFillInBlank(fillInBlankData)
  1576. }
  1577. if (res.stemInfo && res.stemInfo.length) {
  1578. self.memoryObjective(res.stemInfo, res.chooseAnswerStemInfo)
  1579. }
  1580. }
  1581. //然后再布局
  1582. self.memoryShortAnswer(shortAnswerData)
  1583. },
  1584. //把每一题的数据整合到一起
  1585. memoryDataFormat: function (res) {
  1586. var self = this
  1587. //选择题可以设置选项排列方向
  1588. var singleSelectData = []
  1589. var moreSelectData = []
  1590. //填空题可以设置每行列数、分值格式等
  1591. var fillInBlankData = []
  1592. var shortAnswerData = []
  1593. var linkQuestionData = {}
  1594. res.pages.forEach(function (pageData, index) {
  1595. for (
  1596. var i = 0, questionItem;
  1597. (questionItem = pageData.questions[i++]);
  1598. ) {
  1599. var questionType = questionItem.type
  1600. switch (questionType) {
  1601. //选择题
  1602. case self.questionTypeMapForPhp.singleSelect:
  1603. singleSelectData.push(questionItem)
  1604. break
  1605. case self.questionTypeMapForPhp.moreSelect:
  1606. moreSelectData.push(questionItem)
  1607. break
  1608. //填空题
  1609. case self.questionTypeMapForPhp.fillInBlank:
  1610. fillInBlankData.push(questionItem)
  1611. break
  1612. //解答题 or 选做题
  1613. case self.questionTypeMapForPhp.answer:
  1614. case self.questionTypeMapForPhp.chooseAnswer:
  1615. case self.questionTypeMapForPhp.mustAnswer:
  1616. //非多选题
  1617. var isShortAnswer = questionType === 1
  1618. var linkParm = isShortAnswer
  1619. ? questionItem.cut.linkparm
  1620. : questionItem.selectqts[0].cut.linkparm
  1621. //linkParm > 0 补充模块 如果存在补充模块 , 则先合并
  1622. if (linkParm) {
  1623. //第一个补充模块
  1624. if (linkParm === 1) {
  1625. if (JSON.stringify(linkQuestionData) !== '{}') {
  1626. shortAnswerData.push(linkQuestionData)
  1627. linkQuestionData = {}
  1628. }
  1629. linkQuestionData = questionItem
  1630. } else {
  1631. //后面几个补充模块
  1632. if (isShortAnswer) {
  1633. linkQuestionData.cut.height += questionItem.cut.height
  1634. } else {
  1635. linkQuestionData.selectqts[0].cut.height +=
  1636. questionItem.selectqts[0].cut.height
  1637. }
  1638. linkQuestionData.contents += questionItem.contents
  1639. }
  1640. if (
  1641. ((res.pages[index + 1] &&
  1642. !res.pages[index + 1].questions.length) ||
  1643. index + 1 === res.pages.length) &&
  1644. !pageData.questions[i + 1]
  1645. ) {
  1646. shortAnswerData.push(linkQuestionData)
  1647. }
  1648. } else {
  1649. if (JSON.stringify(linkQuestionData) !== '{}') {
  1650. shortAnswerData.push(linkQuestionData)
  1651. linkQuestionData = {}
  1652. }
  1653. shortAnswerData.push(questionItem)
  1654. }
  1655. break
  1656. }
  1657. }
  1658. })
  1659. return {
  1660. shortAnswerData: shortAnswerData,
  1661. fillInBlankData: fillInBlankData,
  1662. singleSelectData: singleSelectData,
  1663. moreSelectData: moreSelectData
  1664. }
  1665. },
  1666. memoryHasBindLine: function (hasBindingLine) {
  1667. if (hasBindingLine) {
  1668. $('#hasBindingLine .h_radioItem').eq(0).trigger('click')
  1669. }
  1670. },
  1671. //基本布局 纸张规格方向分栏
  1672. memoryPaperDirectColumn: function (paper, direction, column) {
  1673. var self = this
  1674. $('#paperOptions .h_radioItem').each(function () {
  1675. if ($(this).attr('data-paper') === paper) {
  1676. $(this).trigger('click')
  1677. }
  1678. })
  1679. $('#paperDirection .h_radioItem').each(function () {
  1680. if ($(this).attr('data-direction') === direction) {
  1681. $(this).trigger('click')
  1682. }
  1683. })
  1684. $('.layoutList .layoutItem').each(function () {
  1685. //column type:number
  1686. if ($(this).attr('data-column') == column) {
  1687. $(this).trigger('click')
  1688. }
  1689. })
  1690. },
  1691. //记忆布局--考号配置
  1692. memoryExamNumberConfig: function (examNumberConfig, useQrCode) {
  1693. var self = this
  1694. $('#examNumberConfig .h_checkItem').each(function () {
  1695. var configName = $(this).attr('data-value')
  1696. var isChecked = $(this).hasClass('checked')
  1697. if (examNumberConfig[configName]) {
  1698. if (!isChecked) $(this).trigger('click')
  1699. } else {
  1700. if (isChecked) $(this).trigger('click')
  1701. }
  1702. })
  1703. //是否使用二维码
  1704. var useQrCodeStatus = $('#useQrCode').hasClass('open')
  1705. if (useQrCode) {
  1706. if (!useQrCodeStatus) {
  1707. $('#useQrCode').trigger('click')
  1708. }
  1709. } else {
  1710. if (useQrCodeStatus) {
  1711. $('#useQrCode').trigger('click')
  1712. }
  1713. }
  1714. },
  1715. //记忆布局--信息栏
  1716. memoryHasPaperMsgConfig: function (hasPaperMsgConfig) {
  1717. var self = this
  1718. // $('#hasPaperMsg .h_checkItem').each(function () {
  1719. // var configName = $(this).attr('data-value')
  1720. // var isChecked = $(this).hasClass('checked')
  1721. // if (hasPaperMsgConfig[hasPaperMsg]) {
  1722. // if (!isChecked) $(this).trigger('click')
  1723. // } else {
  1724. // if (isChecked) $(this).trigger('click')
  1725. // }
  1726. // })
  1727. self.examInfoConfigText=hasPaperMsgConfig.examInfoConfigText;
  1728. self.examInfoConfig=hasPaperMsgConfig.examInfoConfig;
  1729. self.hasPaperMsg=hasPaperMsgConfig.hasPaperMsg;
  1730. self.isShowPaperMsg();
  1731. },
  1732. memorySelectData: function (direction, type) {
  1733. var self = this
  1734. var $this = $('.' + type)
  1735. .eq(0)
  1736. .find('.settingBtn')
  1737. self.selectStyleChange($this, direction)
  1738. },
  1739. memoryFillInBlank: function (fillInBlankData) {
  1740. var self = this
  1741. var questionItem = fillInBlankData[0]
  1742. var modelId = questionItem.modelId
  1743. //当前答题卡只有一大填空题大题的情况下
  1744. var $this = null
  1745. var column = questionItem.column || 1
  1746. var rowLinHeight = questionItem.rowLinHeight || 40
  1747. var scoreStyle = questionItem.scoreStyle || ''
  1748. $('.completion-topic').each(function () {
  1749. if ($(this).attr('data-modelId') === modelId) {
  1750. $this = $(this)
  1751. return false
  1752. }
  1753. })
  1754. self.fillInBlankStyleChange($this, column, rowLinHeight, scoreStyle)
  1755. },
  1756. /**
  1757. *
  1758. * ajax 异步图片加载完成
  1759. * srcList
  1760. * _img = new Image()
  1761. * _img.src = srcList[i]
  1762. */
  1763. judegeImgsLoaded: function (imgBoxSelector, cb) {
  1764. var imgList = []
  1765. var $imgBox = $(imgBoxSelector)
  1766. $imgBox.find('img').each(function () {
  1767. var imge = $(this)
  1768. var styles = imge.attr('style')
  1769. if (styles) {
  1770. styles = styles.replace(/height:auto;/g, '')
  1771. imge.attr('style', styles)
  1772. }
  1773. imgList.push($(this).attr('src'))
  1774. })
  1775. if (!imgList.length) return
  1776. var self = this
  1777. var i = 0
  1778. var imgLen = imgList.length
  1779. function imgLoad() {
  1780. var _img = new Image()
  1781. _img.src = imgList[i]
  1782. _img.onload = function () {
  1783. i++
  1784. if (i >= imgLen) {
  1785. self.changeUnitForFormulaPic($(imgBoxSelector))
  1786. cb && cb()
  1787. } else {
  1788. imgLoad()
  1789. }
  1790. }
  1791. _img.onerror = function () {
  1792. i++
  1793. if (i >= imgLen) {
  1794. self.changeUnitForFormulaPic($(imgBoxSelector))
  1795. cb && cb()
  1796. } else {
  1797. imgLoad()
  1798. }
  1799. }
  1800. }
  1801. imgLoad()
  1802. },
  1803. memoryObjective: function (stemInfo, chooseAnswerStemInfo) {
  1804. var self = this
  1805. stemInfo = typeof stemInfo === 'object' ? stemInfo : stemInfo.split('|end|')
  1806. var isBase64Save = isBase64(stemInfo[0])
  1807. var imgList = []
  1808. $('.objectiveItem').each(function (index) {
  1809. var replaceStr = ''
  1810. if (isBase64Save) {
  1811. replaceStr = decode(stemInfo[index]);
  1812. } else {
  1813. replaceStr = decodeURIComponent(stemInfo[index]);
  1814. }
  1815. $(this)[0].outerHTML = replaceStr
  1816. })
  1817. //选做题单独处理
  1818. if (chooseAnswerStemInfo) {
  1819. var $chooseAnswer = $('.answerModule[data-type="chooseAnswer"]')
  1820. var $chooseAnswerObjective = $chooseAnswer.find('.originSubjectInfo')
  1821. var memoryObjectiveHtml = decodeURIComponent(chooseAnswerStemInfo)
  1822. var delHMemory = memoryObjectiveHtml.replace(/height:auto;/g, '')
  1823. if ($chooseAnswerObjective.length) {
  1824. $chooseAnswerObjective[0].outerHTML = delHMemory
  1825. } else {
  1826. $chooseAnswer.eq(0).children('h3').append(delHMemory)
  1827. }
  1828. //重置图片高度
  1829. self.judegeImgsLoaded(
  1830. '.answerModule[data-type="chooseAnswer"] .originSubjectInfo'
  1831. )
  1832. }
  1833. },
  1834. memoryShortAnswer: function (shortAnswerData) {
  1835. var self = this
  1836. //2 解答题区域高度修改
  1837. //shortAnswerData 所有解答题的区域信息
  1838. //多选题特殊处理
  1839. var checkQuestionData = {}
  1840. var checkmoduleEl = {}
  1841. for (var i = 0, questionItem; i < shortAnswerData.length; i++) {
  1842. var questionItem = shortAnswerData[i]
  1843. var moduleHeight = questionItem.cut
  1844. ? questionItem.cut.height
  1845. : questionItem.selectqts[0].cut.height
  1846. var scoreLimitKey = questionItem.scoreLimit
  1847. var isAddHalf = questionItem.isAddHalf
  1848. $('#printcontent .pageContent .short-answer .module').each(function (
  1849. pageIndex,
  1850. moduleItem
  1851. ) {
  1852. var $pageItem = $(moduleItem).closest('.pageContent')
  1853. var $moduleItem = $(moduleItem)
  1854. var isOverPage = false
  1855. var titleNumber = Number($moduleItem.attr('title-number'))
  1856. var dataEditorIndex = $moduleItem.attr('data-editorindex')
  1857. if (self.isSurplusModule($moduleItem)) return
  1858. //该题已经布局就无需重复布局--针对选择题
  1859. if (
  1860. titleNumber === Number(questionItem.name) &&
  1861. !checkQuestionData[questionItem.editorId] &&
  1862. !checkQuestionData[dataEditorIndex]
  1863. ) {
  1864. checkQuestionData[questionItem.editorId] = true
  1865. checkQuestionData[dataEditorIndex] = true
  1866. //同步之前设置的内容
  1867. if (questionItem.contents) {
  1868. // var editorId = questionItem.id
  1869. var editorId = dataEditorIndex
  1870. self.editorArea['editor' + editorId].txt.html(
  1871. decodeURIComponent(questionItem.contents)
  1872. )
  1873. }
  1874. var $this = $moduleItem.children('.settingBtn')
  1875. let isAddHalf = questionItem.scorebox.point==1 ? true: false;
  1876. self.shortAnswerStyleChange($this, scoreLimitKey, isAddHalf, questionItem.scorebox.limit)
  1877. //设置大题区域高度
  1878. $moduleItem
  1879. .children('.editorContent')
  1880. .height(moduleHeight - self.modulePadding)
  1881. // $moduleItem
  1882. // .children('.editorContent')
  1883. // .css('min-height',moduleHeight - self.modulePadding)
  1884. curPageEl = $pageItem
  1885. //如果当前有page分栏页有超出 则直接调到下一个分页
  1886. isOverPage = self.getOverModule(curPageEl)
  1887. self.changePrintArea(curPageEl)
  1888. }
  1889. if (isOverPage) return false
  1890. // if (isOverPage) {
  1891. // isOverPage = false
  1892. // }
  1893. })
  1894. }
  1895. },
  1896. /*--------------------------------------------------------------------------------------------------------------------------------
  1897. 记忆布局功能结束
  1898. ------------------------------------------------------------------------------------------------------------------------------------*/
  1899. /**
  1900. * --------------------------------------------------------------------------------------------------------------------------------
  1901. 还原原题题干信息开始
  1902. --------------------------------------------------------------------------------------------------------------------------------
  1903. */
  1904. restoreObjectiveInfo: function (data) {
  1905. var self = this
  1906. var clearStatus = data.clearStatus
  1907. if (clearStatus) {
  1908. var $pageContent
  1909. $('.answerModule').each(function () {
  1910. if ($(this).attr('data-type') === 'objective') {
  1911. if (!$pageContent) {
  1912. $pageContent = $(this).closest('.pageContent')
  1913. }
  1914. $(this).remove()
  1915. }
  1916. })
  1917. self.changePrintArea($pageContent)
  1918. return
  1919. }
  1920. $('.objectiveItem').each(function (index) {
  1921. $(this)[0].outerHTML = decodeURIComponent(self.originStemInfos[index])
  1922. })
  1923. //图片加载时间
  1924. self.judegeImgsLoaded('.objectiveItem')
  1925. },
  1926. restoreAnswerInfo: function (data) {
  1927. var self = this
  1928. var clearStatus = data.clearStatus
  1929. /**
  1930. * 清空之前所有的内容
  1931. * 包括清空统一题的本体模块和补充模块
  1932. * 然后用新内容放在本体模块里面
  1933. */
  1934. var overPageEl = []
  1935. //第一次出现
  1936. var firstChooseAnswer = true
  1937. $('.short-answer').each(function () {
  1938. var $shortAnswer = $(this)
  1939. var $modules = $(this).find('.module')
  1940. if ($shortAnswer.attr('data-type') === 'chooseAnswer') {
  1941. if (!firstChooseAnswer) {
  1942. $shortAnswer.find('h3').remove()
  1943. return
  1944. }
  1945. firstChooseAnswer = false
  1946. var chooseObjectiveEl = $shortAnswer.find('.originSubjectInfo')
  1947. if (chooseObjectiveEl.length) {
  1948. if (clearStatus) {
  1949. chooseObjectiveEl.remove()
  1950. } else {
  1951. chooseObjectiveEl[0].outerHTML = self.chooseAnswerObjective
  1952. }
  1953. } else {
  1954. $shortAnswer.find('h3').append(self.chooseAnswerObjective)
  1955. }
  1956. var overHeight = self.getOverHeight($shortAnswer)
  1957. if (overHeight > 0) {
  1958. overPageEl.push($shortAnswer.closest('.pageContent'))
  1959. }
  1960. return
  1961. }
  1962. $modules.each(function () {
  1963. var $module = $(this)
  1964. var questionNum = $(this).attr('title-number')
  1965. var editorIndex = $(this).attr('data-editorIndex')
  1966. var $moduleEditorContent = $(this).find('.w-e-text')
  1967. var $moduleContentWrap = $(this).find('.w-e-text-container')
  1968. //如果是补充模块直接清空内容
  1969. if (self.isSurplusModule($(this))) {
  1970. $moduleEditorContent.html('')
  1971. } else {
  1972. var flexibleIconHtml =
  1973. '<div class="flexible_icon"><i class="resize_nwse"></i></div>'
  1974. var questionNumHtml =
  1975. '<div class="editorQuestionNum">' + questionNum + '、</div>'
  1976. var baseContent = questionNumHtml + flexibleIconHtml
  1977. $moduleEditorContent.html(
  1978. baseContent +
  1979. (clearStatus ? '' : self.editorAreaOriginContent[questionNum])
  1980. )
  1981. var minHeight = self.calcEditorContentHeight($moduleEditorContent)
  1982. if ($moduleContentWrap.height() < minHeight) {
  1983. $moduleContentWrap.height(minHeight)
  1984. }
  1985. var overHeight = self.getOverHeight($module)
  1986. if (overHeight > 0) {
  1987. overPageEl.push($module.closest('.pageContent'))
  1988. }
  1989. }
  1990. })
  1991. })
  1992. //图片加载时间
  1993. self.judegeImgsLoaded('.short-answer')
  1994. if (overPageEl.length) {
  1995. overPageEl.forEach(function (pageEl) {
  1996. self.changePrintArea($(pageEl))
  1997. })
  1998. }
  1999. },
  2000. /**
  2001. * --------------------------------------------------------------------------------------------------------------------------------
  2002. 还原原题题干信息结束
  2003. --------------------------------------------------------------------------------------------------------------------------------
  2004. */
  2005. initDom: function () {
  2006. var self = this
  2007. self.$layoutItem = $('#hgc_print .layoutItem')
  2008. self.$checkBindLineItem = $('.selOptions input[name="hasBinding"]')
  2009. //第一个page分页的元素,永远不会变
  2010. self.$firstPageContent = $('#printcontent .pageContent').eq(0)
  2011. //答题卡名称
  2012. self.$dtkName = $('#dtkName textarea')
  2013. },
  2014. initEvent: function () {
  2015. var self = this
  2016. //当前默认是 A3 两栏 有装订线 有条形码 有准考证号
  2017. self.linkageForPaper(self.paper)
  2018. },
  2019. /**
  2020. *
  2021. * @param {$element} $editorContentWrapEl 富文本包装内容的div
  2022. * 语文作文格子需要格外加高度10
  2023. */
  2024. calcEditorContentHeight: function ($editorContentWrapEl) {
  2025. var self = this
  2026. var minScaleHeight = 0
  2027. $editorContentWrapEl.children().each(function () {
  2028. var boxWrap = $(this).hasClass('composition-column') ? 10 : 0
  2029. if($(this).hasClass('en')){
  2030. boxWrap = 33
  2031. }
  2032. minScaleHeight += $(this)[0].getBoundingClientRect().height + boxWrap
  2033. })
  2034. return minScaleHeight
  2035. },
  2036. bindEvent: function () {
  2037. var self = this
  2038. var testFormData = JSON.parse(localStorage.getItem('testFormData'))
  2039. let exam_group_id = ''
  2040. if (testFormData) {
  2041. exam_group_id = testFormData.examGroupId;
  2042. self.examGroupId = testFormData.examGroupId;
  2043. }
  2044. var base64_img = jrQrcode.getQrBase64(exam_group_id)
  2045. $('#dtkEwm').attr('src', base64_img)
  2046. //编辑标题
  2047. $('#printcontent').on('blur', 'h3', function () {
  2048. var curPageEl = $(this).closest('.pageContent')
  2049. self.changePrintArea(curPageEl)
  2050. })
  2051. $('#printcontent').on('blur', '.objectiveItem', function () {
  2052. var curPageEl = $(this).closest('.pageContent')
  2053. self.changePrintArea(curPageEl)
  2054. })
  2055. // 限制标题输入内容
  2056. $('#printcontent').on('keypress', 'h3', function () {
  2057. let lock = true;
  2058. let fullContent = '';
  2059. let modelId = $(this).parent().attr('data-modelid');
  2060. $('h3').on('compositionstart', function () {
  2061. lock = false;
  2062. });
  2063. $('h3').on('compositionend', function (event) {
  2064. lock = true;
  2065. addInput(event, $(this));
  2066. });
  2067. $('h3').on('keyup input propertychange', function (event) {
  2068. addInput(event, $(this));
  2069. });
  2070. // 字数限制
  2071. function addInput(event, that) {
  2072. let _words = that.text();
  2073. if (lock) {
  2074. let num = _words.length;
  2075. if (num >= 10) {
  2076. event.target.innerText = fullContent;
  2077. event.target.innerText = _words.substring(0, 12);
  2078. fullContent = _words.substring(0, 12);
  2079. set_focus(event);
  2080. seBigTopicTitle(fullContent,modelId)
  2081. } else {
  2082. fullContent = ''
  2083. seBigTopicTitle(_words,modelId)
  2084. }
  2085. } else if (fullContent) {
  2086. event.target.innerText = fullContent;
  2087. lock = true;
  2088. set_focus(event);
  2089. seBigTopicTitle(fullContent,modelId)
  2090. }
  2091. }
  2092. // 超过字数光标定位到末端
  2093. function set_focus(e) {
  2094. let el = document.getElementById(e.target.id);
  2095. el.focus();
  2096. if ($.support.msie) {
  2097. let range = document.selection.createRange();
  2098. this.last = range;
  2099. range.moveToElementText(el);
  2100. range.select();
  2101. document.selection.empty();
  2102. } else {
  2103. let range = document.createRange();
  2104. range.selectNodeContents(el);
  2105. range.collapse(false);
  2106. let sel = window.getSelection();
  2107. sel.removeAllRanges();
  2108. sel.addRange(range);
  2109. }
  2110. }
  2111. // 设置大题title
  2112. function seBigTopicTitle(text,modId) {
  2113. let reg2 = /([^、/]+)$/;
  2114. questionTypeTitle = text.match(reg2)[1];
  2115. self.questionMap[modId].bigTitle=text
  2116. self.questionMap[modId].commonFields.questionTypeTitle = questionTypeTitle
  2117. }
  2118. })
  2119. //图片可扩展
  2120. //控制答题卡区域缩放事件
  2121. $('#printcontent').on('mousedown', '.short-answer .dragBtn', function (e) {
  2122. e.stopPropagation()
  2123. if (!self.isCanEditCard) return
  2124. e.preventDefault()
  2125. var inscreaseTop = $('#contentWrap').scrollTop()
  2126. //当前操作的分页
  2127. var curPageEl = $(this).closest('.pageContent')
  2128. var curPageOffsetTop = curPageEl.offset().top + inscreaseTop
  2129. //当前缩放分页下面的按钮
  2130. var curDtkModelEl = $(this).closest('.module')
  2131. var curDtkModelOffsetTop = curDtkModelEl.offset().top + inscreaseTop
  2132. //只要改变高度的模块
  2133. var changeEl = $(this).siblings('.editorContent')
  2134. //改变之前的初始高度
  2135. var startHeight = changeEl.height()
  2136. var startPageY = e.pageY
  2137. var distance = 0
  2138. //计算可以缩放的最小高度
  2139. var scaleMinHeight = self.calcEditorContentHeight(
  2140. changeEl.children('.w-e-text')
  2141. )
  2142. // console.log('scaleMinHeight', scaleMinHeight)
  2143. // console.log('startHeight', startHeight)
  2144. // 如果题卡合一的话,最小高度就是里面内容的高度
  2145. // 否则最小高度就是默认的高度
  2146. // if(this.isSubjectInfoToCard){
  2147. // }
  2148. /**
  2149. * 超过当前纸张的情况下 当鼠标松开的时候
  2150. * 1先把当前纸张放满
  2151. * 2剩余高度重新新到下个版本新建一个富文本高度一样没有内容
  2152. * 3单词拖动鼠标控制解答题区域缩放只能拖动到当前页面最底部
  2153. */
  2154. document.onmousemove = function (e) {
  2155. distance = e.pageY - startPageY
  2156. var newHeight = startHeight + distance
  2157. if (newHeight < scaleMinHeight) {
  2158. newHeight = scaleMinHeight
  2159. changeEl.height(newHeight)
  2160. document.onmouseup(e)
  2161. return
  2162. }
  2163. changeEl.height(newHeight)
  2164. }
  2165. //判断是否超过了一页
  2166. /**
  2167. * 1当前模块已经缩放超过了当前页
  2168. * a>该区域后面的内容板块自动清空
  2169. * b>该区域不可再移动,自动新建一页,然后在下一页新建一个富文本默认是上一页超出的区域
  2170. * 2后面的模块超过了当前缩放页面
  2171. * a>直接把后面的题放到新排版页面
  2172. */
  2173. document.onmouseup = function (e) {
  2174. e.stopPropagation()
  2175. self.changePrintArea(curPageEl)
  2176. document.onmouseup = null
  2177. document.onmousemove = null
  2178. self.initPageTopic();
  2179. }
  2180. })
  2181. //删除一个分页超出的部分
  2182. $('#printcontent').on('click', '.delBtn', function (e) {
  2183. if (!self.isCanEditCard) return
  2184. var $this = $(this)
  2185. self.delPageOverPart($this, 'surplus', true)
  2186. })
  2187. //预览
  2188. $('#previewBtn').click(function () {
  2189. self.previewPrintDiv('printcontent')
  2190. })
  2191. //保存
  2192. $('#saveBtn').click(function () {
  2193. if (!self.isCanEditCard) {
  2194. if (self.isSubjectInfoToCard) {
  2195. self.modal.init({
  2196. content: '当前考试为“题卡合一”模式,是否需要重新替换成原题干内容?',
  2197. sureCb: function () {
  2198. //针对数学非第三方试卷:题卡分离的,原题信息都在改问题的后面,试卷固定顺序 选择--填空--解答--必答
  2199. //渲染客观题题目信息
  2200. //如果第一次题卡分离
  2201. if (!$('.objectiveItem').length) {
  2202. self.renderObjective(function (pageEl) {
  2203. self.changePrintArea(pageEl)
  2204. })
  2205. } else {
  2206. self.restoreObjectiveInfo({ clearStatus: false })
  2207. }
  2208. self.restoreAnswerInfo({ clearStatus: false })
  2209. }
  2210. })
  2211. self.isCanEditCard = true
  2212. self.changeCardEditStatus()
  2213. } else {
  2214. // hgc_layer.msg('考试已被设置为【题卡分离】,请注意答题卡已被重置!')
  2215. // if ($('.objectiveItem').length) {
  2216. // self.restoreObjectiveInfo({ clearStatus: true })
  2217. // }
  2218. // self.restoreAnswerInfo({ clearStatus: true })
  2219. self.isCanEditCard = true
  2220. self.changeCardEditStatus()
  2221. }
  2222. return
  2223. }
  2224. self.totalPage = $('.pageContent').length
  2225. if (self.totalPage > self.columns * 2) {
  2226. hgc_layer.msg('答题卡最多支持' + self.columns * 2 + '页')
  2227. return
  2228. }
  2229. // 如果是全学科答题卡,保存并且返回 需要先设置主观题答案
  2230. if (isNewBuild) {
  2231. if ($.isEmptyObject(self.questionMap)) {
  2232. hgc_layer.msg('请添加试题')
  2233. return false
  2234. }
  2235. var allSetAnswer = true
  2236. var buildQuestions = self.questionMap
  2237. for (var modelId in buildQuestions) {
  2238. var modelItem = buildQuestions[modelId]
  2239. if (~[1, 2, 11].indexOf(modelItem.questionType)) {
  2240. allSetAnswer = modelItem.questions.every(function (question) {
  2241. return question.answer
  2242. })
  2243. if (!allSetAnswer) break
  2244. }
  2245. }
  2246. if (!allSetAnswer) {
  2247. self.modal.init({
  2248. title: '提示',
  2249. content: '请先设置客观题答案',
  2250. ensureText: '去设置',
  2251. cancelText: '关闭',
  2252. sureCb: function () {
  2253. $('#setAnswerBtn').trigger('click')
  2254. }
  2255. })
  2256. return
  2257. }
  2258. if (self.$dtkName.val() == '') {
  2259. self.modal.init({
  2260. title: '提示',
  2261. content: '请先设置标题',
  2262. cancelText: '关闭'
  2263. })
  2264. return
  2265. }
  2266. // self.$dtkName.val()
  2267. self.savePrintPosition('printcontent')
  2268. return
  2269. }
  2270. if (!self.isCanEditCard) {
  2271. self.isCanEditCard = true
  2272. self.changeCardEditStatus()
  2273. return
  2274. }
  2275. self.judgeHasPrintClass(function () {
  2276. self.savePrintPosition('printcontent')
  2277. })
  2278. })
  2279. //下载pdf
  2280. $('#downLoadBtn').click(function () {
  2281. if (self.isCanEditCard && !isNewBuild) return
  2282. var $this = $(this)
  2283. if (self.totalPage > self.columns * 2) {
  2284. hgc_layer.msg('答题卡最多支持' + self.columns * 2 + '页')
  2285. return
  2286. }
  2287. /**
  2288. * 1 可编辑状态 编辑-保存 --编辑状态不可直接生成或者下载,只有保存状态下,才能生成或者下载
  2289. * 2 是否和接口返回的记忆布局数据一样 --如果一样,默认没有修改,可直接下载或者生成
  2290. * 3 判断是否已经存在在打印的班级 --如果已经存在正在打印的班级学生,则提示是否覆盖,然后才能生成或者下载
  2291. * 4 是否使用二维码 --如果使用二维码,则使用生成pdf的那套逻辑
  2292. *
  2293. * 如果是创建答题卡 直接下载
  2294. */
  2295. if (isNewBuild) {
  2296. self.downLoadPdf()
  2297. return
  2298. }
  2299. //保存状态不用重新执行保存逻辑直接下载或者批量生成
  2300. if (!self.isCanEditCard) {
  2301. if (self.useQrCode) {
  2302. self.judgeHasPrintClass(function () {
  2303. setTimeout(function () {
  2304. self.modal.init({
  2305. title: '批量生成',
  2306. content: '该操作会把该场考试下面的所有班级学生考试模板进行批量生成',
  2307. sureCb: function () {
  2308. self.batchGeneratePdf()
  2309. }
  2310. })
  2311. }, 0)
  2312. })
  2313. } else {
  2314. self.downLoadPdf()
  2315. }
  2316. return
  2317. }
  2318. //如果使用了二维码后台批量生成,不影响当前页面
  2319. var nowPosition = JSON.stringify(self.getPositions())
  2320. if (self.useQrCode) {
  2321. if (nowPosition !== self.saveLocationPosition) {
  2322. self.judgeHasPrintClass(function () {
  2323. self.savePrintPosition('printcontent', function () {
  2324. self.modal.init({
  2325. title: '批量生成',
  2326. content: '该操作会把该场考试下面的所有班级学生考试模板进行批量生成',
  2327. sureCb: function () {
  2328. self.batchGeneratePdf()
  2329. }
  2330. })
  2331. })
  2332. })
  2333. } else {
  2334. self.judgeHasPrintClass(function () {
  2335. setTimeout(function () {
  2336. self.modal.init({
  2337. title: '批量生成',
  2338. content: '该操作会把该场考试下面的所有班级学生考试模板进行批量生成',
  2339. sureCb: function () {
  2340. self.batchGeneratePdf()
  2341. }
  2342. })
  2343. }, 0)
  2344. })
  2345. }
  2346. } else {
  2347. //保存状态不用重新执行保存逻辑直接下载或者批量生成
  2348. if (!self.isCanEditCard) {
  2349. self.downLoadPdf()
  2350. return
  2351. }
  2352. if (nowPosition !== self.saveLocationPosition) {
  2353. self.judgeHasPrintClass(function () {
  2354. self.savePrintPosition('printcontent', function () {
  2355. self.downLoadPdf()
  2356. })
  2357. })
  2358. } else {
  2359. self.downLoadPdf()
  2360. }
  2361. }
  2362. })
  2363. //答题卡布局
  2364. //选择纸张
  2365. new RadioBoxItem($('#paperOptions'), function ($radioItem, status) {
  2366. var paper = $radioItem.attr('data-paper')
  2367. self.paper = paper
  2368. self.linkageForPaper(paper)
  2369. // self.reInitPageForNewBuild();
  2370. })
  2371. //选择排版方向
  2372. new RadioBoxItem($('#paperDirection'), function ($radioItem, status) {
  2373. var direction = $radioItem.attr('data-direction')
  2374. self.direction = direction
  2375. self.setPageWidthHeightForDirection(direction)
  2376. self.linkageForDirection(self.config.direction[direction])
  2377. })
  2378. //选择分栏
  2379. self.$layoutItem.click(function () {
  2380. var column = +$(this).attr('data-column')
  2381. //|| $(this).hasClass('current')
  2382. if ($(this).hasClass('disabled')) return
  2383. $(this).addClass('current').siblings().removeClass('current')
  2384. self.columns = column
  2385. self.initPrintContentArea()
  2386. })
  2387. //选择是否有装订线
  2388. new RadioBoxItem($('#hasBindingLine'), function ($radioItem, status) {
  2389. var bindingLineStatus = $radioItem.attr('data-value') === 'yes'
  2390. self.hasBindingLine = bindingLineStatus
  2391. self.ifBindingLine()
  2392. })
  2393. //选择是否显示信息栏
  2394. new RadioBoxItem($('#hasPaperMsg'), function ($radioItem, status) {
  2395. var bindingPaperMsgStatus = $radioItem.attr('data-value') === 'yes'
  2396. self.hasPaperMsg = bindingPaperMsgStatus
  2397. self.isShowPaperMsg()
  2398. })
  2399. //信息栏设置
  2400. $('#printcontent').on('click', '.btn-examInfo', function () {
  2401. if (!self.isCanEditCard) return
  2402. $('#examInfoEditDialog').show()
  2403. })
  2404. $('#examInfoEditDialog').on('click', '.btn-hide-dialog', function () {
  2405. $('#examInfoEditDialog').hide()
  2406. })
  2407. $('#examInfoEditDialog').on('click', '.btn-save-examInfo', function () {
  2408. $('#examInfoEditDialog').hide()
  2409. self.showExamInfoHtml();
  2410. self.getSaveSubjectInfo(self.questionMap)
  2411. })
  2412. $('.opratorArea').on('mouseover', '.hgc_notice', function (e) {
  2413. let el = e.target
  2414. let noticeEl = $(this).parent('.notice-item').find('.noticeContent');
  2415. let triangleEl = $(this).parent('.notice-item').find('.noticeContent').find('b');
  2416. $(noticeEl).show();
  2417. let noticeH = $(noticeEl).get(0).offsetHeight
  2418. let noticeW = $(noticeEl).get(0).offsetWidth
  2419. let { top, left } = el.getBoundingClientRect();
  2420. $(noticeEl).css('top', top - noticeH - 10 + 'px')
  2421. $(noticeEl).css('left', left - noticeW / 2 + 'px');
  2422. $(triangleEl).css('top', top - 10 + 'px');
  2423. $(triangleEl).css('left', left + 'px');
  2424. })
  2425. $('.opratorArea').on('mouseout', '.hgc_notice', function (e) {
  2426. let el = e.target
  2427. let noticeEl = $(this).parent('.notice-item').find('.noticeContent');
  2428. $(noticeEl).hide();
  2429. })
  2430. //考号配置
  2431. new CheckBoxItem(
  2432. $('#examNumberConfig'),
  2433. function () { },
  2434. self.selExamNumberStyle.bind(self)
  2435. )
  2436. //信息栏弹窗配置
  2437. new CheckBoxItem(
  2438. $('#examInfoConfig'),
  2439. function () { },
  2440. self.selExamInfoStyle.bind(self)
  2441. )
  2442. //是否使用二维码
  2443. new Switch($('#useQrCode'), function (status) {
  2444. var $examNumberConfigOptions = $('#examNumberConfig .h_checkItem')
  2445. var $examNumberLayout = $('.examNumberLayout')
  2446. var $downLoadBtn = $('#downLoadBtn')
  2447. var $ewmTips = $('#ewmTips')
  2448. self.useQrCode = status
  2449. $downLoadBtn.html(status ? '生成' : '下载')
  2450. $examNumberConfigOptions.each(function () {
  2451. $(this)[status ? 'addClass' : 'removeClass']('disabled')
  2452. })
  2453. $('.className').html(status ? self.tpls.systemClassNoticeInfoTpl : '')
  2454. $('.examineeName').html(status ? self.tpls.systemNameNoticeInfoTpl : '')
  2455. $('.bindLineClassName').html(
  2456. status ? self.tpls.systemClassNoticeInfoForLineTpl : ''
  2457. )
  2458. $('.bindLineExamineeName').html(
  2459. status ? self.tpls.systemNameNoticeInfoForLineTpl : ''
  2460. )
  2461. self.editNoticeDetail(status,self.cardStatus)
  2462. $examNumberLayout[status ? 'addClass' : 'removeClass']('useqrcode')
  2463. $ewmTips.css('display', status ? 'flex' : 'none')
  2464. self.changePrintArea(self.$firstPageContent)
  2465. })
  2466. //单模块设置
  2467. $('#printcontent').on('click', '.settingBtn', function () {
  2468. if (!self.isCanEditCard) return
  2469. var $this = $(this)
  2470. var type = $this.attr('data-type')
  2471. var modelId = $this.closest('.answerModule').attr('data-modelId')
  2472. //如果是创建答题卡则跳转到编辑页面
  2473. if (isNewBuild) {
  2474. self.setBuildQuestions()
  2475. window.QE.questionEditStatus = true
  2476. window.QE.questionData = JSON.parse(
  2477. JSON.stringify({
  2478. ...self.questionMap[modelId],
  2479. subjectId: subjectId,
  2480. isAdd: false,
  2481. SelectbigNoArr: getSelectbigNoArr(self.questionMap)
  2482. })
  2483. )
  2484. $('#questionEdit').show()
  2485. return
  2486. }
  2487. //填空
  2488. if (type === 'fillInBlank') {
  2489. self.fillInBlankSet($this)
  2490. //选择 单选-多选
  2491. } else if (~type.indexOf('Select')) {
  2492. self.selectSetLayout($this, type)
  2493. } else {
  2494. self.shortAnswerSet($this)
  2495. }
  2496. })
  2497. //单模块删除
  2498. $('#printcontent').on('click', '.delTopicBtn', function () {
  2499. if (!self.isCanEditCard) return
  2500. var $this = $(this);
  2501. var type = $this.attr('data-type');
  2502. var modelId = $this.closest('.answerModule').attr('data-modelId');
  2503. let $replaceEl = null
  2504. self.modal.init({
  2505. title: '提示',
  2506. content: '确定要删除当前题目吗?',
  2507. ensureText: '确定',
  2508. cancelText: '取消',
  2509. sureCb: function () {
  2510. $('.answerModule').each(function () {
  2511. if ($(this).attr('data-modelId') === modelId) {
  2512. $replaceEl = $(this)
  2513. }
  2514. })
  2515. if(type!=='shortAnswer'){
  2516. $this.parents('.answerModule').remove();
  2517. }
  2518. //填空
  2519. if (type === 'fillInBlank') {
  2520. delete self.questionMap[modelId]
  2521. //选择 单选-多选
  2522. } else if (~type.indexOf('Select')) {
  2523. delete self.questionMap[modelId]
  2524. } else if (~type.indexOf('uncertain')) {
  2525. delete self.questionMap[modelId]
  2526. } else if (~type.indexOf('chooseAnswer')) {
  2527. delete self.questionMap[modelId]
  2528. $('.pageContent').find('.short-answer').each(function(){
  2529. let modelid = $(this).attr('data-modelid');
  2530. if(modelid = modelId){
  2531. $(this).remove();
  2532. }
  2533. })
  2534. } else if (~type.indexOf('shortAnswer')) {
  2535. let titleNumber = $this.closest('.module').attr('title-number');
  2536. let questionsAll = JSON.parse(JSON.stringify(self.questionMap[modelId].questions));
  2537. questionsAll.forEach((topic, index) => {
  2538. if (topic.questionNum == titleNumber) {
  2539. if (self.questionMap[modelId].questions.length === 1) {
  2540. delete self.questionMap[modelId]
  2541. // $this.parents('.answerModule').remove();
  2542. $('.pageContent').find('.short-answer').each(function(){
  2543. let modelid = $(this).attr('data-modelid');
  2544. if(modelid = modelId){
  2545. $(this).remove();
  2546. }
  2547. })
  2548. } else {
  2549. // $this.parents('.module').remove();
  2550. $('.pageContent').find('.short-answer .module').each(function(){
  2551. let moduleTitleNumber = $(this).attr('title-number');
  2552. if(moduleTitleNumber = titleNumber){
  2553. $(this).remove();
  2554. }
  2555. })
  2556. self.questionMap[modelId].questions.splice(index, 1);
  2557. self.questionMap[modelId].originQuestions.splice(index, 1);
  2558. self.questionMap[modelId].commonFields.questionTypeArr.forEach((n, ni) => {
  2559. if (titleNumber == n.startNo || titleNumber == n.endNo) {
  2560. if (n.startNo == n.endNo) {
  2561. self.questionMap[modelId].commonFields.questionTypeArr.splice(ni, 1);
  2562. } else {
  2563. if (titleNumber == n.startNo) {
  2564. n.startNo = Number(n.startNo) + 1
  2565. } else {
  2566. n.endNo = Number(n.endNo) - 1
  2567. }
  2568. }
  2569. } else if (titleNumber > n.startNo && titleNumber < n.endNo) {
  2570. let ndata = JSON.parse(JSON.stringify(n))
  2571. let questionType = {
  2572. startNo: '',
  2573. endNo: n.endNo,
  2574. score: ndata.score
  2575. };
  2576. n.endNo = Number(titleNumber) - 1;
  2577. questionType.startNo = Number(titleNumber) + 1;
  2578. self.questionMap[modelId].commonFields.questionTypeArr.splice(ni + 1, 0, questionType);
  2579. }
  2580. })
  2581. }
  2582. }
  2583. })
  2584. }
  2585. //重新设置
  2586. localStorage.setItem('buildQuestions', JSON.stringify(self.questionMap))
  2587. var DelPosition = self.getPositions();
  2588. localStorage.setItem('position', JSON.stringify(DelPosition))
  2589. self.reInitPageForNewBuild();
  2590. if ($.isEmptyObject(self.questionMap)) {
  2591. $('.addTips').show();
  2592. // 当答题卡没有题时设置总分为空
  2593. $('.fraction').val('')
  2594. }
  2595. }
  2596. })
  2597. })
  2598. // 给模块标题设置高度
  2599. $('#printcontent').on('click', '.answerModule h3', function () {
  2600. $(this).css('height','auto')
  2601. })
  2602. function isPx(str) {
  2603. return /^\d+$/.test(str)
  2604. }
  2605. document.addEventListener(
  2606. 'error',
  2607. function (e) {
  2608. var elem = e.target
  2609. if (elem.tagName.toLowerCase() === 'img') {
  2610. var oh = $(elem).attr('height')
  2611. var ow = $(elem).attr('width')
  2612. if (!isPx(oh) || !isPx(ow)) return
  2613. var h = parseInt($(elem).attr('height'))
  2614. var w = parseInt($(elem).attr('width'))
  2615. var hmm = self.unitConversion.pxConversionMm(h)
  2616. var wmm = self.unitConversion.pxConversionMm(w)
  2617. $(elem).attr(
  2618. 'style',
  2619. $(elem).attr('style') +
  2620. ';height:' +
  2621. hmm +
  2622. 'mm !important;width:' +
  2623. wmm +
  2624. 'mm !important;'
  2625. )
  2626. }
  2627. },
  2628. true
  2629. )
  2630. document.addEventListener(
  2631. 'load',
  2632. function (e) {
  2633. var elem = e.target
  2634. if (
  2635. elem.tagName.toLowerCase() === 'img' &&
  2636. typeof $(elem).attr('word_img') === 'string'
  2637. ) {
  2638. var h = parseInt($(elem).attr('height'))
  2639. var w = parseInt($(elem).attr('width'))
  2640. var hmm = self.unitConversion.pxConversionMm(h)
  2641. var wmm = self.unitConversion.pxConversionMm(w)
  2642. $(elem).attr(
  2643. 'style',
  2644. $(elem).attr('style') +
  2645. ';height:' +
  2646. hmm +
  2647. 'mm !important;width:' +
  2648. wmm +
  2649. 'mm !important;'
  2650. )
  2651. }
  2652. },
  2653. true
  2654. )
  2655. function getSelectbigNoArr(data) {
  2656. var SelectbigNoArr = [];
  2657. for (var i in data) {
  2658. // console.log(i,":",obj[i]);
  2659. SelectbigNoArr.push(data[i].commonFields.bigNo)
  2660. }
  2661. // for(var i = 0; i < data.length; i++) { // 这里的i是代表数组的下标
  2662. // let key = 'modelId' + i+1;
  2663. // SelectbigNoArr.push(data[key].commonFields.bigNo)
  2664. // }
  2665. return SelectbigNoArr
  2666. }
  2667. //添加试题
  2668. $('#addQustionBtn').click(function () {
  2669. var modelId = guid()
  2670. window.QE.questionEditStatus = true
  2671. window.QE.questionData = JSON.parse(
  2672. JSON.stringify({
  2673. ...window.defaultQuestionData,
  2674. modelId: modelId,
  2675. isAdd: true,
  2676. subjectId: subjectId,
  2677. SelectbigNoArr: getSelectbigNoArr(self.questionMap)
  2678. })
  2679. )
  2680. $('#questionEdit').show()
  2681. })
  2682. //设置答案
  2683. //保存备选答案
  2684. var tempQuestions = null
  2685. $('#setAnswerBtn').click(function () {
  2686. self.showSettingAnswerArea()
  2687. tempQuestions = JSON.parse(JSON.stringify(self.questionMap))
  2688. $('#setAnswer').show()
  2689. })
  2690. $('#returnAnswer').click(function () {
  2691. tempQuestions = null
  2692. $('#setAnswer').hide()
  2693. })
  2694. $('#saveAnswer').click(function () {
  2695. self.questionMap = tempQuestions
  2696. tempQuestions = null
  2697. self.getSaveSubjectInfo(self.questionMap);
  2698. $('#setAnswer').hide()
  2699. })
  2700. //设置备选答案
  2701. $('.answerList').on('click', '.answesOption', function () {
  2702. var modelId = $(this).attr('data-id')
  2703. var _index = +$(this).attr('data-index')
  2704. var answer = $(this).attr('data-answer')
  2705. var modelQuestionType = tempQuestions[modelId].questionType
  2706. if (modelQuestionType === 1) {
  2707. if ($(this).hasClass('active')) return
  2708. $(this).addClass('active').siblings('i').removeClass('active')
  2709. tempQuestions[modelId].questions[_index].answer = answer
  2710. } else {
  2711. $(this).toggleClass('active');
  2712. // $(this).addClass('active');
  2713. var arrAnswer = ""
  2714. $(this).parent().find('.active').each(function (index) {
  2715. arrAnswer = arrAnswer + (arrAnswer.length > 0 ? ',' : '') + $(this).attr('data-answer')
  2716. // arrAnswer = arrAnswer + $(this).attr('data-answer')
  2717. })
  2718. tempQuestions[modelId].questions[_index].answer = arrAnswer
  2719. // console.log(tempQuestions,arrAnswer,22)
  2720. }
  2721. })
  2722. //公式编辑器插件
  2723. self.eventForFormula()
  2724. },
  2725. //公式编辑器相关事件
  2726. eventForFormula: function () {
  2727. var self = this
  2728. var curEditorFormula = null
  2729. $('body').on('click', '.kfformula,.gsImgLatex', function () {
  2730. if (!self.isCanEditCard) return
  2731. self.formulaing = true
  2732. $('#formulaBox').show()
  2733. curEditorFormula = $(this)
  2734. var imgLatex =
  2735. $(this).attr('data-latex') || $(this).attr('src').split('?')[1]
  2736. var latexUse = decodeURIComponent(imgLatex)
  2737. if (window.kfe) {
  2738. window.kfe.execCommand('render', latexUse || '\\placeholder')
  2739. } else {
  2740. window.factory = window.kf.EditorFactory.create(
  2741. $('#kfEditorContainer')[0],
  2742. {
  2743. render: {
  2744. fontsize: 18
  2745. },
  2746. resource: {
  2747. path: './kityformula/resource/'
  2748. }
  2749. }
  2750. )
  2751. window.factory.ready(function (KFEditor) {
  2752. KFEditor.execCommand('render', latexUse || '\\placeholder')
  2753. KFEditor.execCommand('focus')
  2754. window.kfe = KFEditor
  2755. })
  2756. $('#kf-formula-ensure')[0].onclick = function () {
  2757. window.kfe.execCommand('get.image.data', function (data) {
  2758. var latex = window.kfe.execCommand('get.source')
  2759. $.post(self.apis.getMathtexApi, { mathtex: latex }, function (res) {
  2760. var newh = self.unitConversion.pxConversionMm(res.height)
  2761. var neww = self.unitConversion.pxConversionMm(res.width)
  2762. var newLatexImg =
  2763. '<img src="{url}" class="gsImgLatex mathType" style="vertical-align: middle;height:{newh}mm;width:{neww}mm;" data-latex="{latex}">'
  2764. curEditorFormula[0].outerHTML = newLatexImg.substitute({
  2765. url: res.url,
  2766. latex: latex,
  2767. newh: newh,
  2768. neww: neww
  2769. })
  2770. })
  2771. return true
  2772. })
  2773. $('#formulaBox').hide()
  2774. self.formulaing = false
  2775. return false
  2776. }
  2777. $('#kf-formula-cancel')
  2778. .off('click')
  2779. .click(function () {
  2780. $('#formulaBox').hide()
  2781. self.formulaing = false
  2782. })
  2783. }
  2784. })
  2785. },
  2786. showSettingAnswerArea: function () {
  2787. var self = this
  2788. var answerItemTpl =
  2789. '<div class="answerItem">\
  2790. <span>{questionNum}</span>\
  2791. <span>{questionName}</span>\
  2792. <p>{answers}</p>\
  2793. </div>'
  2794. //拿到主观题数据
  2795. // 通过modelId 和 题目索引来定位一个题
  2796. var questionClassify = self.questionMap
  2797. var answerHtml = ''
  2798. for (var modelId in questionClassify) {
  2799. var modelData = questionClassify[modelId]
  2800. var modelType = modelData.questionType
  2801. if (!~[1, 2, 11].indexOf(modelType)) continue
  2802. answerHtml += modelData.questions.reduce(function (
  2803. answerItemHtml,
  2804. cur,
  2805. index
  2806. ) {
  2807. var selectHtml = ''
  2808. for (var i = 0; i < cur.optionCount; i++) {
  2809. var content = String.fromCharCode(65 + i)
  2810. var activeClass = ''
  2811. var isActiveOption = cur.answer.indexOf(content)
  2812. if (isActiveOption > -1) activeClass = 'active'
  2813. selectHtml += '<i class="answesOption {activeClass}" data-id="{modelId}" data-index="{index}" data-answer="{content}">{content}</i>'.substitute(
  2814. {
  2815. content: content,
  2816. modelId: modelId,
  2817. index: index,
  2818. activeClass: activeClass
  2819. }
  2820. )
  2821. }
  2822. answerItemHtml += answerItemTpl.substitute({
  2823. questionNum: cur.questionNum,
  2824. questionName: self.questionNameMap[self.questionTypeMapForC[modelType]],
  2825. answers: selectHtml
  2826. })
  2827. return answerItemHtml
  2828. },
  2829. '')
  2830. }
  2831. $('#answerList').html(answerHtml)
  2832. },
  2833. //修改答题卡编辑状态
  2834. changeCardEditStatus: function () {
  2835. var self = this
  2836. $('#dtkName textarea').prop('disabled', !self.isCanEditCard)
  2837. $('#examInfo input').prop('disabled', !self.isCanEditCard)
  2838. $('#saveBtn').html(self.isCanEditCard ? '保存' : '编辑')
  2839. $('#downLoadBtn')[self.isCanEditCard ? 'addClass' : 'removeClass'](
  2840. 'disabled'
  2841. )
  2842. //右侧操作栏目
  2843. $('#disabledCover')[self.isCanEditCard ? 'hide' : 'show']()
  2844. //题干信息
  2845. $('.objectiveItem').each(function () {
  2846. $(this).prop('contenteditable', self.isCanEditCard)
  2847. })
  2848. //编辑器
  2849. for (var editorId in self.editorArea) {
  2850. self.editorArea[editorId].$textElem.attr(
  2851. 'contenteditable',
  2852. self.isCanEditCard
  2853. )
  2854. }
  2855. //标题
  2856. $('.answerModule h3').each(function () {
  2857. $(this).prop('contenteditable', self.isCanEditCard)
  2858. })
  2859. },
  2860. //检测是否有已经生成的答题卡
  2861. judgeHasPrintClass: function (cb) {
  2862. var self = this
  2863. if (self.printClassStatus) {
  2864. self.modal.init({
  2865. title: '批量生成',
  2866. content: '保存后,会重置原答题卡数据,将恢复班级/学生的打印状态,且可能会导致已打印出的答题卡扫描无效,请谨慎操作!',
  2867. sureCb: function () {
  2868. cb && cb()
  2869. }
  2870. })
  2871. } else {
  2872. cb && cb()
  2873. }
  2874. },
  2875. //根据选择排版方向设置答题卡的视觉排版宽高
  2876. setPageWidthHeightForDirection: function (direction) {
  2877. var self = this
  2878. var isVertical = direction === 'vertical'
  2879. //设置横竖版面
  2880. self.config[isVertical ? 'width' : 'height'] = self.configOrigin.width
  2881. self.config[isVertical ? 'height' : 'width'] = self.configOrigin.height
  2882. },
  2883. //点击选择纸张联动,纸张方向和纸张分栏选择
  2884. linkageForPaper: function (paper) {
  2885. var self = this
  2886. // '8K': {
  2887. // width: 267,
  2888. // height: 390,
  2889. // direction: {
  2890. // horizontal: [2, 3]
  2891. // }
  2892. // },
  2893. //layoutList
  2894. self.config = simpleCopy(sizeConfig[paper])
  2895. self.configOrigin = simpleCopy(sizeConfig[paper])
  2896. var directions = self.config.direction
  2897. var isPaperDirectionStop = false
  2898. $('#paperDirection .h_radioItem').each(function () {
  2899. var direction = $(this).attr('data-direction')
  2900. if (direction in directions) {
  2901. $(this).removeClass('disabled')
  2902. if (!isPaperDirectionStop) {
  2903. isPaperDirectionStop = true
  2904. $(this).trigger('click')
  2905. }
  2906. } else {
  2907. $(this).addClass('disabled')
  2908. }
  2909. })
  2910. },
  2911. //点击选择纸张方向联动 分栏选择
  2912. linkageForDirection: function (columns) {
  2913. var self = this
  2914. var isLayoutItemStop = false
  2915. let isClick = 0
  2916. self.$layoutItem.each(function () {
  2917. var $this = $(this)
  2918. var dataColumn = +$this.attr('data-column')
  2919. if (~columns.indexOf(dataColumn)) {
  2920. if(isClick==0){
  2921. isClick = dataColumn
  2922. } else {
  2923. if(self.columns == dataColumn){
  2924. isClick = dataColumn
  2925. }
  2926. }
  2927. }
  2928. })
  2929. self.columns = isClick
  2930. self.$layoutItem.each(function () {
  2931. var $this = $(this)
  2932. var dataColumn = +$this.attr('data-column')
  2933. if (~columns.indexOf(dataColumn)) {
  2934. $this.removeClass('disabled')
  2935. if(self.columns){
  2936. if(self.columns == dataColumn){
  2937. isLayoutItemStop = true
  2938. $this.trigger('click')
  2939. }
  2940. } else {
  2941. if (!isLayoutItemStop) {
  2942. isLayoutItemStop = true
  2943. $this.trigger('click')
  2944. }
  2945. }
  2946. } else {
  2947. $this.addClass('disabled')
  2948. }
  2949. })
  2950. },
  2951. //获取settingBtn
  2952. getSettingBtn: function (modelId) {
  2953. var $settingBtn = null
  2954. $('#printcontent .answerModule').each(function () {
  2955. if ($(this).attr('data-modelId') === modelId && !$settingBtn) {
  2956. $settingBtn = $(this).find('.settingBtn')
  2957. }
  2958. })
  2959. return $settingBtn
  2960. },
  2961. //获取大题模块
  2962. getAnswerModuleForModelId: function (modelId) {
  2963. var $answerModule = null
  2964. $('#printcontent .answerModule').each(function () {
  2965. if ($(this).attr('data-modelId') === modelId && !$answerModule) {
  2966. $answerModule = $(this)
  2967. }
  2968. })
  2969. return $answerModule
  2970. },
  2971. //选择题
  2972. selectSetLayout: function ($this, type) {
  2973. var self = this
  2974. var memoryDirection = $this.closest('.answerModule').attr('data-direction')
  2975. var directionCheckMap = {
  2976. vertical: 'verticalChecked',
  2977. horizontal: 'horizontalChecked'
  2978. }
  2979. var substituteData = {}
  2980. substituteData[directionCheckMap[memoryDirection]] = 'checked'
  2981. var tempDirection = ''
  2982. self.modal.init({
  2983. title: '选择题设置',
  2984. content: self.tpls.selectSetTpl.substitute(substituteData),
  2985. afterCb: function () {
  2986. new RadioBoxItem($('#selectDirection'), function ($radioItem, status) {
  2987. var direction = $radioItem.attr('data-value')
  2988. tempDirection = direction
  2989. })
  2990. },
  2991. sureCb: function () {
  2992. self.selectStyleChange($this, tempDirection)
  2993. }
  2994. })
  2995. },
  2996. selectStyleChange: function ($this, direction) {
  2997. var self = this
  2998. var curPageIndex = $this.closest('.pageContent').index() + 1
  2999. var $selectModule = $this.closest('.single-select')
  3000. var $curPage = $this.closest('.pageContent')
  3001. var modelId = $selectModule.attr('data-modelId')
  3002. var modelData = self.questionMap[modelId]
  3003. var modelPagesData = modelData.pages
  3004. //modelData.direction = direction
  3005. function setDirection($selectModule) {
  3006. if (!$selectModule.hasClass(direction)) {
  3007. var isHorizontal = direction === 'horizontal'
  3008. $selectModule
  3009. .removeClass(isHorizontal ? 'vertical' : 'horizontal')
  3010. .addClass(isHorizontal ? 'horizontal' : 'vertical')
  3011. .attr('data-direction', direction)
  3012. }
  3013. curPageIndex++
  3014. if (modelPagesData[curPageIndex]) {
  3015. var $nextPage = $('.pageContent').eq(curPageIndex - 1)
  3016. var $nextPageFirstSelect = $nextPage.find('.single-select').eq(0)
  3017. if ($nextPageFirstSelect.attr('data-modelId') === modelId) {
  3018. setDirection($nextPageFirstSelect)
  3019. }
  3020. }
  3021. }
  3022. setDirection($selectModule)
  3023. self.changePrintArea($curPage)
  3024. },
  3025. //填空题设置
  3026. fillInBlankSet: function ($this) {
  3027. var self = this
  3028. var $subjectCol = $this.siblings('.subjectCol')
  3029. var columnSelectedMap = {
  3030. 1: 'columnOneSelected',
  3031. 2: 'columnTwoSelected',
  3032. 3: 'columnThreeSelected'
  3033. }
  3034. var rowLineHeightSelectedMap = {
  3035. 25: 'rowLineOneSelected',
  3036. 30: 'rowLineTwoSelected',
  3037. 35: 'rowLineThreeSelected',
  3038. 40: 'rowLineFourSelected',
  3039. 45: 'rowLineFiveSelected',
  3040. 50: 'rowLineSixSelected'
  3041. }
  3042. var scoreSelectedMap = {
  3043. '2/3/5': 'scoreOneSelected',
  3044. '2/3/4/6': 'scoreTwoSelected',
  3045. '2/4': 'scoreThreeSelected'
  3046. }
  3047. var memoryColumn = $subjectCol.attr('data-column') || 1
  3048. var memoryColumnRowLineHeight = $subjectCol.attr('data-rowLineHeight') || 40
  3049. var memoryScoreStyle = $subjectCol.attr('data-scoreStyle') || ''
  3050. var maxScore = $subjectCol
  3051. .children('.subjectItem')
  3052. .eq(0)
  3053. .attr('data-fullScore')
  3054. var substituteData = {}
  3055. substituteData[columnSelectedMap[memoryColumn]] = 'selected'
  3056. substituteData[rowLineHeightSelectedMap[memoryColumnRowLineHeight]] =
  3057. 'selected'
  3058. substituteData[scoreSelectedMap[memoryScoreStyle]] = 'selected'
  3059. for (var scoreFormat in scoreSelectedMap) {
  3060. if (!~scoreFormat.split('/').indexOf(maxScore)) {
  3061. substituteData[scoreSelectedMap[scoreFormat]] = 'disabled'
  3062. }
  3063. }
  3064. self.modal.init({
  3065. title: '填空题设置',
  3066. content: self.tpls.fillInBlankSetTpl.substitute(substituteData),
  3067. sureCb: function () {
  3068. //每行列数
  3069. var column = $('#fillInBlankColumn').val()
  3070. //行间距
  3071. var rowLinHeight = $('#fillInBlankLineHeight').val()
  3072. //手写打分
  3073. var scoreStyle = $('#scoringBox').val()
  3074. //修改填空题样式
  3075. self.fillInBlankStyleChange($this, column, rowLinHeight, scoreStyle)
  3076. }
  3077. })
  3078. },
  3079. fillInBlankStyleChange: function ($this, column, rowLinHeight, scoreStyle) {
  3080. var self = this
  3081. var curPageEl = $this.closest('.pageContent')
  3082. var modelId = $this.closest('.answerModule').attr('data-modelId')
  3083. var $fillInBlankCol = $('.pageContent').find('.subjectCol')
  3084. scoreStyle = scoreStyle || ''
  3085. //重新计算fillInBlank 查看是否需要修改手动打分样式
  3086. self.calcFillInBlankData(modelId, scoreStyle)
  3087. self.reRenderFillInBlank(modelId)
  3088. $fillInBlankCol.attr({
  3089. 'data-column': column,
  3090. 'data-rowLineHeight': rowLinHeight,
  3091. 'data-scoreStyle': scoreStyle,
  3092. class: 'subjectCol clearfix col-' + column + ' rowLineHeight-' + rowLinHeight
  3093. })
  3094. //如果填空题由原来的一行变成多行,就有可能影响所有的布局样式,重新布局整个答题卡
  3095. //fiexd:curPageEl 需要修改成该填空题答题最后数据所在的pageEl
  3096. self.changePrintArea(curPageEl)
  3097. },
  3098. //解答题设置
  3099. shortAnswerSet: function ($this) {
  3100. var self = this
  3101. var $module = $this.closest('.module')
  3102. var memoryScoreLimitKey = $module.attr('scoreLimit')
  3103. var fullScore = +$module.attr('data-fullScore')
  3104. var memoryIsAddHalf = $module.attr('isAddHalf') === 'true'
  3105. var disabledScoreKey
  3106. var limitSelectedMap = {
  3107. 15: 'limit15selected',
  3108. 16: 'limit16selected',
  3109. 29: 'limit29selected',
  3110. 49: 'limit49selected'
  3111. }
  3112. //禁用标识
  3113. var disabledSelectMap = {
  3114. 15: 'disabled15',
  3115. 16: 'disabled16',
  3116. 29: 'disabled29',
  3117. 49: 'disabled49'
  3118. }
  3119. var formatParam = {}
  3120. formatParam[limitSelectedMap[memoryScoreLimitKey]] = 'selected'
  3121. formatParam.isAddHalfChecked = memoryIsAddHalf ? 'checked' : ''
  3122. for (var scoreLimit in self.answerScoreLimitKeyArr) {
  3123. if (scoreLimit < fullScore) {
  3124. formatParam[disabledSelectMap[scoreLimit]] = 'disabled'
  3125. }
  3126. }
  3127. self.modal.init({
  3128. title: '解答题设置',
  3129. content: self.tpls.shortAnswerOptionTpl.substitute(formatParam),
  3130. sureCb: function () {
  3131. var scoreLimitKey = $('#scoreLimit').val()
  3132. var isAddHalf = $('#isAddHalf').prop('checked')
  3133. self.shortAnswerStyleChange($this, scoreLimitKey, isAddHalf)
  3134. }
  3135. })
  3136. },
  3137. /**
  3138. * @param {当前要修改的解答题区域内的标示符} $this
  3139. * @param {分值上限} scoreLimitKey
  3140. */
  3141. shortAnswerStyleChange: function ($this, scoreLimitKey, isAddHalf, topicScore) {
  3142. var self = this
  3143. var scorePartEl = $this.siblings('.scortColumn')
  3144. var colClass = 'col-' + scoreLimitKey
  3145. var scoreModuleHtml = self.generateScoreBox(scoreLimitKey, isAddHalf, topicScore)
  3146. //解答题分值上限配置
  3147. scorePartEl
  3148. .html(scoreModuleHtml)
  3149. .attr('class', 'scortColumn clearfix ' + colClass)
  3150. .parent('.module')
  3151. .attr('scoreLimit', scoreLimitKey)
  3152. .attr('isAddHalf', isAddHalf)
  3153. },
  3154. generateScoreBox: function (scoreLimitKey, isAddHalf, topicScore) {
  3155. var self = this
  3156. function rendScore(score) {
  3157. return '<span>' + score + '</span>'
  3158. }
  3159. var bit = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  3160. //各个分值对应的分值 布局格式
  3161. var scoreLimitMap = {
  3162. '16': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
  3163. '15': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
  3164. '29': {
  3165. tenPlace: [1, 2],
  3166. bit: bit
  3167. },
  3168. '49': {
  3169. tenPlace: [1, 2, 3, 4],
  3170. bit: bit
  3171. },
  3172. '69': {
  3173. tenPlace: [1, 2, 3, 4, 5, 6],
  3174. bit: bit
  3175. }
  3176. }
  3177. var scoreLimit = scoreLimitMap[scoreLimitKey]
  3178. var scoreModuleHtml = ''
  3179. var scoreLimitArr = []
  3180. var noScoringW = 42
  3181. let pw = $('#printcontent').width();
  3182. noScoringW = pw/17
  3183. // switch (self.paper) {
  3184. // case 'A4':
  3185. // case '16K':
  3186. // noScoringW = 22
  3187. // break
  3188. // default:
  3189. // noScoringW = 42
  3190. // break
  3191. // }
  3192. if (~'16|15'.indexOf(scoreLimitKey)) {
  3193. if (Number(topicScore) < Number(scoreLimitKey)) {
  3194. for (let index = 0; index < topicScore; index++) {
  3195. scoreLimitArr.push(index + 1)
  3196. }
  3197. } else {
  3198. scoreLimitArr = scoreLimit
  3199. }
  3200. } else {
  3201. scoreLimitArr.push('十位')
  3202. scoreLimitArr = scoreLimitArr.concat(scoreLimit.tenPlace)
  3203. scoreLimitArr.push('个位')
  3204. scoreLimitArr = scoreLimitArr.concat(scoreLimit.bit)
  3205. }
  3206. //是否增加0.5分机制
  3207. isAddHalf && scoreLimitArr.push('0.5')
  3208. scoreLimitArr.forEach(function (score, index) {
  3209. scoreModuleHtml += rendScore(score)
  3210. })
  3211. if (Number(topicScore) < Number(scoreLimitKey) && Number(scoreLimitKey) < 17) {
  3212. let width = (15 - topicScore) * noScoringW;
  3213. if (width < 48) {
  3214. width = 48
  3215. }
  3216. scoreModuleHtml += "<span class='no-scoring' style='flex: initial; width:" + width + "px; color: #dddddd;'>禁打分区</span>"
  3217. }
  3218. return scoreModuleHtml
  3219. },
  3220. editNoScoringWidth: function () {
  3221. let pw = $('#printcontent').width();
  3222. $('.scortColumn').each(function(i,k){
  3223. let kL = $(k).find('span').length;
  3224. let kw = pw/17*(16-kL);
  3225. if(kw<48){
  3226. kw = 48
  3227. }
  3228. $(k).find('.no-scoring').width(kw);
  3229. })
  3230. },
  3231. //是否有装订线
  3232. ifBindingLine: function () {
  3233. var self = this
  3234. var curPageEl = self.$firstPageContent
  3235. var isUseClass = self.hasBindingLine ? 'addClass' : 'removeClass'
  3236. var isHideBinding = self.hasBindingLine ? 'show' : 'hide'
  3237. var isHideExamineeInfo = !self.hasBindingLine ? 'show' : 'hide'
  3238. $('#printcontent')
  3239. [isUseClass]('hasBindingLine')
  3240. .find('.bindingLine')
  3241. [isHideBinding]()
  3242. $('#examineeInfoForLayout')[isHideExamineeInfo]()
  3243. //隐藏考生的姓名 班级信息也会影响布局
  3244. self.changePrintArea(curPageEl)
  3245. },
  3246. //是否显示信息栏
  3247. isShowPaperMsg: function () {
  3248. var self = this
  3249. if (self.hasPaperMsg) {
  3250. // let examInfo ={}
  3251. // var examInfoHtml = self.tpls.examInfoTpl.substitute(examInfo)
  3252. // $('#examInfo').html(examInfoHtml)
  3253. self.showExamInfoHtml();
  3254. self.getSaveSubjectInfo(self.questionMap)
  3255. $('#examInfo').css('display', 'flex');
  3256. $('#hasPaperMsg').find('.h_radioItem').eq(0).addClass('checked')
  3257. $('#hasPaperMsg').find('.h_radioItem').eq(1).removeClass('checked')
  3258. } else {
  3259. $('#hasPaperMsg').find('.h_radioItem').eq(0).removeClass('checked')
  3260. $('#hasPaperMsg').find('.h_radioItem').eq(1).addClass('checked')
  3261. $('#printcontent').find('#examInfo').html('');
  3262. $('#examInfo').css('display', 'none');
  3263. }
  3264. },
  3265. //是否只使用条形码
  3266. isOnlyBarCode: function () {
  3267. var self = this
  3268. return self.examNumberConfig.barCode && !self.examNumberConfig.ticketNumber
  3269. },
  3270. //判断当前选中个数
  3271. getExamConfigSeledCount: function () {
  3272. var self = this
  3273. var seledCount = 0
  3274. //条形码 和 考号 至少选择一个
  3275. for (var examKey in self.examNumberConfig) {
  3276. if (self.examNumberConfig[examKey]) {
  3277. seledCount += 1
  3278. }
  3279. }
  3280. return seledCount
  3281. },
  3282. //选择考号版式
  3283. selExamNumberStyle: function ($this, singleStatus) {
  3284. var self = this
  3285. var value = $this.attr('data-value')
  3286. //当前选考号配置的数量
  3287. var curExamConfigCount = self.getExamConfigSeledCount()
  3288. if (!singleStatus && curExamConfigCount === 1) {
  3289. hgc_layer.msg('不使用二维码的情况下,填涂考号和条形码至少选择一个')
  3290. $this.trigger('click')
  3291. return
  3292. }
  3293. self.examNumberConfig[value] = singleStatus
  3294. $('#hgc_examNumber .' + value)[singleStatus ? 'show' : 'hide']()
  3295. //只使用条形码
  3296. var isOnlyBarCode = self.isOnlyBarCode()
  3297. $('#hgc_examNumber').css('display', isOnlyBarCode ? 'none' : 'flex')
  3298. $('#hgc_examNumberForOnlyBarcode').css(
  3299. 'display',
  3300. isOnlyBarCode ? 'flex' : 'none'
  3301. )
  3302. self.changePrintArea(self.$firstPageContent)
  3303. },
  3304. //选择信息栏显示模块
  3305. selExamInfoStyle: function ($this, singleStatus) {
  3306. var self = this
  3307. let value = $this.attr('data-value');
  3308. self.examInfoConfig[value] = singleStatus;
  3309. },
  3310. //更新label显示文本
  3311. refrushPageLabel: function () {
  3312. var self = this
  3313. $('.pageLabel').each(function (index, $label) {
  3314. var curTotalPage = index + 1
  3315. var currentPaper = Math.ceil((index + 1) / (self.columns * 2))
  3316. //第一张纸 正面1 正面2 第一张至反面1 反面2
  3317. var paperDirection =
  3318. (curTotalPage % (self.columns * 2)
  3319. ? curTotalPage % (self.columns * 2)
  3320. : self.columns * 2) <= self.columns
  3321. ? '正面'
  3322. : '反面'
  3323. var pageForPaperDirection =
  3324. curTotalPage % self.columns ? curTotalPage % self.columns : self.columns
  3325. var currentPaperPage = paperDirection + pageForPaperDirection
  3326. var labelHtml = self.tpls.pageLabelTpl.substitute({
  3327. currentPage: curTotalPage,
  3328. totalPage: self.totalPage,
  3329. currentPaper: currentPaper,
  3330. currentPaperPage: currentPaperPage
  3331. })
  3332. $(this).html(labelHtml)
  3333. })
  3334. },
  3335. //重新计算同一题相同模块的
  3336. //存储当前超出缺没有被执行超出事件的模块
  3337. forgetOverPage: null,
  3338. saveForgetPage: function (forgetPage) {
  3339. var self = this
  3340. //之前当前被遗忘的分页在前面,就可以直接替换
  3341. if (self.forgetOverPage) {
  3342. if (forgetPage.index() < self.forgetOverPage.index()) {
  3343. self.forgetOverPage = forgetPage
  3344. }
  3345. } else {
  3346. self.forgetOverPage = forgetPage
  3347. }
  3348. },
  3349. resetPrevEditorContent: function ($surplusModule, $prevModule) {
  3350. var self = this
  3351. var surplusModuleContentHeight = self.calcEditorContentHeight(
  3352. $surplusModule.find('.w-e-text')
  3353. )
  3354. var prevPage = $prevModule.closest('.pageContent')
  3355. var prevPageContentHeight = prevPage.height() - self.pagePadding * 2
  3356. //内容区域
  3357. var $prevContentArea = $prevModule.find('.w-e-text-container')
  3358. var prevEditorIndex = $prevModule.attr('data-editorIndex')
  3359. var surplusEditorIndex = $surplusModule.attr('data-editorIndex')
  3360. var surplusEditorContent = self.editorArea[
  3361. 'editor' + surplusEditorIndex
  3362. ].txt
  3363. .html()
  3364. .clearFixible()
  3365. var prevEditorContent = self.editorArea['editor' + prevEditorIndex].txt
  3366. .html()
  3367. .clearFixible()
  3368. var prevCalcHeight = $prevContentArea.height() + surplusModuleContentHeight
  3369. self.editorArea['editor' + prevEditorIndex].txt.html(
  3370. (
  3371. prevEditorContent +
  3372. surplusEditorContent +
  3373. self.tpls.flexibleIconTpl
  3374. ).replace(self.replaceEditorRegexp, '')
  3375. )
  3376. $prevContentArea.height(prevCalcHeight)
  3377. if (self.getOverHeight($prevModule) > 0) {
  3378. //之前当前被遗忘的分页在前面,就可以直接替换
  3379. self.saveForgetPage(prevPage)
  3380. }
  3381. },
  3382. /**
  3383. * 删除一个分页超出的部分
  3384. * @param {*} $delBtn 删除按钮
  3385. * @param {el} type 下面两种类型的值 over surplus
  3386. * @param {boolean} isUserTrigger 是否用户主动手动触发---触发
  3387. * 1 上一页有超出模块,下一页的补充模块需要删除的情况
  3388. * 2 上一页有剩余空间,下一页的补充模块一样需要删除的情况
  3389. * 两种情况计算当前需要删除的补充模块的上一个模块的方式有所不同
  3390. */
  3391. //判断是不是补充模块
  3392. isSurplusModule: function (module) {
  3393. return typeof module.attr('isSurplus') === 'string'
  3394. },
  3395. //需要把内容部分全部移到上面的部分,然后上面的高度要重置一下
  3396. delPageOverPart: function ($delBtn, type, isUserTrigger) {
  3397. var self = this
  3398. var answerModel = $delBtn.closest('.short-answer')
  3399. var delModel = $delBtn.closest('.module')
  3400. var delPage = delModel.closest('.pageContent')
  3401. var prevPage = delPage.prev()
  3402. //默认上一页有超出模块的时候计算方式
  3403. var memoryPrevModule = delModel
  3404. .closest('.answerModule')
  3405. .prev('.answerModule')
  3406. .children('.module:last()')
  3407. var prevPageLastEditor = memoryPrevModule.children('.editorContent')
  3408. //如果是上一页有剩余空间才来的话
  3409. if (type === 'surplus') {
  3410. var loopPrevPage = delPage.prev()
  3411. while (!memoryPrevModule.length) {
  3412. memoryPrevModule = loopPrevPage.find('.module:last()')
  3413. loopPrevPage = loopPrevPage.prev()
  3414. }
  3415. }
  3416. self.resetPrevEditorContent(delModel, memoryPrevModule)
  3417. prevPageLastEditor.height(
  3418. prevPageLastEditor.height() - self.modulePaddingBottom
  3419. )
  3420. delModel.remove()
  3421. self.updatePageElement(delPage, answerModel)
  3422. //判断上一个模块是否是第一个链接模块
  3423. // if (prevPageLastModule.attr('data-linkparm') === '1') {
  3424. // prevPageLastModule.removeAttr('data-linkparm')
  3425. // }
  3426. if (!answerModel.children('.module').length) answerModel.remove()
  3427. if (isUserTrigger) {
  3428. self.changePrintArea(delPage)
  3429. }
  3430. },
  3431. /**
  3432. * 获取超出当前page的模块 作答大题区域模块 作答小题区域模块
  3433. * @return {answerModule,subjectModule}
  3434. */
  3435. getOverModule: function (curPageEl) {
  3436. var self = this
  3437. var overPart = false
  3438. //当前第几页,用做后面计算的高度距离的倍数
  3439. var times = curPageEl.index() + 1
  3440. //判断超出当前页面的条件
  3441. var overHeight =
  3442. self.pageHeight * times + self.layoutPadding - self.pagePadding
  3443. //判断当前区域是否超出
  3444. function isOver(el) {
  3445. var moduleTop =
  3446. $(el).outerHeight() + $(el).offset().top + $('#contentWrap').scrollTop()
  3447. return moduleTop >= overHeight
  3448. }
  3449. /**
  3450. * 1 判断当前页面里面的答题区域内容是否超过了当前页面所能承受的内容的高度
  3451. * a 如果超出了,从当前移动的那个模块开始向后判断,取出所有超出的模块
  3452. * I 在下一页的排版中,如果下一页存在直接插入最前面,如果不存在,直接新建一页==>>然后循环【1】操作
  3453. * b 如果没有超出直接退出
  3454. */
  3455. //需要判断当前page里面所有模块是否有超出
  3456. //当前答题卡区域
  3457. var curDtkPartEl = curPageEl.children('.dtk-content')
  3458. if (curDtkPartEl.height() + self.pagePadding * 2 >= self.pageHeight) {
  3459. //区分原题题干和答题区域
  3460. var shortAnswerEl = [].splice.call(
  3461. curDtkPartEl.children('.answerModule'),
  3462. 0
  3463. )
  3464. //var shortAnswerEl = objectiveModule.concat(shortANswerModule)
  3465. for (var i = 0, ilen = shortAnswerEl.length; i < ilen; i++) {
  3466. var shortAnswerItem = $(shortAnswerEl[i])
  3467. //找到第一个超过当前页面的元素,把这个以及以后的模块提取出来在下一个版面进行重新排版
  3468. //得到第一个大题的index 第一个大题下面小题的index
  3469. if (isOver(shortAnswerItem)) {
  3470. var answerType = shortAnswerItem.attr('data-type')
  3471. var isChooseAnswer = answerType === 'chooseAnswer'
  3472. var hasObjective = shortAnswerItem.find('.originSubjectInfo').length
  3473. var isObjective = answerType === 'objective'
  3474. var childrenSelector =
  3475. isChooseAnswer && hasObjective
  3476. ? ''
  3477. : isObjective
  3478. ? '.objectiveItem'
  3479. : '.module'
  3480. var moduleEl = $(shortAnswerItem).children(childrenSelector)
  3481. for (var m = 0, mlen = moduleEl.length; m < mlen; m++) {
  3482. var moduleItem = moduleEl.eq(m)
  3483. if (isOver(moduleItem)) {
  3484. var subjectModule = null
  3485. //选做题如果题干信息超出的话,也特殊模块超出,因为选做题模块可能很长
  3486. var objectiveModule = null
  3487. if (isChooseAnswer) {
  3488. if (moduleItem[0].tagName === 'H3') {
  3489. objectiveModule = moduleItem
  3490. if (moduleItem.next().length) {
  3491. subjectModule = moduleItem.next()
  3492. }
  3493. } else {
  3494. subjectModule = moduleItem
  3495. }
  3496. } else {
  3497. subjectModule = moduleItem
  3498. }
  3499. overPart = {
  3500. curPage: curPageEl,
  3501. //当前超出的answerModule
  3502. answerModule: shortAnswerItem,
  3503. //当前超出的module
  3504. subjectModule: subjectModule,
  3505. //当前超出的选做题题干信息
  3506. objectiveModule: objectiveModule
  3507. }
  3508. return overPart
  3509. }
  3510. }
  3511. }
  3512. }
  3513. }
  3514. return overPart
  3515. },
  3516. //获取超出模块高度
  3517. getOverHeight: function (el) {
  3518. var self = this
  3519. var curPageEl = $(el).closest('.pageContent')
  3520. //当前第几页,用做后面计算的高度距离的倍数
  3521. var times = curPageEl.index() + 1
  3522. var overHeight =
  3523. self.pageHeight * times + self.layoutPadding - self.pagePadding
  3524. var moduleTop =
  3525. $(el).outerHeight() + $(el).offset().top + $('#contentWrap').scrollTop()
  3526. return moduleTop - overHeight - 4
  3527. },
  3528. //根据缩放的要求拓宽需要打印的区域
  3529. /*
  3530. * 1拓宽打印区域
  3531. * 2减小打印区域
  3532. */
  3533. changePrintArea: function (curPageEl) {
  3534. var self = this
  3535. if (self.forgetOverPage && self.forgetOverPage[0] === curPageEl[0]) {
  3536. self.forgetOverPage = null
  3537. }
  3538. //找出超出的区域
  3539. var overPart = self.getOverModule(curPageEl)
  3540. if (overPart) {
  3541. //填空题选择题特殊对待
  3542. var moduleType = overPart.answerModule.attr('data-type')
  3543. if (moduleType === 'fillInBlank') {
  3544. self.addPrintForFillInBlank(curPageEl, overPart)
  3545. } else if (~moduleType.indexOf('Select') ||~moduleType.indexOf('uncertainOption')) {
  3546. self.addPrintForSelect(curPageEl, overPart, moduleType)
  3547. } else if (moduleType === 'objective') {
  3548. self.addPrintForObjective(curPageEl, overPart)
  3549. self.judegeImgsLoaded('.objectiveItem')
  3550. } else {
  3551. self.addPrintForAnswer(curPageEl, overPart)
  3552. }
  3553. } else {
  3554. self.reducePrintArea(curPageEl)
  3555. }
  3556. },
  3557. showExamInfoHtml: function () {
  3558. if(!this.hasPaperMsg){
  3559. return false
  3560. }
  3561. let examInfoHtml = '';
  3562. if (this.examInfoConfig.wpTimes) {
  3563. if(this.examInfoConfigText.wpTimes == undefined) {
  3564. this.examInfoConfigText.wpTimes = ''
  3565. }
  3566. examInfoHtml += '<span>时间:<input class="input-examInfo time" name="wpTimes" maxlength="3" value="' + this.examInfoConfigText.wpTimes + '"></input>分钟</span>'
  3567. }
  3568. if (this.examInfoConfig.fullScore) {
  3569. if(this.examInfoConfigText.fullScore == undefined) {
  3570. this.examInfoConfigText.fullScore = ''
  3571. }
  3572. examInfoHtml += '<span>满分:<input readonly="readonly" class="input-examInfo fraction" name="fullScore" maxlength="3" value="' + this.examInfoConfigText.fullScore + '"></input>分</span>'
  3573. }
  3574. if (this.examInfoConfig.wpAuthor) {
  3575. if(this.examInfoConfigText.wpAuthor == undefined) {
  3576. this.examInfoConfigText.wpAuthor = ''
  3577. }
  3578. examInfoHtml += '<span>命卷人:<input class="input-examInfo" name="wpAuthor" maxlength="9" value="' + this.examInfoConfigText.wpAuthor + '"></input></span>'
  3579. }
  3580. if (this.examInfoConfig.wpReviewer) {
  3581. if(this.examInfoConfigText.wpReviewer == undefined) {
  3582. this.examInfoConfigText.wpReviewer = ''
  3583. }
  3584. examInfoHtml += '<span>审核人:<input class="input-examInfo" name="wpReviewer" maxlength="9" value="' + this.examInfoConfigText.wpReviewer + '"></input></span>'
  3585. }
  3586. examInfoHtml += '<div class="btn-examInfo"></div>'
  3587. $('#examInfo').html(examInfoHtml);
  3588. if (examInfoHtml.length < 33) {
  3589. $('#hasPaperMsg').find('.h_radioItem').removeClass('checked')
  3590. $('#hasPaperMsg').find('.h_radioItem').eq(1).addClass('checked')
  3591. $('#examInfo').css('display', 'none')
  3592. } else {
  3593. $('#hasPaperMsg').find('.h_radioItem').removeClass('checked')
  3594. $('#hasPaperMsg').find('.h_radioItem').eq(0).addClass('checked')
  3595. $('#examInfo').css('display', 'flex')
  3596. }
  3597. },
  3598. //重新计算填空题渲染数据,改变填空题手动打分分值样式
  3599. calcFillInBlankData: function (modelId, scoreStyle) {
  3600. var fillInBlankData = this.questionMap[modelId].pages
  3601. for (var pageKey in fillInBlankData) {
  3602. if (fillInBlankData[pageKey].length) {
  3603. fillInBlankData[pageKey] = fillInBlankData[pageKey].map(function (
  3604. item
  3605. ) {
  3606. item.scoreStyle = scoreStyle
  3607. return item
  3608. })
  3609. }
  3610. }
  3611. },
  3612. //题干区域超出
  3613. addPrintForObjective: function (curPageEl, overPart) {
  3614. var self = this
  3615. var curPageIndex = curPageEl.index()
  3616. var times = curPageIndex + 1
  3617. var part = overPart.subjectModule
  3618. //判断超出简答题区域
  3619. var overAnswerModule = overPart.answerModule
  3620. //超出区域模块的题型
  3621. var overAnswerModuleType = overAnswerModule.attr('data-type') || 'objective'
  3622. var resetEditorIds = []
  3623. //简答小题
  3624. var subjectHtml = ''
  3625. //合并的简答题区域
  3626. var overAnswerHtml = ''
  3627. //通过缩放确定每个页面需要移除的元素
  3628. var removeElements = []
  3629. var nextPageEl = curPageEl.next()
  3630. //首先判断是要删除下一个分页的补充模块如果下一个分页存在的话
  3631. var nextPageFirstModule = null
  3632. if (nextPageEl.length) {
  3633. nextPageFirstModule = nextPageEl.find('.module').eq(0)
  3634. }
  3635. while (part.length) {
  3636. subjectHtml += self.addNewModuleForObjective(
  3637. part,
  3638. overAnswerModuleType,
  3639. removeElements
  3640. )
  3641. part = part.next()
  3642. }
  3643. //根据module 的data-type来确定使用的module 模板
  3644. var tplForTypeMap = {
  3645. singleSelect: 'selectTpl',
  3646. moreSelect: 'selectTpl',
  3647. fillInBlank: 'answerModulForFillInBlankTpl',
  3648. answer: 'answerModuleTpl',
  3649. chooseAnswer: 'answerModuleTpl',
  3650. mustAnswer: 'answerModuleTpl',
  3651. objective: 'objectiveWrapTpl'
  3652. }
  3653. //超出模块
  3654. while (overAnswerModule.length) {
  3655. var editModuleHtml = ''
  3656. var moduleTitle = ''
  3657. overAnswerModuleType = overAnswerModule.attr('data-type')
  3658. var modelId = overAnswerModule.attr('data-modelId')
  3659. var isObjective = overAnswerModuleType === 'objective'
  3660. var direction = overAnswerModule.attr('data-direction')
  3661. var isSelect = ~overAnswerModuleType.indexOf('Select')
  3662. //如果是当前超出模块,则直接用上面的多余的moduleHtml来填充
  3663. //否则,直接用answerModule的内容来填充
  3664. if (overAnswerModule[0] === overPart.answerModule[0]) {
  3665. editModuleHtml = subjectHtml
  3666. } else {
  3667. //如果下一个大模块是选做题,并且只有选做题提文字信息
  3668. if (
  3669. overAnswerModuleType === 'chooseAnswer' &&
  3670. !overAnswerModule.find('.module').length &&
  3671. overAnswerModule.children().length &&
  3672. overAnswerModule.find('.originSubjectInfo').length
  3673. ) {
  3674. var objectiveReg = /<div class="originSubjectInfo">(.*)<\/div>/
  3675. var objectiveRegG = /<div class="originSubjectInfo">(.*)<\/div>/g
  3676. //超出的选做题标题元素
  3677. var overAnswerModuleH3Html = overAnswerModule.find('h3')[0].outerHTML
  3678. //超出选做题标题的题干内容
  3679. var overAnswerModuleH3ObjectiveHtml = overAnswerModuleH3Html.match(
  3680. objectiveReg
  3681. )[1]
  3682. var nextPageFirstH3 = nextPageFirstAnswerModule.children('h3')
  3683. if (nextPageFirstH3.length) {
  3684. var nextPageFIrstH3ObjectiveHtml = nextPageFirstH3
  3685. .children('.originSubjectInfo')
  3686. .html()
  3687. //如果下一页存在选做题h3 则 需要拿当前的h3 做替换
  3688. nextPageFirstH3[0].outerHTML = overAnswerModuleH3Html.replace(
  3689. objectiveRegG,
  3690. '<div class="originSubjectInfo">' +
  3691. overAnswerModuleH3ObjectiveHtml +
  3692. nextPageFIrstH3ObjectiveHtml +
  3693. '</div>'
  3694. )
  3695. } else {
  3696. //如果下一页没有标题,直接插入到下一个模块的
  3697. // subjectHtml = nextPageFirstH3.children('.originSubjectInfo').prepend(overAnswerModule[0].outerHTML.replace(objectiveRegG,'<div class="originSubjectInfo">'+curPageH3ObjectiveHtml+'<\/div>'))
  3698. subjectHtml = overAnswerModule.children('h3')[0].outerHTML
  3699. nextPageFirstAnswerModule.prepend(subjectHtml)
  3700. }
  3701. overAnswerModule.remove()
  3702. break
  3703. }
  3704. var isSelect = ~overAnswerModuleType.indexOf('Select')
  3705. var isFillInBlank = overAnswerModuleType === 'fillInBlank'
  3706. self.resetPageDataForSubject(
  3707. overAnswerModule,
  3708. times,
  3709. resetEditorIds,
  3710. nextPageEl
  3711. )
  3712. if (isSelect || isFillInBlank) {
  3713. moduleTitle = self.titleHtml(self.questionMap[modelId].bigTitle)
  3714. if (isSelect) {
  3715. editModuleHtml =
  3716. '<div class="single-option more-option clearfix">' +
  3717. overAnswerModule.find('.single-option').html() +
  3718. '</div>'
  3719. }
  3720. }
  3721. if (!isSelect) editModuleHtml = overAnswerModule.html()
  3722. removeElements.push(overAnswerModule)
  3723. }
  3724. overAnswerHtml += self.tpls[
  3725. tplForTypeMap[overAnswerModuleType]
  3726. ].substitute({
  3727. editModule: editModuleHtml,
  3728. moduleType: overAnswerModuleType,
  3729. selectType: overAnswerModuleType,
  3730. selectContent: editModuleHtml,
  3731. direction: direction,
  3732. title: moduleTitle
  3733. })
  3734. overAnswerModule = overAnswerModule.next()
  3735. }
  3736. /**
  3737. * 【优化】
  3738. * 模块删除关系需要优化
  3739. */
  3740. removeElements.forEach(function (element) {
  3741. $(element).remove()
  3742. })
  3743. if (!overPart.answerModule.children('.objectiveItem').length)
  3744. overPart.answerModule.remove()
  3745. //是否存在下一个分页
  3746. if (nextPageEl.length) {
  3747. nextPageEl.children('.dtk-content').prepend(overAnswerHtml)
  3748. if (self.isSurplusModule(nextPageFirstModule)) {
  3749. self.delPageOverPart(nextPageFirstModule.children('.delBtn'), 'over')
  3750. }
  3751. } else {
  3752. self.addPage(overAnswerHtml)
  3753. nextPageEl = $('#printcontent').children('.pageContent:last()')
  3754. }
  3755. //重置富文本
  3756. resetEditorIds.length && self.resetAddNewModuleEditor(resetEditorIds)
  3757. //递归轮询判断
  3758. self.changePrintArea(nextPageEl)
  3759. },
  3760. //超出的大模块计算
  3761. addPrintForAnswerModule: function (
  3762. overPart,
  3763. curPageIndex,
  3764. subjectHtml,
  3765. resetEditorIds,
  3766. removeElements,
  3767. nextPageEl
  3768. ) {
  3769. var self = this
  3770. var moduleTitle = ''
  3771. var overAnswerHtml = ''
  3772. var overAnswerModule = overPart.answerModule
  3773. //根据module 的data-type来确定使用的module 模板
  3774. var tplForTypeMap = {
  3775. singleSelect: 'selectAnswerTpl',
  3776. moreSelect: 'selectAnswerTpl',
  3777. uncertainOption: 'selectAnswerTpl',
  3778. fillInBlank: 'answerModulForFillInBlankTpl',
  3779. answer: 'answerModuleTpl',
  3780. chooseAnswer: 'answerModuleTpl',
  3781. mustAnswer: 'answerModuleTpl',
  3782. objective: 'objectiveWrapTpl'
  3783. }
  3784. //超出模块 选择-填空
  3785. while (overAnswerModule.length) {
  3786. var editModuleHtml = ''
  3787. var overAnswerModuleType = overAnswerModule.attr('data-type')
  3788. var modelId = overAnswerModule.attr('data-modelId')
  3789. var direction = overAnswerModule.attr('data-direction')
  3790. //如果是当前超出模块,则直接用上面的多余的moduleHtml来填充
  3791. //否则,直接用answerModule的内容来填充
  3792. if (overAnswerModule[0] === overPart.answerModule[0]) {
  3793. editModuleHtml = subjectHtml
  3794. } else {
  3795. //如果下一个大模块是选做题,并且只有选做题提文字信息
  3796. if (
  3797. overAnswerModuleType === 'chooseAnswer' &&
  3798. !overAnswerModule.find('.module').length &&
  3799. overAnswerModule.children().length &&
  3800. overAnswerModule.find('.originSubjectInfo').length
  3801. ) {
  3802. var objectiveReg = /<div class="originSubjectInfo">(.*)<\/div>/
  3803. var objectiveRegG = /<div class="originSubjectInfo">(.*)<\/div>/g
  3804. //超出的选做题标题元素
  3805. var overAnswerModuleH3Html = overAnswerModule.find('h3')[0].outerHTML
  3806. //超出选做题标题的题干内容
  3807. var overAnswerModuleH3ObjectiveHtml = overAnswerModuleH3Html.match(
  3808. objectiveReg
  3809. )[1]
  3810. var nextPageFirstH3 = nextPageFirstAnswerModule.children('h3')
  3811. if (nextPageFirstH3.length) {
  3812. var nextPageFIrstH3ObjectiveHtml = nextPageFirstH3
  3813. .children('.originSubjectInfo')
  3814. .html()
  3815. //如果下一页存在选做题h3 则 需要拿当前的h3 做替换
  3816. nextPageFirstH3[0].outerHTML = overAnswerModuleH3Html.replace(
  3817. objectiveRegG,
  3818. '<div class="originSubjectInfo">' +
  3819. overAnswerModuleH3ObjectiveHtml +
  3820. nextPageFIrstH3ObjectiveHtml +
  3821. '</div>'
  3822. )
  3823. } else {
  3824. //如果下一页没有标题,直接插入到下一个模块的
  3825. // subjectHtml = nextPageFirstH3.children('.originSubjectInfo').prepend(overAnswerModule[0].outerHTML.replace(objectiveRegG,'<div class="originSubjectInfo">'+curPageH3ObjectiveHtml+'<\/div>'))
  3826. subjectHtml = overAnswerModule.children('h3')[0].outerHTML
  3827. nextPageFirstAnswerModule.prepend(subjectHtml)
  3828. }
  3829. overAnswerModule.remove()
  3830. break
  3831. }
  3832. var isSelect = ~overAnswerModuleType.indexOf('Select')
  3833. var isFillInBlank = overAnswerModuleType === 'fillInBlank'
  3834. self.resetPageDataForSubject(
  3835. overAnswerModule,
  3836. curPageIndex,
  3837. resetEditorIds,
  3838. nextPageEl
  3839. )
  3840. if (isSelect || isFillInBlank) {
  3841. moduleTitle = self.titleHtml(self.questionMap[modelId].bigTitle)
  3842. if (isSelect) {
  3843. editModuleHtml = overAnswerModule.html()
  3844. }
  3845. }
  3846. if (!isSelect) editModuleHtml = overAnswerModule.html()
  3847. removeElements.push(overAnswerModule)
  3848. }
  3849. overAnswerHtml += self.tpls[
  3850. tplForTypeMap[overAnswerModuleType]
  3851. ].substitute({
  3852. editModule: editModuleHtml,
  3853. moduleType: overAnswerModuleType,
  3854. selectType: overAnswerModuleType,
  3855. selectContent: editModuleHtml,
  3856. direction: direction,
  3857. title: moduleTitle,
  3858. modelId: modelId
  3859. })
  3860. overAnswerModule = overAnswerModule.next()
  3861. }
  3862. return overAnswerHtml
  3863. },
  3864. /**
  3865. * 超出情况
  3866. * ** 如果下一页的模块有补充模块,最终都需要删除,增加新的补充模块
  3867. * 1 如果剩余解答区域小于默认解答区域高度--则直接全部拿到下一页,高度和下一个区域的补充模块高度累加,下一页的补充模块自动移除
  3868. * 2 如果剩余解答区域大于默认解答区域高度--则超出部分高度和之前下一区域的补充模块高度累加,下一页补充模块高度自动移除
  3869. * 缺失情况
  3870. * 1 如果剩余空间大于下一个模块
  3871. * -如果是补充模块,直接拿上来,高度累加该补充模块的高度
  3872. * -如果不是补充模块,直接拿上来,然后递归下一页的下一个模块,直到该页面没有剩余空间
  3873. * 2 如果剩余空间小于下一个模块
  3874. * a如果有标题
  3875. * - 如果小于标题加题号的空间,则不动,递归下一页的缺失情况
  3876. * - 如果大于标题加题号的空间,则直接拿上去,下一页保留多余高度的作答区域 (可以高度缩小直接拿上去,然后再补一个剩余高度的拓展模块)
  3877. * b如果没有标题(小题或者补充模块)
  3878. * - 如果下一页的第一个模块是补充模块,直接缩小对应的高度,上一个页面增加对应的高度
  3879. * - 如果下一个面是小题模块,则直接拿上去,下一页保留多余高度的作答区域 (可以高度缩小直接拿上去,然后再补一个剩余高度的拓展模块)
  3880. */
  3881. addPrintForAnswer: function (curPageEl, overPart) {
  3882. var self = this
  3883. var curPageIndex = curPageEl.index()
  3884. var times = curPageIndex + 1
  3885. var part = overPart.subjectModule
  3886. //判断超出简答题区域
  3887. var overAnswerModule = overPart.answerModule
  3888. //超出区域模块的题型
  3889. var overAnswerModuleType = overAnswerModule.attr('data-type')
  3890. //简答小题
  3891. var subjectHtml = ''
  3892. //合并的简答题区域
  3893. var overAnswerHtml = ''
  3894. //判断是否是当前鼠标操作答题区域的坐标
  3895. //var curOperation = part[0] === self.curDtkModelEl[0]
  3896. //通过缩放确定每个页面需要移除的元素
  3897. var removeElements = []
  3898. //需要重置富文本编辑功能区域的id
  3899. var resetEditorIds = []
  3900. //判断是否有需要新增的富文本
  3901. var hasNewRichText = false
  3902. //超出的富文本的内容部分
  3903. var editorOverContent = ''
  3904. var nextPageEl = curPageEl.next()
  3905. //首先判断是要删除下一个分页的补充模块如果下一个分页存在的话
  3906. var nextPageFirstModule = null
  3907. var nextPageFirstAnswerModule = null
  3908. if (nextPageEl.length) {
  3909. nextPageFirstModule = nextPageEl.find('.module').eq(0)
  3910. nextPageFirstAnswerModule = nextPageEl.find('.answerModule').eq(0)
  3911. }
  3912. while (part && part.length) {
  3913. /**
  3914. * 如果是当前缩放的模块超出,直接在下一模块新建当前模块的子模块
  3915. * 如果不是,则直接拷贝超出模块所有内容到下一页
  3916. */
  3917. //当前缩放的模块没有超出规定区域 则超出的所有模块全局复制
  3918. if (part !== overPart.subjectModule) {
  3919. //1 新增新模块resetEditorIds removeElements
  3920. subjectHtml += self.addNewModule(
  3921. part,
  3922. overAnswerModuleType,
  3923. resetEditorIds,
  3924. removeElements
  3925. )
  3926. } else {
  3927. //如果剩余模块的高度小于 最小高度,直接放到下一页
  3928. var surplusHeight = self.getOverHeight(part)
  3929. if (part.outerHeight() - surplusHeight <= 100) {
  3930. //判断超出简答题区域
  3931. var overAnswerModule = part.closest('.answerModule')
  3932. //超出区域模块的题型
  3933. var overAnswerModuleType = overAnswerModule.attr('data-type')
  3934. //1 新增新模块resetEditorIds removeElements
  3935. subjectHtml += self.addNewModule(
  3936. part,
  3937. overAnswerModuleType,
  3938. resetEditorIds,
  3939. removeElements
  3940. )
  3941. } else {
  3942. //1 拓展新模块
  3943. hasNewRichText = true
  3944. //当前超出的模块height
  3945. //计算超出文本内容区域,同时原来的富文本区域对应超出的内容
  3946. var overContentObj = self.getOverContent(
  3947. part,
  3948. surplusHeight,
  3949. removeElements
  3950. )
  3951. editorOverContent = overContentObj.overContent
  3952. var editorOverHeight = overContentObj.overHeight
  3953. subjectHtml += self.expandModule(part, editorOverHeight)
  3954. }
  3955. }
  3956. part = part.next()
  3957. }
  3958. //当前超出小模块只是选做题题干信息
  3959. if (!subjectHtml) {
  3960. var removeTemps = []
  3961. var $itemBodys = overPart.objectiveModule.find('.questionItemBody')
  3962. for (var i = 0; i < $itemBodys.length; i++) {
  3963. var $itemBody = $itemBodys.eq(i)
  3964. if (self.getOverHeight($itemBody) > 0) {
  3965. subjectHtml += $itemBody[0].outerHTML
  3966. removeTemps.push($itemBody)
  3967. }
  3968. }
  3969. var objectiveReg = /<div class="originSubjectInfo">(.*)<\/div>/
  3970. var objectiveRegG = /<div class="originSubjectInfo">(.*)<\/div>/g
  3971. var curPageH3ObjectiveHtml = overPart.objectiveModule[0].outerHTML.match(
  3972. objectiveReg
  3973. )[1]
  3974. if (removeTemps.length >= $itemBodys.length) {
  3975. //如果下一页存在标题
  3976. var nextPageFirstH3 = nextPageFirstAnswerModule.children('h3')
  3977. if (nextPageFirstH3.length) {
  3978. var nextPageFirstH3Html = nextPageFirstH3
  3979. .children('.originSubjectInfo')
  3980. .html()
  3981. subjectHtml = overPart.objectiveModule[0].outerHTML.replace(
  3982. objectiveRegG,
  3983. '<div class="originSubjectInfo">' +
  3984. curPageH3ObjectiveHtml +
  3985. nextPageFirstH3Html +
  3986. '</div>'
  3987. )
  3988. nextPageFirstH3[0].outerHTML = subjectHtml
  3989. } else {
  3990. subjectHtml = overPart.objectiveModule[0].outerHTML.replace(
  3991. objectiveRegG,
  3992. '<div class="originSubjectInfo">' +
  3993. curPageH3ObjectiveHtml +
  3994. '</div>'
  3995. )
  3996. nextPageFirstAnswerModule.prepend(subjectHtml)
  3997. }
  3998. overPart.objectiveModule.closest('.answerModule').remove()
  3999. } else {
  4000. //如果下一页存在标题
  4001. var nextPageFirstH3 = nextPageFirstAnswerModule.children('h3')
  4002. if (nextPageFirstH3.length) {
  4003. nextPageFirstH3.children('.originSubjectInfo').prepend(subjectHtml)
  4004. } else {
  4005. //overPart.objectiveModule[0].outerHTML.replace(objectiveRegG,'');
  4006. nextPageFirstAnswerModule.prepend(
  4007. '<h3><div class="originSubjectInfo">' + subjectHtml + '</div></h3>'
  4008. )
  4009. }
  4010. removeTemps.forEach(function (el) {
  4011. $(el).remove()
  4012. })
  4013. }
  4014. self.changePrintArea(nextPageEl)
  4015. return
  4016. }
  4017. //计算超出大模块
  4018. overAnswerHtml += self.addPrintForAnswerModule(
  4019. overPart,
  4020. times,
  4021. subjectHtml,
  4022. resetEditorIds,
  4023. removeElements,
  4024. nextPageEl
  4025. )
  4026. //重置上一页第一个超出模块的高度 = pageHeight - subject.offset().top - subjectModullePadding的模块高度
  4027. //上一个页面其他剩余模块的所占的高度
  4028. //如果上一页本来就是一个超出的模块,那modulePadding 就要少点了打分区域的高度
  4029. var linkparm = overPart.subjectModule.attr('data-linkparm')
  4030. var isLinkparmModule = linkparm && linkparm !== '1'
  4031. var preOtherModuleHeight =
  4032. overPart.subjectModule.offset().top +
  4033. $('#contentWrap').scrollTop() +
  4034. self.pagePadding +
  4035. self.modulePadding -
  4036. (isLinkparmModule ? 30 : 0)
  4037. //上一个页面第一个超出模块所能占用的高度
  4038. var preFirstOverModuleHeight =
  4039. self.pageHeight * times - preOtherModuleHeight
  4040. overPart.subjectModule
  4041. .children('.editorContent')
  4042. .height(preFirstOverModuleHeight)
  4043. // overPart.subjectModule
  4044. // .children('.editorContent')
  4045. // .css('min-height',preFirstOverModuleHeight)
  4046. /**
  4047. * 【优化】
  4048. * 模块删除关系需要优化
  4049. */
  4050. removeElements.forEach(function (element) {
  4051. $(element).remove()
  4052. })
  4053. if (
  4054. !overPart.answerModule.children('.module').length &&
  4055. !overPart.answerModule.find('h3').length
  4056. )
  4057. overPart.answerModule.remove()
  4058. //是否存在下一个分页
  4059. if (nextPageEl.length) {
  4060. nextPageEl.children('.dtk-content').prepend(overAnswerHtml)
  4061. } else {
  4062. self.addPage(overAnswerHtml)
  4063. nextPageEl = $('#printcontent').children('.pageContent:last()')
  4064. }
  4065. //curOperation
  4066. hasNewRichText &&
  4067. self.createShortAnswer(editorIndexUp != '' ? editorIndexUp : self.editorIndex, editorOverContent)
  4068. //下一页存在上一页最后一个模块的拓展模块,也必须等上一页的新拓展(超出模块)放到下一页之后再执行老拓展模块的删除
  4069. //因为删除功能会进行下一页是否有内容模块,对下一页整个页面进行选择性的删除,如果删除了下一页,超出的内容就不知道放到哪里了
  4070. if (nextPageFirstModule && self.isSurplusModule(nextPageFirstModule)) {
  4071. self.delPageOverPart(nextPageFirstModule.children('.delBtn'), 'over')
  4072. }
  4073. //重置富文本
  4074. self.resetAddNewModuleEditor(resetEditorIds)
  4075. //递归轮询判断
  4076. self.changePrintArea(nextPageEl)
  4077. },
  4078. //填空题超出
  4079. addPrintForFillInBlank: function (curPageEl, overPart) {
  4080. var self = this
  4081. var part = overPart.subjectModule
  4082. var modelId = overPart.answerModule.attr('data-modelId')
  4083. var curPageIndex = curPageEl.index() + 1
  4084. //合并的简答题区域
  4085. var overAnswerHtml = ''
  4086. //通过缩放确定每个页面需要移除的元素
  4087. var removeElements = []
  4088. //需要重置富文本编辑功能区域的id
  4089. var resetEditorIds = []
  4090. var nextPageEl = curPageEl.next()
  4091. //首先判断是要删除下一个分页的补充模块如果下一个分页存在的话
  4092. var nextPageFirstModule = null
  4093. if (nextPageEl.length) {
  4094. nextPageFirstModule = nextPageEl.find('.module').eq(0)
  4095. //按照模块id 归类删除
  4096. nextPageEl.find('.answerModule').each(function () {
  4097. if ($(this).attr('data-modelId') === modelId) {
  4098. $(this).remove()
  4099. }
  4100. })
  4101. }
  4102. //当前超出的模块height
  4103. var overHeight = self.getOverHeight(part)
  4104. //一行几栏
  4105. var $firstColForInfoEl = part.children('.subjectCol')
  4106. var dataColumns = $firstColForInfoEl.attr('data-column')
  4107. var scoreStyle = $firstColForInfoEl.attr('data-scoreStyle')
  4108. var columns = dataColumns ? +dataColumns : 1
  4109. var rowLineHeight = $firstColForInfoEl.attr('data-rowlineheight')
  4110. //计算每个填空题item的高度 默认40 padding 10 border 1
  4111. var fillInBlankItemHeight = (+rowLineHeight || 40) + 11
  4112. //当前模块有几个填空题
  4113. var fillInBlankCount = part.find('.subjectItem').length
  4114. //最后一排几个
  4115. var lastRowCount =
  4116. fillInBlankCount % columns ? fillInBlankCount % columns : columns
  4117. //需要复制几个填空题
  4118. //超出的行数量
  4119. var overRows = Math.ceil(overHeight / fillInBlankItemHeight)
  4120. //如果最后一行计算最后一行有几个
  4121. var copyFillInBlankLength = lastRowCount + (overRows - 1) * columns
  4122. var curModuleDataIndex = 'page' + curPageIndex
  4123. var nextExpendDataIndex = 'page' + (curPageIndex + 1)
  4124. var modelData = self.questionMap[modelId]
  4125. var modelPagesData = modelData.pages
  4126. var nextExpendDataLength = modelPagesData[curModuleDataIndex].length
  4127. if(modelPagesData[curModuleDataIndex].length<1){
  4128. let upModuleDataIndex = 'page' + (curPageIndex -1)
  4129. modelPagesData[curModuleDataIndex] = modelPagesData[upModuleDataIndex]
  4130. modelPagesData[upModuleDataIndex] = []
  4131. nextExpendDataLength = modelPagesData[curModuleDataIndex].length
  4132. }
  4133. copyFillInBlankLength =
  4134. copyFillInBlankLength > nextExpendDataLength
  4135. ? nextExpendDataLength
  4136. : copyFillInBlankLength
  4137. //原页面保留的题目
  4138. modelPagesData[nextExpendDataIndex] =
  4139. modelPagesData[nextExpendDataIndex] || []
  4140. let modelPagesDatas = JSON.parse(JSON.stringify(modelPagesData))
  4141. modelPagesData = modelPagesDatas
  4142. modelPagesData[nextExpendDataIndex] = modelPagesData[curModuleDataIndex]
  4143. .splice(nextExpendDataLength - copyFillInBlankLength)
  4144. .concat(modelPagesData[nextExpendDataIndex])
  4145. modelData.pages = modelPagesData
  4146. // var renderData = self.formatRenderDataForFillInBlank(modelPagesData[curModuleDataIndex], modelData.scoreStyle)
  4147. var originPageRetainHtml = self.getFillInBlankHtml(
  4148. self.formatRenderDataForFillInBlank(modelPagesData[curModuleDataIndex], modelData.scoreStyle)
  4149. )
  4150. var overFillInBlankItemsHtml = self.getFillInBlankHtml(
  4151. // modelPagesData[nextExpendDataIndex]
  4152. self.formatRenderDataForFillInBlank(modelPagesData[nextExpendDataIndex], modelData.scoreStyle)
  4153. )
  4154. if (!originPageRetainHtml) {
  4155. removeElements.push(part.closest('.completion-topic'))
  4156. } else {
  4157. part.find('.subjectCol').html(originPageRetainHtml)
  4158. }
  4159. //超出的放在新页面上 如果原页面没有保留模块则需要加上title 并且需要setting按钮
  4160. overFillInBlankItemsHtml =
  4161. self.titleHtml(!originPageRetainHtml ? modelData.bigTitle : '') +
  4162. self.tpls.fillInBlankContentTpl.substitute({
  4163. addFillInBlankHtml: overFillInBlankItemsHtml,
  4164. columns: columns,
  4165. scoreStyle: scoreStyle,
  4166. rowLineHeight: rowLineHeight,
  4167. settingBtn: !originPageRetainHtml
  4168. ? self.tpls.fillInBlankSettingBtnTpl
  4169. : ''
  4170. })
  4171. //计算超出大模块
  4172. //判断超出简答题区域
  4173. var overAnswerModule = overPart.answerModule
  4174. overAnswerHtml += self.addPrintForAnswerModule(
  4175. overPart,
  4176. curPageIndex,
  4177. overFillInBlankItemsHtml,
  4178. resetEditorIds,
  4179. removeElements,
  4180. nextPageEl
  4181. )
  4182. /**
  4183. * 【优化】
  4184. * 模块删除关系需要优化
  4185. */
  4186. removeElements.forEach(function (element) {
  4187. $(element).remove()
  4188. })
  4189. //是否存在下一个分页
  4190. if (nextPageEl.length) {
  4191. nextPageEl.children('.dtk-content').prepend(overAnswerHtml)
  4192. if (self.isSurplusModule(nextPageFirstModule)) {
  4193. self.delPageOverPart(nextPageFirstModule.children('.delBtn'), 'over')
  4194. }
  4195. } else {
  4196. self.addPage(overAnswerHtml)
  4197. nextPageEl = $('#printcontent').children('.pageContent:last()')
  4198. }
  4199. //重置富文本
  4200. self.resetAddNewModuleEditor(resetEditorIds)
  4201. //递归轮询判断
  4202. self.changePrintArea(nextPageEl)
  4203. },
  4204. //选择题超出
  4205. /**
  4206. *
  4207. * @param {*} curPageEl
  4208. * @param {*} overPart
  4209. */
  4210. addPrintForSelect: function (curPageEl, overPart, type) {
  4211. var self = this
  4212. //是否存在下一页
  4213. var nextPageEl = curPageEl.next()
  4214. //超出选择题的题目
  4215. var curPageIndex = curPageEl.index()+1
  4216. // var curPageIndex = curPageEl.index()==0?curPageEl.index()+1:curPageEl.index()
  4217. //合并的简答题区域
  4218. var overAnswerHtml = ''
  4219. //通过缩放确定每个页面需要移除的元素
  4220. var removeElements = []
  4221. //需要重置富文本编辑功能区域的id
  4222. var resetEditorIds = []
  4223. //当前超出的模块height
  4224. var part = overPart.subjectModule
  4225. var modelId = overPart.answerModule.attr('data-modelId')
  4226. var modDataType = overPart.answerModule.attr('data-type')
  4227. var selectItemType = overPart.answerModule.attr('data-direction')
  4228. //模块数据
  4229. var curModuleDataIndex = 'page' + curPageIndex
  4230. var nextExpendDataIndex = 'page' + (curPageIndex + 1)
  4231. var modelData = self.questionMap[modelId]
  4232. var modelPagesData = modelData.pages
  4233. if(modelPagesData[curModuleDataIndex].length<1){
  4234. let upModuleDataIndex = 'page' + (curPageIndex -1)
  4235. modelPagesData[curModuleDataIndex] = modelPagesData[upModuleDataIndex]
  4236. modelPagesData[upModuleDataIndex] = []
  4237. }
  4238. //每小题的高度
  4239. var overHeight = self.getOverHeight(part)
  4240. // 单个选项高度
  4241. let optItemHeight = overPart.answerModule.find('.single-option li').eq(0).outerHeight()
  4242. //20 选择题一个题组的padding值
  4243. var selectItemHeight = optItemHeight * 5 + 20
  4244. if(selectItemType=='vertical'){
  4245. selectItemHeight = optItemHeight + 20
  4246. }
  4247. //针对选择题竖版一行排几个
  4248. var curConfigForLine =
  4249. self.config[self.direction][self.hasBindingLine ? 'yesLine' : 'noLine']
  4250. var rowLength = curConfigForLine[self.columns]
  4251. //一共多少个选择ul module
  4252. var optionsModuleLength = part.children('.single-option').length
  4253. //当前布局下面有几排
  4254. var optionsRowLength = Math.floor(part.outerHeight() / selectItemHeight)
  4255. //一排几个options 模块
  4256. var optionsModule = rowLength / 5
  4257. //最后一个排放几个选项
  4258. // var lastRowOptionLength =
  4259. // optionsModuleLength - (optionsRowLength - 1) * optionsModule
  4260. var lastRowOptionLength =
  4261. modelPagesData[curModuleDataIndex].length -
  4262. (optionsRowLength - 1) * optionsModule * 5
  4263. //如果当前页面超过一排的情况下,则超出的数量需要计算到最后一排没有排满的情况
  4264. /**
  4265. * 超出的计算单位以 一整排为单位
  4266. * 每一排的一列以5题为单位 计算
  4267. *
  4268. */
  4269. //计算超出多少小题
  4270. var overSelectItemsLength
  4271. var overRowLength = Math.ceil(overHeight / selectItemHeight)
  4272. if (overRowLength <= 1) {
  4273. overSelectItemsLength = lastRowOptionLength
  4274. } else {
  4275. overSelectItemsLength =
  4276. (overRowLength - 1) * rowLength + lastRowOptionLength
  4277. }
  4278. var nextExpendDataLength = modelPagesData['page' + curPageIndex].length
  4279. //超出的放在新页面上,顺表保存一份用来给下一次使用
  4280. modelPagesData[nextExpendDataIndex] =
  4281. modelPagesData[nextExpendDataIndex] || []
  4282. let modelPagesDatas = JSON.parse(JSON.stringify(modelPagesData))
  4283. modelPagesData = modelPagesDatas
  4284. modelPagesData[nextExpendDataIndex] = modelPagesData[curModuleDataIndex]
  4285. .splice(nextExpendDataLength - overSelectItemsLength)
  4286. .concat(modelPagesData[nextExpendDataIndex])
  4287. //首先判断是要删除下一个分页的补充模块如果下一个分页存在的话
  4288. var nextPageFirstModule = null
  4289. var nextPageFirstAnswerModule = null
  4290. if (nextPageEl.length) {
  4291. nextPageFirstAnswerModule = nextPageEl.find('.answerModule').eq(0)
  4292. nextPageFirstModule = nextPageEl.find('.module').eq(0)
  4293. //按照模块id 归类删除
  4294. nextPageEl.find('.answerModule').each(function () {
  4295. if ($(this).attr('data-modelId') === modelId) {
  4296. $(this).remove()
  4297. }
  4298. })
  4299. }
  4300. //计算留在当前页面的和下一个页面的数据
  4301. var originPageRetainHtml = self.getSingleSelectHtml(
  4302. modelPagesData[curModuleDataIndex]
  4303. )
  4304. var overSelectItemsHtml = self.getSingleSelectHtml(
  4305. modelPagesData[nextExpendDataIndex]
  4306. )
  4307. let btnHtml = '<div class="settingBtn" data-type="' + modDataType + '"></div><div class="delTopicBtn" data-type="' + modDataType + '">X</div>'
  4308. if (!originPageRetainHtml) {
  4309. removeElements.push(part.closest('.single-select'))
  4310. } else {
  4311. part.html(btnHtml + originPageRetainHtml)
  4312. }
  4313. overSelectItemsHtml =
  4314. self.titleHtml(!originPageRetainHtml ? modelData.bigTitle : '') +
  4315. self.tpls.selectContentTpl.substitute({
  4316. selectContent: overSelectItemsHtml,
  4317. moduleType: overPart.answerModule.attr('data-type')
  4318. })
  4319. var overAnswerModule = overPart.answerModule
  4320. overAnswerHtml += self.addPrintForAnswerModule(
  4321. overPart,
  4322. curPageIndex,
  4323. overSelectItemsHtml,
  4324. resetEditorIds,
  4325. removeElements,
  4326. nextPageEl
  4327. )
  4328. /**
  4329. * 【优化】
  4330. * 模块删除关系需要优化
  4331. */
  4332. removeElements.forEach(function (element) {
  4333. $(element).remove()
  4334. })
  4335. //是否存在下一个分页
  4336. if (nextPageEl.length) {
  4337. nextPageEl.children('.dtk-content').prepend(overAnswerHtml)
  4338. if (self.isSurplusModule(nextPageFirstModule)) {
  4339. self.delPageOverPart(nextPageFirstModule.children('.delBtn'), 'over')
  4340. }
  4341. } else {
  4342. self.addPage(overAnswerHtml)
  4343. nextPageEl = $('#printcontent').children('.pageContent:last()')
  4344. }
  4345. //重置富文本
  4346. self.resetAddNewModuleEditor(resetEditorIds)
  4347. //递归轮询判断
  4348. self.changePrintArea(nextPageEl)
  4349. },
  4350. //重新计算分页数据
  4351. resetPageDataForSubject: function (
  4352. overAnswerModule,
  4353. curPageIndex,
  4354. resetEditorIds,
  4355. nextPageEl
  4356. ) {
  4357. var self = this
  4358. //page data index
  4359. var curModuleDataIndex = 'page' + curPageIndex
  4360. var nextExpendDataIndex = 'page' + (curPageIndex + 1)
  4361. var overModuleType = overAnswerModule.attr('data-type')
  4362. //如果下一个页面的第一个模块是选择题或者填空题的补充模块,则特殊处理
  4363. var isSelect = ~overModuleType.indexOf('Select')
  4364. var isFillInBlank = overModuleType === 'fillInBlank'
  4365. if (isSelect || isFillInBlank) {
  4366. var modelId = overAnswerModule.attr('data-modelId')
  4367. // var modelPagesData = self.questionMap[modelId].pages
  4368. var modelPagesData = JSON.parse(JSON.stringify(self.questionMap[modelId].pages))
  4369. var bigTitle = self.questionMap[modelId].bigTitle
  4370. var nextHasData = false
  4371. modelPagesData[nextExpendDataIndex] =
  4372. modelPagesData[nextExpendDataIndex] || []
  4373. modelPagesData[curModuleDataIndex] =
  4374. modelPagesData[curModuleDataIndex] || []
  4375. var nextExpendData = modelPagesData[nextExpendDataIndex]
  4376. var curModuleData = modelPagesData[curModuleDataIndex]
  4377. if (nextExpendData.length) {
  4378. nextHasData = true
  4379. modelPagesData[nextExpendDataIndex] = curModuleData.concat(
  4380. nextExpendData
  4381. )
  4382. } else {
  4383. modelPagesData[nextExpendDataIndex] = [].concat(curModuleData)
  4384. }
  4385. modelPagesData[curModuleDataIndex].length = 0
  4386. //如果是选择题下一页的数据处理
  4387. if (isSelect) {
  4388. if (nextHasData) {
  4389. var $expendModule = overAnswerModule.find('.singleContent')
  4390. var $nextRemoveModule = nextPageEl.find('.single-select').eq(0)
  4391. var $expendHtml =
  4392. self.titleHtml(bigTitle) +
  4393. self.getSingleSelectHtml(modelPagesData[curModuleDataIndex])
  4394. $expendModule.html($expendHtml)
  4395. //如果下一页的第一个模块是当前超出这个模块的补充模块,则直接删除
  4396. if ($nextRemoveModule.attr('data-modelId') === modelId) {
  4397. $nextRemoveModule.remove()
  4398. }
  4399. }
  4400. } else if (overModuleType === 'fillInBlank') {
  4401. if (nextHasData) {
  4402. var $expendModule = overAnswerModule.find('.subjectCol')
  4403. var $nextRemoveModule = nextPageEl.find('.completion-topic').eq(0)
  4404. var $expendHtml = self.getFillInBlankHtml(
  4405. modelPagesData[nextExpendDataIndex]
  4406. )
  4407. $expendModule.html($expendHtml)
  4408. //如果下一页的第一个模块是当前超出这个模块的补充模块,则直接删除
  4409. if ($nextRemoveModule.attr('data-modelId') === modelId) {
  4410. $nextRemoveModule.remove()
  4411. }
  4412. }
  4413. }
  4414. } else {
  4415. //解答题重置富文本
  4416. //2 判断是否有需要重置的富文本
  4417. var editorEls = overAnswerModule.find('.editorContent')
  4418. editorEls.length &&
  4419. editorEls.each(function () {
  4420. resetEditorIds.push({
  4421. editorId: $(this).attr('id'),
  4422. toolbarId: $(this).prev().attr('id')
  4423. })
  4424. })
  4425. }
  4426. },
  4427. //新建分栏
  4428. /**
  4429. * @param {上一栏超出的模块html} overAnswerHtml
  4430. */
  4431. addPage: function (overAnswerHtml) {
  4432. var self = this
  4433. //新建的分页
  4434. self.totalPage++
  4435. self.currentPage++
  4436. self.currentPaper = Math.ceil(self.totalPage / (self.columns * 2))
  4437. //第一张纸 正面1 正面2 第一张至反面1 反面2
  4438. var paperDirection =
  4439. (self.totalPage % (self.columns * 2)
  4440. ? self.totalPage % (self.columns * 2)
  4441. : self.columns * 2) <= self.columns
  4442. ? '正面'
  4443. : '反面'
  4444. var pageForPaperDirection =
  4445. self.totalPage % self.columns ? self.totalPage % self.columns : 2
  4446. var currentPaperPage = paperDirection + pageForPaperDirection
  4447. //新建page
  4448. var newPage = self.tpls.pageModuleTpl.substitute({
  4449. subjectModule: overAnswerHtml,
  4450. currentPage: self.currentPage,
  4451. totalPage: self.totalPage,
  4452. currentPaper: self.currentPaper,
  4453. currentPaperPage: currentPaperPage
  4454. })
  4455. $('#printcontent').append(newPage)
  4456. self.refrushPageLabel()
  4457. },
  4458. //重新初始化移动的富文本题目编辑区域
  4459. resetAddNewModuleEditor: function (resetEditorIds) {
  4460. var self = this
  4461. /**
  4462. * editorId
  4463. * toolbarId
  4464. */
  4465. resetEditorIds.forEach(function (resetEditorId) {
  4466. if (!$('#' + resetEditorId.toolbarId).length) return
  4467. // var editorIndex = resetEditorId.editorId.match(/\d+/g)[0]
  4468. // var reg = /(?<=editorContent).+(?=")/;
  4469. var reg = /([^editorContent]+)$/;
  4470. var editorIndex = resetEditorId.editorId.match(reg)[1];
  4471. var editTopic = {};
  4472. jQuery.each(self.questionMap, function (i, bigTopic) {
  4473. jQuery.each(bigTopic.questions, function (j, Topic) {
  4474. if (editorIndex == Topic.questionNum) {
  4475. editTopic = Topic
  4476. }
  4477. })
  4478. })
  4479. let topicType = editTopic.questionTypeId
  4480. if (topicType == 7) {
  4481. topicType = editTopic.markQuestionType
  4482. }
  4483. $('#' + resetEditorId.toolbarId).html('')
  4484. var editor = new self.EDITOR(
  4485. '#' + resetEditorId.toolbarId,
  4486. '#' + resetEditorId.editorId
  4487. )
  4488. editor.customConfig.menus = topicType == '7c' ? self.EDITOR_CONFIG_ZW : self.EDITOR_CONFIG
  4489. editor.customConfig.onfocus = function () {
  4490. if (!self.isCanEditCard) return
  4491. $('#' + resetEditorId.editorId)
  4492. .siblings('.toolbar')
  4493. .addClass('seled')
  4494. }
  4495. editor.customConfig.onblur = function () {
  4496. //如果当前答题卡模板不在编辑状态,或者 正在使用公式编辑器,都不用启动这个事件
  4497. if (!self.isCanEditCard || self.formulaing) return
  4498. $('#' + resetEditorId.editorId)
  4499. .siblings('.toolbar')
  4500. .removeClass('seled')
  4501. //过滤所有的空标签 换行产生的标签
  4502. var newEditorHtml = editor.txt
  4503. .html()
  4504. .replace(self.replaceEditorRegexp, '')
  4505. editor.txt.html(newEditorHtml)
  4506. }
  4507. editor.customConfig.linkImgCallback = function (url) {
  4508. editor.$textElem.find('img').forEach(function (el) {
  4509. var src = $(el).attr('src')
  4510. if (src === url) {
  4511. $(el).addClass('customImg')
  4512. }
  4513. return false
  4514. })
  4515. }
  4516. // 关闭粘贴样式的过滤
  4517. editor.customConfig.pasteFilterStyle = true
  4518. editor.customConfig.customUploadImg = function (files, insert) {
  4519. self.addImgToEditor(files, editor)
  4520. }
  4521. //#747474
  4522. editor.create()
  4523. //记录模块信息
  4524. var editorText = self.editorArea['editor' + editorIndex].txt
  4525. .html()
  4526. .clearFixible()
  4527. if (!~editorText.indexOf('flexible_icon')) {
  4528. //设置图片伸缩使用icon
  4529. editorText += self.tpls.flexibleIconTpl
  4530. }
  4531. editor.txt.html(editorText)
  4532. self.editorArea['editor' + editorIndex] = editor
  4533. })
  4534. },
  4535. //可编辑区域
  4536. editorArea: {},
  4537. editorIndex: 0,
  4538. editorAreaOriginContent: {},
  4539. //解答题区域添加图片
  4540. addImgToEditor: function (files, editor) {
  4541. var self = this
  4542. var uploadForm = new FormData()
  4543. uploadForm.append('editor_file', files[0])
  4544. $.ajax({
  4545. url: self.apis.uploadFileApi,
  4546. method: 'POST',
  4547. processData: false,
  4548. contentType: false,
  4549. dataType: 'json',
  4550. data: uploadForm,
  4551. success: function (result) {
  4552. var imgTpl =
  4553. '<img style="max-height:calc(100% - {maxHeight}px);" src="{imgUrl}" class="customImg">'
  4554. var editorContetEl = editor.$textContainerElem.children('.w-e-text')
  4555. var contentHeihgt = self.calcEditorContentHeight($(editorContetEl))
  4556. var maxHeight = contentHeihgt + 64
  4557. editor.txt.html(
  4558. editor.txt.html() +
  4559. imgTpl.substitute({ maxHeight: maxHeight, imgUrl: result.data })
  4560. )
  4561. }
  4562. })
  4563. },
  4564. //创建作答区域模块
  4565. createShortAnswer: function (editorIndex, originContent, topicType) {
  4566. var self = this
  4567. originContent = originContent || ''
  4568. //this.createShortAnswer("#toolbar2", "#editorContent2", 2);
  4569. if (!$('#toolbar' + editorIndex).length) return
  4570. var editor = new self.EDITOR(
  4571. '#toolbar' + editorIndex,
  4572. '#editorContent' + editorIndex
  4573. )
  4574. // 自定义菜单配置
  4575. editor.customConfig.menus = topicType == '7c' ? self.EDITOR_CONFIG_ZW : self.EDITOR_CONFIG
  4576. editor.customConfig.onfocus = function () {
  4577. if (!self.isCanEditCard) return
  4578. $('#editorContent' + editorIndex)
  4579. .siblings('.toolbar')
  4580. .addClass('seled')
  4581. }
  4582. editor.customConfig.onblur = function () {
  4583. if (!self.isCanEditCard || self.formulaing) return
  4584. $('#editorContent' + editorIndex)
  4585. .siblings('.toolbar')
  4586. .removeClass('seled')
  4587. //过滤所有的空标签 换行产生的标签
  4588. var newEditorHtml = editor.txt
  4589. .html()
  4590. .replace(self.replaceEditorRegexp, '')
  4591. editor.txt.html(newEditorHtml)
  4592. }
  4593. //网络图片自定义类名
  4594. editor.customConfig.linkImgCallback = function (url) {
  4595. editor.$textElem.find('img').forEach(function (el) {
  4596. var src = $(el).attr('src')
  4597. if (src === url) {
  4598. $(el).addClass('customImg')
  4599. }
  4600. return false
  4601. })
  4602. }
  4603. // 关闭粘贴样式的过滤
  4604. editor.customConfig.pasteFilterStyle = false
  4605. //editor.customConfig.uploadImgShowBase64 = true
  4606. editor.customConfig.customUploadImg = function (files, insert) {
  4607. self.addImgToEditor(files, editor)
  4608. }
  4609. editor.create()
  4610. //记录模块信息
  4611. var editorText = editor.txt.html().clearFixible()
  4612. if (!~editorText.indexOf('flexible_icon')) {
  4613. //设置图片伸缩使用icon
  4614. editorText += self.tpls.flexibleIconTpl
  4615. }
  4616. editorText += originContent.clearFixible()
  4617. editor.txt.html(editorText.replace(self.replaceEditorRegexp, ''))
  4618. // if(editorIndexUp==''){
  4619. self.editorIndex = editorIndex
  4620. // }
  4621. editorIndexUp = ''
  4622. self.editorArea['editor' + editorIndex] = editor
  4623. },
  4624. //答题区域文本图片位置更换
  4625. shortAnswerImgPositionChange: function () {
  4626. var self = this
  4627. var curOpratorImg = null
  4628. var fa = null
  4629. $('#hgc_print').on('mousedown', '.editorContent .customImg', function (e) {
  4630. e.preventDefault()
  4631. var moveImgEl = $(this)[0]
  4632. var boundaryEl = $(moveImgEl).closest('.module')[0]
  4633. var flexibleIcon = $(this).closest('.module').find('.flexible_icon')[0]
  4634. var moveElHeight = moveImgEl.offsetHeight
  4635. var moveElWidth = moveImgEl.offsetWidth
  4636. var oldX = e.clientX
  4637. var oldY = e.clientY
  4638. var startLeft = moveImgEl.offsetLeft
  4639. var startTop = moveImgEl.offsetTop
  4640. document.onmousemove = function (ev) {
  4641. var maxTop =
  4642. boundaryEl.offsetHeight - self.modulePaddingBottom - moveElHeight
  4643. var maxLeft =
  4644. boundaryEl.offsetWidth - self.modulePaddingSide - moveElWidth
  4645. var distanceX = ev.clientX - oldX
  4646. var distanceY = ev.clientY - oldY
  4647. var newLeft = startLeft + distanceX
  4648. var newTop = startTop + distanceY
  4649. if (newLeft <= self.modulePaddingSide / 2)
  4650. newLeft = self.modulePaddingSide / 2
  4651. if (newTop <= self.modulePaddingTop) newTop = self.modulePaddingTop
  4652. if (newTop >= maxTop) newTop = maxTop
  4653. if (newLeft >= maxLeft) newLeft = maxLeft
  4654. moveImgEl.style.left = newLeft + 'px'
  4655. moveImgEl.style.top = newTop + 'px'
  4656. flexibleIcon.style.left = newLeft + moveElWidth - 20 + 'px'
  4657. flexibleIcon.style.top = newTop + moveElHeight - 20 + 'px'
  4658. }
  4659. document.onmouseup = function () {
  4660. document.onmousemove = null
  4661. document.onmouseup = null
  4662. flexibleIcon.style.display = 'none'
  4663. }
  4664. })
  4665. function resetFlexibleIcon($flexibleIcon, $curImg) {
  4666. $flexibleIcon.css({
  4667. left: parseFloat($curImg.css('left')) + $curImg.width() - 20,
  4668. top: parseFloat($curImg.css('top')) + $curImg.height() - 20
  4669. })
  4670. }
  4671. //图片缩放
  4672. $('#hgc_print').on('mouseover', '.editorContent .customImg', function (e) {
  4673. //缩放icon
  4674. var $curImg = $(this)
  4675. var $curModule = $curImg.closest('.module')
  4676. var $flexibleIcon = $curModule.find('.flexible_icon')
  4677. $flexibleIcon.show()
  4678. curOpratorImg = $curImg[0]
  4679. fa = $curModule[0]
  4680. $flexibleIcon.show()
  4681. resetFlexibleIcon($flexibleIcon, $curImg)
  4682. })
  4683. $('#hgc_print').on('mouseout', '.editorContent .customImg', function (e) {
  4684. e.stopPropagation()
  4685. //缩放icon
  4686. var $curImg = $(this)
  4687. var $curModule = $curImg.closest('.module')
  4688. var $flexibleIcon = $curModule.find('.flexible_icon')
  4689. $flexibleIcon.hide()
  4690. })
  4691. $('#hgc_print').on('mouseover', '.editorContent .flexible_icon', function (
  4692. e
  4693. ) {
  4694. //缩放icon
  4695. var $curImg = $(this)
  4696. var $curModule = $curImg.closest('.module')
  4697. var $flexibleIcon = $curModule.find('.flexible_icon')
  4698. $flexibleIcon.show()
  4699. })
  4700. //图片缩放
  4701. $('#hgc_print').on('mousedown', '.editorContent .flexible_icon', function (
  4702. e
  4703. ) {
  4704. // 阻止冒泡,避免缩放时触发移动事件
  4705. e.stopPropagation()
  4706. e.preventDefault()
  4707. var $flexibleIcon = $(this)
  4708. var pos = {
  4709. w: curOpratorImg.offsetWidth,
  4710. h: curOpratorImg.offsetHeight,
  4711. x: e.clientX,
  4712. y: e.clientY
  4713. }
  4714. fa.onmousemove = function (ev) {
  4715. ev.preventDefault()
  4716. // 设置图片的最小缩放为30*30
  4717. var w = Math.max(30, ev.clientX - pos.x + pos.w)
  4718. var h = Math.max(30, ev.clientY - pos.y + pos.h)
  4719. // console.log(w,h)
  4720. // 设置图片的最大宽高
  4721. w =
  4722. w >= fa.offsetWidth - curOpratorImg.offsetLeft
  4723. ? fa.offsetWidth - curOpratorImg.offsetLeft
  4724. : w
  4725. h =
  4726. h >= fa.offsetHeight - curOpratorImg.offsetTop
  4727. ? fa.offsetHeight - curOpratorImg.offsetTop
  4728. : h
  4729. curOpratorImg.style.width = w + 'px'
  4730. curOpratorImg.style.height = h + 'px'
  4731. resetFlexibleIcon($flexibleIcon, $(curOpratorImg))
  4732. // console.log(box.offsetWidth,box.offsetHeight)
  4733. }
  4734. fa.onmouseup = function () {
  4735. fa.onmousemove = null
  4736. fa.onmouseup = null
  4737. }
  4738. })
  4739. },
  4740. //新模块 part
  4741. addNewModule: function (part, moduleType, resetEditorIds, removeElements) {
  4742. var self = this
  4743. var moduleTitle = ''
  4744. var modulePrev = part.prev()
  4745. var hasTitle = modulePrev.length && modulePrev[0].tagName === 'H3'
  4746. //1 新增新模块resetEditorIds removeElements
  4747. //2 判断是否有需要重置的富文本
  4748. var editorEl = part.children('.editorContent')
  4749. if (editorEl.length) {
  4750. resetEditorIds.push({
  4751. editorId: editorEl.attr('id'),
  4752. toolbarId: editorEl.prev().attr('id')
  4753. })
  4754. }
  4755. //3 移除老模块
  4756. removeElements.push(part)
  4757. if (hasTitle) {
  4758. //self.titleHtml(modulePrev.html())
  4759. moduleTitle = modulePrev[0].outerHTML
  4760. removeElements.push(modulePrev)
  4761. }
  4762. return moduleTitle + part[0].outerHTML
  4763. },
  4764. addNewModuleForObjective: function (part, moduleType, removeElements) {
  4765. var self = this
  4766. var moduleTitle = ''
  4767. var modulePrev = part.prev()
  4768. var hasTitle = modulePrev.length && modulePrev[0].tagName === 'H3'
  4769. //3 移除老模块
  4770. removeElements.push(part)
  4771. if (hasTitle) {
  4772. moduleTitle = self.singleSelectObjectiveTitle
  4773. removeElements.push(modulePrev)
  4774. }
  4775. return moduleTitle + part[0].outerHTML
  4776. },
  4777. //拿到富文本超出的内容 顺便计算一下下一个模块该有的最低高度
  4778. getOverContent: function (part, surplusHeight, removeElements) {
  4779. var self = this
  4780. var editorContentEl = part.find('.w-e-text')
  4781. var overContent = []
  4782. var overHeight = 0
  4783. //富文本可视化高度
  4784. var surplusEditorViewportHeight =
  4785. // editorContentEl.height() - surplusHeight + 30
  4786. editorContentEl.height() - surplusHeight
  4787. //看看当前富文本内容的高度有没有被超出的高度区域截掉
  4788. var editorContentHeight = self.calcEditorContentHeight(editorContentEl)
  4789. //如果剩余高度还能装的下答题文本 直接返回空
  4790. if (surplusEditorViewportHeight > editorContentHeight)
  4791. return {
  4792. overContent: overContent.reverse().join(''),
  4793. overHeight: overHeight
  4794. }
  4795. //当前超出富文本内容元素集合,倒序递归删除放到下一页
  4796. var editorContentElements = [].slice
  4797. .call(part.find('.w-e-text').children(), 0)
  4798. .reverse()
  4799. for (var i = 0, elItem; (elItem = editorContentElements[i++]);) {
  4800. if ($(elItem).hasClass("flexible_icon")) continue
  4801. if (editorContentHeight < surplusEditorViewportHeight) break
  4802. var elItemHeight = $(elItem).height() + 10
  4803. if ($(elItem).hasClass("en")){
  4804. elItemHeight = 34
  4805. }
  4806. editorContentHeight -= elItemHeight
  4807. overHeight += elItemHeight
  4808. removeElements.push($(elItem))
  4809. overContent.push(elItem.outerHTML)
  4810. }
  4811. return {
  4812. overContent: overContent.reverse().join(''),
  4813. overHeight: overHeight > surplusHeight ? overHeight + 50 : surplusHeight
  4814. }
  4815. },
  4816. //上一个模块的拓展模块
  4817. expandModule: function (part, nextContentMinHeight) {
  4818. var self = this
  4819. var titleNumber = part.attr('title-number')
  4820. var partEditorIndexUp = part.attr('data-editorindex')
  4821. //当前超出的模块height
  4822. var overHeight = self.getOverHeight(part)
  4823. var $nextPage = part.closest('.pageContent').next()
  4824. var $nextPageFirstModule = $nextPage.find('.module').eq(0)
  4825. var $nextPageModuleTitleNumber = $nextPageFirstModule.attr('title-number')
  4826. overHeight =
  4827. overHeight < self.moduleMinHeight ? self.moduleDefaultHeihgt : overHeight
  4828. //如果下一页已经存在当前模块的 高度累加
  4829. if ($nextPageModuleTitleNumber === titleNumber) {
  4830. overHeight += 0 //$nextPageFirstModule.height()
  4831. }
  4832. //如果该模块超出区域 这需要通过linkparam 去 排列超出的顺序
  4833. editorIndexUp = titleNumber + '-' + editorIndexLi
  4834. if(partEditorIndexUp!=undefined){
  4835. editorIndexUp = partEditorIndexUp+'-' + editorIndexLi
  4836. }
  4837. ++editorIndexLi
  4838. var linkparm = 1
  4839. var cutId = editorIndexUp
  4840. //如果该模块是首次超出 则直接从1开始计数,否则从当前位置开始计数
  4841. if (!part.attr('data-linkparm')) {
  4842. part.attr({
  4843. 'data-cutId': editorIndexUp,
  4844. 'data-linkparm': linkparm
  4845. })
  4846. linkparm++
  4847. } else {
  4848. linkparm = +part.attr('data-linkparm')
  4849. cutId = +part.attr('data-cutId')
  4850. linkparm++
  4851. }
  4852. return self.tpls.overModuleTpl.substitute({
  4853. overIndex: editorIndexUp,
  4854. cutId: cutId,
  4855. linkparm: linkparm,
  4856. titleNumber: titleNumber,
  4857. editorContentHeight:
  4858. overHeight < nextContentMinHeight ? nextContentMinHeight : overHeight
  4859. })
  4860. },
  4861. reduceFillInBlank: function (part, surplusHeight, $dtKContent) {
  4862. var self = this
  4863. var curPageIndex = $dtKContent.closest('.pageContent').index() + 1
  4864. var fromPageIndex = part.closest('.pageContent').index() + 1
  4865. var $answerModule = part.closest('.answerModule')
  4866. var modelId = $answerModule.attr('data-modelId')
  4867. var modelData = self.questionMap[modelId]
  4868. var modelPagesData = modelData.pages
  4869. //一行几栏
  4870. var $firstColForInfoEl = part.children('.subjectCol')
  4871. var dataColumns = $firstColForInfoEl.attr('data-column')
  4872. var columns = dataColumns ? +dataColumns : 1
  4873. //计算每个填空题item的高度
  4874. var rowLinHeight = $firstColForInfoEl.attr('data-rowlineheight')
  4875. var fillInBlankItemHeight = (+rowLinHeight || 40) + 11
  4876. var scoreStyle = $firstColForInfoEl.attr('data-scoreStyle')
  4877. //需要复制几个填空题-如果有标题要减去比哀痛的高度
  4878. if (part.prev().length && part.prev()[0].tagName === 'H3') {
  4879. surplusHeight -= part.prev().height()
  4880. }
  4881. var copyFillInBlankLength =
  4882. Math.floor(surplusHeight / fillInBlankItemHeight) * columns
  4883. //原页面保留的题目
  4884. //超出的放在新页面上
  4885. var curModuleDataIndex = 'page' + curPageIndex
  4886. var nextExpendDataIndex = 'page' + fromPageIndex
  4887. modelPagesData[curModuleDataIndex] =
  4888. modelPagesData[curModuleDataIndex] || []
  4889. modelPagesData[curModuleDataIndex] = modelPagesData[
  4890. curModuleDataIndex
  4891. ].concat(
  4892. modelPagesData[nextExpendDataIndex].splice(0, copyFillInBlankLength)
  4893. )
  4894. //原页面残留
  4895. var originPageRetainHtml = self.getFillInBlankHtml(
  4896. modelPagesData[curModuleDataIndex]
  4897. )
  4898. //新页面超出
  4899. var overFillInBlankItemsHtml = self.getFillInBlankHtml(
  4900. modelPagesData[nextExpendDataIndex]
  4901. )
  4902. var $overFillInBlank = part.closest('.completion-topic')
  4903. var $overDtkContent = $overFillInBlank.closest('.dtk-content')
  4904. $overFillInBlank.remove()
  4905. if (overFillInBlankItemsHtml) {
  4906. overFillInBlankItemsHtml =
  4907. self.titleHtml(originPageRetainHtml ? '' : modelData.bigTitle) +
  4908. self.tpls.fillInBlankContentTpl.substitute({
  4909. addFillInBlankHtml: overFillInBlankItemsHtml,
  4910. columns: columns,
  4911. scoreStyle: scoreStyle,
  4912. rowLinHeight: rowLinHeight,
  4913. settingBtn: originPageRetainHtml
  4914. ? ''
  4915. : self.tpls.fillInBlankSettingBtnTpl
  4916. })
  4917. overFillInBlankItemsHtml = self.tpls.answerModulForFillInBlankTpl.substitute(
  4918. {
  4919. editModule: overFillInBlankItemsHtml,
  4920. moduleType: 'fillInBlank',
  4921. modelId: modelId
  4922. }
  4923. )
  4924. $overDtkContent.prepend(overFillInBlankItemsHtml)
  4925. }
  4926. //老页面残留填空题模块--寻找模块id 相同的模块
  4927. var $prevFillInBlank = { length: 0 }
  4928. $dtKContent.find('.completion-topic').each(function () {
  4929. if ($(this).attr('data-modelId') === modelId) {
  4930. $prevFillInBlank = $(this)
  4931. }
  4932. })
  4933. if (!$prevFillInBlank.length) {
  4934. originPageRetainHtml =
  4935. self.titleHtml(modelData.bigTitle) +
  4936. self.tpls.fillInBlankContentTpl.substitute({
  4937. addFillInBlankHtml: originPageRetainHtml,
  4938. columns: columns,
  4939. scoreStyle: scoreStyle,
  4940. rowLinHeight: rowLinHeight,
  4941. settingBtn: self.tpls.fillInBlankSettingBtnTpl
  4942. })
  4943. originPageRetainHtml = self.tpls.answerModulForFillInBlankTpl.substitute({
  4944. editModule: originPageRetainHtml,
  4945. moduleType: 'fillInBlank',
  4946. modelId: modelId
  4947. })
  4948. $dtKContent.append(originPageRetainHtml)
  4949. } else {
  4950. $prevFillInBlank.find('.subjectCol').html(originPageRetainHtml)
  4951. }
  4952. return !overFillInBlankItemsHtml
  4953. },
  4954. reduceSingleSelect: function (part, surplusHeight, $dtKContent) {
  4955. var self = this
  4956. var curPageIndex = $dtKContent.closest('.pageContent').index()==0?$dtKContent.closest('.pageContent').index() + 1:$dtKContent.closest('.pageContent').index()
  4957. // var fromPageIndex = part.closest('.pageContent').index()==0?part.closest('.pageContent').index() + 1:part.closest('.pageContent').index()
  4958. var fromPageIndex = curPageIndex +1
  4959. var $answerModule = part.closest('.answerModule')
  4960. var type = $answerModule.attr('data-type')
  4961. var modelId = $answerModule.attr('data-modelId')
  4962. var direction = $answerModule.attr('data-direction')
  4963. var prevTag = part.prev()[0]
  4964. if (prevTag && prevTag.tagName === 'H3') {
  4965. surplusHeight -= part.prev().height()
  4966. }
  4967. //每小题的高度
  4968. var selectItemHeight = $('.single-option').eq(0).outerHeight()
  4969. //当前超出的模块height
  4970. if (Math.floor(surplusHeight / selectItemHeight) < 1) return
  4971. //针对选择题竖版一行排几个
  4972. /**
  4973. * 超出的计算单位以 一整排为单位
  4974. * 每一排的一列以5题为单位 计算
  4975. */
  4976. var rowSubjectNum =
  4977. self.config[self.direction][self.hasBindingLine ? 'yesLine' : 'noLine'][
  4978. self.columns
  4979. ]
  4980. //计算超出多少小题
  4981. var overSelectItemsLength =
  4982. Math.floor(surplusHeight / selectItemHeight) * rowSubjectNum
  4983. //该模块的数据
  4984. var modelPagesData = self.questionMap[modelId].pages
  4985. //超出的放在新页面上
  4986. var curModuleDataIndex = 'page' + curPageIndex
  4987. var nextExpendDataIndex = 'page' + fromPageIndex
  4988. modelPagesData[curModuleDataIndex] =
  4989. modelPagesData[curModuleDataIndex] || []
  4990. modelPagesData[curModuleDataIndex] = modelPagesData[
  4991. curModuleDataIndex
  4992. ].concat(
  4993. modelPagesData[nextExpendDataIndex].splice(0, overSelectItemsLength)
  4994. )
  4995. //计算留在当前页面的和下一个页面的数据
  4996. var originPageRetainHtml = self.getSingleSelectHtml(
  4997. modelPagesData[curModuleDataIndex]
  4998. )
  4999. var overSelectItemsHtml = self.getSingleSelectHtml(
  5000. modelPagesData[nextExpendDataIndex]
  5001. )
  5002. //超出页面的数据处理
  5003. var $overAnswerModule = part.closest('.single-select')
  5004. var $overDtkContent = $overAnswerModule.closest('.dtk-content')
  5005. $overAnswerModule.remove()
  5006. if (overSelectItemsHtml) {
  5007. //获取超出选择题区域模块html
  5008. //selectContent, title, direction, hasTitle
  5009. overSelectItemsHtml = self.getSelectRenderContent({
  5010. selectContent: overSelectItemsHtml,
  5011. moduleType: type,
  5012. direction: direction,
  5013. hasTitle: originPageRetainHtml ? false : true,
  5014. bigTitle: self.questionMap[modelId].bigTitle,
  5015. modelId: modelId
  5016. })
  5017. $overDtkContent.prepend(overSelectItemsHtml)
  5018. }
  5019. //老页面残留填空题模块处理
  5020. var $originAnswerModule = self.getAnswerModuleForModelId(modelId)
  5021. if (!$originAnswerModule || !$originAnswerModule.length) {
  5022. //获取整个选择题区域模块html
  5023. originPageRetainHtml = self.getSelectRenderContent({
  5024. selectContent: originPageRetainHtml,
  5025. direction: direction,
  5026. moduleType: type,
  5027. bigTitle: self.questionMap[modelId].bigTitle,
  5028. modelId: modelId
  5029. })
  5030. $dtKContent.append(originPageRetainHtml)
  5031. } else {
  5032. let btnHtml = '<div class="settingBtn" data-type="' + type + '"></div><div class="delTopicBtn" data-type="' + type + '">X</div>'
  5033. $originAnswerModule.find('.singleContent').html(btnHtml + originPageRetainHtml)
  5034. }
  5035. return !overSelectItemsHtml
  5036. },
  5037. reducePrintArea: function (curPageEl) {
  5038. var self = this
  5039. var nextPage = curPageEl.next()
  5040. if (!nextPage.length) {
  5041. //在delPageOverModule 的方法中可能存在被遗忘的超出模块此时做重置
  5042. if (self.forgetOverPage) {
  5043. self.changePrintArea(self.forgetOverPage)
  5044. }
  5045. return
  5046. }
  5047. var curPageIndex = curPageEl.index()
  5048. //当前模块下面所有的模块都可以上移,只要当前剩余空间足够大
  5049. var canUpMovePage = $('#printcontent').children(
  5050. '.pageContent:gt(' + curPageIndex + ')'
  5051. )
  5052. /**
  5053. * 首先通过判断当前页面的剩余空间是否够下一个页面的第一个模块使用
  5054. * 1 如果下一页第一个是第一页的模块补充模块 直接合并
  5055. * 2 如果下一页第一个不是补充模块,如果上一页的空间大于当前这一页
  5056. * a. 直接把标题带着第一个模块一起拿上去
  5057. * b. 如果是一个小题 直接把当前小题拿上去,归并到上一个页面的大题下面
  5058. */
  5059. //var answerModule = [].splice.call(canUpMovePage.find('.answerModule'), 0)
  5060. //var objectiveModule = [].splice.call(canUpMovePage.find('.objectiveModule'), 0)
  5061. var nextPageAllModule = [].splice.call(
  5062. canUpMovePage.find('.answerModule'),
  5063. 0
  5064. )
  5065. var isContiune = true
  5066. nextPageAllModule.forEach(function (answerEl, index) {
  5067. if (!isContiune) return false
  5068. var firstAnswer = $(answerEl)
  5069. var nextUpPage = firstAnswer.closest('.pageContent')
  5070. var answerModuleType = firstAnswer.attr('data-type')
  5071. //题干信息
  5072. var isObjective = answerModuleType === 'objective'
  5073. var isSelect = ~answerModuleType.indexOf('Select') || ~answerModuleType.indexOf('uncertainOption')
  5074. var isFillInBlank = answerModuleType === 'fillInBlank'
  5075. var isChooseAnswer = answerModuleType === 'chooseAnswer'
  5076. var firstModule = firstAnswer.children('.module').eq(0)
  5077. var curPageContent = curPageEl.children('.dtk-content')
  5078. //具体分页内容容器的宽度
  5079. var contentAndHeight = curPageContent.outerHeight()
  5080. //当前分页剩余空间
  5081. var surplusHeight = curPageEl.height() - contentAndHeight
  5082. if (surplusHeight <= 10) {
  5083. //如果当前分页超出直接重新计算排版方式
  5084. if (
  5085. surplusHeight < -10 &&
  5086. curPageEl.find('.answerModule:last()').children('.module').length
  5087. ) {
  5088. self.changePrintArea(curPageEl)
  5089. }
  5090. isContiune = false
  5091. return false
  5092. }
  5093. if (isFillInBlank) {
  5094. //下一页面第一个填空题的高度
  5095. var firstModuleHeight = self.getNextPageFirstModuleHeight(
  5096. firstModule,
  5097. 'fillInBlank'
  5098. )
  5099. if (surplusHeight >= firstModuleHeight) {
  5100. self.reduceFillInBlank(firstModule, surplusHeight, curPageContent)
  5101. self.updatePageElement(nextUpPage, firstAnswer)
  5102. } else {
  5103. isContiune = false
  5104. return false
  5105. }
  5106. } else if (isSelect) {
  5107. var firstModuleHeight = self.getNextPageFirstModuleHeight(
  5108. firstModule,
  5109. 'singleSelect'
  5110. )
  5111. if (surplusHeight >= firstModuleHeight) {
  5112. self.reduceSingleSelect(firstModule, surplusHeight, curPageContent)
  5113. self.updatePageElement(nextUpPage, firstAnswer)
  5114. } else {
  5115. isContiune = false
  5116. return false
  5117. }
  5118. } else if (isObjective) {
  5119. $(answerEl)
  5120. .children('.objectiveItem')
  5121. .each(function (idx, moduleEl) {
  5122. //解答题一个小题就是一个module
  5123. firstModule = $(moduleEl)
  5124. contentAndHeight = curPageContent.outerHeight()
  5125. surplusHeight = curPageEl.height() - contentAndHeight
  5126. //下一个页面第一个解答题模块
  5127. var firstModuleHeight = self.getNextPageFirstModuleHeight(
  5128. firstModule,
  5129. 'objective'
  5130. )
  5131. if (surplusHeight >= firstModuleHeight) {
  5132. self.copyModuleForObjective(firstModule, firstAnswer, curPageEl)
  5133. self.updatePageElement(nextUpPage, firstAnswer, 'objective')
  5134. } else {
  5135. isContiune = false
  5136. return false
  5137. }
  5138. })
  5139. } else {
  5140. //选做题特殊处理,题干信息一个一个往上拿
  5141. var $chooseAnswerObjectiveItems = $(answerEl).find('.questionItemBody')
  5142. //如果有单独的模块还是可以
  5143. // && !$(answerEl).children('.module').length
  5144. if (isChooseAnswer && $chooseAnswerObjectiveItems.length) {
  5145. contentAndHeight = curPageContent.outerHeight()
  5146. surplusHeight =
  5147. curPageEl.height() -
  5148. contentAndHeight -
  5149. $(answerEl).find('h3').children('span').height()
  5150. var removeItems = []
  5151. $chooseAnswerObjectiveItems.each(function () {
  5152. //如果上一页有选做题模块
  5153. var prePageLastAnswer = curPageEl.find('.answerModule:last')
  5154. var prevLastModuleIsChooseAnswer = prePageLastAnswer.length
  5155. ? prePageLastAnswer.attr('data-type') === 'chooseAnswer'
  5156. : false
  5157. var $item = $(this)
  5158. var itemHeight = $(this).height()
  5159. var itemHtml = $(this)[0].outerHTML
  5160. if (surplusHeight > itemHeight) {
  5161. if (prePageLastAnswer.length && prevLastModuleIsChooseAnswer) {
  5162. prePageLastAnswer
  5163. .children('h3')
  5164. .children('.originSubjectInfo')
  5165. .append(itemHtml)
  5166. surplusHeight -= itemHeight
  5167. removeItems.push($item)
  5168. } else {
  5169. //如果上一页没有多选题模块
  5170. //1 先拿到当前多选题的基础信息
  5171. var $h3 = $(answerEl).find('h3')
  5172. var baseInfo = $h3[0].outerHTML.replace(
  5173. /<div class="originSubjectInfo">(.*)<\/div>/g,
  5174. '<div class="originSubjectInfo">' + itemHtml + '</div>'
  5175. )
  5176. curPageContent.append(
  5177. '<div class="short-answer answerModule" data-type="chooseAnswer">' +
  5178. baseInfo +
  5179. '</div>'
  5180. )
  5181. surplusHeight -= itemHeight
  5182. removeItems.push($item)
  5183. }
  5184. } else {
  5185. isContiune = false
  5186. return false
  5187. }
  5188. })
  5189. if (removeItems.length >= $chooseAnswerObjectiveItems.length) {
  5190. $(answerEl).find('h3').remove()
  5191. } else {
  5192. if (removeItems.length) {
  5193. removeItems.forEach(function (el) {
  5194. $(el).remove()
  5195. })
  5196. $(answerEl)
  5197. .find('h3')
  5198. .html(
  5199. '<div class="originSubjectInfo">' +
  5200. $(answerEl)
  5201. .find('h3')
  5202. .children('.originSubjectInfo')
  5203. .html() +
  5204. '</div>'
  5205. )
  5206. }
  5207. }
  5208. self.updatePageElement(nextUpPage, firstAnswer, 'chooseAnswer')
  5209. //self.reducePrintArea(nextPage)
  5210. return
  5211. }
  5212. $(answerEl)
  5213. .children('.module')
  5214. .each(function (idx, moduleEl) {
  5215. var resetEditorIds = []
  5216. //解答题一个小题就是一个module
  5217. firstModule = $(moduleEl)
  5218. contentAndHeight = curPageContent.outerHeight()
  5219. surplusHeight = curPageEl.height() - contentAndHeight
  5220. //如果是补充模块--直接删除再计算其他高度
  5221. if (self.isSurplusModule(firstModule)) {
  5222. self.delPageOverPart(firstModule.find('.delBtn'), 'surplus')
  5223. return
  5224. }
  5225. //下一个页面第一个解答题模块
  5226. var firstModuleHeight = self.getNextPageFirstModuleHeight(
  5227. firstModule,
  5228. 'answer'
  5229. )
  5230. if (surplusHeight >= firstModuleHeight) {
  5231. self.copyModuleToSurplus(
  5232. firstModule,
  5233. firstAnswer,
  5234. curPageEl,
  5235. resetEditorIds
  5236. )
  5237. } else {
  5238. //判断是否是一个大题的开始
  5239. var modulePrev = firstModule.prev()
  5240. var hasTitle = modulePrev.length && modulePrev[0].tagName === 'H3'
  5241. var titleHeight = hasTitle ? modulePrev.height() : 0
  5242. if (surplusHeight <= titleHeight + 100) {
  5243. isContiune = false
  5244. return false
  5245. } else {
  5246. self.copyModuleToSurplus(
  5247. firstModule,
  5248. firstAnswer,
  5249. curPageEl,
  5250. resetEditorIds
  5251. )
  5252. if (self.getOverHeight(curPageEl.find('.module:last()'))) {
  5253. self.saveForgetPage(curPageEl)
  5254. }
  5255. }
  5256. }
  5257. self.updatePageElement(nextUpPage, firstAnswer)
  5258. //重置富文本
  5259. self.resetAddNewModuleEditor(resetEditorIds)
  5260. })
  5261. }
  5262. })
  5263. self.changePrintArea(nextPage)
  5264. },
  5265. //复制一个模块到上一个页面的剩余空间 type whole | few表示整体模块上移还是部分模块上去
  5266. copyModuleToSurplus: function (
  5267. firstModule,
  5268. firstAnswer,
  5269. curPageEl,
  5270. resetEditorIds
  5271. ) {
  5272. var self = this
  5273. //判断是否是一个大题的开始
  5274. var modulePrev = firstModule.prev()
  5275. var hasTitle = modulePrev.length && modulePrev[0].tagName === 'H3'
  5276. var moduleType = firstAnswer.attr('data-type')
  5277. var modelId = firstAnswer.attr('data-modelId')
  5278. var cloneHtml = ''
  5279. //准备重新初始化富文本所需要的 editorId
  5280. var editorEl = firstModule.children('.editorContent')
  5281. if (editorEl.length) {
  5282. resetEditorIds.push({
  5283. editorId: editorEl.attr('id'),
  5284. toolbarId: editorEl.prev().attr('id')
  5285. })
  5286. }
  5287. //如果没有标题 则认为是 上一页最后一大题的一个小题
  5288. var moduleHtml = firstModule[0].outerHTML
  5289. var $dtkContent = curPageEl.children('.dtk-content')
  5290. var $shortAnswerLast = curPageEl.find('.short-answer:last()')
  5291. if (hasTitle) {
  5292. var editModuleHtml = modulePrev[0].outerHTML + moduleHtml
  5293. cloneHtml = self.tpls.answerModuleTpl.substitute({
  5294. editModule: editModuleHtml,
  5295. moduleType: moduleType,
  5296. modelId: modelId
  5297. })
  5298. $dtkContent.append(cloneHtml)
  5299. modulePrev.remove()
  5300. } else {
  5301. var $shortAnswerLast = curPageEl.find('.short-answer:last()')
  5302. cloneHtml = moduleHtml
  5303. //可能中间出现真空区域
  5304. if (!$shortAnswerLast.length) {
  5305. cloneHtml = self.tpls.answerModuleTpl.substitute({
  5306. editModule: cloneHtml,
  5307. moduleType: moduleType,
  5308. modelId: modelId
  5309. })
  5310. $dtkContent.append(cloneHtml)
  5311. } else {
  5312. $shortAnswerLast.append(cloneHtml)
  5313. }
  5314. }
  5315. //清理模块
  5316. firstModule.remove()
  5317. },
  5318. //题干信息copy
  5319. copyModuleForObjective: function (firstModule, firstAnswer, curPageEl) {
  5320. var self = this
  5321. //判断是否是一个大题的开始
  5322. var modulePrev = firstModule.prev()
  5323. var hasTitle = modulePrev.length && modulePrev[0].tagName === 'H3'
  5324. var cloneHtml = ''
  5325. //如果没有标题 则认为是 上一页最后一大题的一个小题
  5326. var moduleHtml = firstModule[0].outerHTML
  5327. // self.tpls.objectiveItemTpl.substitute({
  5328. // content: firstModule.html()
  5329. // })
  5330. var $dtkContent = curPageEl.children('.dtk-content')
  5331. if (hasTitle) {
  5332. var editModuleHtml = modulePrev[0].outerHTML + moduleHtml
  5333. cloneHtml = self.tpls.objectiveWrapTpl.substitute({
  5334. editModule: editModuleHtml
  5335. })
  5336. $dtkContent.append(cloneHtml)
  5337. modulePrev.remove()
  5338. } else {
  5339. var $shortAnswerLast = curPageEl.find('.objectiveModule:last()')
  5340. cloneHtml = moduleHtml
  5341. //可能中间出现真空区域
  5342. if (!$shortAnswerLast.length) {
  5343. cloneHtml = self.tpls.objectiveWrapTpl.substitute({
  5344. editModule: cloneHtml
  5345. })
  5346. $dtkContent.append(cloneHtml)
  5347. } else {
  5348. $shortAnswerLast.append(cloneHtml)
  5349. }
  5350. }
  5351. //清理模块
  5352. firstModule.remove()
  5353. },
  5354. //获取当前也页面的剩余空间
  5355. getCurPageSurplusHeight: function (curPageEl) {
  5356. var curPageContent = curPageEl.children('.dtk-content')
  5357. //具体分页内容容器的宽度
  5358. var contentAndHeight = curPageContent.outerHeight()
  5359. //当前分页剩余空间
  5360. return curPageEl.height() - contentAndHeight
  5361. },
  5362. //获取下一个页面第一个模块的高度,用来和上一个页面的剩余高度做对比
  5363. getNextPageFirstModuleHeight: function (firstModule, type) {
  5364. var self = this
  5365. //判断是否是一个大题的开始
  5366. var modulePrev = firstModule.prev()
  5367. var hasTitle = modulePrev.length && modulePrev[0].tagName === 'H3'
  5368. //如果包含title 必须满足上一页面剩余的高度大于 当前页面第一个模块的高度加上模块对应title的高度
  5369. //留点空间余地不能抵到最底下
  5370. var titleHeight = (hasTitle ? modulePrev.height() : 0) + 10
  5371. //type包含选择,填空,解答题
  5372. if (type === 'fillInBlank') {
  5373. var firstFillInBlank = firstModule.find('.subjectItem').eq(0)
  5374. return firstFillInBlank.outerHeight() + titleHeight
  5375. } else if (~type.indexOf('Select')) {
  5376. var firstSelect = firstModule.find('.single-option').eq(0)
  5377. return firstSelect.outerHeight() + titleHeight
  5378. } else {
  5379. return firstModule.outerHeight() + titleHeight
  5380. }
  5381. },
  5382. //页面之间模版串位之后更新每个页面的元素
  5383. updatePageElement: function (nextUpPage, firstAnswer, type) {
  5384. var self = this
  5385. //题干信息单独处理
  5386. var nextPage = nextUpPage
  5387. var isObjective = type === 'objective'
  5388. //选做题如果有题干信息
  5389. var isChooseAnswer =
  5390. type === 'chooseAnswer' && firstAnswer.find('.originSubjectInfo').length
  5391. if (firstAnswer) {
  5392. if (
  5393. !firstAnswer.children(isObjective ? '.objectiveItem' : '.module')
  5394. .length &&
  5395. !isChooseAnswer
  5396. ) {
  5397. firstAnswer.remove()
  5398. }
  5399. }
  5400. if (
  5401. !nextPage.find('.answerModule').length &&
  5402. !nextPage.find('.objectiveModule').length
  5403. ) {
  5404. // 判断当前页面是否最后一页----如果最后一页为空才直接删除该页面
  5405. // 选择题和填空题的数据是根据页面显示的,如果你删除了,选择题和填空题的数据就错位了
  5406. if ($('#printcontent .pageContent').length === nextPage.index() + 1) {
  5407. var prevPage = nextPage.prev()
  5408. nextPage.remove()
  5409. self.currentPage--
  5410. //新建的分页
  5411. self.totalPage--
  5412. self.refrushPageLabel()
  5413. if (prevPage.length) {
  5414. self.updatePageElement(prevPage)
  5415. }
  5416. }
  5417. }
  5418. },
  5419. //新页面预览
  5420. previewPrintDiv: function (printPart) {
  5421. var self = this
  5422. var priviewHtml = self.formatPrintHtml(printPart, 'preview')
  5423. var iframe = document.createElement('iframe')
  5424. iframe.setAttribute('id', 'preview-iframe')
  5425. document.body.appendChild(iframe)
  5426. var doc = iframe.contentWindow.document
  5427. doc.write(
  5428. '<link rel="stylesheet" type="text/css" href="' + printCssPath + '">'
  5429. )
  5430. doc.write(priviewHtml)
  5431. if (isShowPreview > -1) {
  5432. $('body').append('<div class="h_btn previewbackbtn"><a href="javascript:;" class="btn-go-back">返回</a></div>')
  5433. } else {
  5434. $('body').append('<div id="closeIframeBtn" class="h_btn">关闭</div>')
  5435. $('body').on('click', '#closeIframeBtn', function () {
  5436. $('#preview-iframe').remove()
  5437. $(this).remove()
  5438. })
  5439. }
  5440. },
  5441. //保存题目坐标信息
  5442. //保存的时候传点坐标和原图
  5443. /**
  5444. *
  5445. timu:{"KeGuanTi":5,"TianKongTi":10,"ZhuGuanTi":1,"XuanZuoTi":0}
  5446. sheet_answer:{"1":"A","2":"A","3":"A","4":"A","5":"A"}
  5447. sheet_score:{"1":"2","2":"2","3":"2","4":"2","5":"2","6":"2","7":"3","8":"4","9":"5","10":"6","11":"6","12":"7","13":"8","14":"9","15":"10","16":"20"}
  5448. title:22
  5449. exam_id:17464269385543527633
  5450. position
  5451. imgFiles:[fileobj,fileobj]
  5452. */
  5453. //保存题目定位点的时候 获取 题目数量 分数 等信息
  5454. getSaveSubjectInfo: function (questionClassify) {
  5455. var self = this
  5456. var title = self.$dtkName.val()
  5457. // examInfo
  5458. //信息栏
  5459. //数量
  5460. var timu = {
  5461. KeGuanTi: 0,
  5462. TianKongTi: 0,
  5463. ZhuGuanTi: 0,
  5464. XuanZuoTi: 0
  5465. }
  5466. //选择题答案
  5467. var sheet_answer = {}
  5468. //每题对应分数
  5469. var sheet_score = {}
  5470. // 半对分
  5471. var sheet_halfscore = {}
  5472. // 总分
  5473. var scoreAll = 0
  5474. let pId = 0
  5475. var key = 0
  5476. for (var uid in questionClassify) {
  5477. questionClassify[uid].questions.forEach(function (question, index) {
  5478. //计算每个题目数量
  5479. var type = question.questionTypeId
  5480. if (~[1, 2, 11].indexOf(type)) {
  5481. timu.KeGuanTi += 1
  5482. } else if (type === 5) {
  5483. timu.TianKongTi += 1
  5484. } else if (type === 7) {
  5485. timu.ZhuGuanTi += 1
  5486. } else {
  5487. timu.XuanZuoTi += 1
  5488. }
  5489. key += 1
  5490. if(question.answer!=''){
  5491. sheet_answer[key] = question.answer
  5492. }
  5493. sheet_score[key] = '' + question.fullScore
  5494. sheet_halfscore[key] = question.halfScore
  5495. if (type == 17) {
  5496. if (pId != question.topicNo)
  5497. scoreAll = scoreAll + Number(question.fullScore)
  5498. pId = question.topicNo
  5499. } else {
  5500. scoreAll = scoreAll + Number(question.fullScore)
  5501. }
  5502. })
  5503. }
  5504. self.savePrintInfo = {
  5505. title: title,
  5506. timu: timu,
  5507. sheet_answer: sheet_answer,
  5508. sheet_score: sheet_score,
  5509. sheet_halfscore: sheet_halfscore
  5510. }
  5511. self.examInfoConfigText.wpTimes = $('#examInfo input[name|="wpTimes"]').val()
  5512. // self.examInfoConfigText.fullScore = $('#examInfo input[name|="fullScore"]').val()
  5513. self.examInfoConfigText.fullScore = scoreAll
  5514. self.examInfoConfigText.wpAuthor = $('#examInfo input[name|="wpAuthor"]').val()
  5515. self.examInfoConfigText.wpReviewer = $('#examInfo input[name|="wpReviewer"]').val()
  5516. self.examInfoConfigText.fullScore =
  5517. self.showExamInfoHtml()
  5518. },
  5519. //printcontent --- printPart
  5520. savePrintPosition: function (printPart, cb) {
  5521. var self = this
  5522. // 给模块标题设置高度
  5523. $('.answerModule').find('h3').each(function (){
  5524. $(this).css('height',$(this).height())
  5525. })
  5526. var position = self.getPositions()
  5527. //保存当前坐标点用于和下次一点击保存做对比,如果没有变化就可以防止重复提交
  5528. self.saveLocationPosition = JSON.stringify(position)
  5529. //console.log(JSON.stringify(position, null, 4))
  5530. var printHtml = self.formatPrintHtml(printPart)
  5531. var iframe = document.createElement('iframe')
  5532. iframe.setAttribute('id', 'print-iframe')
  5533. iframe.setAttribute('style', 'position:fixed;')
  5534. document.body.appendChild(iframe)
  5535. var doc = iframe.contentWindow.document
  5536. doc.write(
  5537. '<link rel="stylesheet" type="text/css" href="' + printCssPath + '">'
  5538. )
  5539. doc.write(printHtml)
  5540. doc.close()
  5541. iframe.contentWindow.focus()
  5542. iframe.contentWindow.onload = function () {
  5543. var pages = doc.getElementsByClassName('printIframeContent')
  5544. //生成的pdf所需要的html
  5545. var pdfHtml = (
  5546. self.tpls.htmlSkeleton +
  5547. printHtml +
  5548. '</body></html>'
  5549. ).replace(/\'/g, '"')
  5550. hgc_layer.msg('pdf生成中,请稍后...', { time: 0, shade: 0.4 })
  5551. $.post(
  5552. self.apis.getOnlinePdfApi,
  5553. {
  5554. width: self.config.width + 'mm',
  5555. height: self.config.height + 'mm',
  5556. identifier: self.identifier,
  5557. examGroupId:self.examGroupId || '26566294892575975',
  5558. pdfHtml: pdfHtml
  5559. },
  5560. function (res) {
  5561. var pdfFileUrl = ''
  5562. let resData = JSON.parse(res)
  5563. if(resData.success==1){
  5564. pdfFileUrl = resData.data
  5565. // hgc_layer.closeAll()
  5566. // location.href = self.apis.downloadPdfUrl + self.identifier
  5567. } else {
  5568. hgc_layer.msg(resData.message)
  5569. return false
  5570. }
  5571. //处理模版html
  5572. var pdfHtmlStream = new Blob([pdfHtml], {
  5573. type: 'text/plain;charset=utf-8'
  5574. })
  5575. self.savePrintInfo.title = self.$dtkName.val()
  5576. self.savePrintInfo.pdfHtml = pdfHtml
  5577. self.savePrintInfo.position = position
  5578. //pdf 模版唯一标识符--主要用于创建考试页面模版下载
  5579. self.savePrintInfo.identifier = self.identifier
  5580. self.savePrintInfo.examGroupId = self.examGroupId
  5581. self.savePrintInfo.useQrCode = self.useQrCode ? 1 : 0
  5582. self.savePrintInfo.columns = self.columns
  5583. self.savePrintInfo.pdfTemplate = pdfHtmlStream
  5584. self.savePrintInfo.pdf_url = pdfFileUrl
  5585. var formData = new FormData()
  5586. formData.append('pdfTemplate', pdfHtmlStream, 'pdfTepmlate.txt')
  5587. //pdf链接
  5588. formData.append('pdf_url', pdfFileUrl)
  5589. //针对全学科,在保留题型数据的同时,也需要当前定位点的所有信息
  5590. if (isNewBuild) {
  5591. var questions = []
  5592. var buildQuestions = self.questionMap
  5593. for (var modelId in buildQuestions) {
  5594. questions = questions.concat(buildQuestions[modelId].questions)
  5595. }
  5596. //题号重新排序
  5597. let PositionData = JSON.parse(JSON.stringify(questions))
  5598. function compare(key){
  5599. return function(value1,value2){
  5600. var val1=value1[key];
  5601. var val2=value2[key];
  5602. return val1-val2;
  5603. }
  5604. }
  5605. PositionData.sort(compare('questionNum'));
  5606. jQuery.each( PositionData, function( i, topicItem ) {
  5607. topicItem.name = i+1
  5608. });
  5609. jQuery.each( questions, function( q, questionsItem ) {
  5610. questionsItem.isEdit = false
  5611. });
  5612. let score = {};
  5613. let halfScore = {};
  5614. let answer = {};
  5615. jQuery.each( questions, function( j, paperTopicItem ) {
  5616. jQuery.each( PositionData, function( k, topicAllItem ) {
  5617. if(!paperTopicItem.isEdit){
  5618. if(paperTopicItem.questionNum == topicAllItem.questionNum){
  5619. let topic = JSON.parse(JSON.stringify(topicAllItem))
  5620. let key = topic.name.toString();
  5621. paperTopicItem.questionNum = topic.name.toString()
  5622. paperTopicItem.isEdit = true
  5623. if(paperTopicItem.answer!=''){
  5624. answer[key] = paperTopicItem.answer
  5625. }
  5626. score[key] = '' + paperTopicItem.fullScore
  5627. halfScore[key] = paperTopicItem.halfScore
  5628. }
  5629. }
  5630. });
  5631. });
  5632. self.savePrintInfo.sheet_score = score;
  5633. self.savePrintInfo.sheet_halfscore = halfScore;
  5634. self.savePrintInfo.sheet_answer = answer;
  5635. self.savePrintInfo.question_info = {
  5636. content: questions
  5637. }
  5638. console.log(JSON.stringify(self.savePrintInfo))
  5639. //全学科,该页面还是做编辑使用,不做任何的操作
  5640. localStorage.setItem(
  5641. 'savePrintInfo',
  5642. JSON.stringify(self.savePrintInfo)
  5643. )
  5644. hgc_layer.closeAll()
  5645. self.isCanEditCard = false
  5646. self.changeCardEditStatus()
  5647. // location.href = document.referrer
  5648. // if(localStorage.referrerUrl){
  5649. // var referrerUrl = JSON.parse(localStorage.getItem('referrerUrl'));
  5650. // window.location.href = referrerUrl+"/isCardReturn=true"
  5651. // }else{
  5652. // window.history.back();
  5653. // }
  5654. return
  5655. }
  5656. for (var field in self.savePrintInfo) {
  5657. if (typeof self.savePrintInfo[field] === 'object') {
  5658. formData.append(field, JSON.stringify(self.savePrintInfo[field]))
  5659. } else {
  5660. formData.append(field, self.savePrintInfo[field])
  5661. }
  5662. }
  5663. //localStorage.setItem('savePrintInfo',JSON.stringify(self.savePrintInfo))
  5664. /**
  5665. * 新页面需要特殊处理的地方
  5666. * var pdfHtmlStream = new Blob([pdfHtml], {
  5667. type: 'text/plain;charset=utf-8'
  5668. })
  5669. * formData.append('pdfTemplate', pdfHtmlStream, 'pdfTepmlate.txt')
  5670. * imgFiles
  5671. * formData.append('imgFiles' + index, img)
  5672. *
  5673. * examNumberConfig
  5674. */
  5675. $.ajax({
  5676. //'//192.168.1.51/index.php/print/saveCardOnline' + loginStatus,
  5677. url: self.apis.saveTopicsDetailsApi,
  5678. method: 'POST',
  5679. processData: false,
  5680. contentType: false,
  5681. dataType: 'json',
  5682. data: formData,
  5683. success: function (data) {
  5684. hgc_layer.closeAll()
  5685. if (data.success === 1) {
  5686. hgc_layer.msg('保存成功')
  5687. self.isCanEditCard = false
  5688. self.changeCardEditStatus()
  5689. self.alreadySave = true
  5690. //如果使用二维码
  5691. //考号 和 条形码 都没有了,导致试卷内所有定位点错误,需要重新保存定位点
  5692. cb && cb()
  5693. } else {
  5694. hgc_layer.msg('保存失败')
  5695. }
  5696. }
  5697. })
  5698. document.body.removeChild(iframe)
  5699. }
  5700. )
  5701. }
  5702. },
  5703. //重置学生状态
  5704. resetExamStudentStatus: function (cb) {
  5705. var self = this
  5706. $.post(
  5707. self.apis.resetExamStudentApi,
  5708. {
  5709. schoolId: this.schoolId,
  5710. examGroupId: this.examGroupId
  5711. },
  5712. function (res) {
  5713. // console.log(res)
  5714. cb && cb()
  5715. }
  5716. )
  5717. },
  5718. //后台批量生成examgroupid下面的所有考试
  5719. batchGeneratePdf: function () {
  5720. var self = this
  5721. var printHtml = self.formatPrintHtml('printcontent')
  5722. var pdfHtml = (
  5723. self.tpls.htmlSkeleton +
  5724. printHtml +
  5725. '</body></html>'
  5726. ).replace(/\'/g, '"')
  5727. var batchParams = {
  5728. width: self.config.width + 'mm',
  5729. height: self.config.height + 'mm',
  5730. examGroupId: self.examGroupId,
  5731. examIds: self.examIds,
  5732. schoolId: self.schoolId,
  5733. direction: self.direction,
  5734. pdfTpl: pdfHtml
  5735. //savedInfoUrl: 'http://zxhx-test.cn-bj.ufileos.com/zsyas2%2Fcardonline%2F3865%2F2020%2F04%2F10%2F565798454967058432.zip?r=888'
  5736. }
  5737. // hgc_layer.msg('学生模板批量生成中,请稍后...', { time: 0, shade: 0.4 })
  5738. $.ajax({
  5739. url: self.apis.batchGeneratePdfApi,
  5740. method: 'POST',
  5741. data: batchParams,
  5742. success: function (res) {
  5743. hgc_layer.closeAll()
  5744. hgc_layer.msg(res.msg)
  5745. }
  5746. })
  5747. // batchInstance = $.post(self.apis.batchGeneratePdfApi, batchParams, function(res) {
  5748. // })
  5749. },
  5750. downLoadPdf: function () {
  5751. var self = this
  5752. if (!self.alreadySave && !isNewBuild) {
  5753. hgc_layer.msg('请先保存答题卡')
  5754. return
  5755. }
  5756. //如果是创建答题卡,直接下载即可
  5757. if (isNewBuild) {
  5758. hgc_layer.msg('pdf生成中,请稍后...', { time: 0, shade: 0.4 })
  5759. var printHtml = self.formatPrintHtml('printcontent')
  5760. var pdfHtml = (
  5761. self.tpls.htmlSkeleton +
  5762. printHtml +
  5763. '</body></html>'
  5764. ).replace(/\'/g, '"')
  5765. $.post(
  5766. self.apis.getOnlinePdfApi,
  5767. {
  5768. width: self.config.width + 'mm',
  5769. height: self.config.height + 'mm',
  5770. identifier: self.identifier,
  5771. examGroupId:self.examGroupId,
  5772. pdfHtml: pdfHtml
  5773. },
  5774. function (res) {
  5775. let resData = JSON.parse(res)
  5776. if(resData.success==1){
  5777. hgc_layer.closeAll()
  5778. // location.href = self.apis.downloadPdfUrl + self.identifier
  5779. location.href = self.apis.downOnlinePdfApi + '?url=' + resData.data + '&title=pdf-'+self.examGroupId+'.pdf'
  5780. // location.href = resData.data
  5781. } else {
  5782. hgc_layer.msg(resData.message)
  5783. }
  5784. }
  5785. )
  5786. return
  5787. }
  5788. var downloadUrl =
  5789. // self.apis.downPdfApi + '?exam_group_id=' + self.examGroupId
  5790. self.apis.downOnlinePdfApi + '?url=' + self.downPdfUrl + '&title='+self.examGroupId
  5791. location.href = downloadUrl
  5792. },
  5793. /**
  5794. * 处理需要打印的html
  5795. * 返回处理之后直接可以打印的html
  5796. */
  5797. formatPrintHtml: function (elId, type) {
  5798. //format-需要打印的iframe里面的内容
  5799. //origin-原网页的内容
  5800. var self = this
  5801. $('#examInfo').find('.input-examInfo').each(function(i ,item){
  5802. $(this).attr('value',$(this).val())
  5803. })
  5804. //type 预览效果存储的html 和 用于转pdf 的不一样
  5805. var isPreview = type === 'preview'
  5806. var $formatContent = $('#formatContent').html($('#' + elId).html())
  5807. var $formatPageContent = $formatContent.children('.pageContent')
  5808. var $formatPageObjective = $formatPageContent.find('.objectiveItem')
  5809. var $formatDtkTitle = $formatPageContent.eq(0).find('.dtkName')
  5810. var $formatDtkNoticeDetail = $formatPageContent.eq(0).find('.noticeDetail')
  5811. var $formatShortAnswer = $formatContent.find('.short-answer')
  5812. var $originShortAnswer = $('#' + elId + ' .short-answer')
  5813. var $originShortAnswer = $('#' + elId + ' .short-answer')
  5814. var $originDtkTitle = $('#' + elId + ' .pageContent')
  5815. .eq(0)
  5816. .find('.dtkName')
  5817. //设置每个分页的高度
  5818. $formatPageContent.height(self.config.height + 'mm')
  5819. $formatPageContent.find('.pageLabel .size').remove()
  5820. //设置答题卡title
  5821. $formatDtkTitle.html($originDtkTitle.children('textarea').val())
  5822. //设置注意事项-所有标题预览页面不可编辑
  5823. $formatDtkNoticeDetail.prop('contenteditable', false)
  5824. $formatPageContent.find('h3').prop('contenteditable', false)
  5825. $formatPageObjective.prop('contenteditable', false)
  5826. //模块格式化html
  5827. $originShortAnswer.each(function (index, el) {
  5828. $(el)
  5829. .children('.module')
  5830. .each(function (idx, elm) {
  5831. var $formatModuleItem = $formatShortAnswer
  5832. .eq(index)
  5833. .children('.module')
  5834. .eq(idx)
  5835. var $scortColumn = $(elm).children('.scortColumn')
  5836. var $chooseArea = $(elm).children('.selTopic')
  5837. var editorIndex = $(elm).attr('data-editorIndex')
  5838. if (!editorIndex) return
  5839. //富文本编辑内容
  5840. var textareaContent = self.editorArea[
  5841. 'editor' + editorIndex
  5842. ].txt.html()
  5843. //打分区域
  5844. var scortAreaContent = $scortColumn.length
  5845. ? $scortColumn[0].outerHTML
  5846. : ''
  5847. //多选区域
  5848. var chooseAreaHtml = ''
  5849. if ($chooseArea.length) {
  5850. chooseAreaHtml += $chooseArea[0].outerHTML
  5851. }
  5852. //height content
  5853. var modulePrintHeight = self.unitConversion.pxConversionMm(
  5854. $(elm).height()
  5855. )
  5856. $formatModuleItem
  5857. .height(modulePrintHeight + 'mm')
  5858. .html(
  5859. scortAreaContent +
  5860. chooseAreaHtml +
  5861. '<div class="modulePosition">' +
  5862. textareaContent +
  5863. '</div>'
  5864. )
  5865. })
  5866. })
  5867. //第三方静态资源识别
  5868. var linkSrc = ''
  5869. var scriptSrc = ''
  5870. //用几张纸
  5871. var paperLength = Math.ceil($formatPageContent.length / self.columns)
  5872. paperLength = paperLength < 2 ? paperLength + 1 : paperLength
  5873. var printHtmlForPaperHtml = ''
  5874. for (var j = 0; j < paperLength; j++) {
  5875. var printHtml = ''
  5876. //判断奇数页 还是 偶数页
  5877. var isEvenPaper = !((j + 1) % 2)
  5878. var isFirstPaper = !j
  5879. var scanDotPaperIndex = (j + 1) % 2 ? 1 : 2
  5880. for (var k = 0; k < self.columns; k++) {
  5881. var pageItem = $formatPageContent.eq(j * self.columns + k)
  5882. var pageClass = pageItem.attr('class') || 'pageContent'
  5883. var dtkContentHtml = pageItem.length
  5884. ? pageItem.html()
  5885. : self.tpls.forbiddenAreaTpl
  5886. var bindingLineHtml = ''
  5887. //奇数页面装订线在左边,偶数页面装订线在右边
  5888. //奇数页面的第一个分栏 和 偶数页面的最后一个分栏 加上装订线,除了第一个
  5889. if (self.hasBindingLine) {
  5890. if (isEvenPaper && k + 1 === self.columns) {
  5891. bindingLineHtml = self.tpls.bindLineTpl.substitute({ pos: 'right' })
  5892. } else if (!isEvenPaper && !k && !isFirstPaper) {
  5893. bindingLineHtml = self.tpls.bindLineTpl.substitute({ pos: 'left' })
  5894. }
  5895. }
  5896. printHtml +=
  5897. '<div class="' +
  5898. pageClass +
  5899. '" style="break-after: page;height:' +
  5900. self.config.height +
  5901. 'mm">' +
  5902. bindingLineHtml +
  5903. dtkContentHtml +
  5904. '</div>'
  5905. }
  5906. var scanDotHtml = self.tpls['scanDotPaper' + scanDotPaperIndex]
  5907. printHtmlForPaperHtml += self.tpls.printIframeContentTpl.substitute({
  5908. bindingLine: self.hasBindingLine ? 'hasBindingLine' : '',
  5909. previewClass: isPreview ? 'previewIframe' : '',
  5910. columns: self.columns,
  5911. widthMm: self.config.width,
  5912. printHtml: printHtml + scanDotHtml,
  5913. linkSrc: linkSrc,
  5914. scriptSrc: scriptSrc
  5915. })
  5916. }
  5917. //清空
  5918. $('#formatContent').html('')
  5919. return printHtmlForPaperHtml
  5920. },
  5921. //获取定位的基准点
  5922. getPositionOriginPoint: function () {
  5923. var self = this
  5924. //每个分页的定位基准点都是当前分页的左上角
  5925. self.printAreaLeft = $('#printcontent').offset().left
  5926. self.printAreaTop = $('#printcontent').offset().top
  5927. },
  5928. //获取扫描点信息
  5929. getScanPointInfo: function (currentPaper) {
  5930. var self = this
  5931. self.dotWidth = 40
  5932. self.dotHeight = 20
  5933. //大定位点上下间隙
  5934. self.dotTBGap = 20
  5935. //为了区分正反面,大定位点上面中间的那个点,需要正反面反向偏移一定距离
  5936. self.offsetDistance = self.pageWidth / 2 - 50
  5937. //获取页面的扫描点
  5938. /**
  5939. * 1.产品定义的区域
  5940. * 2.客观题区域
  5941. * 3.图片考号区域
  5942. * 4.选做题区域
  5943. */
  5944. var hasBinding = self.hasBindingLine
  5945. var pagePaddingSide = self.pagePaddingSide + (hasBinding ? 20 : 0)
  5946. var location = [
  5947. //上左
  5948. {
  5949. x: pagePaddingSide * self.dpiRadio,
  5950. y: self.dotTBGap * self.dpiRadio,
  5951. width: self.dotWidth * self.dpiRadio,
  5952. height: self.dotHeight * self.dpiRadio,
  5953. type: 1
  5954. },
  5955. //上右
  5956. {
  5957. x:
  5958. (self.pageWidth - self.pagePaddingSide - self.dotWidth) *
  5959. self.dpiRadio,
  5960. y: self.dotTBGap * self.dpiRadio,
  5961. width: self.dotWidth * self.dpiRadio,
  5962. height: self.dotHeight * self.dpiRadio,
  5963. type: 1
  5964. },
  5965. //下右
  5966. {
  5967. x: (self.pageWidth - self.pagePaddingSide - self.dotWidth) *
  5968. self.dpiRadio,
  5969. y: (self.pageHeight - self.dotTBGap - self.dotHeight) * self.dpiRadio,
  5970. width: self.dotWidth * self.dpiRadio,
  5971. height: self.dotHeight * self.dpiRadio,
  5972. type: 1
  5973. },
  5974. //下左
  5975. {
  5976. x: pagePaddingSide * self.dpiRadio,
  5977. y: (self.pageHeight - self.dotTBGap - self.dotHeight) * self.dpiRadio,
  5978. width: self.dotWidth * self.dpiRadio,
  5979. height: self.dotHeight * self.dpiRadio,
  5980. type: 1
  5981. }
  5982. ]
  5983. if (currentPaper === 1) {
  5984. //上靠左边
  5985. location.splice(1, 0, {
  5986. x: self.offsetDistance * self.dpiRadio,
  5987. y: self.dotTBGap * self.dpiRadio,
  5988. width: self.dotWidth * self.dpiRadio,
  5989. height: self.dotHeight * self.dpiRadio,
  5990. type: 1
  5991. })
  5992. } else {
  5993. //上靠右边
  5994. location.splice(1, 0, {
  5995. x: (self.pageWidth - self.offsetDistance - self.dotWidth) *
  5996. self.dpiRadio,
  5997. y: self.dotTBGap * self.dpiRadio,
  5998. width: self.dotWidth * self.dpiRadio,
  5999. height: self.dotHeight * self.dpiRadio,
  6000. type: 1
  6001. })
  6002. }
  6003. return location
  6004. },
  6005. getElementWidth: function (el, type) {
  6006. var self = this
  6007. var width = $(el).outerWidth()
  6008. return width * self.dpiRadio
  6009. },
  6010. getElementHeight: function (el, type) {
  6011. var self = this
  6012. var height = $(el).outerHeight()
  6013. return height * self.dpiRadio
  6014. },
  6015. getPositions: function () {
  6016. var self = this
  6017. /**
  6018. * {paper,direction,hasBindingLine,examNumberConfig:{barCode,ticketNumber},useQrCode}
  6019. */
  6020. //Math.ceil(self.totalPage / self.columns)
  6021. //每次获取每张纸的每一页定位信息,先确定 x轴,y轴的定位基准点
  6022. self.getPositionOriginPoint()
  6023. //是否合并题卡信息
  6024. var $chooseAnswerInfo = $('.answerModule[data-type="chooseAnswer"]')
  6025. var isConcat =
  6026. self.isSubjectInfoToCard &&
  6027. $('.objectiveItem').length &&
  6028. $chooseAnswerInfo.length &&
  6029. $chooseAnswerInfo.find('.originSubjectInfo').length
  6030. //存储供新建答题卡的以及答题卡信息使用
  6031. var memoryDtkInfo = {}
  6032. if (isNewBuild) {
  6033. var buildQuestions = self.questionMap
  6034. if(self.$dtkName.val()){
  6035. self.savePrintInfo.title = self.$dtkName.val()
  6036. }
  6037. // self.savePrintInfo.title = self.$dtkName.val()
  6038. memoryDtkInfo = {
  6039. ...self.savePrintInfo,
  6040. buildQuestions,
  6041. examInfoConfigText:self.examInfoConfigText,
  6042. examInfoConfig:self.examInfoConfig,
  6043. hasPaperMsg:self.hasPaperMsg
  6044. }
  6045. }
  6046. var printPositionInfo = {
  6047. totalPage: 2,
  6048. //准考证类型
  6049. school_card_status: self.school_card_status,
  6050. //需要记录本次的paperTplType 是否为题卡合一
  6051. isSubjectInfoToCard: self.isSubjectInfoToCard,
  6052. //选做题题干信息单独保存
  6053. chooseAnswerStemInfo: isConcat
  6054. ? encodeURIComponent(
  6055. $chooseAnswerInfo.find('.originSubjectInfo')[0].outerHTML
  6056. )
  6057. : '',
  6058. //纸张大小、方向、分栏、装订线、考号配置等,需要记忆布局
  6059. columns: self.columns,
  6060. paper: self.paper,
  6061. direction: self.direction,
  6062. hasBindingLine: self.hasBindingLine,
  6063. examNumberConfig: self.examNumberConfig,
  6064. useQrCode: self.useQrCode,
  6065. width: self.config.width,
  6066. height: self.config.height,
  6067. ...memoryDtkInfo,
  6068. pages: []
  6069. }
  6070. //每张纸的一面
  6071. var examNumberAreaData = self.getExamNumberPosition()
  6072. var paperPosition = {
  6073. 1: {
  6074. pageNo: 1,
  6075. //四个定位点信息
  6076. location: self.getScanPointInfo(1),
  6077. //条形码
  6078. studentcode_bar: examNumberAreaData.studentcode_bar,
  6079. //准考证号码
  6080. studentcode_fill: examNumberAreaData.studentcode_fill,
  6081. //缺考标记定位信息
  6082. absent: self.getAbsentMarkPostion(),
  6083. //学生二维码信息
  6084. QrCode: self.getQrCodePosition(),
  6085. //打印区域宽高
  6086. imge: {
  6087. width: self.pageWidth * self.dpiRadio, //self.config.width,
  6088. height: self.pageHeight * self.dpiRadio //self.config.height
  6089. },
  6090. //题目坐标信息
  6091. questions: []
  6092. },
  6093. 2: {
  6094. pageNo: 2,
  6095. //四个定位点信息
  6096. location: self.getScanPointInfo(2),
  6097. //打印区域宽高
  6098. imge: {
  6099. width: self.pageWidth * self.dpiRadio, //self.config.width,
  6100. height: self.pageHeight * self.dpiRadio //self.config.height
  6101. },
  6102. //题目坐标信息
  6103. questions: []
  6104. }
  6105. }
  6106. //首先获取每个纸张一页的扫描点信息
  6107. $('#printcontent .pageContent').each(function (pageIndex, pageItem) {
  6108. var $pageItem = $(pageItem)
  6109. //判断纸张的第一面还是第二面 or 正面还是反面
  6110. var paperNo = Math.ceil((pageIndex + 1) / self.columns)
  6111. $pageItem.find('.answerModule').each(function (k, moduleItem) {
  6112. var type = $(moduleItem).attr('data-type')
  6113. var modelId = $(moduleItem).attr('data-modelId')
  6114. var moduleInfo = {
  6115. type: self.questionTypeMapForPhp[type],
  6116. modelId: modelId
  6117. }
  6118. var positionInfos = []
  6119. switch (type) {
  6120. case 'singleSelect':
  6121. case 'moreSelect':
  6122. case 'uncertainOption':
  6123. positionInfos = self.getSingleSelectPositions(
  6124. moduleItem,
  6125. moduleInfo
  6126. )
  6127. break
  6128. case 'answer':
  6129. case 'mustAnswer':
  6130. positionInfos = self.getAswerPositions(moduleItem, moduleInfo)
  6131. break
  6132. case 'chooseAnswer':
  6133. positionInfos = self.getChooseAswerPositions(moduleItem, moduleInfo)
  6134. break
  6135. case 'fillInBlank':
  6136. positionInfos = self.getFillInBlankPOsitions(moduleItem, moduleInfo)
  6137. break
  6138. }
  6139. paperPosition[paperNo].questions = paperPosition[
  6140. paperNo
  6141. ].questions.concat(positionInfos)
  6142. })
  6143. })
  6144. //题号重新排序
  6145. let PositionData = JSON.parse(JSON.stringify(paperPosition))
  6146. let TopicAll = [];
  6147. jQuery.each(PositionData, function (i, val) {
  6148. TopicAll = TopicAll.concat(val.questions)
  6149. });
  6150. function compare(key) {
  6151. return function (value1, value2) {
  6152. var val1 = value1[key];
  6153. var val2 = value2[key];
  6154. return val1 - val2;
  6155. }
  6156. }
  6157. TopicAll.sort(compare('id'));
  6158. let no = 0
  6159. let pId = 0
  6160. jQuery.each(TopicAll, function (i, topicItem) {
  6161. if (topicItem.ChooseNum === undefined) {
  6162. if (pId == topicItem.id) {
  6163. topicItem.name = no
  6164. } else {
  6165. topicItem.name = no + 1
  6166. no = no + 1
  6167. }
  6168. pId = topicItem.id
  6169. } else {
  6170. if (pId == topicItem.id) {
  6171. topicItem.name = no
  6172. } else {
  6173. let tName = '';
  6174. for (let ChooseNum = 0; ChooseNum < Number(topicItem.ChooseNum); ChooseNum++) {
  6175. tName = tName + (tName != '' ? ',' : '') + (no + 1)
  6176. no = no + 1
  6177. }
  6178. topicItem.name = tName
  6179. pId = topicItem.id
  6180. }
  6181. }
  6182. });
  6183. jQuery.each(paperPosition, function (i, paperTopic) {
  6184. jQuery.each(paperTopic.questions, function (j, paperTopicItem) {
  6185. jQuery.each(TopicAll, function (k, topicAllItem) {
  6186. if (!paperTopicItem.name) {
  6187. if (Number(paperTopicItem.id) == Number(topicAllItem.id)) {
  6188. let topic = JSON.parse(JSON.stringify(topicAllItem))
  6189. paperTopicItem.id = topic.name.toString();
  6190. paperTopicItem.name = topic.id;
  6191. }
  6192. }
  6193. });
  6194. });
  6195. });
  6196. for (var paperKey in paperPosition) {
  6197. printPositionInfo.pages.push(paperPosition[paperKey])
  6198. }
  6199. printPositionInfo.identifier = self.identifier;
  6200. // console.log(printPositionInfo)
  6201. return printPositionInfo
  6202. },
  6203. //获取填空题获取选择题的题干信息
  6204. getStemInfo: function () {
  6205. var self = this
  6206. var memoryObjectiveHtmls = ''
  6207. $('.objectiveItem').each(function () {
  6208. memoryObjectiveHtmls += encodeURIComponent($(this)[0].outerHTML) + '|end|'
  6209. })
  6210. return memoryObjectiveHtmls
  6211. },
  6212. //准考证和条形码区域
  6213. getExamNumberPosition: function () {
  6214. var self = this
  6215. //是否使用二维码
  6216. if (self.useQrCode) return {}
  6217. //是否只是使用条形码
  6218. var isOnlyBarCode = self.isOnlyBarCode()
  6219. //判断显示的是准考证号还是条形码
  6220. var isTicketNumber = self.examNumberConfig.ticketNumber
  6221. var isBarCode = self.examNumberConfig.barCode
  6222. var studentcodePosition = {
  6223. studentcode_bar: {},
  6224. studentcode_fill: {}
  6225. }
  6226. //准考证号
  6227. if (isTicketNumber) {
  6228. var numberWidth = false
  6229. var numberHeight = false
  6230. var $ticketNumberCol = $('#hgc_examNumber ul.ticketNumber').children(
  6231. '.numberCol'
  6232. )
  6233. studentcodePosition.studentcode_fill = {
  6234. object: []
  6235. }
  6236. $ticketNumberCol.each(function (k, numberColItem) {
  6237. var group = []
  6238. var $ticketNumberItem = $(numberColItem).find('i')
  6239. $ticketNumberItem.each(function (m, numberItem) {
  6240. var numberPosition = self.getItemPosition(numberItem, 'examNumber')
  6241. numberWidth = numberWidth || self.getElementWidth(numberItem)
  6242. numberHeight = numberHeight || self.getElementHeight(numberItem)
  6243. group.push({
  6244. x: numberPosition.x,
  6245. y: numberPosition.y,
  6246. width: numberWidth,
  6247. height: numberHeight,
  6248. optName: m
  6249. })
  6250. })
  6251. studentcodePosition.studentcode_fill.object.push({
  6252. group: group
  6253. })
  6254. })
  6255. }
  6256. //条形码
  6257. if (isBarCode) {
  6258. var examMarkEl = isOnlyBarCode
  6259. ? $('#hgc_examNumberForOnlyBarcode .barCode')
  6260. : $('#hgc_examNumber .barCode')
  6261. var barCodePosition = self.getItemPosition(examMarkEl, 'barCode')
  6262. studentcodePosition.studentcode_bar = {
  6263. object: {
  6264. x: barCodePosition.x,
  6265. y: barCodePosition.y,
  6266. width: self.getElementWidth(examMarkEl),
  6267. height: self.getElementHeight(examMarkEl)
  6268. }
  6269. }
  6270. }
  6271. return studentcodePosition
  6272. },
  6273. //缺考标记
  6274. getAbsentMarkPostion: function () {
  6275. var self = this
  6276. var $absentMark = $('.absentMark')
  6277. var absentMarkPosition = self.getItemPosition($absentMark)
  6278. var absentWidth = self.getElementWidth($absentMark)
  6279. var absentHeight = self.getElementHeight($absentMark)
  6280. return {
  6281. x: absentMarkPosition.x,
  6282. y: absentMarkPosition.y,
  6283. width: absentWidth,
  6284. height: absentHeight
  6285. }
  6286. },
  6287. //二维码定位信息
  6288. getQrCodePosition: function () {
  6289. var self = this
  6290. var $dtkEwm = $('#dtkEwm')
  6291. var dtkEwmPosition = self.getItemPosition($dtkEwm)
  6292. var dtkEwmWidth = self.getElementWidth($dtkEwm)
  6293. var dtkEwmHeight = self.getElementHeight($dtkEwm)
  6294. //if (!self.useQrCode) return {}
  6295. return {
  6296. x: dtkEwmPosition.x,
  6297. y: dtkEwmPosition.y,
  6298. width: dtkEwmWidth,
  6299. height: dtkEwmHeight
  6300. }
  6301. },
  6302. //单选题坐标获取
  6303. getSingleSelectPositions: function (moduleItem, moduleInfo) {
  6304. var self = this
  6305. var optionInfos = []
  6306. var direction = $(moduleItem).attr('data-direction')
  6307. $(moduleItem)
  6308. .find('li')
  6309. .each(function (i, optionItems) {
  6310. var optionInfo = {
  6311. type: moduleInfo.type,
  6312. modelId: moduleInfo.modelId,
  6313. answer: $(optionItems).attr('data-answer'),
  6314. score: {
  6315. full: 5
  6316. },
  6317. id: $(optionItems).attr('title-number'),
  6318. opt: [],
  6319. direction: direction
  6320. }
  6321. $(optionItems)
  6322. .children('span')
  6323. .each(function (k, option) {
  6324. var optionPosition = self.getItemPosition(option, 'select')
  6325. var width = self.getElementWidth(option)
  6326. var height = self.getElementHeight(option)
  6327. var optName = $(option).attr('data-option')
  6328. optionInfo.opt.push({
  6329. x: optionPosition.x,
  6330. y: optionPosition.y,
  6331. width: width,
  6332. height: height,
  6333. optName: optName
  6334. })
  6335. })
  6336. optionInfos.push(optionInfo)
  6337. })
  6338. return optionInfos
  6339. },
  6340. //填空题
  6341. getFillInBlankPOsitions: function (moduleItem, moduleInfo) {
  6342. var self = this
  6343. var optionInfos = []
  6344. $(moduleItem)
  6345. .find('.subjectItem')
  6346. .each(function (i, optionItems) {
  6347. var $subjectCol = $(optionItems).parent('.subjectCol')
  6348. var $score = $(optionItems).children('strong')
  6349. var column = $subjectCol.attr('data-column')
  6350. var scoreStyle = $subjectCol.attr('data-scoreStyle')
  6351. var rowLineHeight = $subjectCol.attr('data-rowLineHeight')
  6352. var optionPosition = self.getItemPosition(optionItems, 'fillInBlank')
  6353. var width = self.getElementWidth(optionItems, 'fillInBlank')
  6354. var height = self.getElementHeight(optionItems, 'fillInBlank')
  6355. var scorePosition = self.getItemPosition($score)
  6356. var scoreWidth = self.getElementWidth($score)
  6357. var scoreHeight = self.getElementHeight($score)
  6358. var optionInfo = {
  6359. type: moduleInfo.type,
  6360. modelId: moduleInfo.modelId,
  6361. scorebox: {
  6362. type: 3,
  6363. Score: scoreStyle.split('/'),
  6364. x: scorePosition.x,
  6365. y: scorePosition.y,
  6366. width: scoreWidth,
  6367. height: scoreHeight
  6368. },
  6369. score: {
  6370. full: 5
  6371. },
  6372. column: column || 1,
  6373. scoreStyle: scoreStyle || '',
  6374. rowLinHeight: rowLineHeight || '',
  6375. id: $(optionItems).attr('title-number'),
  6376. cut: {
  6377. x: optionPosition.x,
  6378. y: optionPosition.y,
  6379. width: width,
  6380. height: height
  6381. }
  6382. }
  6383. optionInfos.push(optionInfo)
  6384. })
  6385. return optionInfos
  6386. },
  6387. //解答题坐标获取
  6388. //针对全学科的记忆布局不同,全学科记忆布局都是一套数据源
  6389. getAswerPositions: function (moduleItem, moduleInfo) {
  6390. var self = this
  6391. var answerInfos = []
  6392. var modelId = $(moduleItem).attr('data-modelid');
  6393. $(moduleItem)
  6394. .find('.module')
  6395. .each(function (m, moduleEl) {
  6396. var marktype = 0;
  6397. var modulePositon = self.getItemPosition(moduleEl, 'answer')
  6398. var width = self.getElementWidth(moduleEl, 'answer')
  6399. var height = self.getElementHeight(moduleEl, 'answer')
  6400. var titleNumber = $(moduleEl).attr('title-number') //questionNum
  6401. var isAddHalf = false
  6402. self.questionMap[modelId].questions.forEach(function (item) {
  6403. if (item.questionNum == titleNumber) {
  6404. marktype = item.marktype ? item.marktype : 0;
  6405. }
  6406. })
  6407. isAddHalf = self.questionMap[modelId].dialogData.isAddHalf
  6408. //分值格式
  6409. var $scoreColumn = $(moduleEl).children('.scortColumn')
  6410. var scoreLimit = $(moduleEl).attr('scorelimit') || '16'
  6411. var limit = $(moduleEl).attr('data-fullscore') || '16'
  6412. // var isAddHalf = $(moduleEl).attr('isAddHalf') === 'true'
  6413. var scorePosition = self.getItemPosition($scoreColumn)
  6414. var scoreWidth = self.getElementWidth($scoreColumn, 'answer')
  6415. var scoreHeight = self.getElementHeight($scoreColumn, 'answer')
  6416. let noScoringWidth = $($scoreColumn).find('.no-scoring').width();
  6417. if (noScoringWidth != null) {
  6418. scoreWidth = scoreWidth - noScoringWidth
  6419. }
  6420. /**
  6421. * "scorebox":{
  6422. "type":1,
  6423. "Score":[2, 3,5]
  6424. limit:16
  6425. "x":1517.4015748031497,
  6426. "y":20,
  6427. "width":40,
  6428. "height":20,
  6429. }
  6430. point:1 表示最后一个是0.5分 0表示没有0.5
  6431. type 1: 16 limit:12 OR 14 OR 16
  6432. type 2: 29/49 limit: 29 49
  6433. type 3:具体分值在score里面给出枚举: 2 3 5 , 2 3 4 6 limit 无效
  6434. */
  6435. //判断当前区域是否有超出的链接模块
  6436. var linkParm = +$(moduleEl).attr('data-linkparm') || 0
  6437. var cutId = $(moduleEl).attr('data-cutId')
  6438. var editorId = $(moduleEl).attr('data-editorindex')
  6439. var answerInfo = {
  6440. type: moduleInfo.type,
  6441. modelId: moduleInfo.modelId,
  6442. id: titleNumber,
  6443. marktype: marktype,
  6444. scoreLimit: scoreLimit,
  6445. editorId: editorId,
  6446. contents: encodeURIComponent(
  6447. self.editorArea['editor' + editorId].txt.html().replace(/<!--[\w\W\r\n]*?-->/gim, '')
  6448. ),
  6449. cut: {
  6450. x: modulePositon.x,
  6451. y: modulePositon.y,
  6452. width: width,
  6453. height: height,
  6454. cutid: cutId,
  6455. linkparm: linkParm
  6456. },
  6457. scorebox: {
  6458. type: ~'16|15'.indexOf(Number(scoreLimit)) ? '1' : '2',
  6459. limit: limit,
  6460. point: isAddHalf ? 1 : 2,
  6461. x: scorePosition.x,
  6462. y: scorePosition.y,
  6463. width: scoreWidth,
  6464. height: scoreHeight
  6465. }
  6466. }
  6467. answerInfos.push(answerInfo)
  6468. })
  6469. return answerInfos
  6470. },
  6471. //选做题坐标获取
  6472. getChooseAswerPositions: function (moduleItem, moduleInfo) {
  6473. var self = this
  6474. var chooseAnswerInfos = []
  6475. var modelId = $(moduleItem).attr('data-modelid');
  6476. $(moduleItem)
  6477. .find('.module')
  6478. .each(function (n, moduleEl) {
  6479. var modulePositon = self.getItemPosition(moduleEl, 'chooseAnswer')
  6480. var width = self.getElementWidth(moduleEl, 'answer')
  6481. var height = self.getElementHeight(moduleEl, 'answer')
  6482. var titleNumber = $(moduleEl).attr('title-number')
  6483. var scoreLimit = $(moduleEl).attr('scorelimit') || '16'
  6484. var limit = $(moduleEl).attr('data-fullscore') || '16'
  6485. //分值格式
  6486. var $scoreColumn = $(moduleEl).children('.scortColumn')
  6487. var scoreLimit = $(moduleEl).attr('scorelimit') || '16'
  6488. // var isAddHalf = $(moduleEl).attr('isAddHalf') === 'true'
  6489. isAddHalf = self.questionMap[modelId].dialogData.isAddHalf
  6490. var scorePosition = self.getItemPosition($scoreColumn)
  6491. var scoreWidth = self.getElementWidth($scoreColumn, 'answer')
  6492. var scoreHeight = self.getElementHeight($scoreColumn, 'answer')
  6493. let noScoringWidth = $($scoreColumn).find('.no-scoring').width();
  6494. if (noScoringWidth != null) {
  6495. scoreWidth = scoreWidth - noScoringWidth
  6496. }
  6497. //是否是上一题的补充区域
  6498. //判断当前区域是否有超出的链接模块
  6499. var linkParm = +$(moduleEl).attr('data-linkparm') || 0
  6500. var cutId = $(moduleEl).attr('data-cutId')
  6501. var editorId = $(moduleEl).attr('data-editorindex')
  6502. //选择题目数量
  6503. var selCount = 1
  6504. for (var choosePage in self.chooseAnswer) {
  6505. var pageChooseAnswer = self.chooseAnswer[choosePage]
  6506. if (pageChooseAnswer.length) {
  6507. selCount = pageChooseAnswer[0].required
  6508. break
  6509. }
  6510. }
  6511. let bigTopicData = self.questionMap[moduleInfo.modelId]
  6512. var chooseAnswerInfo = {
  6513. type: moduleInfo.type,
  6514. modelId: moduleInfo.modelId,
  6515. id: titleNumber,
  6516. ChooseNum: bigTopicData.commonFields.ChooseNum,
  6517. scoreLimit: scoreLimit,
  6518. editorId: editorId,
  6519. select: selCount,
  6520. contents: encodeURIComponent(
  6521. self.editorArea['editor' + editorId].txt.html().replace(/<!--[\w\W\r\n]*?-->/gim, '')
  6522. ),
  6523. total: titleNumber.split(',').length,
  6524. scorebox: {
  6525. type: ~'15|16'.indexOf(Number(scoreLimit)) ? '1' : '2',
  6526. limit: limit,
  6527. point: isAddHalf ? 1 : 2,
  6528. x: scorePosition.x,
  6529. y: scorePosition.y,
  6530. width: scoreWidth,
  6531. height: scoreHeight
  6532. },
  6533. selectqts: [
  6534. {
  6535. cut: {
  6536. x: modulePositon.x,
  6537. y: modulePositon.y,
  6538. width: width,
  6539. height: height,
  6540. cutid: cutId,
  6541. linkparm: linkParm
  6542. },
  6543. opt: []
  6544. }
  6545. ]
  6546. }
  6547. $(moduleEl)
  6548. .find('.selTopic span')
  6549. .each(function (l, selItem) {
  6550. var optName = $(selItem).attr('data-titleNumber')
  6551. var selItemPosition = self.getItemPosition(selItem, 'selTopic')
  6552. var width = self.getElementWidth(selItem)
  6553. var height = self.getElementHeight(selItem)
  6554. var optNameAbc = String.fromCharCode(65 + l)
  6555. ////console.log(width,height)
  6556. chooseAnswerInfo.selectqts[0].opt.push({
  6557. optName: optNameAbc,
  6558. width: width,
  6559. height: height,
  6560. x: selItemPosition.x,
  6561. y: selItemPosition.y
  6562. })
  6563. })
  6564. chooseAnswerInfos.push(chooseAnswerInfo)
  6565. })
  6566. return chooseAnswerInfos
  6567. },
  6568. /**
  6569. *
  6570. * @param {想要定位的元素} el
  6571. * @param {打印区域靠左距离} printAreaLeft
  6572. * @param {打印区域靠右距离} printAreaTop
  6573. * @param {是不是富文本解答题} isModule
  6574. * 如果是分栏 偶数页面的X轴定位点都要 加一个固定分页的宽
  6575. */
  6576. getItemPosition: function (el, moduleType) {
  6577. var self = this
  6578. if (!$(el).length) return {}
  6579. var curPage = $(el).closest('.pageContent')
  6580. var curPageIndex = curPage.index() + 1
  6581. var positionY = $(el).offset().top - self.printAreaTop
  6582. var positionX = $(el).offset().left - self.printAreaLeft
  6583. //定位坐标向右偏移位置
  6584. var columnLeft = 0
  6585. //是否第一面
  6586. var isFirstPaper = curPageIndex <= self.columns
  6587. //考虑分栏的定位点
  6588. //当前在第几栏
  6589. var curPageColumns =
  6590. curPageIndex % self.columns ? curPageIndex % self.columns : self.columns
  6591. //一栏宽度
  6592. var oneColumnsWidth = self.pageWidth / self.columns
  6593. columnLeft = oneColumnsWidth * (curPageColumns - 1)
  6594. //有装订线的情况需要第一页减去多余的
  6595. if (self.hasBindingLine) {
  6596. positionX -= 20
  6597. }
  6598. if (curPageIndex > 1) {
  6599. positionY -= (curPageIndex - 1) * self.pageHeight
  6600. }
  6601. return {
  6602. x: (positionX + columnLeft - self.pagePaddingSide) * self.dpiRadio,
  6603. y: (positionY - 20) * self.dpiRadio
  6604. }
  6605. },
  6606. /**
  6607. *
  6608. * 添加题目
  6609. * 根据题目类型,重置 该题型的所有数据
  6610. */
  6611. appendSubject: function (buildQuestions, modelId) {
  6612. var self = this
  6613. var questionModel = buildQuestions[modelId]
  6614. var modelRenderKey = self.questionTypeMapForC[questionModel.questionType]
  6615. var $lastPage = $('#printcontent .pageContent:last()')
  6616. var $lastPageContent = $lastPage.children('.dtk-content')
  6617. var currentPage = $lastPage.index() + 1
  6618. questionModel.pages = questionModel.pages || {}
  6619. questionModel.pages['page' + currentPage] = questionModel.questions
  6620. //新加分页字段,重新设置
  6621. localStorage.setItem('buildQuestions', JSON.stringify(buildQuestions))
  6622. self.questionMap = buildQuestions
  6623. //渲染右侧操作栏 题目列表信息 -- 可重复执行
  6624. self.renderSubjectListInfo(buildQuestions)
  6625. //保存题目定位点的时候 获取 题目数量 分数 等信息 -- 可重复执行
  6626. self.getSaveSubjectInfo(buildQuestions)
  6627. //模块渲染
  6628. self[modelRenderKey + 'Render'](questionModel, $lastPageContent)
  6629. self.changePrintArea($lastPage)
  6630. },
  6631. //编辑试题
  6632. editSubject: function (buildQuestions, modelId) {
  6633. var self = this
  6634. var questionModel = buildQuestions[modelId]
  6635. var modelRenderKey = self.questionTypeMapForC[questionModel.questionType]
  6636. var $changePage = null
  6637. var $replaceEl = null
  6638. $('.answerModule').each(function () {
  6639. if ($(this).attr('data-modelId') === modelId) {
  6640. if ($changePage) {
  6641. $(this).remove()
  6642. } else {
  6643. $changePage = $(this).closest('.pageContent')
  6644. $replaceEl = $(this)
  6645. }
  6646. }
  6647. })
  6648. var currentPage = $changePage.index() + 1
  6649. questionModel.pages = questionModel.pages || {}
  6650. questionModel.pages['page' + currentPage] = questionModel.questions
  6651. //重新设置
  6652. localStorage.setItem('buildQuestions', JSON.stringify(buildQuestions))
  6653. //渲染右侧操作栏 题目列表信息 -- 可重复执行
  6654. self.renderSubjectListInfo(buildQuestions)
  6655. //保存题目定位点的时候 获取 题目数量 分数 等信息 -- 可重复执行
  6656. self.getSaveSubjectInfo(buildQuestions)
  6657. //模块渲染
  6658. self[modelRenderKey + 'Render'](questionModel, null, $replaceEl)
  6659. // selectStyleChange: function($this, direction)
  6660. // fillInBlankStyleChange: function($this, column, rowLinHeight, scoreStyle)
  6661. // shortAnswerStyleChange: function($this, scoreLimitKey, isAddHalf)
  6662. var $settingBtn = self.getSettingBtn(modelId)
  6663. if (~modelRenderKey.indexOf('Select') || ~modelRenderKey.indexOf('uncertainOption')) {
  6664. var direction = questionModel.direction ? 'vertical' : 'horizontal'
  6665. self.selectStyleChange($settingBtn, direction)
  6666. } else if (modelRenderKey === 'fillInBlank') {
  6667. var columns = questionModel.columns
  6668. var rowLineHeight = questionModel.rowLineHeight
  6669. var scoreStyle = questionModel.scoreStyle
  6670. self.fillInBlankStyleChange(
  6671. $settingBtn,
  6672. columns,
  6673. rowLineHeight,
  6674. scoreStyle
  6675. )
  6676. } else {
  6677. var isAddHalf = questionModel.isAddHalf
  6678. var scoreLimit = questionModel.scoreLimit
  6679. // self.shortAnswerStyleChange($settingBtn, scoreLimit, isAddHalf)
  6680. }
  6681. this.initPageTopic();
  6682. },
  6683. initPageTopic() {
  6684. $('.h_radioItem.checked').eq(1).click();
  6685. $('.pageContent').each(function () {
  6686. if ($(this).children().eq(0).children().length == 0) {
  6687. $(this).remove();
  6688. }
  6689. })
  6690. $(".pageContent .totalPage").html($('.pageContent').length)
  6691. self.totalPage = $('.pageContent').length
  6692. }
  6693. }
  6694. $(function () {
  6695. Print.init(sizeConfig)
  6696. })