| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131 |
- import moment from 'moment';
- import _ from 'lodash';
- import axios from 'axios';
- import fs from 'fs';
- import { promises as fsPromises } from 'fs';
- import path from 'path';
- import COS from 'cos-nodejs-sdk-v5';
- import config from '../../config/index.js';
- import { globalCache } from '../../util/GlobalCache.js';
- import constantClass from '../../util/constant/index.js';
- import { stringUtils } from '../../util/stringClass.js';
- import miaoguo from '../../model/miaoguo.js';
- import commonModel from '../../model/commonModel.js';
- import hanzi from '../../model/hanzi.js';
- import { Decrypt, Encrypt } from '../../util/crypto/index.js';
- import * as payInfo from '../../model/payInfo.js';
- import * as wxusersall from '../../model/wxUsersAll.js';
- import WXBizDataCrypt from '../../util/WXBizDataCrypt.js';
- async function requestMiaoguoSession(param) {
- const url = `https://api.weixin.qq.com/sns/jscode2session?appid=${config.wx.miaoguo_appid}&secret=${config.wx.miaoguo_appsecret}&js_code=${param.Code}&grant_type=authorization_code`;
- try {
- const res = await axios.get(url, {
- transformResponse: [(data) => data],
- });
- const htmlString = res.data;
- const json = JSON.parse(htmlString);
- if (json && json.openid) {
- param.OpenID = json.openid;
- param.sessionKey = json.session_key;
- if (json.unionid)
- param.UnionID = json.unionid;
- return { errcode: 10000 };
- }
- return htmlString;
- } catch (err) {
- return { errcode: 101, errStr: err.message || String(err) };
- }
- }
- async function syncMiaoguoWXUsersAll(userInfo) {
- let obj = {
- UnionID: userInfo.UnionID,
- UserID: userInfo.UserID,
- ProductID: 166,
- };
- let wxUserList = await wxusersall.GetWXUsersAllInfo(obj);
- if (!wxUserList || wxUserList.length == 0) {
- obj = {
- UserID: userInfo.UserID,
- ProductID: 166,
- };
- wxUserList = await wxusersall.GetWXUsersAllInfo(obj);
- if (wxUserList && wxUserList.length > 0) {
- obj = {
- UnionID: userInfo.UnionID,
- ChangYiID: wxUserList[0].ChangYiID,
- };
- await wxusersall.UpdateWXUsersAll(obj);
- } else {
- obj = {
- UnionID: userInfo.UnionID,
- };
- wxUserList = await wxusersall.GetWXUsersAllInfo(obj);
- if (wxUserList && wxUserList.length > 0) {
- obj = {
- UserID166: userInfo.UserID,
- ChangYiID: wxUserList[0].ChangYiID,
- };
- await wxusersall.UpdateWXUsersAll(obj);
- } else {
- obj = {
- UnionID: userInfo.UnionID,
- UserID166: userInfo.UserID,
- };
- await wxusersall.AddWXUsersAll(obj);
- }
- }
- }
- }
- export async function MiaoguoLogin(ctx) {
- let param = ctx.request.body || {};
- if (param.Introducer) {
- if (param.Introducer.toString().indexOf("UserID") >= 0)
- param.Introducer = Number(param.Introducer.replace("UserID=", ""));
- }
- if (param.param) {
- const paramStr = Decrypt(param.param, config.urlSecrets.aes_key, config.urlSecrets.aes_iv);
- param = JSON.parse(paramStr);
- }
- let result = await requestMiaoguoSession(param);
- if (result.errcode == 10000) {
- delete param.Code;
- if (param.sessionKey && param.iv && param.encryptedData) {
- const pc = new WXBizDataCrypt(config.wx.miaoguo_appid, param.sessionKey);
- const dataUnionID = pc.decryptData(param.encryptedData, param.iv);
- param.UnionID = dataUnionID.unionId;
- }
- delete param.sessionKey;
- delete param.iv;
- delete param.encryptedData;
- let currentUserID = 0;
- let userList = {};
- if (param.UserFamilyID && param.UserFamilyID > 0) {
- userList = await miaoguo.GetUsersInfo(param);
- if (userList && userList.length > 0)
- currentUserID = userList[0].UserID;
- const param2 = { UserID: param.UserFamilyID };
- userList = await miaoguo.GetUsersInfoByUserID(param2);
- param.OpenID = userList[0].OpenID;
- param.UnionID = userList[0].UnionID;
- } else {
- userList = await miaoguo.GetUsersInfo(param);
- if (userList && userList.length > 0) {
- currentUserID = userList[0].UserID;
- if (param.UnionID && userList[0].UserID && userList[0].OpenID && (!userList[0].UnionID || userList[0].UnionID == "")) {
- const paramUnionID = {};
- paramUnionID.OpenID = userList[0].OpenID;
- paramUnionID.UnionID = param.UnionID;
- await miaoguo.UpdateUsers(paramUnionID);
- userList[0].UnionID = param.UnionID;
- }
- }
- }
- if (userList && userList.length > 0) {
- let isLoseEfficary = 0;
- const time3 = moment().format('YYYYMMDD');
- const time4 = moment(userList[0].ProductServiceTime).format('YYYYMMDD');
- if (time3 > time4) {
- let obj = {};
- obj.ParentUserID = userList[0].UserID;
- await miaoguo.UpdateUserBinding(obj);
- obj = {};
- obj.UserID = userList[0].UserID;
- await miaoguo.DeleteMiaoguoFamily(obj);
- const param2 = {};
- param2.UserID = currentUserID;
- userList = await miaoguo.GetUsersInfoByUserID(param2);
- param.OpenID = userList[0].OpenID;
- param.UnionID = userList[0].UnionID;
- isLoseEfficary = 1;
- }
- delete param.UserFamilyID;
- param.LastLoginTime = new Date();
- if (!userList[0].IsMember && param.Introducer && userList[0].UserID != param.Introducer) {
- const param2 = {};
- param2.UserID = userList[0].UserID;
- const wechatUserInfo = await miaoguo.GetWechatServiceInfoByMGUserID(param2);
- if (wechatUserInfo && wechatUserInfo[0]) {
- if (!wechatUserInfo[0].IsProbation || wechatUserInfo[0].IsProbation == 0) {
- const obj2 = {};
- obj2.UserID = wechatUserInfo[0].WechatUserID;
- obj2.Introducer = param.Introducer;
- await miaoguo.UpdateWechatServiceUsersByUserID(obj2);
- } else {
- delete param.Introducer;
- }
- }
- } else {
- delete param.Introducer;
- }
- delete param.UserSource;
- delete param.SourceID;
- if (param.NickName == "陌生用户") {
- delete param.NickName;
- delete param.AvatarUrl;
- delete param.Language;
- delete param.Gender;
- delete param.City;
- delete param.Province;
- delete param.Country;
- }
- if (param.NickName == "微信用户")
- param.NickName = "陌生用户";
- if (!userList[0].ShowUserID || userList[0].ShowUserID == "")
- param.ShowUserID = stringUtils.Random(100, 999).toString() + userList[0].UserID.toString() + stringUtils.Random(100, 999).toString();
- if (ctx.query.IsPromotion) {
- if (!userList[0].PromotionLimitTime)
- param.PromotionLimitTime = userList[0].ProductServiceTime;
- }
- await miaoguo.UpdateUsers(param);
- userList = await miaoguo.GetUsersInfo(param);
- if ((!ctx.query.IsPromotion || userList[0].IsPromoter == 0) && userList && userList.length > 0) {
- delete userList[0].UserTree;
- delete userList[0].PromotionLimitTime;
- delete userList[0].WXAccount;
- delete userList[0].RealName;
- delete userList[0].IdentityCard;
- delete userList[0].Phone;
- } else {
- if (userList[0] && userList[0].PromotionLimitTime) {
- const a = moment(userList[0].PromotionLimitTime);
- const b = moment();
- const days = a.diff(b, 'days');
- userList[0].PromotionLimitDays = days;
- userList[0].PromotionLimitTime = moment(userList[0].PromotionLimitTime).format('YYYY.MM.DD');
- userList[0].WXServiceCharge = config.WXServiceCharge;
- userList[0].IndividualIncomeTax = config.IndividualIncomeTax;
- if (!userList[0].PayeeWechatAccount)
- userList[0].PayeeWechatAccount = userList[0].NickName;
- if (!userList[0].WXAccount)
- userList[0].WXAccount = userList[0].NickName;
- if (!userList[0].RealName)
- userList[0].RealName = "";
- if (userList[0].Introducer) {
- const param2 = {};
- param2.UserID = userList[0].Introducer;
- param2.FieldStr = "NickName,AvatarUrl";
- const userInfo2 = await miaoguo.GetUsersInfoByUserID(param2);
- if (userInfo2 && userInfo2[0]) {
- userList[0].IntroducerNickName = userInfo2[0].NickName;
- userList[0].IntroducerAvatarUrl = userInfo2[0].AvatarUrl;
- }
- }
- }
- }
- userList[0].ProductServiceTime = moment(userList[0].ProductServiceTime).format('YYYY/MM/DD 23:59:59');
- if (isLoseEfficary == 1) {
- userList[0].IsLoseEfficacy = 1;
- currentUserID = userList[0].UserID;
- }
- userList[0].IsNewUser = 0;
- } else {
- delete param.UserFamilyID;
- param.CreateTime = new Date();
- param.LastLoginTime = param.CreateTime;
- param.ProductServiceTime = param.CreateTime;
- param.PromotionDeliveryTimeIsUp = '2099-12-31 23:59:59';
- if (param.NickName == "微信用户")
- param.NickName = "陌生用户";
- await miaoguo.AddUsers(param);
- userList = await miaoguo.GetUsersInfo(param);
- userList[0].IsNewUser = 1;
- if (!userList[0].ShowUserID || userList[0].ShowUserID == "")
- userList[0].ShowUserID = stringUtils.Random(100, 999).toString() + userList[0].UserID.toString() + stringUtils.Random(100, 999).toString();
- const param3 = {};
- param3.UserID = userList[0].UserID || 0;
- param3.CardMaxNumberNew = 10;
- param3.CardMaxNumberHistory = 40;
- param3.BasicCardLimit = param3.CardMaxNumberNew + param3.CardMaxNumberHistory;
- param3.CardMaxNumberNewUrgent = 10;
- param3.CardMaxNumberHistoryUrgent = 40;
- param3.CardType = 0;
- param3.SortTypeIndex = 0;
- param3.MemoryLevel = 0;
- param3.ClickType = 0;
- param3.SecondConfigArray = "0,0,0";
- param3.ColorIndexArr = "1,2,3,4";
- await miaoguo.AddUserConfig(param3);
- }
- if (userList[0].ParentUserID > 0) {
- const userid = userList[0].UserID;
- const obj = {};
- obj.UserID = userList[0].ParentUserID;
- userList = await miaoguo.GetUsersInfoByUserID(obj);
- userList[0].ChildUserID = userid;
- }
- userList[0].Subscribe = 0;
- if (userList[0].UnionID) {
- await syncMiaoguoWXUsersAll(userList[0]);
- const obj2 = {
- UnionID: userList[0].UnionID,
- };
- const wccUserList = await miaoguo.GetWechatServiceUsersInfoByUnionID(obj2);
- if (wccUserList && wccUserList[0]) {
- userList[0].Subscribe = wccUserList[0].Subscribe;
- userList[0].IsProbation = wccUserList[0].IsProbation;
- if (userList[0].IsProbation == 0 && userList[0].IsPay == 1) {
- userList[0].IsProbation = 1;
- } else if (userList[0].IsProbation == 0 && userList[0].UserID < 1000) {
- const time4 = moment(userList[0].ProductServiceTime).format('YYYYMMDD');
- if (time4 > '20190801') {
- userList[0].IsProbation = 1;
- }
- }
- if (wccUserList[0].TempClassID > 0 || wccUserList[0].TempIsMember > 0) {
- const obj3 = {};
- obj3.UserID = userList[0].UserID;
- if (wccUserList[0].TempClassID && wccUserList[0].TempClassID > 0)
- obj3.ClassID = wccUserList[0].TempClassID;
- if (wccUserList[0].TempIsMember && wccUserList[0].TempIsMember > 0)
- obj3.IsMember = wccUserList[0].TempIsMember;
- await miaoguo.UpdateUsersByUserID(obj3);
- const obj4 = {};
- obj4.UserID = wccUserList[0].UserID;
- if (wccUserList[0].TempClassID && wccUserList[0].TempClassID > 0)
- obj4.TempClassID = 0;
- if (wccUserList[0].TempIsMember && wccUserList[0].TempIsMember > 0)
- obj4.TempIsMember = 0;
- await miaoguo.UpdateWechatServiceUsersByUserID(obj4);
- }
- }
- }
- delete userList[0].OpenID;
- delete userList[0].UnionID;
- const param2 = {};
- param2.ProgramID = 166;
- param2.Version = param.ProgramVersion;
- const result3 = await commonModel.GetProductVersionList(param2);
- if (result3 && result3[0]) {
- if ((param2.Version == result3[0].Version && result3[0].IsShowPay <= 0)
- || param2.Version > result3[0].Version) {
- userList[0].IsShow = result3[0].IsShowPay;
- } else {
- userList[0].IsShow = 1;
- }
- if (process.env.NODE_ENV != 'development') {
- const today = moment().format('YYYYMMDD');
- if ((userList[0].UserSource == '1001' && userList[0].System == "iOS 10.0.1")
- || (!userList[0].UserSource && (!userList[0].LastUserSource || userList[0].LastUserSource > 10000))
- || ((userList[0].NickName || "").indexOf("dgztest") >= 0)) {
- userList[0].IsShow = -1;
- } else if (userList[0].UserID == 28631 && today < "20230526") {
- userList[0].IsShow = -1;
- } else if (userList[0].LastUserSource == '1012'
- && userList[0].IsPay == 0
- && userList[0].IsMember == 0
- && userList[0].IsApply == 0
- && userList[0].IsTryOut == 0
- && userList[0].Model == "iPhone XS MAX China-exclusive<iPhone 11,6>") {
- userList[0].IsShow = -1;
- }
- }
- if (userList[0].IsMember === 1)
- userList[0].IsShow = 1;
- if (userList[0].IsShow == 1)
- userList[0].ShowText1 = "分享";
- else
- userList[0].ShowText1 = "";
- }
- if (userList[0].ClassID > 0) {
- const classList = await miaoguo.GetClassList(userList[0]);
- if (classList && classList[0]) {
- userList[0].ClassStartDate = moment(classList[0].StartDate).format('YYYY-MM-DD');
- userList[0].ClassEndDate = moment(classList[0].StartDate).add(classList[0].DayNumber - 1, "days").format('YYYY-MM-DD');
- userList[0].ClassDayNumber = moment(moment().format("YYYY-MM-DD 00:00:00")).diff(classList[0].StartDate + " 00:00:00", 'days');
- userList[0].ClassTotalDayNumber = classList[0].DayNumber;
- }
- }
- if (userList[0].IsShow <= 0 || userList[0].IsPay == 0) {
- userList[0].HasIntroducer = 1;
- } else {
- userList[0].HasIntroducer = 0;
- }
- if (userList[0].UserID == 0) {
- userList[0].IsMaintain = 1;
- }
- if (currentUserID > 0) {
- userList[0].CurrentUserID = currentUserID;
- userList[0].MainUserID = currentUserID;
- }
- result = { errcode: 10000, result: userList[0] };
- const log = {};
- log.UserID = userList[0].UserID;
- log.LogID = 374;
- log.Content = userList[0];
- log.Content = JSON.stringify(log.Content);
- miaoguo.AddMiaoguoLog(log).catch(err => console.error('AddMiaoguoLog failed:', err));
- }
- ctx.body = result;
- }
- export async function GetClassList(ctx) {
- const param = {
- ClassID: ctx.query.ClassID || 0,
- Sort: ctx.query.Sort || "desc",
- Flag: ctx.query.Flag,
- SqlType: ctx.query.SqlType,
- };
- const list = await miaoguo.GetClassList(param);
- for (const item of list) {
- item.EndDate = moment(item.StartDate).add(item.DayNumber, 'days').format('YYYY-MM-DD');
- }
- ctx.body = { errcode: 10000, result: list };
- }
- export async function GetMiaoguoCoupon(ctx) {
- const param = {
- UserID: ctx.query.UserID || 0,
- CouponType: ctx.query.CouponType || 0,
- };
- const list = await miaoguo.GetMiaoguoCoupon(param);
- if (param.CouponType == 0) {
- for (const item of list) {
- const arr = item.Name.split("#");
- item.Content = arr;
- delete item.Name;
- const today = moment().format("YYYY年MM月DD日");
- item.LimitTime = moment(item.LimitTime).format("YYYY年MM月DD日");
- if (today > item.LimitTime)
- item.IsLoseEfficacy = 1;
- }
- }
- ctx.body = { errcode: 10000, result: list };
- }
- export async function GetUserFolderList(ctx) {
- const param = {
- UserID: ctx.query.UserID || 0,
- OrderType: ctx.query.OrderType,
- IsNewData: ctx.query.IsNewData || 0,
- };
- const url = "GetUserFolderList?UserID=" + param.UserID;
- let result = globalCache.get(url);
- if (param.IsNewData == 1 || param.IsNewData == "1")
- result = 0;
- if (result === 0) {
- if (!param.OrderType) {
- const userConfig = await miaoguo.GetUserConfigData(param);
- if (userConfig && userConfig.length > 0)
- param.OrderType = userConfig[0].FolderOrder;
- param.OrderType = param.OrderType || 'UpdateTime desc';
- }
- const list = await miaoguo.GetUserFolderList(param);
- const arr = [];
- for (const item of list)
- arr.push(item.ID);
- param.FolderIDStr = arr.join(",");
- const list2 = await miaoguo.GetUserFolderCount(param);
- for (const item of list) {
- for (const countItem of list2) {
- if (item.ID == countItem.FolderID)
- item.Total = countItem.Total;
- }
- }
- result = list;
- if (param.OrderType == "CreateTime desc")
- result = _.orderBy(result, ['CreateTime'], ['desc']);
- else if (param.OrderType == "CreateTime asc")
- result = _.orderBy(result, ['CreateTime'], ['asc']);
- else if (param.OrderType == "UpdateTime desc")
- result = _.orderBy(result, ['UpdateTime'], ['desc']);
- else if (param.OrderType == "UpdateTime asc")
- result = _.orderBy(result, ['UpdateTime'], ['asc']);
- else if (param.OrderType == "Total desc")
- result = _.orderBy(result, ['Total'], ['desc']);
- else if (param.OrderType == "Total asc")
- result = _.orderBy(result, ['Total'], ['asc']);
- else if (param.OrderType == "Name desc")
- result = _.orderBy(result, ['Name'], ['desc']);
- else if (param.OrderType == "Name asc")
- result = _.orderBy(result, ['Name'], ['asc']);
- globalCache.set(url, result, config.BufferMemoryTimeLowNormal);
- }
- ctx.body = { errcode: 10000, result };
- }
- export async function GetUserFolderInfo(ctx) {
- const param = {
- UserID: ctx.query.UserID || 0,
- FolderID: ctx.query.FolderID || 0,
- };
- const url = "GetUserFolderInfo?FolderID=" + param.FolderID;
- let result = globalCache.get(url);
- if (result === 0) {
- const list = await miaoguo.GetUserFolderList(param);
- for (const item of list) {
- if (item.ID == param.FolderID)
- result = item;
- }
- globalCache.set(url, result, config.BufferMemoryTimeLowNormal);
- }
- ctx.body = { errcode: 10000, result };
- }
- function decryptWebID(value) {
- return Decrypt(String(value).replace(/@@@/g, '+'), config.urlSecrets.aes_key, config.urlSecrets.aes_iv);
- }
- function encryptWebID(value) {
- return Encrypt(String(value), config.urlSecrets.aes_key, config.urlSecrets.aes_iv);
- }
- function decryptWebIDList(list) {
- if (!list)
- return [];
- const source = Array.isArray(list) ? list : String(list).split(',');
- return source
- .filter(item => item !== undefined && item !== null && item !== '')
- .map(item => Number(decryptWebID(item)));
- }
- function formatMiaoguoCardTime(card, isDeleteList = false) {
- if (card.CreateTime) {
- card.CreateTime = moment(card.CreateTime).format('YYYY-MM-DD HH:mm:ss');
- card.CreateTimeStr = stringUtils.GetDateTimeFormat(card.CreateTime);
- }
- if (card.UpdateTime) {
- card.UpdateTime = moment(card.UpdateTime).format('YYYY-MM-DD HH:mm:ss');
- card.UpdateTimeStr = stringUtils.GetDateTimeFormat(card.UpdateTime);
- }
- if (card.FirstTime)
- card.FirstTime = moment(card.FirstTime).format('YYYY-MM-DD HH:mm:ss');
- if (card.LastTime) {
- card.LastTimeStr = isDeleteList ? stringUtils.GetDateTimeFormat(card.LastTime) : moment(card.LastTime).format('YYYY-MM-DD');
- card.LastTime = moment(card.LastTime).format('YYYY-MM-DD HH:mm:ss');
- }
- if (card.LimitTime) {
- card.LimitTime = moment(card.LimitTime).format('YYYY-MM-DD HH:mm:ss');
- if (!isDeleteList)
- card.LimitTimeStr = moment(card.LimitTime).format('YYYY-MM-DD');
- }
- if (card.PigeonholeTime)
- card.PigeonholeTime = moment(card.PigeonholeTime).format('YYYY-MM-DD HH:mm:ss');
- return card;
- }
- function buildCardListFromRows(rows, folderList = [], isDeleteList = false) {
- const list = [];
- let card = null;
- let content = [];
- for (let i = 0; i <= rows.length; i++) {
- if (card != null && (i == rows.length || card.MiaoguoCardID != rows[i].MiaoguoCardID)) {
- card = formatMiaoguoCardTime(card, isDeleteList);
- card.Content = content;
- if (!isDeleteList)
- delete card.Flag;
- delete card.MiaoguoContentID;
- delete card.ContentType;
- delete card.MiaoguoDeckID;
- delete card.UserID;
- if (!isDeleteList) {
- delete card.HistoryUpdateTime;
- delete card.HistoryFirstTime;
- delete card.HistoryLastTime;
- delete card.HistoryLimitTime;
- delete card.HistoryIntervalDay;
- delete card.HistoryRepetitionCoefficient;
- delete card.HistoryLearnNumber;
- }
- if (folderList.length > 0) {
- const folder = folderList.find(item => item.ID == card.FolderID);
- if (folder)
- card.FolderName = folder.Name;
- }
- list.push(card);
- content = [];
- if (i == rows.length)
- break;
- }
- const item = rows[i];
- content.push({
- ContentType: item.ContentType,
- Content: stringUtils.ReplaceAllString(item.Content || '', "''", "'"),
- });
- card = { ...item };
- }
- return list;
- }
- async function getCachedMiaoguoCardList(param) {
- const cacheKey = "GetMiaoguoCard###UserID=" + param.UserID;
- const cacheValue = globalCache.get(cacheKey);
- if (cacheValue !== 0) {
- const list = typeof cacheValue === 'string' ? JSON.parse(cacheValue) : cacheValue;
- return list.map(item => formatMiaoguoCardTime({ ...item }));
- }
- const listID = await miaoguo.GetCardListID(param);
- const ids = listID.map(item => item.MiaoguoCardID);
- if (ids.length == 0)
- return [];
- const folderList = await miaoguo.GetUserFolderList(param);
- const rows = await miaoguo.GetCardList({
- UserID: param.UserID,
- IDArr: ids.join(','),
- OrderType: param.OrderType,
- });
- const list = buildCardListFromRows(rows, folderList);
- globalCache.set(cacheKey, JSON.stringify(list), config.BufferMemoryTimeLowNormal);
- return list;
- }
- async function getMiaoguoCardListResult(param) {
- if (param.CardType == 2)
- param.CardType = "all";
- let list = await getCachedMiaoguoCardList(param);
- let urgentCount = 0;
- let emptyCount = 0;
- for (const item of list) {
- if (item.CardType == 1)
- urgentCount++;
- else if (item.CardType == -1)
- emptyCount++;
- }
- const result = {
- Count: list.length,
- UrgentCount: urgentCount,
- EmptyCount: emptyCount,
- };
- if (param.DataType == -1) {
- result.List = list;
- return result;
- }
- if (param.IsToday == 2) {
- list = list.filter(item => item.LastTime >= moment().format('YYYY-MM-DD 00:00:00') && item.LimitTime >= moment().add(1, "days").format('YYYY-MM-DD 00:00:00'));
- result.Count = list.length;
- param.PageCount = list.length;
- } else if (param.IsToday == 3) {
- list = _.orderBy(list, ['LastTime'], ['desc']);
- let lastDate = "";
- const listTemp = [];
- for (const item of list) {
- if (item.LastTime < moment().format('YYYY-MM-DD 00:00:00')) {
- if (lastDate == "")
- lastDate = moment(item.LastTime).format('YYYY-MM-DD 00:00:00');
- if (item.LastTime >= lastDate)
- listTemp.push(item);
- }
- }
- list = listTemp;
- result.Count = list.length;
- param.PageCount = list.length;
- } else if (param.IsToday == 4) {
- list = _.orderBy(list, ['LimitTime'], ['desc'])
- .filter(item => item.LimitTime < moment().format('YYYY-MM-DD 23:59:59') && param.CardType == item.CardType);
- result.Count = list.length;
- } else if (param.IsToday == 5 || param.IsToday == 6 || param.IsToday == 7) {
- list = _.orderBy(list, ['LastTime'], ['desc']);
- const param3 = {
- UserID: param.UserID,
- CreateTime: moment().add(-param.DayNumber, "days").format('YYYY-MM-DD 00:00:00'),
- DataType: param.IsToday == 5 ? "TimeShort" : param.IsToday == 6 ? "ClickBlue" : "ClickShelve",
- };
- const listID = await miaoguo.GetCardListID(param3);
- const idSet = new Set(listID.map(item => Number(item.MiaoguoCardID)));
- list = list.filter(item => idSet.has(Number(item.MiaoguoCardID)));
- result.Count = list.length;
- } else {
- if (param.CardType != "all") {
- list = list.filter(item => item.CardType === Number(param.CardType));
- result.Count = list.length;
- }
- if (param.CardType == "all" && param.OrderType.indexOf("LimitTime") >= 0) {
- list = list.filter(item => item.CardType != -1);
- result.Count = list.length;
- }
- }
- if (param.IsCollect == 1) {
- list = list.filter(item => item.IsCollect == 1);
- result.Count = list.length;
- }
- if (param.FolderID) {
- list = list.filter(item => {
- if (param.FolderID > 0)
- return item.FolderID == param.FolderID;
- if (param.FolderID == -1)
- return item.FolderID === 0;
- return true;
- });
- result.Count = list.length;
- }
- if (param.Key) {
- const key = String(param.Key).toLowerCase();
- const listTemp = [];
- for (const item of list) {
- for (const content of item.Content || []) {
- if ((content.Content || '').toLowerCase().indexOf(key) >= 0) {
- listTemp.unshift(item);
- break;
- }
- }
- }
- for (let i = 0; i < listTemp.length; i++) {
- const primary = listTemp[i].Content && listTemp[i].Content[1] ? listTemp[i].Content[1].Content : "";
- if (primary && primary.toLowerCase().indexOf(key) >= 0) {
- const item = listTemp.splice(i, 1);
- listTemp.unshift(item[0]);
- }
- }
- list = listTemp;
- result.Count = list.length;
- }
- if (param.OrderType == "ac.UpdateTime desc,ac.CreateTime desc")
- list = _.orderBy(list, ['UpdateTime', 'CreateTime'], ['desc', 'desc']);
- else if (param.OrderType == "ac.MiaoguoCardID desc")
- list = _.orderBy(list, ['MiaoguoCardID'], ['desc']);
- else if (param.OrderType == "ac.MiaoguoCardID asc")
- list = _.orderBy(list, ['MiaoguoCardID'], ['asc']);
- else if (param.OrderType == "ac.LearnNumber desc,ac.MiaoguoCardID desc")
- list = _.orderBy(list, ['LearnNumber', 'MiaoguoCardID'], ['desc', 'desc']);
- else if (param.OrderType == "ac.LearnNumber,ac.MiaoguoCardID")
- list = _.orderBy(list, ['LearnNumber', 'MiaoguoCardID'], ['asc', 'asc']);
- else if (param.OrderType == "ac.LastTime desc")
- list = _.orderBy(list, ['LastTime'], ['desc']);
- else if (param.OrderType == "ac.LimitTime desc")
- list = _.orderBy(list, ['LimitTime'], ['desc']);
- else if (param.OrderType == "ac.LimitTime asc")
- list = _.orderBy(list, ['LimitTime'], ['asc']);
- else if (param.OrderType == "ac.PigeonholeTime asc")
- list = _.orderBy(list, ['PigeonholeTime'], ['asc']);
- else if (param.OrderType == "ac.PigeonholeTime desc")
- list = _.orderBy(list, ['PigeonholeTime'], ['desc']);
- const arr = [];
- if (param.IDSelect || param.PrintID) {
- if (param.PrintID && param.PrintID > 0) {
- const miaoguoPrint = await miaoguo.GetMiaoguoPrintByID(param);
- if (miaoguoPrint && miaoguoPrint.length > 0)
- param.IDSelect = miaoguoPrint[0].CardID;
- }
- const selectedIDs = String(param.IDSelect || '').split(',');
- for (const id of selectedIDs) {
- const item = list.find(card => String(card.MiaoguoCardID) == String(id));
- if (item)
- arr.push(item);
- }
- } else {
- let index = 0;
- let canPush = false;
- const pageIDForCompare = param.Type == "web" && param.PageID > 0 ? encryptWebID(param.PageID) : param.PageID;
- for (const item of list) {
- const cardIDForCompare = param.Type == "web" ? encryptWebID(item.MiaoguoCardID) : item.MiaoguoCardID;
- if (param.PageID == 0 || cardIDForCompare == pageIDForCompare)
- canPush = true;
- if (canPush) {
- if (param.PageID == 0) {
- arr.push(item);
- index++;
- if (index >= param.PageCount)
- break;
- } else {
- if (index > 0)
- arr.push(item);
- index++;
- if (index > param.PageCount)
- break;
- }
- }
- }
- }
- result.List = arr;
- if (param.Type == "web") {
- result.List = result.List.map(item => ({
- ...item,
- MiaoguoCardID: encryptWebID(item.MiaoguoCardID),
- }));
- if (param.IDSelect) {
- const miaoguoPrint = await miaoguo.AddMiaoguoPrint({
- UserID: param.UserID,
- CardID: param.IDSelect,
- });
- result.PrintID = miaoguoPrint.insertId;
- }
- }
- return result;
- }
- export async function GetMiaoguoCardListWeb(ctx) {
- const body = ctx.request.body || {};
- const param = {
- ...body,
- UserID: ctx.query.UserID || "0",
- PageID: body.PageID ? decryptWebID(body.PageID) : 0,
- PageCount: ctx.query.PageCount || "10",
- DataType: body.DataType || "",
- IsCollect: body.IsCollect == 1 ? 1 : 0,
- OrderType: body.OrderType || ctx.query.OrderType || "ac.UpdateTime desc",
- Type: "web",
- CardType: body.CardType || "2",
- FolderID: body.FolderID || 0,
- DayNumber: body.DayNumber || 7,
- };
- if (param.Key)
- param.PageCount = 500;
- else if (param.DataType)
- param.PageCount = 1000;
- if (body.IDSelect) {
- const ids = String(body.IDSelect).split(',').map(item => decryptWebID(item));
- param.IDSelect = ids.join(',');
- }
- const result = await getMiaoguoCardListResult(param);
- ctx.body = { errcode: 10000, result };
- }
- export async function GetMiaoguoCardList2(ctx) {
- const param = {
- UserID: ctx.query.UserID || "0",
- Key: ctx.query.Key || "",
- IsToday: ctx.query.IsToday || "0",
- OrderType: ctx.query.OrderType || "ac.UpdateTime desc,ac.CreateTime desc",
- PageID: ctx.query.PageID || 0,
- PageCount: ctx.query.PageCount || 20,
- IsCollect: ctx.query.IsCollect || 0,
- Type: ctx.query.Type || "app",
- DataType: ctx.query.DataType || "",
- CardType: ctx.query.CardType || "2",
- IDSelect: ctx.query.IDSelect || "",
- PrintID: ctx.query.PrintID || 0,
- FolderID: ctx.query.FolderID || 0,
- DayNumber: ctx.query.DayNumber || 7,
- };
- const result = await getMiaoguoCardListResult(param);
- ctx.body = { errcode: 10000, result };
- }
- function clearMiaoguoCardCache(userID) {
- globalCache.delete("GetMiaoguoCard###UserID=" + userID);
- }
- function addMiaoguoLog(log) {
- miaoguo.AddMiaoguoLog(log).catch(err => console.error('AddMiaoguoLog failed:', err));
- }
- function formatTodayCardTime(item) {
- item.CreateTime = moment(item.CreateTime).format('YYYY-MM-DD HH:mm:ss');
- item.CreateTimeStr = stringUtils.GetDateTimeFormat(item.CreateTime);
- item.UpdateTime = moment(item.UpdateTime).format('YYYY-MM-DD HH:mm:ss');
- item.UpdateTimeStr = stringUtils.GetDateTimeFormat(item.UpdateTime);
- item.FirstTime = moment(item.FirstTime).format('YYYY-MM-DD HH:mm:ss');
- item.LastTime = moment(item.LastTime).format('YYYY-MM-DD HH:mm:ss');
- item.LimitTime = moment(item.LimitTime).format('YYYY-MM-DD HH:mm:ss');
- item.PigeonholeTime = moment(item.PigeonholeTime).format('YYYY-MM-DD HH:mm:ss');
- return item;
- }
- function sm2(data, EF) {
- const result = Math.round(data * EF);
- return result < 1 ? 1 : result;
- }
- function computerMilestone(dayNumber0, dayNumber1, dayNumber2) {
- return Math.round(100 * (dayNumber0 - dayNumber1) / (dayNumber2 - dayNumber1)) / 100;
- }
- export async function GetMiaoguoCardInfo(ctx) {
- const param = {
- UserID: ctx.query.UserID || "0",
- MiaoguoCardID: ctx.query.MiaoguoCardID || "",
- };
- const info = await miaoguo.GetCardInfo(param);
- if (info && info.length > 0) {
- const listContent = await miaoguo.GetCardContentList(param.MiaoguoCardID);
- info[0].Content = listContent;
- info[0] = formatTodayCardTime(info[0]);
- }
- ctx.body = { errcode: 10000, result: info[0] };
- }
- export async function CollectMiaoguoCard(ctx) {
- const param = {
- UserID: ctx.query.UserIDSource || "0",
- UserIDTarget: ctx.query.UserIDTarget || "0",
- MiaoguoCardID: ctx.query.MiaoguoCardID || "",
- };
- let result = 0;
- const info = await miaoguo.GetCardInfo(param);
- if (info && info.length > 0) {
- const listContent = await miaoguo.GetCardContentList(param.MiaoguoCardID);
- if (listContent && listContent.length > 1) {
- param.Content = stringUtils.ReplaceSingleQuotes(listContent[1].Content || "");
- let count = await miaoguo.CheckCardInfoExist(param);
- if (count.length > 0) {
- if (param.MiaoguoCardID == count[0].MiaoguoCardID) {
- result = -1;
- } else {
- param.Content = stringUtils.ReplaceSingleQuotes(listContent[2]?.Content || "");
- param.CardID = count[0].MiaoguoCardID;
- count = await miaoguo.CheckCardInfoExist(param);
- if (count.length > 0) {
- param.Content = stringUtils.ReplaceSingleQuotes(listContent[3]?.Content || "");
- param.CardID = count[0].MiaoguoCardID;
- count = await miaoguo.CheckCardInfoExist(param);
- result = count.length > 0 ? 0 : 1;
- } else {
- result = 1;
- }
- }
- } else {
- result = 1;
- }
- }
- if (result == 1) {
- const now = moment().format('YYYY-MM-DD HH:mm:ss');
- const insertInfo = await miaoguo.AddCard({
- UserID: param.UserIDTarget,
- CreateTime: now,
- LimitTime: now,
- UpdateTime: now,
- CardType: -1,
- IsTodayStudy: 0,
- SourceCardID: param.MiaoguoCardID,
- });
- for (const content of listContent) {
- await miaoguo.AddCardContent({
- MiaoguoCardID: insertInfo.insertId,
- ContentType: content.ContentType,
- Content: stringUtils.ReplaceAllString(content.Content || "", "'", "''"),
- });
- }
- addMiaoguoLog({
- UserID: param.UserIDTarget,
- LogID: 316,
- Content: JSON.stringify({ ...param, NewMiaoguoCardID: insertInfo.insertId }),
- });
- }
- }
- clearMiaoguoCardCache(param.UserIDTarget);
- ctx.body = { errcode: 10000, result };
- }
- export async function SetGrade(ctx) {
- const param = {
- UserID: ctx.query.UserID || "0",
- Grade: ctx.query.Grade || 0,
- UpperAndLowerSemesters: ctx.query.UpperAndLowerSemesters || 0,
- };
- await miaoguo.UpdateUsersByUserID(param);
- const list = await miaoguo.GetCardListID(param);
- if (list.length == 0) {
- const folder = {
- UserID: param.UserID || 0,
- Name: "样例题卡",
- FolderType: 1,
- ColorName: "#FEAF3F",
- IconName: "cardlist_joy_white_80x80",
- UpdateTime: moment().format("YYYY-MM-DD HH:mm:ss"),
- Flag: 0,
- };
- const insertID = await miaoguo.AddFolderInfo(folder);
- const arrID = [];
- for (let i = 0; i < 10; i++) {
- const now = moment().format('YYYY-MM-DD HH:mm:ss');
- const insertInfo = await miaoguo.AddCard({
- UserID: param.UserID,
- CreateTime: now,
- LimitTime: now,
- UpdateTime: now,
- IsTodayStudy: 1,
- FolderID: insertID.insertId,
- });
- arrID.push(insertInfo.insertId);
- }
- let grade = param.Grade;
- if (grade == 0)
- grade = 1;
- if (grade == 100)
- grade = 7;
- const start = grade * 10 + 1;
- const end = grade * 10 + 10;
- let index = 0;
- for (let i = start; i <= end; i++) {
- const listContent = await miaoguo.GetCardContentList(i);
- for (const content of listContent) {
- await miaoguo.AddCardContent({
- MiaoguoCardID: arrID[index],
- ContentType: content.ContentType,
- Content: content.Content,
- });
- }
- index++;
- }
- }
- clearMiaoguoCardCache(param.UserID);
- setTimeout(() => {
- const sql = "select c.MiaoguoCardID from MiaoguoCard c left join MiaoguoContent mc on c.MiaoguoCardID=mc.MiaoguoCardID where c.UserID=? and mc.Content is null;";
- miaoguo.RunSql([param.UserID], sql).then(list => {
- for (const item of list)
- miaoguo.RunSql([item.MiaoguoCardID], "delete from MiaoguoCard where MiaoguoCardID=?;").catch(err => console.error('cleanup empty card failed:', err));
- }).catch(err => console.error('cleanup empty cards query failed:', err));
- }, 1000 * 60);
- ctx.body = { errcode: 10000 };
- }
- export async function GetMiaoguoCardToday2(ctx) {
- const param = {
- UserID: ctx.query.UserID || 0,
- };
- if (param.UserID == "undefined")
- param.UserID = 0;
- let result;
- if (param.UserID > 0) {
- const userConfig = await miaoguo.GetUserConfigData(param);
- if (userConfig && userConfig.length > 0) {
- param.BasicCardLimit = userConfig[0].BasicCardLimit;
- param.CardMaxNumberNew = userConfig[0].CardMaxNumberNew;
- param.CardMaxNumberHistory = userConfig[0].CardMaxNumberHistory;
- param.SortTypeIndex = userConfig[0].SortTypeIndex;
- param.CardMaxNumberNewUrgent = userConfig[0].CardMaxNumberNewUrgent;
- param.CardMaxNumberHistoryUrgent = userConfig[0].CardMaxNumberHistoryUrgent;
- param.CardTypeConfig = userConfig[0].CardType;
- } else {
- Object.assign(param, {
- TaskSetting: 0,
- BasicCardLimit: 50,
- CardMaxNumberNew: 10,
- CardMaxNumberHistory: 40,
- CardMaxNumberNewUrgent: 10,
- CardMaxNumberHistoryUrgent: 40,
- CardType: 0,
- SortTypeIndex: 0,
- MemoryLevel: 0,
- ClickType: 0,
- SecondConfigArray: "0,0,0",
- ColorIndexArr: "1,2,3,4",
- });
- await miaoguo.AddUserConfig(param);
- param.CardTypeConfig = 0;
- }
- const url = ctx.request.url + "&CardType=" + param.CardTypeConfig;
- result = globalCache.get(url);
- if (result === 0) {
- result = {};
- const param2 = { UserID: param.UserID, CardType: 0 };
- param2.Type = "NewLimitTimeToday";
- result.NewLimitTimeToday = (await miaoguo.GetMiaoguoCardTotal(param2))[0].Count;
- param2.Type = "HistoryLimitTimeToday";
- result.HistoryLimitTimeToday = (await miaoguo.GetMiaoguoCardTotal(param2))[0].Count;
- const todayStart = moment().format('YYYY-MM-DD 00:00:00');
- const tomorrowStart = moment().add(1, "days").format('YYYY-MM-DD 00:00:00');
- const practiceParam = {
- UserID: param.UserID,
- LimitTime: tomorrowStart,
- LastTime: todayStart,
- GetCount: true,
- };
- const alreadyPracticeNumber = await miaoguo.GetCardListID(practiceParam);
- result.AlreadyPracticeNumber = alreadyPracticeNumber[0].Count;
- if (param.BasicCardLimit > 0) {
- const historyPracticeParam = {
- UserID: param.UserID,
- LimitTime: tomorrowStart,
- LastTime: todayStart,
- GetCount: true,
- CardType: 0,
- IsNew: 0,
- };
- const alreadyPracticeNumberHistory = await miaoguo.GetCardListID(historyPracticeParam);
- const alreadyPracticeNumberCountHistory = alreadyPracticeNumberHistory[0].Count;
- let shouldUpdate = 0;
- if (result.HistoryLimitTimeToday >= param.BasicCardLimit) {
- param.CardMaxNumberNew = 0;
- param.CardMaxNumberHistory = param.BasicCardLimit;
- shouldUpdate = 1;
- } else if (result.HistoryLimitTimeToday < param.BasicCardLimit) {
- param.CardMaxNumberNew = param.BasicCardLimit - result.HistoryLimitTimeToday - alreadyPracticeNumberCountHistory;
- if (param.CardMaxNumberNew < 0)
- param.CardMaxNumberNew = 0;
- param.CardMaxNumberHistory = result.HistoryLimitTimeToday + alreadyPracticeNumberCountHistory;
- if (param.CardMaxNumberHistory > (param.BasicCardLimit + param.CardMaxNumberNew))
- param.CardMaxNumberHistory = param.BasicCardLimit + param.CardMaxNumberNew;
- shouldUpdate = 1;
- }
- if (shouldUpdate) {
- await miaoguo.UpdateUserConfig({
- UserID: param.UserID,
- CardMaxNumberNew: param.CardMaxNumberNew,
- CardMaxNumberHistory: param.CardMaxNumberHistory,
- });
- }
- result.BasicCardLimit = param.BasicCardLimit;
- } else {
- result.BasicCardLimit = 0;
- }
- const arrID = [];
- const listNew = [];
- const listReview = [];
- const listHistory = [];
- result.UrgentNewLength = 0;
- result.UrgentOldLength = 0;
- result.CommonNewLength = 0;
- result.CommonOldLength = 0;
- async function appendTaskList(isUrgent) {
- let list1 = [];
- const list2 = [];
- const list3 = [];
- param.CardType = isUrgent ? 1 : 0;
- let history = isUrgent ? param.CardMaxNumberHistoryUrgent : param.CardMaxNumberHistory;
- if (isUrgent)
- delete param.CardMaxNumberHistoryUrgent;
- else
- delete param.CardMaxNumberHistory;
- param.LimitTime = tomorrowStart;
- param.LastTime = todayStart;
- const countNew = isUrgent ? await miaoguo.GetCardListTodayAlreadyUrgent(param) : await miaoguo.GetCardListTodayAlready(param);
- if (isUrgent) {
- param.CardMaxNumberNewUrgent = (param.CardMaxNumberNewUrgent - countNew[0].count) > 0 ? (param.CardMaxNumberNewUrgent - countNew[0].count) : 0;
- param.SortType = "LimitTime asc,MiaoguoCardID asc";
- if (param.CardMaxNumberNewUrgent > 0)
- list1 = await miaoguo.GetCardListTodayUrgent(param);
- } else {
- param.CardMaxNumberNew = (param.CardMaxNumberNew - countNew[0].count) > 0 ? (param.CardMaxNumberNew - countNew[0].count) : 0;
- if (param.SortTypeIndex == 0)
- param.SortType = "RAND()";
- else if (param.SortTypeIndex == 1)
- param.SortType = "LimitTime asc,MiaoguoCardID asc";
- else if (param.SortTypeIndex == 2)
- param.SortType = "LimitTime desc,MiaoguoCardID desc";
- if (param.CardMaxNumberNew > 0)
- list1 = await miaoguo.GetCardListToday(param);
- }
- const newCount = isUrgent
- ? Math.min(param.CardMaxNumberNewUrgent || 0, list1.length)
- : Math.min(param.CardMaxNumberNew || 0, list1.length);
- list1 = list1.slice(0, newCount).map(item => {
- item.Number0 = "1m";
- item.Number2 = "10m";
- item.Number3 = "4d";
- arrID.unshift(item.MiaoguoCardID);
- return formatTodayCardTime(item);
- });
- param.IsReview = true;
- const reviewList = isUrgent ? await miaoguo.GetCardListTodayUrgent(param) : await miaoguo.GetCardListToday(param);
- for (const item of reviewList) {
- item.Number0 = "10m";
- item.Number2 = "1d";
- item.Number3 = "4d";
- list2.push(formatTodayCardTime(item));
- arrID.unshift(item.MiaoguoCardID);
- }
- delete param.IsReview;
- delete param.IsTodayStudy;
- for (const item of reviewList) {
- if (moment(item.FirstTime).format('YYYY-MM-DD HH:mm:ss') < param.LastTime)
- history--;
- }
- if (history > 0) {
- let oldCount;
- if (isUrgent) {
- param.CardMaxNumberHistoryUrgent = history;
- oldCount = await miaoguo.GetCardListTodayAlreadyUrgent(param);
- param.CardMaxNumberHistoryUrgent = (param.CardMaxNumberHistoryUrgent - oldCount[0].count) > 0 ? (param.CardMaxNumberHistoryUrgent - oldCount[0].count) : 0;
- } else {
- param.CardMaxNumberHistory = history;
- oldCount = await miaoguo.GetCardListTodayAlready(param);
- param.CardMaxNumberHistory = (param.CardMaxNumberHistory - oldCount[0].count) > 0 ? (param.CardMaxNumberHistory - oldCount[0].count) : 0;
- }
- const oldLimit = isUrgent ? param.CardMaxNumberHistoryUrgent : param.CardMaxNumberHistory;
- if (oldLimit > 0) {
- const oldList = isUrgent ? await miaoguo.GetCardListTodayUrgent(param) : await miaoguo.GetCardListToday(param);
- const count = Math.min(oldLimit, oldList.length);
- for (let i = 0; i < count; i++) {
- const item = oldList[i];
- item.Number0 = "10m";
- const normal = sm2(item.IntervalDay, getEF(item.RepetitionCoefficient, 4));
- item.Number1 = sm2(normal, Number(stringUtils.Random(2, 5)) / 10) + "d";
- item.Number2 = normal + "d";
- if (item.Number1 == item.Number2)
- delete item.Number1;
- let number3 = sm2(normal, item.RepetitionCoefficient);
- if (normal + 1 > number3)
- number3 = normal + 1;
- item.Number3 = number3 + "d";
- list3.push(formatTodayCardTime(item));
- arrID.unshift(item.MiaoguoCardID);
- }
- }
- }
- if (isUrgent) {
- result.UrgentNewLength = list1.length;
- result.UrgentOldLength = list2.length + list3.length;
- } else {
- result.CommonNewLength = list1.length;
- result.CommonOldLength = list3.length;
- }
- for (const item of list1)
- item.IsUrgentCard = isUrgent ? 1 : 0;
- for (const item of list2)
- item.IsUrgentCard = isUrgent ? 1 : 0;
- for (const item of list3)
- item.IsUrgentCard = isUrgent ? 1 : 0;
- listNew.push(...list1);
- listReview.push(...list2);
- listHistory.push(...list3);
- }
- if (param.CardTypeConfig == 1 || param.CardTypeConfig == 2)
- await appendTaskList(true);
- if (param.CardTypeConfig == 0 || param.CardTypeConfig == 2)
- await appendTaskList(false);
- if (arrID.length > 0) {
- const listContent = await miaoguo.GetCardContentList(arrID.join(","));
- const contentMap = new Map();
- for (const content of listContent) {
- if (!contentMap.has(content.MiaoguoCardID))
- contentMap.set(content.MiaoguoCardID, []);
- contentMap.get(content.MiaoguoCardID).push({
- ContentType: content.ContentType,
- Content: stringUtils.ReplaceAllString(content.Content || "", "''", "'"),
- });
- }
- for (const list of [listNew, listReview, listHistory]) {
- for (const item of list)
- item.Content = contentMap.get(item.MiaoguoCardID) || [];
- }
- // 保证返回列表中每一项的 Content 均为 4 项,否则从列表中剔除,避免前端渲染异常
- for (const list of [listNew, listReview, listHistory]) {
- for (let i = list.length - 1; i >= 0; i--) {
- if (!Array.isArray(list[i].Content) || list[i].Content.length !== 4)
- list.splice(i, 1);
- }
- }
- // 同步修正剔除后各项数量统计
- result.UrgentNewLength = listNew.filter(item => item.IsUrgentCard === 1).length;
- result.UrgentOldLength = listReview.filter(item => item.IsUrgentCard === 1).length + listHistory.filter(item => item.IsUrgentCard === 1).length;
- result.CommonNewLength = listNew.filter(item => item.IsUrgentCard === 0).length;
- result.CommonOldLength = listHistory.filter(item => item.IsUrgentCard === 0).length;
- for (const list of [listNew, listReview, listHistory]) {
- for (const item of list)
- delete item.IsUrgentCard;
- }
- }
- const dayNumberArr = await miaoguo.GetTaskData(param);
- let dayNumber = (dayNumberArr || []).length + 1;
- let isStart = 1;
- const practiceCount = await miaoguo.GetTaskData({ UserID: param.UserID, CreateTime: todayStart });
- if (practiceCount.length > 0 && practiceCount[0].CardCount > 0) {
- isStart = 0;
- if (dayNumber > 1)
- dayNumber--;
- }
- const cardNumberArr = await miaoguo.GetCardCount(param);
- const cardNumber = cardNumberArr && cardNumberArr.length > 0 ? cardNumberArr[0].count : 0;
- const cardEveryTimeArr = await miaoguo.GetCardEveryTimeAvg({ UserID: param.UserID });
- const cardEveryTime = cardEveryTimeArr && cardEveryTimeArr.length > 0 && cardEveryTimeArr[0].avg ? cardEveryTimeArr[0].avg : 20;
- result.ListNew = listNew;
- result.ListReview = listReview;
- result.ListHistory = listHistory;
- result.PracticeNumber = listNew.length * 2 + listReview.length + listHistory.length;
- result.PracticeTime = Math.round(result.PracticeNumber * cardEveryTime / 60);
- if (result.PracticeTime == 0 && result.PracticeNumber > 0)
- result.PracticeTime = 1;
- result.DayNumber = dayNumber;
- result.CardNumber = cardNumber;
- result.IsStart = isStart;
- result.Today = moment().format('YYYY-MM-DD');
- const cardStudyPlanNumber = await miaoguo.GetStudyPlanCardNumber(param);
- result.CardNumberCommon = 0;
- result.CardNumberUrgent = 0;
- for (const item of cardStudyPlanNumber) {
- if (item.CardType === 0)
- result.CardNumberCommon = item.Count;
- else if (item.CardType === 1)
- result.CardNumberUrgent = item.Count;
- }
- const today = moment().format('YYYYMMDD');
- for (const list of [result.ListNew, result.ListReview, result.ListHistory]) {
- for (const item of list) {
- const historyUpdateTime = moment(item.HistoryUpdateTime).format('YYYYMMDD');
- if (today > historyUpdateTime) {
- miaoguo.UpdateCard({
- MiaoguoCardID: item.MiaoguoCardID,
- HistoryUpdateTime: moment().format('YYYY-MM-DD 00:00:00'),
- HistoryFirstTime: item.FirstTime,
- HistoryLastTime: item.LastTime,
- HistoryLimitTime: item.LimitTime,
- HistoryIntervalDay: item.IntervalDay,
- HistoryRepetitionCoefficient: item.RepetitionCoefficient,
- HistoryLearnNumber: item.LearnNumber,
- }).catch(err => console.error('UpdateCard history failed:', err));
- }
- }
- }
- const listFolder = await miaoguo.GetUserFolderList(param);
- result.FolderName = [{ FolderID: 0, FolderName: "" }];
- for (const folder of listFolder)
- result.FolderName.push({ FolderID: folder.ID, FolderName: folder.Name });
- globalCache.set(url, result, config.BufferMemoryTimeLower || config.BufferMemoryTimeLowNormal);
- }
- } else {
- result = { IsMaintain: 1 };
- }
- ctx.body = { errcode: 10000, result };
- }
- export async function DeleteMiaoguoCard(ctx) {
- const param = {
- MiaoguoCardID: ctx.query.ID,
- UserID: ctx.query.UserID,
- Flag: -1,
- DeleteTime: moment().format("YYYY-MM-DD HH:mm:ss"),
- };
- param.UpdateTime = param.DeleteTime;
- await miaoguo.UpdateCard(param);
- addMiaoguoLog({ UserID: ctx.query.UserID, LogID: 299, Content: JSON.stringify(param) });
- clearMiaoguoCardCache(ctx.query.UserID);
- ctx.body = { errcode: 10000 };
- }
- export async function StartMiaoguoTask(ctx) {
- const param = {
- UserID: ctx.query.UserID || 0,
- CurrentUserID: ctx.query.CurrentUserID,
- };
- addMiaoguoLog({ UserID: ctx.query.UserID, LogID: 304, Content: JSON.stringify(param) });
- ctx.body = { errcode: 10000 };
- }
- export async function ResetMiaoguoCardTask(ctx) {
- const param = { UserID: ctx.query.UserID };
- const list = await miaoguo.GetCardTodayFinished(param);
- const arr = [];
- for (const item of list) {
- await miaoguo.UpdateCard({
- MiaoguoCardID: item.MiaoguoCardID,
- FirstTime: item.HistoryFirstTime,
- LastTime: item.HistoryLastTime,
- LimitTime: item.HistoryLimitTime,
- IntervalDay: item.HistoryIntervalDay,
- RepetitionCoefficient: item.HistoryRepetitionCoefficient,
- LearnNumber: item.HistoryLearnNumber,
- });
- arr.push(item.MiaoguoCardID);
- }
- if (arr.length > 0)
- await miaoguo.ResetTodayFinished({ CardID: arr.join(",") });
- await miaoguo.DeleteMiaoguoTask(param);
- addMiaoguoLog({ UserID: ctx.query.UserID, LogID: 317, Content: JSON.stringify(param) });
- clearMiaoguoCardCache(ctx.query.UserID);
- ctx.body = { errcode: 10000, result: true };
- }
- export async function RemoveFolder(ctx) {
- const param = {
- UserID: ctx.query.UserID || 0,
- MiaoguoCardID: ctx.query.ID || 0,
- FolderID: ctx.query.FolderID || 0,
- UpdateTime: moment().format("YYYY-MM-DD HH:mm:ss"),
- };
- await miaoguo.UpdateFolderInfo({
- UserID: param.UserID,
- ID: param.FolderID,
- UpdateTime: param.UpdateTime,
- });
- param.FolderID = 0;
- await miaoguo.UpdateCard(param);
- addMiaoguoLog({ UserID: ctx.query.UserID, LogID: 311, Content: JSON.stringify(param) });
- clearMiaoguoCardCache(ctx.query.UserID);
- ctx.body = { errcode: 10000 };
- }
- export async function UpdateMiaoguoCardType(ctx) {
- const param = {
- UserID: ctx.query.UserID || 0,
- MiaoguoCardID: ctx.query.ID || 0,
- CardType: ctx.query.CardType || 0,
- FolderType: ctx.query.FolderType || 0,
- LimitTime: ctx.query.LimitTime || "",
- };
- if (param.LimitTime === "" || param.LimitTime == "undefined")
- delete param.LimitTime;
- await miaoguo.UpdateCardType(param);
- if (param.FolderType >= 1) {
- const folderInfo = await miaoguo.GetMiaoguoFolderCount(param);
- let folderID = 0;
- if (folderInfo.length > 0) {
- folderID = folderInfo[0].ID;
- } else {
- const insertID = await miaoguo.AddFolderInfo({
- UserID: ctx.query.UserID || 0,
- Name: "练习中不会的题卡",
- FolderType: 1,
- ColorName: "#FEAF3F",
- IconName: "cardlist_joy_white_80x80",
- UpdateTime: moment().format("YYYY-MM-DD HH:mm:ss"),
- Flag: 0,
- });
- folderID = insertID.insertId;
- }
- await miaoguo.UpdateCard({ MiaoguoCardID: param.MiaoguoCardID, FolderID: folderID });
- }
- addMiaoguoLog({
- UserID: ctx.query.UserID,
- LogID: param.FolderType && param.FolderType >= 1 ? 313 : 301,
- Content: JSON.stringify(param),
- });
- clearMiaoguoCardCache(ctx.query.UserID);
- ctx.body = { errcode: 10000 };
- }
- export async function GetMiaoguoTaskTime(ctx) {
- const param = { UserID: ctx.query.UserID };
- param.CreateTime = moment().format('YYYY-MM-DD 00:00:00');
- const time = await miaoguo.GetTaskData(param);
- delete param.CreateTime;
- const dayNumberArr = await miaoguo.GetTaskData(param);
- let dayNumber = dayNumberArr.length;
- if (dayNumber == 0)
- dayNumber = 1;
- if (time && time.length > 0) {
- time[0].DayNumber = dayNumber;
- if (time[0].CardCount > 0 && time[0].Duration > 0) {
- param.CreateTime = moment().format('YYYY-MM-DD 00:00:00');
- const obj = {
- UserID: param.UserID,
- CreateTime: param.CreateTime,
- CardTask: time[0].CardCount,
- Duration: time[0].Duration,
- };
- const tasks = await miaoguo.GetUserMiaoguoTask(param);
- if (tasks && tasks.length > 0) {
- // 当天任务已存在,dayNumberArr 已包含当天记录,直接用累计练习天数
- obj.DayNumber = dayNumberArr.length;
- await miaoguo.UpdateMiaoguoTask(obj);
- } else {
- // 新增当天任务,DayNumber 为已有累计天数 + 1(注意用原始长度,新用户首日应为 1)
- obj.DayNumber = dayNumberArr.length + 1;
- await miaoguo.AddMiaoguoTask(obj);
- await updateMiaoguoMilestoneInfoByUserID(param.UserID);
- }
- }
- if (!time[0].Duration || time[0].Duration < 60)
- time[0].Duration = 60;
- time[0].Count = time[0].CardCount;
- }
- ctx.body = { errcode: 10000, result: time[0] };
- }
- export async function GetMiaoguoCardTotal(ctx) {
- const param = {
- UserID: ctx.query.UserID || 0,
- CardType: ctx.query.CardType || 0,
- };
- const result = {};
- param.Type = "NewAll";
- result.NewCardAll = (await miaoguo.GetMiaoguoCardTotal(param))[0].Count;
- param.Type = "HistoryAll";
- result.HistoryCardAll = (await miaoguo.GetMiaoguoCardTotal(param))[0].Count;
- param.Type = "NewToday";
- result.NewToday = (await miaoguo.GetMiaoguoCardTotal(param))[0].Count;
- param.Type = "NewLimitTimeToday";
- result.NewLimitTimeToday = (await miaoguo.GetMiaoguoCardTotal(param))[0].Count;
- result.NewCardNumber = result.NewLimitTimeToday;
- param.Type = "HistoryLimitTimeToday";
- result.HistoryLimitTimeToday = (await miaoguo.GetMiaoguoCardTotal(param))[0].Count;
- result.LimitCardNumber = result.HistoryLimitTimeToday;
- param.Type = "NewAndLimitToday";
- result.NewCardNumberAndLimitToday = (await miaoguo.GetMiaoguoCardTotal(param))[0].Count;
- param.Type = "HistoryAndLimitToday";
- result.HistoryCardNumberAndLimitToday = (await miaoguo.GetMiaoguoCardTotal(param))[0].Count;
- result.LimitCardNumberToday = result.HistoryCardNumberAndLimitToday;
- ctx.body = { errcode: 10000, result };
- }
- export async function GetMiaoguoPayInfo3(ctx) {
- const param = {
- UserID: ctx.query.UserID,
- PayType: ctx.query.PayType || 1,
- EndDate: ctx.query.EndDate,
- Price: ctx.query.Price || 0,
- DayNumber: ctx.query.DayNumber || 0,
- };
- const price2 = 199;
- const price2Str = "元 (55折,原价365元)";
- const price3 = 258;
- const price3Str = "元 (7折,原价365元)";
- if (param.EndDate && param.EndDate.indexOf("年") > 0)
- param.EndDate = param.EndDate.replace("年", "-").replace("月", "-").replace("日", "");
- let time1 = moment(new Date(param.EndDate)).format('YYYY-MM-DD');
- const today = moment().format('YYYY-MM-DD');
- if (time1 == "Invalid date" || time1 < today)
- time1 = today;
- const userList = await miaoguo.GetUsersInfoByUserID(param);
- if (userList && userList.length > 0) {
- const productServiceTime = moment(userList[0].ProductServiceTime).format('YYYY-MM-DD');
- if (time1 < productServiceTime)
- time1 = productServiceTime;
- }
- const time2 = moment(time1).add(12, 'months').add(30, 'days').format('YYYY年MM月DD日');
- const time5 = moment(time1).format('YYYY年MM月DD日');
- const result = {};
- if (param.PayType == 2) {
- result.Text1 = "购买";
- result.List1 = [
- { Name: "秒过年费", Content: price2 + price2Str },
- { Name: "赠送时间", Content: "30天" },
- { Name: "有效期", Content: time2 },
- ];
- result.Text2 = "支付前请注意:\n自支付之日起7天内接受无理由退款,此期限过后不予退款。\n支付即代表您接受本条款。";
- result.Text8 = "支付";
- result.Text3 = "支付成功";
- result.Text4 = "";
- result.Text5 = "请点开通";
- result.Text6 = "";
- result.Text7 = "";
- result.PayMoney = price2;
- } else if (param.PayType == 5) {
- result.Text1 = "购买";
- let price = price3;
- let priceStr = price3Str;
- if (userList[0] && userList[0].IsPay == 1) {
- price = price2;
- priceStr = price2Str;
- }
- result.List1 = [
- { Name: "秒过年费", Content: price + priceStr },
- { Name: "有效期", Content: time5 },
- ];
- result.Text2 = "支付前请注意:\n自支付之日起7天内接受无理由退款,此期限过后不予退款。\n支付即代表您接受本条款。";
- result.Text8 = "支付";
- result.Text3 = "支付成功";
- result.Text4 = "";
- result.Text5 = "请点开通";
- result.Text6 = "";
- result.Text7 = "";
- result.PayMoney = price;
- } else if (param.PayType == 6) {
- const time6 = moment(time1).add(param.DayNumber, 'days').format('YYYY年MM月DD日');
- result.Text1 = "购买";
- if (param.Price == 0)
- param.Price = price2;
- let priceStr = "元";
- if (param.Price == price2)
- priceStr = price2Str;
- else if (param.Price == price3)
- priceStr = price3Str;
- result.List1 = [
- { Name: "秒过年费", Content: param.Price + priceStr },
- { Name: "有效期", Content: time6 },
- ];
- result.Text2 = "支付前请注意:\n自支付之日起7天内接受无理由退款,此期限过后不予退款。\n支付即代表您接受本条款。";
- result.Text8 = "支付";
- result.Text3 = "支付成功";
- result.Text4 = "";
- result.Text5 = "请点开通";
- result.Text6 = "";
- result.Text7 = "";
- result.PayMoney = param.Price;
- } else if (param.PayType == 7) {
- result.Text1 = "购买";
- result.List1 = [
- { Name: "秒过年费", Content: price2 + price2Str },
- { Name: "有效期", Content: time5 },
- ];
- result.Text2 = "支付前请注意:\n自支付之日起7天内接受无理由退款,此期限过后不予退款。\n支付即代表您接受本条款。";
- result.Text8 = "支付";
- result.Text3 = "支付成功";
- result.Text4 = "";
- result.Text5 = "请点开通";
- result.Text6 = "";
- result.Text7 = "";
- result.PayMoney = price2;
- }
- ctx.body = { errcode: 10000, result };
- }
- export async function InsertMiaoguoUserLesson(ctx) {
- const param = {
- UserID: ctx.query.UserID || 0,
- LessonID: ctx.query.LessonID || 1,
- CreateTime: moment().format('YYYY-MM-DD HH:mm:ss'),
- Content: ctx.query.Content,
- };
- if (param.Content)
- await miaoguo.AddMiaoguoUserLesson(param);
- ctx.body = { errcode: 10000 };
- }
- export async function UpdateFolderInfo(ctx) {
- const param = {
- UserID: ctx.query.UserID || 0,
- ID: ctx.query.FolderID || 0,
- Name: ctx.query.Name || "",
- Flag: ctx.query.Flag || 0,
- UpdateTime: moment().format("YYYY-MM-DD HH:mm:ss"),
- };
- if (ctx.query.ColorName)
- param.ColorName = "#" + ctx.query.ColorName;
- if (ctx.query.IconName)
- param.IconName = ctx.query.IconName;
- if (param.ID > 0) {
- if (param.Flag == -1) {
- delete param.Name;
- delete param.ColorName;
- delete param.IconName;
- }
- await miaoguo.UpdateFolderInfo(param);
- if (param.Flag == -1) {
- param.FolderOldID = param.ID;
- param.FolderID = 0;
- await miaoguo.UpdateFolderList(param);
- clearMiaoguoCardCache(ctx.query.UserID);
- }
- addMiaoguoLog({ UserID: ctx.query.UserID, LogID: 310, Content: JSON.stringify(param) });
- } else {
- delete param.ID;
- await miaoguo.AddFolderInfo(param);
- addMiaoguoLog({ UserID: ctx.query.UserID, LogID: 309, Content: JSON.stringify(param) });
- }
- ctx.body = { errcode: 10000 };
- }
- export async function ShareMiaoguoCard(ctx) {
- const param = {
- UserID: ctx.query.UserID || 0,
- MiaoguoCardID: ctx.query.MiaoguoCardID || 0,
- IsShare: 1,
- };
- await miaoguo.UpdateCard(param);
- ctx.body = { errcode: 10000 };
- }
- export async function BuildMiaoguoQRCode(ctx) {
- const param = {
- UserID: ctx.query.UserID || 0,
- PrintID: ctx.query.PrintID || 0,
- IsWeb: ctx.query.IsWeb || 0,
- };
- try {
- const tokenUrl = 'https://api.weixin.qq.com/cgi-bin/token?appid=' + config.wx.miaoguo_appid + '&secret=' + config.wx.miaoguo_appsecret + '&grant_type=client_credential';
- const tokenRes = await axios.get(tokenUrl, { transformResponse: [(data) => data] });
- const tokenJson = typeof tokenRes.data === 'string' ? JSON.parse(tokenRes.data) : tokenRes.data;
- if (!tokenJson || !tokenJson.access_token) {
- ctx.body = { errcode: 10000 };
- return;
- }
- const postJSON = {};
- let imageUrl = "";
- if (param.PrintID && param.PrintID > 0) {
- postJSON.width = 280;
- postJSON.scene = "type=print&P=" + param.PrintID + "&U=" + param.UserID;
- imageUrl = 'MiaoguoPrint' + param.PrintID + '.png';
- } else if (param.IsWeb) {
- postJSON.width = 280;
- postJSON.scene = "UserID=" + param.UserID;
- let userID = Encrypt(param.UserID, config.urlSecrets.aes_key, config.urlSecrets.aes_iv);
- userID = stringUtils.ReplaceAllString(userID, "/", "___");
- userID = stringUtils.ReplaceAllString(userID, "+", "___");
- imageUrl = 'MiaoguoUser' + userID + '.png';
- miaoguo.UpdateUsersByUserID({ HasACode: 1, UserID: param.UserID }).catch(err => console.error('UpdateUsersByUserID HasACode failed:', err));
- }
- if (imageUrl) {
- const qrUrl = 'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=' + tokenJson.access_token;
- const dir = './public/images/acode';
- await fsPromises.mkdir(dir, { recursive: true });
- const filePath = path.join(dir, imageUrl);
- const qrRes = await axios.post(qrUrl, postJSON, {
- responseType: 'arraybuffer',
- transformResponse: [(data) => data],
- });
- await fsPromises.writeFile(filePath, Buffer.from(qrRes.data));
- await uploadMiaoguoFile(imageUrl, filePath);
- }
- } catch (err) {
- console.error('BuildMiaoguoQRCode failed:', err);
- }
- ctx.body = { errcode: 10000 };
- }
- async function updateMiaoguoMilestoneInfoByUserID(userID) {
- const param = {
- UserID: userID || 0,
- FieldStr: "*",
- OrderType: "desc",
- };
- const list = await miaoguo.GetUserMiaoguoTaskByUserID(param);
- if (!list || list.length == 0)
- return;
- const count = list.length;
- const arrHasMilestoneID = list.filter(item => item.MilestoneID).map(item => item.MilestoneID);
- const mileStoneArr = constantClass.GetMilestone();
- const maxMileStoneID = mileStoneArr.length;
- const mArr = [];
- for (let i = 1; i < maxMileStoneID; i++) {
- if (!arrHasMilestoneID.includes(i))
- mArr.push(i);
- }
- const mID = mArr.length > 0 ? mArr[stringUtils.Random(0, mArr.length - 1)] : stringUtils.Random(1, maxMileStoneID);
- for (const milestone of mileStoneArr) {
- if (milestone.DayNumber == count) {
- await miaoguo.UpdateMiaoguoTask({
- ID: list[0].ID,
- MilestoneDayNumber: milestone.DayNumber,
- MilestoneID: mID,
- });
- break;
- }
- }
- }
- export async function UpdateMiaoguoMilestoneInfo(ctx) {
- await updateMiaoguoMilestoneInfoByUserID(ctx.query.UserID || 0);
- ctx.body = { errcode: 10000 };
- }
- export async function GetHardworkingList(ctx) {
- const param = {
- UserID: ctx.query.UserID || 0,
- OrderType: "desc",
- };
- const cacheKey = "GetHardworkingList?UserID=" + param.UserID;
- let result = globalCache.get(cacheKey);
- if (result === 0) {
- result = {};
- param.IsHardworking = true;
- const dayNumberArr = await miaoguo.GetTaskData(param);
- result.DayNumber = dayNumberArr[0].Count;
- if (result.DayNumber > 0) {
- const mileStoneArr = constantClass.GetMilestone();
- for (let i = 0; i < mileStoneArr.length; i++) {
- if (result.DayNumber < mileStoneArr[i].DayNumber) {
- result.MilestonePrev = mileStoneArr[i - 1];
- result.MilestoneNext = mileStoneArr[i];
- result.RemainingDays = mileStoneArr[i].DayNumber - result.DayNumber;
- result.PastDays = result.DayNumber - mileStoneArr[i - 1].DayNumber;
- result.Rate = 100 * computerMilestone(result.DayNumber, mileStoneArr[i - 1].DayNumber, mileStoneArr[i].DayNumber) + "%";
- break;
- }
- }
- const createTime = moment().format("YYYY-MM") + "-01";
- param.FieldStr = "ID,CreateTime,IsShare,HardworkingNumber,MilestoneDayNumber,MilestoneID,AphorismID,ImageID";
- result.SevenDays = [];
- result.CurrentMonth = [];
- const list = await miaoguo.GetUserMiaoguoTaskByUserID(param);
- if (list && list.length > 0) {
- const arrAphorism = await miaoguo.GetAphorism();
- for (const item of list) {
- if (item.AphorismID > 0 || item.MilestoneDayNumber > 0) {
- const obj = {
- ID: item.ID,
- HardworkingNumber: item.HardworkingNumber,
- OrdinalPostfix: stringUtils.GetOrdinalPostfix(item.HardworkingNumber),
- };
- if (item.MilestoneDayNumber > 0) {
- for (const milestone of mileStoneArr) {
- if (milestone.DayNumber == item.MilestoneDayNumber) {
- obj.Name = milestone.Name;
- obj.Color2 = milestone.Color2;
- obj.IsMilestone = 1;
- break;
- }
- }
- } else {
- obj.Image = "https://miaguo-1253256735.file.myqcloud.com/web/_share/qmjl_pic_d_" + item.ImageID + ".jpg";
- if (item.AphorismID) {
- for (const aphorism of arrAphorism) {
- if (aphorism.ID == item.AphorismID) {
- obj.Content = aphorism.Content;
- obj.AphorismID = item.AphorismID;
- break;
- }
- }
- }
- }
- obj.CreateTime = moment(item.CreateTime).format("YYYY.MM.DD");
- result.SevenDays.push(obj);
- if (result.SevenDays.length >= 7)
- break;
- }
- }
- let shareNumber = 0;
- let shareNumberYear = 0;
- let shareNumberYearPrev = 0;
- let shareNumberMonth = 0;
- for (let i = list.length - 1; i >= 0; i--) {
- const item = list[i];
- item.CreateTime = moment(item.CreateTime).format("YYYY-MM-DD");
- if (item.CreateTime >= createTime) {
- const obj = {
- ID: item.ID,
- IsShare: item.IsShare,
- Day: moment(item.CreateTime).format("D"),
- HardworkingNumber: item.HardworkingNumber,
- };
- if (item.MilestoneDayNumber > 0) {
- for (const milestone of mileStoneArr) {
- if (milestone.DayNumber == item.MilestoneDayNumber) {
- obj.Name = milestone.Name;
- obj.Color1 = milestone.Color1;
- obj.IsMilestone = 1;
- break;
- }
- }
- }
- if (item.AphorismID > 0 && item.ImageID) {
- obj.Image = "https://miaguo-1253256735.file.myqcloud.com/web/_share/qmjl_pic_c_" + item.ImageID + ".jpg";
- obj.AphorismID = item.AphorismID;
- }
- if (item.IsShare || item.AphorismID > 0 || item.MilestoneDayNumber > 0)
- shareNumberMonth++;
- result.CurrentMonth.push(obj);
- }
- if (item.IsShare || item.AphorismID > 0 || item.MilestoneDayNumber > 0) {
- shareNumber++;
- if (item.CreateTime >= moment().format("YYYY-01-01") && item.IsShare)
- shareNumberYear++;
- if (item.CreateTime >= "2022-01-01" && item.CreateTime < "2023-01-01" && item.IsShare)
- shareNumberYearPrev++;
- }
- }
- result.ShareNumberMonth = shareNumberMonth;
- result.ShareNumberYear = shareNumberYear;
- result.ShareNumberYearPrev = shareNumberYearPrev;
- result.ShareNumberYearRate = Math.round(100 * shareNumberYear / 200);
- if (result.ShareNumberYearRate > 100)
- result.ShareNumberYearRate = 100;
- result.Award = 0;
- if (result.ShareNumberYearPrev >= 100)
- result.Award = 30;
- if (result.ShareNumberYearPrev >= 200)
- result.Award = 60;
- result.ShareNumber = shareNumber;
- result.ShareFirstDay = moment(list[list.length - 1].CreateTime).format("YYYY年MM月DD日");
- }
- }
- globalCache.set(cacheKey, result, config.BufferMemoryTime);
- }
- ctx.body = { errcode: 10000, result };
- }
- export async function GetMilestoneList(ctx) {
- const param = {
- UserID: ctx.query.UserID || 0,
- OrderType: "asc",
- FieldStr: "*",
- };
- const result = {};
- const list = await miaoguo.GetUserMiaoguoTaskByUserID(param);
- if (list && list.length > 0) {
- const mileStoneArr = constantClass.GetMilestone();
- result.DayNumber = list.length;
- result.MilestoneFinished = [];
- let mIndex = 0;
- let mPosition = "";
- for (const item of list) {
- for (let j = 0; j < mileStoneArr.length; j++) {
- if (mileStoneArr[j].DayNumber == item.MilestoneDayNumber) {
- const obj = {
- ID: item.ID,
- Name: mileStoneArr[j].Name,
- DayNumber: item.MilestoneDayNumber,
- Color: mileStoneArr[j].Color1,
- Date: moment(item.CreateTime).format("YYYY.MM.DD"),
- };
- if (mileStoneArr[j].DayNumber == 1) {
- obj.Position = "center";
- } else {
- mPosition = j / 2 == Math.floor(j / 2) ? "left" : "right";
- obj.Position = mPosition + ":400rpx;";
- }
- result.MilestoneFinished.push(obj);
- mIndex = j;
- break;
- }
- }
- }
- if (result.MilestoneFinished.length > 0 && result.MilestoneFinished[result.MilestoneFinished.length - 1].Position == "right:400rpx;") {
- for (const item of result.MilestoneFinished)
- item.Position = item.Position == "left:400rpx;" ? "right:400rpx;" : "left:400rpx;";
- }
- result.MilestoneRemain = [];
- for (let j = mIndex + 1; j < mileStoneArr.length; j++) {
- const item = { ...mileStoneArr[j] };
- delete item.Color1;
- delete item.Color2;
- result.MilestoneRemain.push(item);
- }
- if (result.MilestoneFinished.length > 0 && result.MilestoneRemain.length > 0) {
- result.RemainRate = computerMilestone(list.length, result.MilestoneFinished[result.MilestoneFinished.length - 1].DayNumber, result.MilestoneRemain[0].DayNumber);
- result.RemainRateStr = Math.round(100 * result.RemainRate) + "%";
- result.MilestoneFinished.push({
- ID: list[0].ID,
- Name: result.MilestoneRemain[0].Name,
- HardworkingNumber: result.MilestoneRemain[0].DayNumber,
- Position: "right:425rpx;bottom:-23rpx;",
- });
- result.MilestoneFinished = _.orderBy(result.MilestoneFinished, ['DayNumber'], ["desc"]);
- }
- }
- ctx.body = { errcode: 10000, result };
- }
- export async function GetShareWall(ctx) {
- const param = {
- UserID: ctx.query.UserID || 0,
- PageIndex: ctx.query.PageIndex || 99999,
- OrderType: "asc",
- };
- const result = {};
- let list = await miaoguo.GetUserMiaoguoTaskByUserID(param);
- if (list && list.length > 0) {
- list = list.filter(item => item.IsShare == 1 || item.AphorismID > 0 || item.MilestoneDayNumber > 0);
- result.Total = list.length;
- result.Menu = [];
- const len = Math.ceil(list.length / 100);
- for (let i = len - 1; i >= 0; i--) {
- const obj = {
- PageIndex: i * 100,
- Name: "第" + (i * 100 + 1) + "-" + (i * 100 + 100) + "次",
- };
- if (param.PageIndex == obj.PageIndex) {
- obj.IsSelected = 1;
- } else if (param.PageIndex == 99999 && i == len - 1) {
- obj.IsSelected = 1;
- param.PageIndex = i * 100;
- }
- result.Menu.push(obj);
- }
- let index = 0;
- const mileStoneArr = constantClass.GetMilestone();
- result.List = [];
- for (let i = 0; i < list.length; i++) {
- if (i >= param.PageIndex) {
- const item = {
- ID: list[i].ID,
- CreateTime: moment(list[i].CreateTime).format("YYYY.MM.DD"),
- HardworkingNumber: list[i].HardworkingNumber,
- OrdinalPostfix: stringUtils.GetOrdinalPostfix(list[i].HardworkingNumber),
- Color2: "#4D4D4D",
- };
- if (list[i].ImageID)
- item.Image = "https://miaguo-1253256735.file.myqcloud.com/web/_share/qmjl_pic_e_" + list[i].ImageID + ".jpg";
- if (list[i].MilestoneDayNumber > 0) {
- for (const milestone of mileStoneArr) {
- if (milestone.DayNumber == list[i].MilestoneDayNumber) {
- item.Name = milestone.Name;
- item.Color2 = milestone.Color1;
- item.IsMilestone = 1;
- break;
- }
- }
- }
- result.List.push(item);
- if (++index == 100)
- break;
- }
- }
- result.List = _.orderBy(result.List, ['CreateTime'], ["desc"]);
- if (result.List.length > 0) {
- result.DateStart = moment(new Date(result.List[result.List.length - 1].CreateTime)).format("YYYY年MM月DD日");
- result.DateEnd = moment(new Date(result.List[0].CreateTime)).format("YYYY年MM月DD日");
- }
- }
- ctx.body = { errcode: 10000, result };
- }
- export async function GetShareItemInfo(ctx) {
- const param = {
- UserID: ctx.query.UserID || 0,
- TaskID: ctx.query.TaskID || 0,
- IsHistory: ctx.query.IsHistory || 0,
- IsShow: ctx.query.IsShow || 0,
- };
- if (param.TaskID == -1) {
- let isMilestone = 0;
- let list = await miaoguo.GetUserMiaoguoTask(param);
- if (list && list.length > 0) {
- param.TaskID = list[0].ID;
- if (list[0].MilestoneDayNumber > 0)
- isMilestone = 1;
- if (list[1]) {
- const param2 = {
- ID: list[0].ID,
- DayNumber: list[1].DayNumber + 1,
- };
- if (list[1].HardworkingNumber > 0) {
- param2.HardworkingNumber = list[1].HardworkingNumber + 1;
- } else {
- const param3 = {
- UserID: param.UserID,
- TaskID: -1,
- IsGetHardworkingNumber: 1,
- };
- const hwn = await miaoguo.GetUserMiaoguoTask(param3);
- if (hwn && hwn.length > 0)
- param2.HardworkingNumber = hwn[0].HardworkingNumber + 1;
- }
- await miaoguo.UpdateMiaoguoTask(param2);
- } else {
- await miaoguo.UpdateMiaoguoTask({
- ID: list[0].ID,
- DayNumber: 1,
- HardworkingNumber: 1,
- });
- }
- }
- if (!isMilestone) {
- const maxAphorismID = config.MaxAphorismID;
- const maxImageID = config.MaxImageID;
- const list2 = await miaoguo.GetUserMiaoguoTaskByAphorismIDIsNotNull(param);
- const aphorismID = [];
- const imageID = [];
- for (const item of list2) {
- aphorismID.push(item.AphorismID);
- imageID.push(item.ImageID);
- }
- const aArr = [];
- for (let i = 1; i < maxAphorismID; i++) {
- if (!aphorismID.includes(i))
- aArr.push(i);
- }
- const aID = aArr.length > 0 ? aArr[stringUtils.Random(0, aArr.length - 1)] : stringUtils.Random(1, maxAphorismID);
- const iArr = [];
- for (let i = 1; i < maxImageID; i++) {
- if (!imageID.includes(i))
- iArr.push(i);
- }
- const iID = iArr.length > 0 ? iArr[stringUtils.Random(0, iArr.length - 1)] : stringUtils.Random(1, maxImageID);
- list = await miaoguo.GetUserMiaoguoTask(param);
- if (list && list[0] && list[0].AphorismID == 0) {
- await miaoguo.UpdateMiaoguoTask({
- UserID: param.UserID,
- ID: list[0].ID,
- AphorismID: aID,
- ImageID: iID,
- });
- }
- }
- }
- let result = {};
- if (param.TaskID > 0) {
- const info = await miaoguo.GetUserMiaoguoTask(param);
- if (info && info.length > 0) {
- result = info[0];
- result.OrdinalPostfix = stringUtils.GetOrdinalPostfix(result.HardworkingNumber);
- result.CreateTimeStr1 = moment(result.CreateTime).format("YYYY.MM.DD");
- result.CreateTimeStr2 = moment(result.CreateTime).format("YYYY年MM月DD日");
- if (!param.IsHistory || param.IsHistory == "0") {
- param.CreateTime = moment(result.CreateTime).format("YYYY-MM-DD") + " 23:59:59";
- const totalData1 = await miaoguo.GetUserMiaoguoPractiseCardTotal(param);
- result.CardTaskTotal = totalData1[0].Count;
- const totalData2 = await miaoguo.GetUserMiaoguoTaskTotal(param);
- result.DurationTotal = Math.round((totalData2[0].DurationTotal || 0) / 60);
- }
- delete result.CreateTime;
- if (result.MilestoneDayNumber) {
- const mileStoneArr = constantClass.GetMilestone();
- let indexMileStone = 0;
- for (let i = 0; i < mileStoneArr.length; i++) {
- if (result.MilestoneDayNumber == mileStoneArr[i].DayNumber) {
- indexMileStone = i + 1;
- result.Name = mileStoneArr[i].Name.split("\n");
- result.Color = mileStoneArr[i].Color2;
- break;
- }
- }
- result.MilestoneImage = "https://miaguo-1253256735.file.myqcloud.com/web/_milestone/qmjl_milestone_material_" + indexMileStone + ".png";
- const arrMilestone = await miaoguo.GetMilestone();
- for (const milestone of arrMilestone) {
- if (result.MilestoneID == milestone.ID) {
- result.Content1 = result.CreateTimeStr2 + "是我家孩子用「秒过」做复习的第" + result.MilestoneDayNumber;
- result.Content2 = "天。正在勇敢挑战" + result.CardTaskTotal + "个语数外知识点,专注复习超过";
- result.Content3 = result.DurationTotal + "分钟。";
- result.Content = [];
- let str = milestone.Content;
- do {
- const str1 = str.substr(0, 28);
- result.Content.push(str1);
- str = str.substr(28);
- } while (str != "");
- delete result.AphorismID;
- delete result.ImageID;
- break;
- }
- }
- delete result.MilestoneID;
- } else {
- const arrAphorism = await miaoguo.GetAphorism();
- for (const aphorism of arrAphorism) {
- if (result.AphorismID == aphorism.ID) {
- result.Content = aphorism.Content;
- result.Paraphrase = aphorism.Paraphrase;
- result.AuthorCn = aphorism.AuthorCn;
- result.AuthorEn = aphorism.AuthorEn;
- result.Country = aphorism.Country;
- result.Title = aphorism.Title;
- result.BirthAndDeath = aphorism.BirthAndDeath;
- result.Remark = aphorism.Remark;
- result.AuthorImage = "https://miaguo-1253256735.file.myqcloud.com/web/_portrait/" + aphorism.Avatar;
- result.WordImage = "https://miaguo-1253256735.file.myqcloud.com/web/_quotes/" + aphorism.WordImage;
- delete result.MilestoneDayNumber;
- delete result.MilestoneID;
- break;
- }
- }
- if (result.ImageID)
- result.Image = "https://miaguo-1253256735.file.myqcloud.com/web/_share/qmjl_pic_b_" + result.ImageID + ".jpg";
- delete result.ImageID;
- }
- result.DurationMinute = Math.round(result.Duration / 60);
- if (result.DurationMinute == 0)
- result.DurationMinute = 1;
- result.ButtonString = param.IsShow > 0 ? "生成群接力图片" : "查看详细信息";
- delete result.Flag;
- }
- }
- ctx.body = { errcode: 10000, result };
- }
- export async function GetMiaoguoCardDeleteList2(ctx) {
- const param = ctx.request.body || {};
- param.UserID = ctx.query.UserID || "0";
- if (param.PageID && param.PageID != "0" && param.Type == "web")
- param.PageID = decryptWebID(param.PageID);
- if (!param.PageCount)
- param.PageCount = 20;
- param.PageID = Number(param.PageID);
- param.DataType = "delete";
- const listID = await miaoguo.GetCardListID(param);
- const ids = listID.map(item => item.MiaoguoCardID);
- let list = [];
- if (ids.length > 0) {
- const rows = await miaoguo.GetCardList({
- UserID: param.UserID,
- IDArr: ids.join(','),
- OrderType: "ac.UpdateTime desc,ac.CreateTime desc",
- });
- list = buildCardListFromRows(rows, [], true);
- }
- const result = {
- Count: list.length,
- List: [],
- };
- let index = 0;
- let canPush = false;
- for (const item of list) {
- if (param.PageID == 0 || item.MiaoguoCardID == param.PageID)
- canPush = true;
- if (canPush) {
- if (param.PageID == 0) {
- result.List.push(item);
- index++;
- if (index >= param.PageCount)
- break;
- } else {
- if (index > 0)
- result.List.push(item);
- index++;
- if (index > param.PageCount)
- break;
- }
- }
- }
- if (param.Type == "web") {
- result.List = result.List.map(item => ({
- ...item,
- MiaoguoCardID: encryptWebID(item.MiaoguoCardID),
- }));
- }
- ctx.body = { errcode: 10000, result };
- }
- export async function DeleteMiaoguoCardWeb(ctx) {
- const param = ctx.request.body || {};
- if (param.VisitType && decryptWebID(param.VisitType) == "web") {
- if (stringUtils.IsArray(param.ID)) {
- param.MiaoguoCardID = decryptWebIDList(param.ID).join(",");
- param.IDArr = true;
- } else {
- param.MiaoguoCardID = decryptWebID(param.ID);
- }
- delete param.VisitType;
- delete param.ID;
- if (param.IsRecover == "true") {
- param.Flag = 0;
- delete param.IsRecover;
- param.DeleteTime = null;
- } else {
- param.Flag = -1;
- param.DeleteTime = moment().format("YYYY-MM-DD HH:mm:ss");
- }
- }
- param.UserID = ctx.query.UserID;
- param.UpdateTime = moment().format("YYYY-MM-DD HH:mm:ss");
- await miaoguo.UpdateCard(param);
- miaoguo.AddMiaoguoLog({
- UserID: ctx.query.UserID,
- LogID: String(param.MiaoguoCardID || '').indexOf(",") >= 0 ? 305 : 299,
- Content: JSON.stringify(param),
- }).catch(err => console.error('AddMiaoguoLog failed:', err));
- globalCache.delete("GetMiaoguoCard###UserID=" + param.UserID);
- ctx.body = { errcode: 10000 };
- }
- async function uploadMiaoguoFile(filename, filepath) {
- const cos = new COS(config.QCloud);
- const params = {
- Bucket: 'miaguo-1253256735',
- Region: 'ap-guangzhou',
- Key: filename,
- Body: fs.createReadStream(filepath),
- ContentLength: fs.statSync(filepath).size,
- };
- return new Promise((resolve, reject) => {
- cos.putObject(params, (err, data) => {
- if (err) {
- reject(err);
- } else {
- fsPromises.unlink(filepath).then(() => resolve(data)).catch(reject);
- }
- });
- });
- }
- export async function ExportFileWeb(ctx) {
- const param = ctx.request.body || {};
- if (!param.ID || param.ID.length > 30) {
- ctx.body = { errcode: 1004, errMsg: "上传数据过多!" };
- return;
- }
- param.CardID = decryptWebIDList(param.ID).join(",");
- delete param.ID;
- await miaoguo.UpdateCardExportShare(param);
- param.UserID = ctx.query.UserID;
- const insertResult = await miaoguo.InsertExport(param);
- const exportID = insertResult.insertId;
- const content = encryptWebID(stringUtils.Random(10000, 99999) + "_" + exportID.toString());
- const filename = param.Title + "_" + moment().format("YYYYMMDDHHmmss") + ".mg";
- const dir = "./public/images/print";
- await fsPromises.mkdir(dir, { recursive: true });
- const filepath = path.join(dir, filename);
- await fsPromises.writeFile(filepath, content);
- await uploadMiaoguoFile(filename, filepath);
- miaoguo.AddMiaoguoLog({
- UserID: ctx.query.UserID,
- LogID: 306,
- Content: JSON.stringify({ ...param, ExportID: exportID }),
- }).catch(err => console.error('AddMiaoguoLog failed:', err));
- ctx.body = "https://miaguo-1253256735.file.myqcloud.com/" + decodeURI(filename);
- }
- async function importExportData(exportInfo, userIDTarget) {
- const folderResult = await miaoguo.AddFolderInfo({
- UserID: userIDTarget,
- Name: exportInfo.Title,
- ColorName: "#6B727C",
- IconName: "cardlist_folder_white_66x60",
- UpdateTime: moment().format("YYYY-MM-DD HH:mm:ss"),
- ExportID: exportInfo.ID,
- Flag: 0,
- });
- const folderID = folderResult.insertId;
- const cardIDs = String(exportInfo.CardID || '').split(',').filter(Boolean);
- for (const sourceCardID of cardIDs) {
- const card = {
- UserID: userIDTarget,
- CardType: -1,
- CreateSource: "web",
- CreateTime: moment().format('YYYY-MM-DD HH:mm:ss'),
- LimitTime: moment().format('YYYY-MM-DD HH:mm:ss'),
- UpdateTime: moment().format('YYYY-MM-DD HH:mm:ss'),
- SourceCardID: sourceCardID,
- FolderID: folderID,
- };
- const insertInfo = await miaoguo.AddCard(card);
- const listContent = await miaoguo.GetCardContentList(sourceCardID);
- for (const content of listContent) {
- await miaoguo.AddCardContent({
- MiaoguoCardID: insertInfo.insertId,
- ContentType: content.ContentType,
- Content: content.Content,
- });
- }
- }
- }
- export async function ImportFileWeb(ctx) {
- const file = ctx.file;
- const cleanup = async () => {
- if (file && file.path && fs.existsSync(file.path))
- await fsPromises.unlink(file.path);
- };
- if (!file || !file.originalname) {
- ctx.body = { errcode: 1002, errMsg: "文件上传错误!" };
- return;
- }
- if (file.originalname.indexOf(".mg") <= 0) {
- await cleanup();
- ctx.body = { errcode: 1001, errMsg: "格式不对!" };
- return;
- }
- if (!ctx.query.UserID) {
- await cleanup();
- ctx.body = { errcode: 1002, errMsg: "文件上传错误!" };
- return;
- }
- const userInfo = await miaoguo.GetUsersInfoByUserID({ UserID: ctx.query.UserID });
- if (!userInfo || userInfo.length == 0 || moment(userInfo[0].ProductServiceTime).format("YYYYMMDDHHmmss") <= moment().format("YYYYMMDDHHmmss")) {
- await cleanup();
- ctx.body = { errcode: 1002, errMsg: "文件上传错误!" };
- return;
- }
- try {
- const data = await fsPromises.readFile(file.path);
- const firstLine = data.toString().split("\n")[0];
- let id = decryptWebID(firstLine);
- id = id.substr(id.indexOf("_") + 1);
- const exportInfo = await miaoguo.GetMiaoguoExport({ ID: id });
- if (!exportInfo || exportInfo.length == 0)
- throw new Error("export not found");
- await importExportData(exportInfo[0], ctx.query.UserID);
- globalCache.delete("GetMiaoguoCard###UserID=" + ctx.query.UserID);
- miaoguo.AddMiaoguoLog({
- UserID: ctx.query.UserID,
- LogID: 318,
- Content: JSON.stringify(exportInfo[0]),
- }).catch(err => console.error('AddMiaoguoLog failed:', err));
- ctx.body = { errcode: 10000 };
- } catch (err) {
- ctx.body = { errcode: 1003, result: "文件内容错误!" };
- } finally {
- await cleanup();
- }
- }
- export async function UpdateMiaoguoCardWebType(ctx) {
- const param = ctx.request.body || {};
- if (param.CardType) {
- const cardIDs = decryptWebIDList(param.List);
- const param2 = {
- CardType: param.CardType,
- UserID: ctx.query.UserID,
- MiaoguoCardID: cardIDs.join(","),
- };
- await miaoguo.UpdateCardType(param2);
- if (param.LimitTimeList) {
- for (let i = 0; i < cardIDs.length; i++) {
- await miaoguo.UpdateCard({
- MiaoguoCardID: cardIDs[i],
- LimitTime: param.LimitTimeList[i],
- });
- }
- }
- miaoguo.AddMiaoguoLog({
- UserID: ctx.query.UserID,
- LogID: param.LimitTimeList ? 307 : (param.CardType == -1 || param.CardType == "-1" ? 301 : 300),
- Content: JSON.stringify({ ...param, List: cardIDs }),
- }).catch(err => console.error('AddMiaoguoLog failed:', err));
- }
- globalCache.delete("GetMiaoguoCard###UserID=" + ctx.query.UserID);
- ctx.body = { errcode: 10000 };
- }
- export async function UpdateUserTagInfo(ctx) {
- const param = ctx.request.body || {};
- const param2 = {
- UserID: ctx.query.UserID || 0,
- };
- if (param.CommonTags)
- param2.CommonTags = param.CommonTags;
- if (param.CommonSymbol)
- param2.CommonSymbol = param.CommonSymbol;
- await miaoguo.UpdateUsersByUserID(param2);
- ctx.body = { errcode: 10000 };
- }
- export async function UpdateFolderInfoWeb(ctx) {
- const param = ctx.request.body || {};
- const folderParam = {
- UserID: ctx.query.UserID || 0,
- ID: param.FolderID || 0,
- Name: param.Name || "",
- Flag: param.Flag || 0,
- UpdateTime: moment().format("YYYY-MM-DD HH:mm:ss"),
- };
- if (folderParam.ID > 0) {
- if (folderParam.Flag == -1)
- delete folderParam.Name;
- await miaoguo.UpdateFolderInfo(folderParam);
- if (folderParam.Flag == -1) {
- await miaoguo.UpdateFolderList({
- UserID: folderParam.UserID,
- FolderOldID: folderParam.ID,
- FolderID: 0,
- });
- globalCache.delete("GetMiaoguoCard###UserID=" + ctx.query.UserID);
- }
- miaoguo.AddMiaoguoLog({
- UserID: ctx.query.UserID,
- LogID: 310,
- Content: JSON.stringify(folderParam),
- }).catch(err => console.error('AddMiaoguoLog failed:', err));
- } else {
- delete folderParam.ID;
- await miaoguo.AddFolderInfo(folderParam);
- miaoguo.AddMiaoguoLog({
- UserID: ctx.query.UserID,
- LogID: 309,
- Content: JSON.stringify(folderParam),
- }).catch(err => console.error('AddMiaoguoLog failed:', err));
- }
- globalCache.delete("GetUserFolderList?UserID=" + folderParam.UserID);
- ctx.body = { errcode: 10000 };
- }
- export async function UpdateFolderList(ctx) {
- const param = ctx.request.body || {};
- param.UserID = ctx.query.UserID || 0;
- param.CardID = decryptWebIDList(param.CardID).join(",");
- const updateTimeParam = {
- UpdateTime: moment().format("YYYY-MM-DD HH:mm:ss"),
- UserID: param.UserID,
- };
- if (param.FolderID > 0) {
- updateTimeParam.ID = param.FolderID;
- await miaoguo.UpdateFolderInfo(updateTimeParam);
- } else {
- updateTimeParam.CardID = param.CardID;
- await miaoguo.UpdateFolderInfo(updateTimeParam);
- }
- if (!param.FolderID)
- param.FolderID = 0;
- await miaoguo.UpdateFolderList(param);
- globalCache.delete("GetUserFolderList?UserID=" + param.UserID);
- globalCache.delete("GetMiaoguoCard###UserID=" + ctx.query.UserID);
- miaoguo.AddMiaoguoLog({
- UserID: ctx.query.UserID,
- LogID: 303,
- Content: JSON.stringify(param),
- }).catch(err => console.error('AddMiaoguoLog failed:', err));
- ctx.body = { errcode: 10000 };
- }
- export async function UpdateCollectList(ctx) {
- const param = ctx.request.body || {};
- param.UserID = ctx.query.UserID || 0;
- param.CardID = decryptWebIDList(param.CardID).join(",");
- if (!param.IsCollect)
- param.IsCollect = 0;
- await miaoguo.UpdateCollectList(param);
- globalCache.delete("GetUserFolderList?UserID=" + param.UserID);
- globalCache.delete("GetMiaoguoCard###UserID=" + ctx.query.UserID);
- miaoguo.AddMiaoguoLog({
- UserID: ctx.query.UserID,
- LogID: 302,
- Content: JSON.stringify(param),
- }).catch(err => console.error('AddMiaoguoLog failed:', err));
- ctx.body = { errcode: 10000 };
- }
- export async function ResetUserCard(ctx) {
- const param = ctx.request.body || {};
- if (param.List) {
- const cardIDs = decryptWebIDList(param.List);
- await miaoguo.ResetCard({
- UserID: ctx.query.UserID,
- MiaoguoCardID: cardIDs.join(","),
- CardType: param.CardType,
- });
- miaoguo.AddMiaoguoLog({
- UserID: ctx.query.UserID,
- LogID: 371,
- Content: JSON.stringify({ ...param, List: cardIDs }),
- }).catch(err => console.error('AddMiaoguoLog failed:', err));
- }
- globalCache.delete("GetMiaoguoCard###UserID=" + ctx.query.UserID);
- ctx.body = { errcode: 10000 };
- }
- export async function ImportExcelData(ctx) {
- const param = ctx.request.body || {};
- param.UserID = ctx.query.UserID || "0";
- const folder = {
- UserID: param.UserID,
- Name: "D" + moment().format("HHmmss_YYYYMMDD"),
- ColorName: "#6B727C",
- IconName: "cardlist_folder_white_66x60",
- UpdateTime: moment().format("YYYY-MM-DD HH:mm:ss"),
- ExportID: 0,
- Flag: 0,
- };
- const insertFolder = await miaoguo.AddFolderInfo(folder);
- const list = JSON.parse(param.DataList);
- for (const item of list) {
- const time = moment().format('YYYY-MM-DD HH:mm:ss');
- const insertInfo = await miaoguo.AddCard({
- UserID: param.UserID,
- CardType: -1,
- CreateSource: "web",
- CreateTime: time,
- LimitTime: time,
- UpdateTime: time,
- FolderID: insertFolder.insertId,
- });
- const cardID = insertInfo.insertId;
- await miaoguo.AddCardContent({ MiaoguoCardID: cardID, ContentType: 0, Content: "" });
- await miaoguo.AddCardContent({
- MiaoguoCardID: cardID,
- ContentType: 1,
- Content: stringUtils.ReplaceAllString(item.Question || "", "'", "ˈ"),
- });
- await miaoguo.AddCardContent({
- MiaoguoCardID: cardID,
- ContentType: 2,
- Content: stringUtils.ReplaceAllString(item.Answer || "", "'", "ˈ"),
- });
- await miaoguo.AddCardContent({ MiaoguoCardID: cardID, ContentType: 3, Content: "" });
- }
- globalCache.delete("GetMiaoguoCard###UserID=" + ctx.query.UserID);
- miaoguo.AddMiaoguoLog({
- UserID: ctx.query.UserID,
- LogID: 453,
- Content: JSON.stringify(param.List),
- }).catch(err => console.error('AddMiaoguoLog failed:', err));
- ctx.body = { errcode: 10000 };
- }
- export async function GetAccreditInfo2(ctx) {
- const param = {
- Type: ctx.query.Type || 0,
- };
- const result = {};
- result.Remind = "为安全运作,本功能不能没有用户名字和头像。请补全资料,并尽量与您的微信名字和头像保持一致。点击项目可直接填充微信信息。";
- if (param.Type == 0) {
- result.Text1 = "编辑用户信息";
- result.Text2 = "";
- result.Text3 = "您的头像、名字请尽量与微信保持一致,这对一部分功能的安全运行非常重要。同时,这也大大方便客服为您处理新手班、排除故障、帐户、活动奖励发放等需要微信联系的重要事宜。";
- result.Text4 = "返回";
- } else if (param.Type == "binding") {
- result.Text1 = "请先核对用户信息";
- result.Text2 = "使用「帐号绑定」之前,请先核对头像、名字是否与您的微信保持一致,这对本功能安全运行非常重要。这也大大方便客服在您遇到故障或数据问题时在微信中联络到您,即时了解情况,减少您的损失。\n\n如信息不一致,点击对应项目即可直接填充微信头像或名字,无须手动输入。确认后点「下一步」继续。";
- result.Text3 = "";
- result.Text4 = "下一步";
- } else if (param.Type == "family") {
- result.Text1 = "请先核对用户信息";
- result.Text2 = "使用「家庭用户」之前,请先核对头像、名字是否与您的微信保持一致,这对本功能安全运行非常重要。这也大大方便客服在您遇到故障或数据问题时在微信中联络到您,即时了解情况,减少您的损失。\n\n如信息不一致,点击对应项目即可直接填充微信头像或名字,无须手动输入。确认后点「下一步」继续。";
- result.Text3 = "";
- result.Text4 = "下一步";
- }
- ctx.body = { errcode: 10000, result };
- }
- export async function GetAccreditInfo(ctx) {
- const param = {
- Type: ctx.query.Type || 0,
- };
- const result = {};
- if (param.Type == 0) {
- result.Text1 = "请允许秒过";
- result.Text2 = "获得您的头像、昵称\n用于注册登录";
- result.Text3 = "非常抱歉,不填写名字会造成后续服务无法进行,如要继续使用秒过,烦劳提供名字。由于微信隐私保护,秒过不能直接获得您的信息,这会造成培训、客服、统计、社群、官网等服务无法运行。此信息仅用于秒过,请放心。";
- } else {
- result.Text1 = "用微信注册秒过";
- result.Text2 = "请允许秒过\n获得您的微信头像、昵称";
- result.Text3 = "非常抱歉,不填写名字会造成后续服务无法进行,如要继续使用秒过,烦劳提供名字。由于微信隐私保护,秒过不能直接获得您的信息,这会造成培训、客服、统计、社群、官网等服务无法运行。此信息仅用于秒过,请放心。";
- }
- result.Btn1 = "允许";
- result.Btn2 = "忽略";
- ctx.body = { errcode: 10000, result };
- }
- export async function GetMiaoguoLesson2(ctx) {
- const arr = constantClass.getLessonList();
- ctx.body = { errcode: 10000, result: arr };
- }
- export async function GetMiaoguoNewUserImageList(ctx) {
- const result = constantClass.getNewUserImageList();
- ctx.body = { errcode: 10000, result };
- }
- export async function GetMiaoguoNewUserImageList3126(ctx) {
- const result = constantClass.getNewUserImageList3136();
- ctx.body = { errcode: 10000, result };
- }
- export async function GetMiaoguoTipsList(ctx) {
- const param = {
- Version: ctx.query.version || "?v=8",
- };
- const result = constantClass.GetMiaoguoTipsList();
- for (const section of result) {
- for (const item of section.List) {
- item.Cover = item.Cover + param.Version;
- for (let i = 0; i < item.Images.length; i++)
- item.Images[i] = item.Images[i] + param.Version;
- }
- }
- ctx.body = { errcode: 10000, result };
- }
- export async function UpdateUserNickNameAndAvatar(ctx) {
- const param = ctx.request.body;
- param.UserID = ctx.query.UserID;
- if (!param.NickName)
- param.NickName = "陌生用户";
- await miaoguo.UpdateUsersByUserID(param);
- const log = {
- UserID: param.UserID,
- LogID: 315,
- Content: JSON.stringify(param),
- };
- miaoguo.AddMiaoguoLog(log).catch(err => console.error('AddMiaoguoLog failed:', err));
- ctx.body = { errcode: 10000 };
- }
- export async function UpdateUserMemberInfoPost(ctx) {
- const param = ctx.request.body;
- param.UserID = ctx.query.UserID || "0";
- param.FieldType = ctx.query.FieldType || 0;
- if (param.FieldType == 1)
- param.NickNameRemark = param.Content;
- else if (param.FieldType == 2)
- param.IsMessage = param.Content;
- else if (param.FieldType == 3)
- param.MessageTime = param.Content;
- if (param.FieldType) {
- delete param.Content;
- delete param.FieldType;
- await miaoguo.UpdateUsersByUserID(param);
- }
- ctx.body = { errcode: 10000 };
- }
- export async function UpdateUserMemberInfo(ctx) {
- const param = {
- UserID: ctx.query.UserID || 0,
- WSUUserID: ctx.query.WSUUserID || 0,
- IsTryOut: ctx.query.IsTryOut,
- IsMember: ctx.query.IsMember,
- ClassID: ctx.query.ClassID || 0,
- GroupID: ctx.query.GroupID || 3,
- NickNameRemark: ctx.query.NickNameRemark,
- };
- let canUpdate = true;
- if (ctx.query.NickNameRemark && ctx.query.UserID) {
- delete param.WSUUserID;
- delete param.IsMember;
- delete param.ClassID;
- delete param.GroupID;
- delete param.IsTryOut;
- await miaoguo.UpdateUsersByUserID(param);
- } else if (ctx.query.GroupID && ctx.query.UserID) {
- delete param.WSUUserID;
- delete param.IsMember;
- delete param.ClassID;
- delete param.NickNameRemark;
- delete param.IsTryOut;
- await miaoguo.UpdateUsersByUserID(param);
- } else if (ctx.query.IsTryOut && ctx.query.UserID) {
- delete param.WSUUserID;
- delete param.IsMember;
- delete param.GroupID;
- delete param.NickNameRemark;
- if (param.IsTryOut == -1)
- param.IsTryOut = 0;
- const userInfo = await miaoguo.GetUsersInfoByUserID(param);
- param.ClassID = userInfo[0].ClassID;
- const classList = await miaoguo.GetClassList(param);
- param.ProductServiceTime = moment(classList[0].StartDate).add(classList[0].DayNumber - 1, 'days').format('YYYY-MM-DD 23:59:59');
- delete param.Sort;
- await miaoguo.UpdateUsersByUserID(param);
- } else if (ctx.query.ParentUserID) {
- delete param.GroupID;
- delete param.IsMember;
- delete param.ClassID;
- delete param.NickNameRemark;
- delete param.IsTryOut;
- param.ParentUserID = ctx.query.ParentUserID;
- if (param.UserID != param.ParentUserID) {
- const users = await miaoguo.GetUserBindingList({ UserID: ctx.query.ParentUserID || 0 });
- if (users && users.length > 0)
- canUpdate = false;
- if (canUpdate) {
- delete param.WSUUserID;
- await miaoguo.UpdateUsersByUserID(param);
- }
- }
- } else {
- delete param.NickNameRemark;
- delete param.IsTryOut;
- if (param.IsMember === undefined)
- delete param.IsMember;
- delete param.WSUUserID;
- await miaoguo.UpdateUsersByUserID(param);
- }
- const log = {
- UserID: ctx.query.UserID,
- LogID: 315,
- Content: JSON.stringify(param),
- };
- miaoguo.AddMiaoguoLog(log).catch(err => console.error('AddMiaoguoLog failed:', err));
- ctx.body = { errcode: 10000 };
- }
- export async function GetUserBindingList(ctx) {
- const param = {
- UserID: ctx.query.UserID || 0,
- };
- const userInfo = await miaoguo.GetUserBindingList(param);
- ctx.body = { errcode: 10000, result: userInfo };
- }
- export async function UpdateUserBinding(ctx) {
- const param = {
- ParentUserID: ctx.query.ParentUserID || 0,
- };
- await miaoguo.UpdateUserBinding(param);
- const log = {
- UserID: ctx.query.ParentUserID,
- LogID: 319,
- Content: JSON.stringify(param),
- };
- miaoguo.AddMiaoguoLog(log).catch(err => console.error('AddMiaoguoLog failed:', err));
- ctx.body = { errcode: 10000 };
- }
- export async function GetMiaoguoWXUserInfo(ctx) {
- const param = {
- UserID: ctx.query.UserID || 0,
- FieldStr: ctx.query.FieldStr,
- GetWechatUserID: ctx.query.GetWechatUserID || 0,
- };
- const userInfo = await miaoguo.GetUsersInfoByUserID(param);
- if (param.GetWechatUserID == 1) {
- const wechatUserInfo = await miaoguo.GetWechatServiceInfoByMGUserID(param);
- if (wechatUserInfo && wechatUserInfo.length > 0)
- userInfo[0].WechatUserID = wechatUserInfo[0].WechatUserID;
- }
- const item = userInfo[0];
- if (item && item.IsPromoter > 0) {
- const a = moment(item.PromotionLimitTime);
- const b = moment();
- item.PromotionLimitDays = a.diff(b, 'days');
- item.PromotionLimitTime = moment(item.PromotionLimitTime).format('YYYY.MM.DD');
- item.WXServiceCharge = config.WXServiceCharge;
- item.IndividualIncomeTax = config.IndividualIncomeTax;
- if (!item.PayeeWechatAccount)
- item.PayeeWechatAccount = item.NickName;
- if (!item.WXAccount)
- item.WXAccount = item.NickName;
- if (!item.RealName)
- item.RealName = "";
- if (item.Introducer) {
- const userInfo2 = await miaoguo.GetUsersInfoByUserID({ UserID: item.Introducer, FieldStr: "NickName,AvatarUrl" });
- item.IntroducerNickName = userInfo2[0].NickName;
- item.IntroducerAvatarUrl = userInfo2[0].AvatarUrl;
- }
- }
- if (item) {
- delete item.OpenID;
- delete item.UnionID;
- delete item.Flag;
- }
- ctx.body = { errcode: 10000, result: item };
- }
- export async function GetUserCardCount(ctx) {
- const param = {
- UserID: ctx.query.UserID || 0,
- CardType: ctx.query.CardType || 2,
- IsCollect: ctx.query.IsCollect || 0,
- OrderType: ctx.query.OrderType || 0,
- HasHardworking: ctx.query.HasHardworking || 0,
- };
- if (param.UserID == "undefined")
- param.UserID = 0;
- if (param.CardType == "undefined")
- param.CardType = 2;
- if (param.IsCollect == "undefined")
- param.IsCollect = 0;
- const cardNumber = await miaoguo.GetCardCount(param);
- const result = {
- CardNumber: cardNumber[0].count,
- };
- if (param.CardType == 2) {
- param.CardType = 0;
- const cardNormalNumber = await miaoguo.GetCardCount(param);
- result.NormalNumber = cardNormalNumber[0].count;
- param.CardType = 1;
- const cardUrgentNumber = await miaoguo.GetCardCount(param);
- result.UrgentNumber = cardUrgentNumber[0].count;
- if (param.OrderType == 5 || param.OrderType == 6)
- result.CardNumber = result.NormalNumber + result.UrgentNumber;
- }
- if (param.HasHardworking == 1) {
- const param2 = {
- FieldStr: "ID,CreateTime,IsShare,HardworkingNumber,MilestoneDayNumber,MilestoneID,AphorismID,ImageID",
- UserID: param.UserID,
- OrderType: " desc limit 1",
- WhereStr: " and (MilestoneDayNumber>0 or AphorismID>0) ",
- };
- const list = await miaoguo.GetUserMiaoguoTaskByUserID(param2);
- if (list && list.length > 0) {
- const item = list[0];
- delete item.CreateTime;
- item.OrdinalPostfix = stringUtils.GetOrdinalPostfix(item.HardworkingNumber);
- if (item.MilestoneDayNumber > 0) {
- const mileStoneArr = constantClass.GetMilestone();
- for (const milestone of mileStoneArr) {
- if (milestone.DayNumber == item.MilestoneDayNumber) {
- item.Name = milestone.Name;
- item.BgColor = milestone.Color2;
- item.IsMilestone = 1;
- break;
- }
- }
- } else {
- item.Image = "https://miaguo-1253256735.file.myqcloud.com/web/_share/qmjl_pic_d_" + item.ImageID + ".jpg";
- }
- result.Hardworking = item;
- }
- }
- ctx.body = { errcode: 10000, result };
- }
- export async function GetMiaoguoLearningRecord(ctx) {
- const param = {
- CardID: ctx.query.CardID || 0,
- };
- const list = await miaoguo.GetMiaoguoLearningRecord(param);
- let total = 0;
- for (const item of list) {
- item.CreateTime = moment(item.CreateTime).format('YYYY年MM月DD日 HH:mm');
- total += item.Duration;
- item.Duration = stringUtils.getMinuteSecond(item.Duration, true, true);
- if (item.Duration && item.Duration.indexOf("分") > 0)
- item.Duration = item.Duration.replace("分", "分钟");
- }
- const result = {};
- result.Total = stringUtils.getMinuteSecond(total, true, true);
- if (result.Total && result.Total.indexOf("分") > 0)
- result.Total = result.Total.replace("分", "分钟");
- result.List = list;
- ctx.body = { errcode: 10000, result };
- }
- export async function SendMiaoguoCoupon(ctx) {
- const param = {
- UserID: Number(ctx.query.UserID) || 0,
- CouponType: ctx.query.CouponType,
- LimitTime: ctx.query.LimitTime,
- IsUse: 0,
- Flag: 0,
- };
- param.LimitTime = param.LimitTime.replace("年", "-");
- param.LimitTime = param.LimitTime.replace("月", "-");
- param.LimitTime = param.LimitTime.replace("日", "");
- param.LimitTime = moment(param.LimitTime).format("YYYY-MM-DD 23:59:59");
- const list = await miaoguo.GetMiaoguoCoupon(param);
- if (!list || list.length == 0) {
- if (param.CouponType == 134)
- param.CouponNumber = 20;
- await miaoguo.AddMiaoguoCoupon(param);
- }
- ctx.body = { errcode: 10000 };
- }
- export async function UseMiaoguoCoupon(ctx) {
- const param = {
- UserID: ctx.query.UserID || 0,
- CouponType: ctx.query.CouponType || 0,
- CouponNumber: ctx.query.CouponNumber || 0,
- IsUse: 1,
- };
- await miaoguo.UpdateMiaoguoCoupon(param);
- param.CouponNumber = parseInt(param.CouponNumber);
- if (param.CouponNumber > 0) {
- const userList = await miaoguo.GetUsersInfoByUserID(param);
- if (userList && userList.length > 0) {
- const param2 = {
- UserID: param.UserID,
- ProductServiceTime: moment(userList[0].ProductServiceTime).add(param.CouponNumber, "days").format('YYYY-MM-DD 23:59:59'),
- };
- await miaoguo.UpdateUsersByUserID(param2);
- }
- }
- ctx.body = { errcode: 10000 };
- }
- export async function ShareMiaoguoTask(ctx) {
- const param = {
- UserID: ctx.query.UserID || 0,
- CreateTime: ctx.query.CreateTime + " 00:00:00",
- IsShare: 1,
- };
- if (!param.CreateTime || param.CreateTime == "Invalid date 00:00:00" || param.CreateTime < moment().add(-7, "days").format('YYYY-MM-DD 00:00:00'))
- param.CreateTime = moment().format('YYYY-MM-DD 00:00:00');
- await miaoguo.UpdateMiaoguoTask(param);
- ctx.body = { errcode: 10000 };
- }
- export async function GetIntroducerUserList(ctx) {
- const param = {
- UserID: ctx.query.UserID || 0,
- };
- param.type = "web";
- const list0 = await miaoguo.GetIntroducerUserList(param);
- for (const item of list0) {
- if (item.NickName && item.NickName.length > 5)
- item.NickName = item.NickName.substr(0, 5) + "...";
- else if (item.NickName === "陌生用户")
- item.NickName = "用户未授权";
- if (item.NickName == "用户未授权" && item.NickName != "陌生用户") {
- item.AvatarUrl = item.AvatarUrl2;
- item.NickName = item.NickName2;
- }
- if (item.AvatarUrl === "../images/universalpic_face_default_blue_120x120.png")
- item.AvatarUrl = "../images/universalpic_face_default_gray_114x114.png";
- else if (item.AvatarUrl && item.AvatarUrl.indexOf("/132"))
- item.AvatarUrl = item.AvatarUrl.replace("/132", "/46");
- }
- delete param.type;
- const list = await miaoguo.GetIntroducerUserList(param);
- for (const item of list) {
- if (item.NickName && item.NickName.length > 5)
- item.NickName = item.NickName.substr(0, 5) + "...";
- else if (item.NickName === "陌生用户")
- item.NickName = "用户未授权";
- if (item.AvatarUrl === "../images/universalpic_face_default_blue_120x120.png")
- item.AvatarUrl = "../images/universalpic_face_default_gray_114x114.png";
- else if (item.AvatarUrl && item.AvatarUrl.indexOf("/132"))
- item.AvatarUrl = item.AvatarUrl.replace("/132", "/46");
- item.ProductServiceTime = moment(item.ProductServiceTime).format('YYYY-MM-DD HH:mm:ss');
- if (item.PayTime)
- item.PayTime = moment(item.PayTime).format('YYYY-MM-DD HH:mm:ss');
- else
- item.PayTime = "1900-01-01 00:00:00";
- }
- ctx.body = { errcode: 10000, result: { List1: list0, List2: list } };
- }
- export async function GetMiaoguoShareInfo220(ctx) {
- const param = {
- ProgramID: 166,
- Version: ctx.query.Version,
- };
- const result = [{}];
- result[0].Text1 = "推广物料";
- result[0].Text2 = "转发小程序";
- result[0].Text3 = "成效最佳的方法\n转发含有推广码的小程序到群或朋友";
- result[0].BtnStr = "转发";
- result[0].OpenType = "share";
- result[0].BindTap = "";
- const versionList = await commonModel.GetProductVersionList(param);
- if (versionList && versionList[0] && versionList[0].IsShowPay > 0) {
- result.push({});
- result[1].Text1 = "推广物料";
- result[1].Text2 = "勤勉接力图片";
- result[1].Text3 = "接力图片自带推广二维码\n图片内容丰富,形式生动,非常适合朋友圈\n一方面让关心您的朋友一起见证孩子的努力\n另一方面潜移默化顺带推广";
- result[1].Image = "promotion_materials_qmjl.png?0";
- result[1].BtnStr = "前往勤勉接力栏目生成图片";
- result[1].BindTap = "gotoShareIndex";
- result.push({});
- result[2].Text1 = "推广物料";
- result[2].Text2 = "海报图片";
- result[2].Text3 = "点击效果图,生成含有推广码的海报\n长按图片保存到手机相册";
- result[2].Images = [{ icon: "promotion_materials_hb01.png?0", id: "1" }, { icon: "promotion_materials_hb04.png?0", id: "4" }, { icon: "promotion_materials_hb02.png?0", id: "2" }, { icon: "promotion_materials_hb03.png?0", id: "3" }];
- result.push({});
- result[3].Text1 = "推广物料";
- result[3].Text2 = "配图文案";
- result[3].Text3 = "复制秒过介绍文案\n可自行编辑加工(内含网页链接)";
- result[3].BtnStr = "复制文案";
- result[3].OpenType = "";
- result[3].BindTap = "buildText";
- result.push({});
- result[4].Text1 = "推广物料";
- result[4].Text2 = "网页链接";
- result[4].Text3 = "发布含有推广码的网页\n点击「复制链接」,然后粘贴到文字中";
- result[4].BtnStr = "复制链接";
- result[4].OpenType = "";
- result[4].BindTap = "buildUrl";
- }
- ctx.body = { errcode: 10000, result };
- }
- export async function GetMiaoguoShareInfo(ctx) {
- const param = {
- ProgramID: 166,
- Version: ctx.query.Version,
- };
- const result = [{}];
- result[0].Text2 = "转发小程序";
- result[0].Text3 = "转发含有推荐人信息的小程序";
- result[0].BtnStr = "转发";
- result[0].OpenType = "share";
- result[0].BindTap = "";
- const versionList = await commonModel.GetProductVersionList(param);
- if (versionList && versionList[0] && versionList[0].IsShowPay > 0) {
- result[0].Text1 = "方法一";
- result.push({});
- result[1].Text1 = "方法二";
- result[1].Text2 = "发到朋友圈";
- result[1].Text3 = "发布含有推荐人信息的图片";
- result[1].Text4 = "存图步骤";
- result[1].Text5 = "点击生成图片\n长按图片保存到手机相册";
- result[1].BtnStr = "生成专门图片";
- result[1].OpenType = "";
- result[1].BindTap = "buildImage";
- }
- ctx.body = { errcode: 10000, result };
- }
- export async function BuildData(ctx) {
- const param = {
- Type: ctx.query.Type || 1,
- TypeDetail: ctx.query.TypeDetail || 1,
- };
- const result = [];
- const sleep = milliseconds => new Promise(resolve => setTimeout(resolve, milliseconds));
- const sendTemplateMessage = async (userID, templateID, paramStr, useProduction = false) => {
- const baseURL = useProduction ? 'https://www.kylx365.com' : 'http://localhost:' + config.port;
- await axios.get(baseURL + '/api/SendWXServiceTemplateMessage', {
- params: { UserID: userID, TemplateID: templateID, ...(paramStr ? { ParamStr: paramStr } : {}) },
- });
- };
- if (param.Type == 1) {
- const sql = "select u.UserID,u.NickName,count(distinct DATE_FORMAT(r.CreateTime,'%Y%m%d')) as '天数',sum(r.Duration)/60 as '使用分钟数' " +
- "from MiaoguoWXUsers u " +
- "inner join MiaoguoCard c on u.UserID=c.UserID " +
- "inner join MiaoguoLearningRecord r on c.MiaoguoCardID = r.CardID " +
- "where r.Flag=0 and r.CreateTime>='2019-07-01' and r.CreateTime<'2019-09-01' " +
- "group by u.UserID having 天数>=5 order by 天数 desc;";
- const list = await miaoguo.RunSql([], sql);
- const limitTime = moment().add(6, "months").format("YYYY-MM-DD");
- for (const item of list) {
- let day = 0;
- if (item.天数 >= 50) day = 30;
- else if (item.天数 >= 40) day = 20;
- else if (item.天数 >= 30) day = 15;
- else if (item.天数 >= 20) day = 10;
- else if (item.天数 >= 10) day = 5;
- else if (item.天数 >= 5) day = 2;
- const insertSql = "insert into MiaoguoCoupon (CouponType,UserID,LimitTime,IsUse,CouponNumber) values (136," + item.UserID + ",'" + limitTime + "',0," + day + ");";
- result.push(insertSql);
- }
- } else if (param.Type == 2) {
- const list = await miaoguo.RunSql([], 'select UserID from MiaoguoWXUsers where IsPay=1 and ClassID=4;');
- for (const item of list) {
- const response = await axios.get('http://localhost:' + config.port + '/api/GetMiaoguoCheckList', {
- params: { UserID: item.UserID },
- }).then(res => res.data);
- const checklist = response.result;
- let day = 0;
- for (let i = 1; i < checklist.List.length; i++) {
- if (checklist.List[i].Max <= checklist.List[i].Finished) day += 2;
- }
- await miaoguo.RunSql([
- checklist.UserID,
- moment().add(6, 'months').format('YYYY-MM-DD'),
- day,
- ], 'insert into MiaoguoCoupon (CouponType,UserID,LimitTime,IsUse,CouponNumber) values (134,?,?,0,?);');
- await sleep(500);
- }
- } else if (param.Type == 3) {
- const sql = "select w.UserID from MiaoguoWXUsers u inner join WechatServiceWXUsers w on u.UnionID=w.UnionID " +
- "where u.IsPay=1 and u.UserID not in (" +
- "select w.Introducer from WechatServiceWXUsers w inner join MiaoguoWXUsers u on w.Introducer=u.UserID " +
- "where u.IsPay=1 and u.UserID>7 group by w.Introducer) union all " +
- "select w2.UserID from WechatServiceWXUsers w inner join MiaoguoWXUsers u on w.Introducer=u.UserID " +
- "inner join WechatServiceWXUsers w2 on w.UnionID=w2.UnionID " +
- "where u.IsPay=1 and u.UserID>7 group by w.Introducer having count(*)<3;";
- const list = await miaoguo.RunSql([], sql);
- const userIDs = _.uniq(list.map(item => item.UserID).sort());
- for (const userID of userIDs) {
- if (userID === 1) await sendTemplateMessage(userID, 'PopularizationPlan');
- await sleep(500);
- }
- } else if (param.Type == 4) {
- let sql = "select wu.UserID,u.NickName,count(distinct DATE_FORMAT(r.CreateTime,'%Y%m%d')) as 'Count',sum(r.Duration)/60 as '使用分钟数',count(distinct c.MiaoguoCardID) from MiaoguoWXUsers u inner join WechatServiceWXUsers wu on u.UnionID=wu.UnionID inner join MiaoguoCard c on u.UserID=c.UserID inner join MiaoguoLearningRecord r on c.MiaoguoCardID = r.CardID where r.CreateTime>='2020-01-01' and r.CreateTime<'2021-01-01' and u.IsPay=1 and u.GroupID=1 group by u.UserID having Count>=100 order by Count desc;";
- if (param.TypeDetail == 2) {
- sql = "select wu.UserID,u.NickName,count(distinct DATE_FORMAT(r.CreateTime,'%Y%m%d')) as 'Count',sum(r.Duration)/60 as '使用分钟数',count(distinct c.MiaoguoCardID) from MiaoguoWXUsers u inner join WechatServiceWXUsers wu on u.UnionID=wu.UnionID inner join MiaoguoCard c on u.UserID=c.UserID inner join MiaoguoLearningRecord r on c.MiaoguoCardID = r.CardID where r.CreateTime>='2020-01-01' and r.CreateTime<'2021-01-01' and u.IsPay=1 and u.GroupID=2 group by u.UserID having Count>=50 order by Count desc;";
- } else if (param.TypeDetail == 3) {
- sql = "select wu.UserID,u.NickName,count(mt.ID) as 'Count' from MiaoguoTask mt inner join MiaoguoWXUsers u on mt.UserID=u.UserID inner join WechatServiceWXUsers wu on u.UnionID=wu.UnionID where mt.IsShare=1 and u.IsPay=1 and u.GroupID=1 and mt.CreateTime>='2020-12-07 00:00:00' and mt.CreateTime<'2021-01-06 00:00:00' group by mt.UserID order by count(mt.ID) desc;";
- } else if (param.TypeDetail == 4) {
- sql = "select wu.UserID,u.NickName,count(mt.ID) as 'Count' from MiaoguoTask mt inner join MiaoguoWXUsers u on mt.UserID=u.UserID inner join WechatServiceWXUsers wu on u.UnionID=wu.UnionID where mt.IsShare=1 and u.IsPay=1 and u.GroupID=2 and mt.CreateTime>='2020-12-07 00:00:00' and mt.CreateTime<'2021-01-06 00:00:00' group by mt.UserID order by count(mt.ID) desc;";
- }
- const list = await miaoguo.RunSql([], sql);
- /*
- * 旧系统实际发送语句处于注释状态。以下代码已经转换为 Node.js 24
- * 写法;需要恢复该历史奖励时,可解除注释后先用 UserID=1 验证。
- for (const item of list) {
- let messageParam;
- if (param.TypeDetail == 1) {
- messageParam = { Title1: '2020年度学习勤勉奖', Title2: '奖励有效期[CouponNumber]天', Title3: '您练习我支持,奖励在2020年持续练习的孩子和家长,祝学业进步!', LimitTime: '2021-07-01', CouponNumber: '30' };
- } else if (param.TypeDetail == 2) {
- messageParam = { Title1: '2020年度学习勤勉奖', Title2: '奖励有效期[CouponNumber]天', Title3: '您练习我支持,奖励在2020年持续练习的孩子和家长,祝学业进步!', LimitTime: '2021-07-01', CouponNumber: '20' };
- } else if (param.TypeDetail == 3 || param.TypeDetail == 4) {
- messageParam = { Title1: '2020年第一学期期末备考30天冲刺奖', Title2: '奖励有效期[CouponNumber]天', Title3: '您练习我支持,奖励在2020年12月07日至2021年01月05日期间勤勉接力的孩子和家长,祝学业进步!', LimitTime: '2021-07-01', CouponNumber: String(item.Count) };
- }
- if (messageParam) {
- await sendTemplateMessage(item.UserID, 'CouponSendRemind', JSON.stringify(messageParam));
- await sleep(1000);
- }
- }
- */
- } else if (param.Type == 5) {
- const sql = 'select u.NickName,w.UserID from MiaoguoWXUsers u inner join MiaoguoWXUsers u2 on u.Introducer=u2.UserID inner join WechatServiceWXUsers w on u2.UnionID=w.UnionID where u.IsPay=1 and u.ClassID=4;';
- const list = await miaoguo.RunSql([], sql);
- for (const item of list) {
- if (item.UserID == 1) {
- await sendTemplateMessage(item.UserID, 'IntroducerRemind', JSON.stringify({ NickName: item.NickName }));
- }
- await sleep(500);
- }
- } else if (param.Type == 6) {
- const list = await miaoguo.RunSql([], 'select * from WechatServiceWXUsers where Subscribe=1 and IsProbation=0;');
- for (const item of list) {
- await sendTemplateMessage(item.UserID, 'SubscribeNoPayRemind');
- await sleep(500);
- }
- } else if (param.Type == 7) {
- const sql = "SELECT mt.UserID,u.NickName,u.AvatarUrl,sum(mt.IsShare) as '天数' FROM kylx365_db.MiaoguoTask mt " +
- "inner join MiaoguoWXUsers u on mt.UserID=u.UserID " +
- "where mt.CreateTime>='2019-09-01' and mt.CreateTime<'2019-10-01' and mt.IsShare=1 and u.UserID>7 " +
- "group by mt.UserID having 天数>=1 order by 天数 desc;";
- const list = await miaoguo.RunSql([], sql);
- const limitTime = moment().add(6, 'months').format('YYYY-MM-DD');
- for (const item of list) {
- result.push("insert into MiaoguoCoupon (CouponType,UserID,LimitTime,IsUse,CouponNumber) values (137," + item.UserID + ",'" + limitTime + "',0," + item.天数 + ");");
- }
- } else if (param.Type == 8) {
- /*
- * 旧系统曾按 2024 年任务记录自动筛选名单,后来改成下面的人工确认名单。
- * 保留已转换的旧查询,未来需要恢复自动筛选时可直接替换当前 sql。
- const taskStatisticsSql = "SELECT mt.UserID,w.UserID as 'WUserID',u.NickName as '小程序昵称',w.NickName as '服务号昵称',u.NickNameRemark as '昵称备注',sum(mt.IsShare) as '群接力天数' " +
- "FROM kylx365_db.MiaoguoTask mt inner join MiaoguoWXUsers u on mt.UserID=u.UserID " +
- "inner join WechatServiceWXUsers w on u.UnionID=w.UnionID " +
- "where mt.CreateTime>='2024-01-01' and mt.CreateTime<='2025-01-01' " +
- "and mt.IsShare=1 and u.UserID>7 and u.ProductServiceTime>='2025-01-06' " +
- "group by mt.UserID having 群接力天数>=20 order by 群接力天数 desc;";
- */
- const sql = "SELECT u.UserID,w.UserID as 'WUserID',u.NickName as '小程序昵称',w.NickName as '服务号昵称',u.NickNameRemark as '昵称备注' " +
- "FROM MiaoguoWXUsers u inner join WechatServiceWXUsers w on u.UnionID=w.UnionID " +
- "where u.UserID in " +
- "(1,699,321,17161,15362,30894,36549,24084,16297,26887,21006,5806,199,31917,39733,34777,6168,29864,27170,27101,13239,33957,39392,40981,39421,30393,23093,22192,12683,24149,41274,12164,41795,41573,1760,15387,25473,33746,3232,31117,15456,23731,3438,41817,17110) " +
- 'order by u.UserID;';
- const list = await miaoguo.RunSql([], sql);
- for (const item of list) {
- const day = 20;
- const messageParam = {
- Title1: '2025年度有奖勤勉接力',
- Title2: '赠送[CouponNumber]天',
- Title3: '一年来辛苦您了,恭喜您和孩子在这不平凡的一年取得不平凡的成就。希望勤勉接力活动能为帮助孩子建立练习习惯起到积极作用,感谢您一直以来的支持。祝全家健康,学业进步,事业昌盛,新年快乐!',
- LimitTime: '2026-07-11',
- CouponNumber: String(day),
- };
- await sendTemplateMessage(item.WUserID, 'CouponSendRemind', JSON.stringify(messageParam), true);
- result.push("insert into MiaoguoCoupon (CouponType,UserID,LimitTime,IsUse,CouponNumber) values (423," + item.UserID + ",'2026-07-11',0," + day + ");");
- await sleep(500);
- }
- }
- ctx.body = result.join('\n');
- }
- export async function BuildBookTotal(ctx) {
- const confirmRun = ctx.query.ConfirmRun == 1;
- const books = await miaoguo.RunSql(
- [],
- "SELECT * FROM HanziBook where Flag=0 and Name2 in ('上学期','下学期') order by Sort;",
- );
- const result = [];
- for (const book of books) {
- let wordNum = 0;
- if (book.Name1 == "语文写字" || book.Name1 == "语文识字" || book.Name1 == "语文词语") {
- const units = await hanzi.GetHanziUnits({ BookID: book.ID });
- for (const unit of units) {
- if (book.Name1 == "语文词语") {
- const arr = String(unit.Example || "").split(",").filter(Boolean);
- wordNum += arr.length;
- } else {
- wordNum += String(unit.Example || "").length;
- }
- }
- } else if (book.Name1 == "语文古诗文" || book.Name1 == "语文日积月累") {
- const poems = await hanzi.GetAncientPoetryList({ BookID: book.ID });
- wordNum = poems.length;
- } else {
- continue;
- }
- result.push({ ID: book.ID, Name: book.Name, WordNum: wordNum });
- if (confirmRun) {
- await miaoguo.RunSql([wordNum, book.ID], "update HanziBook set WordNum=? where ID=?;");
- }
- }
- ctx.body = { errcode: 10000, result, executed: confirmRun };
- }
- export async function UpdateUserConfigBasicCardLimit(ctx) {
- const param = {
- UserID: ctx.query.UserID || 0,
- BasicCardLimit: ctx.query.BasicCardLimit || 0,
- CurrentUserID: ctx.query.CurrentUserID || 0,
- };
- const log = {
- UserID: ctx.query.UserID,
- LogID: 314,
- Content: JSON.stringify(param),
- };
- miaoguo.AddMiaoguoLog(log).catch(err => console.error('AddMiaoguoLog failed:', err));
- delete param.CurrentUserID;
- await miaoguo.UpdateUserConfig(param);
- ctx.body = { errcode: 10000 };
- }
- export async function UploadUserConfig(ctx) {
- const param = ctx.request.body || {};
- param.UserID = Number(ctx.query.UserID || 0);
- const dataType = ctx.query.Type || "getData";
- param.CardType = Number(param.CardType) || 0;
- param.CardMaxNumberNew = param.CardMaxNumberNew;
- param.CardMaxNumberHistory = param.CardMaxNumberHistory || 100;
- param.CardMaxNumberNewUrgent = param.CardMaxNumberNewUrgent;
- param.CardMaxNumberHistoryUrgent = param.CardMaxNumberHistoryUrgent || 100;
- param.SortTypeIndex = param.SortTypeIndex || 0;
- param.MemoryLevel = param.MemoryLevel || 0;
- param.ClickType = param.ClickType || 0;
- param.FolderOrder = param.FolderOrder || "UpdateTime desc";
- param.IsFolderPractice = param.IsFolderPractice || 0;
- param.IsAutoSound = param.IsAutoSound;
- const currentUserID = param.CurrentUserID;
- delete param.CurrentUserID;
- if (param.SecondConfigArray) {
- if (stringUtils.IsArray(param.SecondConfigArray))
- param.SecondConfigArray = param.SecondConfigArray.join(",");
- } else {
- param.SecondConfigArray = "0,0,0";
- }
- if (param.ColorIndexArr) {
- if (stringUtils.IsArray(param.ColorIndexArr))
- param.ColorIndexArr = param.ColorIndexArr.join(",");
- } else {
- param.ColorIndexArr = "1,2,3,4";
- }
- if (!param.IsAutoSound && param.IsAutoSound !== "0" && param.IsAutoSound !== 0)
- param.IsAutoSound = 1;
- if (!param.CardMaxNumberNew && param.CardMaxNumberNew != 0)
- param.CardMaxNumberNew = 10;
- if (!param.CardMaxNumberNewUrgent && param.CardMaxNumberNewUrgent != 0)
- param.CardMaxNumberNewUrgent = 10;
- if (dataType == "getData") {
- const userList = await miaoguo.GetUserConfigData(param);
- if (userList[0] && userList[0].SymbolList)
- userList[0].SymbolList = JSON.parse(userList[0].SymbolList);
- if (userList.length > 0)
- ctx.body = { errcode: 10000, result: userList[0] };
- else
- ctx.body = { errcode: 10000, result: param };
- return;
- }
- const dbParam = { ...param };
- if (stringUtils.IsArray(dbParam.SymbolList))
- dbParam.SymbolList = JSON.stringify(dbParam.SymbolList);
- const userList = await miaoguo.GetUserConfigData(param);
- if (userList.length > 0)
- await miaoguo.UpdateUserConfig(dbParam);
- else
- await miaoguo.AddUserConfig(dbParam);
- const logParam = { ...param, CurrentUserID: currentUserID };
- const log = {
- UserID: ctx.query.UserID,
- LogID: 314,
- Content: JSON.stringify(logParam),
- };
- miaoguo.AddMiaoguoLog(log).catch(err => console.error('AddMiaoguoLog failed:', err));
- ctx.body = { errcode: 10000, result: logParam };
- }
- export async function DeleteAllMiaoguoCard(ctx) {
- const param = {
- UserID: ctx.query.UserID,
- Flag: -1,
- IsAll: 1,
- };
- param.DeleteTime = moment().format("YYYY-MM-DD HH:mm:ss");
- param.UpdateTime = param.DeleteTime;
- await miaoguo.UpdateCard(param);
- const log = {
- UserID: ctx.query.UserID,
- LogID: 454,
- Content: JSON.stringify(param),
- };
- miaoguo.AddMiaoguoLog(log).catch(err => console.error('AddMiaoguoLog failed:', err));
- ctx.body = { errcode: 10000 };
- }
- export async function BuildInitData(ctx) {
- const param = {
- UserID: ctx.query.UserID || "0",
- };
- if (Number(param.UserID) > 0) {
- const count = await miaoguo.GetCardCount(param);
- if (count[0] && count[0].count == 0) {
- const cardIDs = [];
- for (let i = 0; i < 10; i++) {
- const now = moment().format('YYYY-MM-DD HH:mm:ss');
- const insertInfo = await miaoguo.AddCard({
- UserID: param.UserID,
- CreateTime: now,
- LimitTime: now,
- IsTodayStudy: 1,
- });
- cardIDs.push(insertInfo.insertId);
- }
- for (let i = 0; i < 10; i++) {
- const listContent = await miaoguo.GetCardContentList(i + 1);
- for (const contentType of [0, 1, 2, 3]) {
- await miaoguo.AddCardContent({
- MiaoguoCardID: cardIDs[i],
- ContentType: contentType,
- Content: listContent[contentType] ? listContent[contentType].Content : "",
- });
- }
- }
- }
- }
- ctx.body = { errcode: 10000, result: 1 };
- }
- export async function updateMiaoguoTaskData(ctx) {
- const param = {
- UserID: ctx.query.UserID || 0,
- };
- let startDate = moment().add(-30, "days").format("YYYY-MM-DD");
- let userFilter = "";
- if (Number(param.UserID) > 0) {
- startDate = moment().add(-1200, "days").format("YYYY-MM-DD");
- userFilter = " and mc.UserID=" + Number(param.UserID);
- }
- const sqlUsers = "select distinct mc.UserID from MiaoguoLearningRecord mlr inner join MiaoguoCard mc on mc.MiaoguoCardID=mlr.CardID where mlr.Flag=0 " + userFilter + " and mlr.CreateTime>=?;";
- const list = await miaoguo.RunSql([startDate], sqlUsers);
- const userIDs = [];
- for (const item of list) {
- const sqlDaily = "select DATE_FORMAT(r.CreateTime,'%Y-%m-%d') as CreateTime,count(distinct r.CardID) as Count,sum(r.Duration) as Sum " +
- "from MiaoguoWXUsers u " +
- "inner join MiaoguoCard c on u.UserID=c.UserID " +
- "inner join MiaoguoLearningRecord r on c.MiaoguoCardID = r.CardID " +
- "where r.Flag=0 and u.UserID=? and r.CreateTime>=? group by CreateTime order by CreateTime;";
- const dailyList = await miaoguo.RunSql([item.UserID, startDate], sqlDaily);
- for (const dayInfo of dailyList) {
- const createTime = dayInfo.CreateTime + " 00:00:00";
- const existing = await miaoguo.RunSql([item.UserID, createTime], "select * from MiaoguoTask where UserID=? and CreateTime=?;");
- if (existing && existing.length > 0) {
- await miaoguo.RunSql(
- [dayInfo.Count, dayInfo.Sum, item.UserID, createTime],
- "update MiaoguoTask set CardTask=?,Duration=? where UserID=? and CreateTime=?;",
- );
- } else {
- await miaoguo.RunSql(
- [item.UserID, createTime, dayInfo.Count, dayInfo.Sum],
- "insert into MiaoguoTask (UserID,CreateTime,CardTask,Duration,IsShare,Flag) values (?,?,?,?,0,0);",
- );
- }
- }
- userIDs.push(item.UserID);
- }
- if (userIDs.length > 0) {
- const ids = userIDs.map(id => Number(id)).filter(id => Number.isInteger(id) && id > 0).join(',');
- const resetSql = Number(param.UserID) > 0
- ? "update MiaoguoTask set MilestoneID=0,MilestoneDayNumber=0,HardworkingNumber=0 where UserID=?;"
- : "update MiaoguoTask set MilestoneID=0,MilestoneDayNumber=0,HardworkingNumber=0 where UserID in (" + ids + ");";
- await miaoguo.RunSql(Number(param.UserID) > 0 ? [Number(param.UserID)] : [], resetSql);
- const taskUsers = await miaoguo.RunSql(
- Number(param.UserID) > 0 ? [Number(param.UserID)] : [],
- Number(param.UserID) > 0
- ? "SELECT distinct UserID FROM MiaoguoTask where UserID=? order by UserID;"
- : "SELECT distinct UserID FROM MiaoguoTask where UserID in (" + ids + ") order by UserID;",
- );
- const milestone = constantClass.GetMilestone();
- for (const user of taskUsers) {
- const tasks = await miaoguo.RunSql([user.UserID], "SELECT * FROM MiaoguoTask where CardTask>0 and UserID=? order by CreateTime;");
- if (!tasks || tasks.length == 0) continue;
- let milestoneIDs = [];
- for (let i = 0; i < 40; i++) milestoneIDs.push(i + 1);
- milestoneIDs = stringUtils.RandomArray(milestoneIDs);
- let milestoneIndex = 0;
- let hardworkingIndex = 0;
- for (let i = 0; i < tasks.length; i++) {
- const update = {
- ID: tasks[i].ID,
- DayNumber: i + 1,
- };
- const milestoneItem = milestone.find(item => item.DayNumber == i + 1);
- if (milestoneItem) {
- update.MilestoneDayNumber = milestoneItem.DayNumber;
- update.MilestoneID = milestoneIDs[milestoneIndex++];
- }
- if (tasks[i].IsShare > 0 || update.MilestoneDayNumber > 0 || tasks[i].AphorismID > 0)
- update.HardworkingNumber = ++hardworkingIndex;
- await miaoguo.UpdateMiaoguoTask(update);
- }
- }
- }
- ctx.body = { errcode: 10000, result: { UserCount: userIDs.length } };
- }
- export async function updateMiaoguoFamily(ctx) {
- const param = {
- UserID: ctx.query.UserID || 0,
- UpdateType: ctx.query.UpdateType || "add",
- NewUserID: ctx.query.NewUserID || 0,
- Time: ctx.query.Time,
- };
- let result = 0;
- const yestoday = moment().add(-10, "minutes").format("YYYY-MM-DD HH:mm:ss");
- if (yestoday > param.Time) {
- result = -1;
- } else {
- const list = await miaoguo.GetMiaoguoFamilyByUserID(param);
- if (list && list.length > 0) {
- if (param.UpdateType == "delete") {
- const obj = {
- ID: list[0].ID,
- UpdateTime: moment().format("YYYY-MM-DD HH:mm:ss"),
- Flag: -1,
- };
- await miaoguo.UpdateMiaoguoFamily(obj);
- miaoguo.AddMiaoguoLog({ UserID: ctx.query.UserID, LogID: 372, Content: JSON.stringify(param) }).catch(err => console.error('AddMiaoguoLog failed:', err));
- } else if (param.UpdateType == "add") {
- if (list[0].UserID1 == param.NewUserID)
- result = -2;
- if (list[0].UserID2 == param.NewUserID)
- result = -2;
- if (list[0].UserID3 == param.NewUserID)
- result = -2;
- if (list[0].UserID1 > 0 && list[0].UserID2 > 0 && list[0].UserID3 > 0)
- result = -3;
- if (result == 0) {
- const obj = {
- ID: list[0].ID,
- UpdateTime: moment().format("YYYY-MM-DD HH:mm:ss"),
- };
- if (!list[0].UserID1 || list[0].UserID1 == "")
- obj.UserID1 = param.NewUserID;
- else if (!list[0].UserID2 || list[0].UserID2 == "")
- obj.UserID2 = param.NewUserID;
- else if (!list[0].UserID3 || list[0].UserID3 == "")
- obj.UserID3 = param.NewUserID;
- await miaoguo.UpdateMiaoguoFamily(obj);
- miaoguo.AddMiaoguoLog({ UserID: ctx.query.UserID, LogID: 373, Content: JSON.stringify(param) }).catch(err => console.error('AddMiaoguoLog failed:', err));
- }
- }
- } else if (param.UpdateType == "add") {
- const obj = {
- UpdateTime: moment().format("YYYY-MM-DD HH:mm:ss"),
- UserID1: param.UserID,
- UserID2: param.NewUserID,
- Flag: 0,
- };
- await miaoguo.AddMiaoguoFamily(obj);
- miaoguo.AddMiaoguoLog({ UserID: ctx.query.UserID, LogID: 373, Content: JSON.stringify(param) }).catch(err => console.error('AddMiaoguoLog failed:', err));
- }
- }
- ctx.body = { errcode: 10000, result };
- }
- export async function GetMiaoguoCheckList(ctx) {
- const param = {
- UserID: ctx.query.UserID || 0,
- FieldStr: 'UserID,IsMember,NickName,AvatarUrl',
- };
- const result = {};
- result.List = [
- {},
- { Title: '加入秒过学习班群(微信群)', Max: 1 },
- { Title: '收集孩子的错题', Max: 1 },
- { Title: '第一课', Remark: "概念课:学习法与记忆规律(约30分钟)", Max: 50, Finished: 0 },
- { Title: '第二课', Remark: "操作课:实战制作合格的题卡(约20分钟)", Max: 50, Finished: 0 },
- { Title: '第三课', Remark: "操作课:陪伴孩子完成学习任务(约20分钟)", Max: 50, Finished: 0 },
- { Title: '第四课', Remark: "精要解析(约10分钟)", Max: 50, Finished: 0 },
- { Title: '添加30张题卡', Max: 30 },
- { Title: '带领孩子完成20分钟学习任务', Max: 1200 },
- { Title: '分享题卡到班群3次', Max: 3 },
- { Title: '勤勉接力到班群3天', Max: 3 },
- ];
- const lessonCount = [0, 28, 7, 6, 14];
- const userInfo = await miaoguo.GetUsersInfoByUserID(param);
- if (userInfo && userInfo.length > 0) {
- result.UserID = userInfo[0].UserID;
- result.NickName = userInfo[0].NickName;
- result.AvatarUrl = userInfo[0].AvatarUrl;
- if (userInfo[0].IsMember == 1) {
- result.List[1].Finished = 1;
- result.List[2].Finished = 1;
- }
- const lesson = await miaoguo.GetUserMiaoguoLesson(param);
- if (lesson && lesson.length > 0) {
- const lessonCount2 = ["", "", "", "", ""];
- for (const item of lesson)
- lessonCount2[item.LessonID] += "," + item.Content;
- for (let i = 1; i < lessonCount2.length; i++) {
- if (lessonCount2[i].length > 0) {
- lessonCount2[i] = _.uniq(lessonCount2[i].substr(1).split(","));
- result.List[i + 2].Finished = Math.round(100 * lessonCount2[i].length / lessonCount[i]);
- } else {
- result.List[i + 2].Finished = 0;
- }
- }
- }
- param.CheckList = 1;
- const cardNumber = await miaoguo.GetCardCount(param);
- result.List[7].Finished = 0;
- if (cardNumber && cardNumber.length > 0)
- result.List[7].Finished = cardNumber[0].count;
- delete param.CheckList;
- param.CreateTime = "2019-03-01";
- const taskData = await miaoguo.GetTaskData(param);
- result.List[8].Finished = 0;
- if (taskData && taskData.length > 0 && taskData[0].Duration)
- result.List[8].Finished = taskData[0].Duration;
- result.List[8].FinishedStr = stringUtils.getMinuteSecond(result.List[8].Finished);
- const cardShare = await miaoguo.GetUserMiaoguoCardShare(param);
- result.List[9].Finished = 0;
- if (cardShare && cardShare.length > 0)
- result.List[9].Finished = cardShare.length;
- const taskShare = await miaoguo.GetUserMiaoguoTaskShare(param);
- result.List[10].Finished = 0;
- if (taskShare && taskShare.length > 0)
- result.List[10].Finished = taskShare.length;
- }
- let finishCount = 0;
- for (let i = 1; i < result.List.length; i++) {
- if (result.List[i].Finished >= result.List[i].Max)
- finishCount++;
- }
- result.FinishedCount = Math.round(100 * finishCount / (result.List.length - 1));
- if (result.FinishedCount == 100)
- await miaoguo.UpdateUsersByUserID({ UserID: param.UserID, IsFinishTask: 1 });
- ctx.body = { errcode: 10000, result };
- }
- export async function GetAnnualReport(ctx) {
- const param = {
- UserID: ctx.query.UserID || 0,
- TimeStart: ctx.query.Time || "2024-01-01 00:00:00",
- TimeEnd: ctx.query.Time || "2024-12-31 23:59:59",
- };
- const result = {};
- let sql = `select u.UserID,count(distinct DATE_FORMAT(r.CreateTime,'%Y%m%d')) as 'DayNumber'
- from MiaoguoWXUsers u inner join MiaoguoCard c on u.UserID=c.UserID inner join MiaoguoLearningRecord r on c.MiaoguoCardID = r.CardID
- where r.Flag=0 and r.CreateTime>='${param.TimeStart}' and r.CreateTime<='${param.TimeEnd}' and IsPay=1
- group by u.UserID order by DayNumber desc;`;
- let result1 = await miaoguo.RunSql({}, sql);
- if (result1 && result1.length > 0) {
- let index = 0;
- for (let i = 0; i < result1.length; i++) {
- if (result1[i].UserID == param.UserID) {
- index = i;
- break;
- }
- }
- result.Hard = Math.round(10000 * (result1.length - index) / result1.length) / 100 + "%";
- }
- sql = `SELECT m.UserID,m.CreateTime,Count(distinct DATE_FORMAT(mlr.CreateTime,'%Y-%m-%d')) as 'DayNum',Count(mlr.ID) as 'RememberNum',Sum(mlr.Duration) as 'PracticeTime'
- FROM MiaoguoWXUsers m left join MiaoguoCard mc on m.UserID=mc.UserID left join MiaoguoLearningRecord mlr on mc.MiaoguoCardID=mlr.CardID
- where mlr.Flag=0 and m.UserID=${param.UserID} and mlr.CreateTime>='${param.TimeStart}' and mlr.CreateTime<='${param.TimeEnd}';`;
- result1 = await miaoguo.RunSql({}, sql);
- if (result1 && result1.length > 0) {
- result.StartDate = moment(result1[0].CreateTime).format("YYYY年MM月DD日");
- if (result.StartDate < moment(param.TimeStart).format("YYYY年MM月DD日"))
- result.StartDate = moment(param.TimeStart).format("YYYY年MM月DD日");
- result.EndDate = moment(param.TimeEnd).format("YYYY年MM月DD日");
- result.DayNum = result1[0].DayNum;
- result.RememberNum = result1[0].RememberNum;
- result.PracticeTime = stringUtils.getMinuteSecond(result1[0].PracticeTime, true);
- }
- const shareInfo = await miaoguo.GetUserMiaoguoTaskShare(param);
- result.ShareNum = 0;
- if (shareInfo && shareInfo.length > 0)
- result.ShareNum = shareInfo.length;
- sql = `SELECT DATE_FORMAT(mlr.CreateTime,'%m月') as MonthName,Sum(mlr.Duration)/60 as 'PracticeTime'
- FROM MiaoguoCard mc left join MiaoguoLearningRecord mlr on mc.MiaoguoCardID=mlr.CardID
- where mlr.Flag=0 and mc.UserID=${param.UserID} and DATE_FORMAT(mlr.CreateTime,'%Y-%m') is not null
- and mlr.CreateTime>='${param.TimeStart}' and mlr.CreateTime<='${param.TimeEnd}' group by DATE_FORMAT(mlr.CreateTime,'%Y-%m');`;
- result1 = await miaoguo.RunSql({}, sql);
- if (result1 && result1.length > 0) {
- for (const item of result1)
- item.PracticeTime = Math.round(item.PracticeTime);
- result.PracticeMonth = result1;
- }
- sql = `SELECT DATE_FORMAT(mc.CreateTime,'%Y%m') as MonthName,Count(mc.MiaoguoCardID) as 'CardNum'
- FROM MiaoguoCard mc where mc.UserID=${param.UserID} and mc.CreateTime>='${param.TimeStart}'
- and mc.CreateTime<='${param.TimeEnd}' and mc.Flag=0 group by DATE_FORMAT(mc.CreateTime,'%Y-%m');`;
- result1 = await miaoguo.RunSql({}, sql);
- if (result1 && result1.length > 0) {
- result.CardNull = "";
- const monthStart = Number(result1[0].MonthName);
- const monthEnd = Number(moment(param.TimeEnd).format("YYYYMM"));
- for (let j = monthStart; j <= monthEnd; j++) {
- let hasMonth = false;
- for (const item of result1) {
- if (j == Number(item.MonthName)) {
- hasMonth = true;
- break;
- }
- }
- if (!hasMonth)
- result.CardNull += Number(j.toString().substr(4)) + " ";
- }
- result.CardNull = stringUtils.Trim(result.CardNull);
- if (!result.CardNull)
- result.CardNull = "每月都有";
- }
- sql = `Select Count(*) as CardNum from MiaoguoCard where UserID=${param.UserID} and Flag=0;`;
- result1 = await miaoguo.RunSql({}, sql);
- if (result1 && result1.length > 0)
- result.CardNum = result1[0].CardNum;
- sql = `Select Count(*) as NewCardNum from MiaoguoCard where UserID=${param.UserID} and Flag=0 and CreateTime>='${param.TimeStart}' and CreateTime<='${param.TimeEnd}';`;
- result1 = await miaoguo.RunSql({}, sql);
- if (result1 && result1.length > 0)
- result.NewCardNum = result1[0].NewCardNum;
- sql = `SELECT BtnNumber,Count(mlr.ID) as 'MemoryEvaluation'
- FROM MiaoguoCard mc left join MiaoguoLearningRecord mlr on mc.MiaoguoCardID=mlr.CardID
- where mlr.Flag=0 and mc.UserID=${param.UserID} and mlr.BtnNumber>=0 and mlr.BtnNumber<>2
- and mlr.CreateTime>='${param.TimeStart}' and mlr.CreateTime<='${param.TimeEnd}' group by BtnNumber;`;
- result1 = await miaoguo.RunSql({}, sql);
- if (result1 && result1.length > 0) {
- let memoryEvaluationTotal = 0;
- for (const item of result1)
- memoryEvaluationTotal += item.MemoryEvaluation;
- const obj = {};
- for (const item of result1) {
- const rate = Math.round(100 * item.MemoryEvaluation / memoryEvaluationTotal) + "%";
- switch (item.BtnNumber) {
- case 0:
- obj.Shelve = rate;
- break;
- case 1:
- obj.Red = rate;
- break;
- case 3:
- obj.Yellow = rate;
- break;
- case 4:
- obj.Green = rate;
- break;
- case 5:
- obj.Blue = rate;
- break;
- }
- }
- if (!obj.Shelve)
- obj.Shelve = "0%";
- if (!obj.Red)
- obj.Red = "0%";
- if (!obj.Yellow)
- obj.Yellow = "0%";
- if (!obj.Green)
- obj.Green = "0%";
- if (!obj.Blue)
- obj.Blue = "0%";
- result.MemoryEvaluation = obj;
- }
- ctx.body = { errcode: 10000, result };
- }
- export async function GetAwardInfo(ctx) {
- const param = {
- UserID: ctx.query.UserID || 0,
- Time: ctx.query.Time || "",
- };
- if (!param.Time)
- param.Time = moment().add(-7, "days").format("YYYY-MM-DD HH:mm:ss");
- const result = {};
- const info = await miaoguo.GetAwardInfo(param);
- const num1 = info[0].Count;
- param.IsWebchat = true;
- const info1 = await miaoguo.GetAwardInfo(param);
- const num2 = info1[0].Count;
- delete param.IsWebchat;
- param.IsBill = true;
- result.AwardDayNumber = 0;
- const info2 = await miaoguo.GetAwardInfo(param);
- if (info2 && info2.length > 0 && info2[0].BillTime) {
- result.BillTime = moment(info2[0].BillTime).format("YYYY年MM月DD日");
- result.AwardDayNumber = Number(info2[0].Count);
- }
- result.List = [
- { Name: "好友报名", PersonNum: Number(num2), Content: "奖励5天/人", Total: Number(num2) * 5 + "天" },
- { Name: "好友续费", PersonNum: Number(num1), Content: "奖励115天/人", Total: Number(num1) * 115 + "天" },
- ];
- result.Time = moment(param.Time).format("YYYY年MM月DD日");
- result.Remark = "报名人数含续费人数(流程为先报名后续费),在续费奖励的120天里,包含了报名奖励的5天。为方便向您说明,表格以单项形式列支,所以续费奖励独立显示为115天。";
- result.Total = Number(num2) * 5 + Number(num1) * 115;
- ctx.body = { errcode: 10000, result };
- }
- export async function GetApprovalUserList(ctx) {
- const param = {
- ClassID: ctx.query.ClassID || 0,
- };
- const url = "GetApprovalUserList";
- let result = globalCache.get(url);
- if (result === 0) {
- result = [];
- let arr = [8, 9, 10, 11, 12, 13, 105, 141, 204, 206, 209, 216, 222, 229, 238, 248, 252, 402, 526, 568, 571, 787, 1355, 1356, 6137, 8055, 12363];
- const list2 = await payInfo.GetMiaoguoPayInfoList();
- for (const item of list2)
- arr.push(item.UserID);
- arr = _.concat(arr, 348, 364, 456, 597, 699, 735, 1025, 1018, 1009, 1021, 1017);
- const list3 = await payInfo.GetMiaoguoPayInfoList({ webtype: "web" });
- for (const item of list3)
- arr.push(item.UserID);
- arr.sort();
- arr = _.union(arr);
- let list = await miaoguo.GetApprovalUserList(param);
- for (const item of list) {
- for (const userID of arr) {
- if (userID == item.UserID) {
- item.CreateTime = moment(item.CreateTime).format('YY.MM.DD HH:mm');
- item.LastLoginTime = moment(item.LastLoginTime).format('YY.MM.DD HH:mm');
- if (item.IsProbation == 1) {
- const time1 = moment().format("YYYYMMDDHHmm");
- const time2 = moment(item.LimitTime).add(48, "hours").format("YYYYMMDDHHmm");
- if (time1 > time2)
- item.CssBg = "background-color: #D32F2F;";
- if (item.ProbationPayTime)
- item.ProbationPayTime = moment(item.ProbationPayTime).format('YY.MM.DD HH:mm');
- else {
- if (item.UserID > 199)
- item.ProbationPayTime = "*";
- else
- item.ProbationPayTime = "#";
- }
- } else {
- item.ProbationPayTime = "";
- }
- if (!item.Subscribe)
- item.Subscribe = "";
- else
- item.Subscribe = moment(item.SubscribeTime).format('YY.MM.DD HH:mm');
- if (item.IsMember == 1) {
- item.ButtonOn = true;
- item.CssBg = "background-color: #e2ffd3;";
- } else {
- item.ButtonOn = false;
- item.CssBg = "background-color: #fff;";
- }
- if (!item.PayTime)
- item.PayTime = "";
- else
- item.PayTime = moment(item.PayTime).format('YY.MM.DD HH:mm');
- if (item.NickName != item.WSUNickName)
- item.NickName += '[' + item.WSUNickName + ']';
- if (item.NickNameRemark)
- item.NickName += '「' + item.NickNameRemark + '」';
- item.GroupID = stringUtils.getGroupName(item.GroupID);
- if (item.Introducer) {
- if (item.IntroducerClassID == 1)
- item.IntroducerClassID = "1~5";
- item.IntroducerGroupID = stringUtils.getGroupName(item.IntroducerGroupID);
- item.Introducer = item.Introducer + "(" + item.IntroducerClassID + "班 " + item.IntroducerGroupID + ")";
- }
- result.push(item);
- break;
- }
- }
- }
- param.type = "NoneMiaoguoData";
- list = await miaoguo.GetApprovalUserList(param);
- for (const item of list) {
- const obj = {};
- obj.UserID = "";
- obj.WSUUserID = item.UserID;
- obj.NickName = "[" + item.NickName + "]";
- obj.WSUAvatarUrl = item.AvatarUrl;
- obj.CreateTime = "";
- obj.LastLoginTime = "";
- if (!item.Subscribe)
- obj.Subscribe = "";
- else
- obj.Subscribe = moment(item.SubscribeTime).format('YY.MM.DD HH:mm');
- if (item.IsProbation == 1) {
- if (item.ProbationPayTime)
- obj.ProbationPayTime = moment(item.ProbationPayTime).format('YY.MM.DD HH:mm');
- else
- obj.ProbationPayTime = "";
- } else {
- obj.ProbationPayTime = "";
- }
- obj.ClassID = item.TempClassID;
- obj.IsMember = item.TempIsMember;
- obj.PayTime = "";
- if (obj.IsMember == 1) {
- obj.ButtonOn = true;
- obj.CssBg = "background-color: #e2ffd3;";
- } else {
- obj.ButtonOn = false;
- obj.CssBg = "background-color: #fff;";
- }
- if (item.IntroducerUserID)
- obj.Introducer = item.IntroducerNickName + "(" + item.IntroducerUserID + ")";
- delete obj.IntroducerUserID;
- delete obj.IntroducerNickName;
- result.unshift(obj);
- }
- globalCache.set(url, result, config.BufferMemoryTimeLower);
- }
- const arr = [];
- for (const item of result) {
- if (item.ClassID == param.ClassID || param.ClassID == "All") {
- if (item.ClassID == 0 && item.IsMember == 1 && item.Subscribe == 0) {
- // Keep old behavior: skip this row.
- } else {
- arr.push(item);
- }
- }
- }
- ctx.body = { errcode: 10000, result: arr };
- }
- export async function GetMiaoguoTestIndex(ctx) {
- const param = {
- UserID: ctx.query.UserID || 0,
- };
- const resultAll = {};
- const userInfo = await miaoguo.GetUsersInfoByUserID(param);
- if (userInfo && userInfo.length) {
- const param2 = {
- UserID: param.UserID,
- Grade: userInfo[0].Grade,
- UpperAndLowerSemesters: userInfo[0].UpperAndLowerSemesters,
- };
- const list = await miaoguo.GetMiaoguoTestIndex(param2);
- const result = {
- List1: [],
- List2: [],
- List3: [],
- List4: [],
- };
- for (const item of list) {
- if (item.Sort2 == 1) {
- item.Name1 = item.Name1.replace("语文", "");
- item.Name1 = item.Name1.replace("拼音基础发音", "拼音基础");
- item.Name1 = item.Name1.replace("拼音发音组合", "拼音组合");
- delete item.BookImageName;
- }
- item.KnowledgeImageName = "pic_" + item.KnowledgeImageName;
- if (item.Sort2 == 1)
- result.List1.push(item);
- else if (item.Sort2 == 2)
- result.List2.push(item);
- else if (item.Sort2 == 3)
- result.List3.push(item);
- else if (item.Sort2 == 4)
- result.List4.push(item);
- }
- if (userInfo[0].Grade >= 7) {
- const temp = result.List2[1];
- result.List2[1] = result.List2[0];
- result.List2[0] = temp;
- }
- const arrTemp = [];
- let arrTemp2 = [];
- for (let k = 0; k < result.List4.length; k++) {
- if (k > 0 && k % 3 == 0) {
- arrTemp.push(arrTemp2);
- arrTemp2 = [];
- }
- arrTemp2.push(result.List4[k]);
- }
- if (arrTemp2.length > 0)
- arrTemp.push(arrTemp2);
- result.List4 = arrTemp;
- result.Grade = stringUtils.GetGrade2(param2.Grade);
- result.UpperAndLowerSemesters = userInfo[0].UpperAndLowerSemesters;
- resultAll.List1 = result;
- const reportParam = {
- UserID: param.UserID,
- BookID: 0,
- };
- resultAll.List2 = await miaoguo.GetMiaoguoTestExamineReport2(reportParam);
- for (const item of resultAll.List2) {
- item.TestTime = moment(item.TestTime).format("YYYY年MM月DD日 HH:mm");
- if (item.JSONData) {
- const arr = JSON.parse(item.JSONData);
- item.RightNum = arr[2].length;
- item.WrongNum = arr[0].length + arr[1].length;
- delete item.JSONData;
- } else {
- item.TestTime += " 已封存";
- }
- }
- }
- ctx.body = { errcode: 10000, result: resultAll };
- }
- export async function GetMiaoguoTestLibrary(ctx) {
- const url = "GetMiaoguoTestLibrary";
- let result = globalCache.get(url);
- if (result === 0) {
- result = await miaoguo.GetMiaoguoBook();
- for (const item of result) {
- let str = "cn";
- if (item.Category == "English")
- str = "en";
- item.BookImageName = "picZs_" + str + "_" + item.BookImageName + "_cov";
- }
- globalCache.set(url, result, config.BufferMemoryTimeHigher);
- }
- ctx.body = { errcode: 10000, result };
- }
- export async function GetMiaoguoTestPackage(ctx) {
- const param = {
- UserID: ctx.query.UserID || 0,
- Category: ctx.query.Category || "",
- LibraryName1: ctx.query.LibraryName1 || "",
- LibraryName2: ctx.query.LibraryName2 || "",
- };
- const url = "GetMiaoguoTestPackage?Category=" + param.Category + "&LibraryName1=" + param.LibraryName1 + "&LibraryName2=" + param.LibraryName2;
- let result = globalCache.get(url);
- if (result === 0) {
- result = await miaoguo.GetMiaoguoPackage(param);
- for (const item of result) {
- item.TestFunction = JSON.parse(item.TestFunction);
- let strCategory = "en";
- if (item.Category == "语文")
- strCategory = "cn";
- item.KnowledgeImageName = "picZs_" + strCategory + "_" + item.BookImageName + "_" + item.KnowledgeImageName;
- }
- globalCache.set(url, result, config.BufferMemoryTimeHigh);
- }
- if (param.UserID) {
- const list = await miaoguo.GetMiaoguoTestExamineReport(param);
- for (const item of result) {
- for (const report of list) {
- if (item.BookName == report.BookName) {
- for (const fn of item.TestFunction) {
- if (fn.N == "read") {
- if (report.ReadNum > item.UnitNum)
- report.ReadNum = item.UnitNum;
- fn.C = Math.round(100 * report.ReadNum / item.UnitNum);
- } else if (fn.N == "write") {
- if (report.WriteNum > item.UnitNum)
- report.WriteNum = item.UnitNum;
- fn.C = Math.round(100 * report.WriteNum / item.UnitNum);
- }
- }
- }
- }
- }
- }
- ctx.body = { errcode: 10000, result };
- }
- export function buildCambridgeCategoryUnits(wordList, testFunction) {
- const units = [];
- for (let start = 0; start < wordList.length; start += 10) {
- const words = wordList.slice(start, start + 10).map(item => item.Word);
- const id = units.length + 1;
- units.push({
- ID: id,
- UnitName: "Lesson " + id,
- ListStr: words.join("、"),
- Length: words.length,
- TestFunction: testFunction,
- });
- }
- return units;
- }
- export async function GetMiaoguoTestUnit(ctx) {
- const param = {
- UserID: ctx.query.UserID || 0,
- BookID: ctx.query.BookID || "0",
- };
- const url = "GetMiaoguoTestUnit?BookID=" + param.BookID;
- let result = globalCache.get(url);
- if (result === 0) {
- const info = await miaoguo.GetMiaoguoPackage(param);
- info[0].TestFunction = JSON.parse(info[0].TestFunction);
- let strCategory = "en";
- if (info[0].Category == "语文")
- strCategory = "cn";
- info[0].KnowledgeImageName = "picZs_" + strCategory + "_" + info[0].BookImageName + "_" + info[0].KnowledgeImageName;
- if (info[0].Category == "语文") {
- if (info[0].BookIDOld == 43) {
- result = constantClass.arrPinyinList;
- for (const item of result) {
- item.UnitName = item.LessonName;
- if (item.List && item.List.length > 0) {
- item.ListStr = item.List.join("、");
- item.Length = item.List.length;
- } else {
- item.ListStr = "";
- }
- item.TestFunction = info[0].TestFunction;
- delete item.List;
- }
- } else if (info[0].BookIDOld == 44) {
- result = constantClass.getPinyinSoundList;
- for (const item of result) {
- item.UnitName = item.Name;
- item.ListStr = item.ListStr;
- item.TestFunction = info[0].TestFunction;
- }
- } else if (info[0].BookIDOld == 86) {
- result = await hanzi.GetAncientChineseProseSentence();
- for (const item of result) {
- item.ID = item.UnitID;
- item.UnitName = item.Unit;
- item.ListStr = "";
- item.Length = item.Count;
- item.TestFunction = info[0].TestFunction;
- delete item.UnitID;
- delete item.Count;
- delete item.Unit;
- }
- } else if (info[0].BookIDOld == 73) {
- result = await hanzi.GetAncientChineseProse({ IsList: true });
- for (const item of result) {
- item.ID = item.UnitID;
- item.UnitName = item.Word;
- item.ListStr = "";
- item.Length = item.Count;
- item.TestFunction = info[0].TestFunction;
- delete item.UnitID;
- delete item.Count;
- delete item.Word;
- }
- } else if (info[0].BookName == "古诗文" || info[0].BookName == "日积月累") {
- result = await hanzi.GetAncientPoetryList({ BookID: info[0].BookIDOld });
- const item = {
- ID: info[0].BookIDOld,
- UnitName: info[0].BookName,
- List: [],
- };
- for (const poetry of result) {
- item.List.push(poetry.Title);
- item.TestFunction = info[0].TestFunction;
- }
- item.ListStr = item.List.join(",");
- item.Length = item.List.length;
- result = [item];
- } else {
- result = await hanzi.GetHanziUnits({ BookID: info[0].BookIDOld });
- for (const item of result) {
- if (item.Example && item.Example.indexOf(",") > 0)
- item.List = item.Example.split(",");
- else
- item.List = item.Example.split("");
- item.ListStr = item.List.join("、");
- item.UnitName = item.Name;
- item.Length = item.List.length;
- delete item.List;
- item.TestFunction = info[0].TestFunction;
- }
- }
- } else {
- let temp = null;
- let item = { List: [] };
- const arr = [];
- if (info[0].BookIDOld == 100) {
- item.ID = 1001;
- item.UnitName = "英文字母";
- item.ListStr = "A、B、C、D、E、F、G、H、I、J、K、L、M、N、O、P、Q、R、S、T、U、V、W、X、Y、Z";
- item.List = item.ListStr.split("、");
- item.Length = 26;
- item.TestFunction = info[0].TestFunction;
- arr.push(item);
- } else if (info[0].BookIDOld == 101) {
- result = [{ "ID": 1, "Name": "单元音", "Words": ["/i:/", "/ɪ/", "/æ/", "/e/", "/ɜ:/", "/ə/", "/a:/", "/ʌ/", "/ɔ:/", "/ɔ/", "/u:/", "/u/"] }, { "ID": 2, "Name": "双元音", "Words": ["/ei/", "/aɪ/", "/au/", "/əʊ/", "/ɔɪ/", "/ɪə/", "/ɛə/", "/uə/"] }, { "ID": 3, "Name": "清辅音", "Words": ["/p/", "/t/", "/k/", "/f/", "/θ/", "/s/", "/ts/", "/tr/", "/ʃ/", "/tʃ/", "/h/"] }, { "ID": 4, "Name": "浊辅音", "Words": ["/b/", "/d/", "/g/", "/r/", "/v/", "/ð/", "/z/", "/dz/", "/dr/", "/ʒ/", "/dʒ/", "/m/", "/n/", "/l/", "/ŋ/", "/j/", "/w/"] }];
- for (const unit of result) {
- unit.UnitName = unit.Name;
- unit.ListStr = unit.Words.join("、");
- unit.Length = unit.Words.length;
- unit.TestFunction = info[0].TestFunction;
- delete unit.Words;
- }
- arr.push(...result);
- } else if (info[0].BookIDOld >= 111 && info[0].BookIDOld <= 119) {
- const engList = await miaoguo.GetWordFrequencyList({ Limit: 3000 });
- const arrTemp = [];
- for (let i = info[0].StartID; i < info[0].StartID + info[0].WordNum; i++) {
- if (i / 10 == Math.floor(i / 10)) {
- arrTemp.push({
- ID: Math.floor(i / 10) + 1,
- UnitName: "单元" + (Math.floor(i / 10) + 1),
- Words: [],
- });
- }
- arrTemp[arrTemp.length - 1].Words.push(engList[i].Word);
- }
- for (const unit of arrTemp) {
- unit.ListStr = unit.Words.join("、");
- unit.Length = unit.Words.length;
- unit.TestFunction = info[0].TestFunction;
- delete unit.Words;
- }
- arr.push(...arrTemp);
- } else if (["剑桥KET", "剑桥PET", "剑桥FCE"].includes(info[0].LibraryName1)) {
- let sourceBookID = 133;
- if (info[0].LibraryName1 == "剑桥PET")
- sourceBookID = 134;
- else if (info[0].LibraryName1 == "剑桥FCE")
- sourceBookID = 136;
- result = await hanzi.GetEnglishUnitData({
- BookID: sourceBookID,
- LessonID: info[0].BookIDOld,
- });
- arr.push(...buildCambridgeCategoryUnits(result, info[0].TestFunction));
- } else {
- const param2 = { BookID: info[0].BookIDOld };
- result = await hanzi.GetEnglishUnitData(param2);
- let unitNameStart = "Lesson ";
- if (param2.BookID > 190 && param2.BookID < 207)
- unitNameStart = "Unit ";
- if (param2.BookID >= 207 && param2.BookID <= 211)
- unitNameStart = "";
- for (let i = 0; i < result.length; i++) {
- if (temp && temp.LessonID != result[i].LessonID) {
- item.ID = temp.LessonID;
- item.UnitName = unitNameStart + temp.LessonID;
- if (param2.BookID >= 207 && param2.BookID <= 211)
- item.UnitName = temp.LessonName;
- item.ListStr = item.List.join("、");
- item.Length = item.List.length;
- item.TestFunction = info[0].TestFunction;
- delete item.List;
- arr.push(item);
- item = { List: [] };
- }
- item.List.push(result[i].Word);
- temp = result[i];
- }
- if (result.length > 0) {
- item.ID = result[result.length - 1].LessonID;
- item.UnitName = unitNameStart + result[result.length - 1].LessonID;
- if (param2.BookID >= 207 && param2.BookID <= 211)
- item.UnitName = result[result.length - 1].LessonName;
- item.ListStr = item.List.join("、");
- item.Length = item.List.length;
- item.TestFunction = info[0].TestFunction;
- delete item.List;
- arr.push(item);
- }
- }
- result = arr;
- }
- result = {
- BookInfo: info[0],
- List1: result,
- };
- globalCache.set(url, result, config.BufferMemoryTimeHigh);
- }
- result.List2 = [];
- if (param.UserID) {
- param.IsNum = 1;
- const list = await miaoguo.GetMiaoguoTestExamineReport2(param);
- if (list && list.length > 0) {
- for (const unit of result.List1) {
- for (const report of list) {
- if (unit.UnitName == report.UnitName) {
- if (report.IsTestRead == 1)
- unit.IsTestRead = 1;
- if (report.IsBuildRead == 1)
- unit.IsBuildRead = 1;
- if (report.IsTestWrite == 1)
- unit.IsTestWrite = 1;
- if (report.IsBuildWrite == 1)
- unit.IsBuildWrite = 1;
- }
- }
- }
- }
- param.IsNum = 0;
- result.List2 = await miaoguo.GetMiaoguoTestExamineReport2(param);
- for (const item of result.List2) {
- item.TestTime = moment(item.TestTime).format("YYYY年MM月DD日 HH:mm");
- if (item.JSONData) {
- const arr = JSON.parse(item.JSONData);
- item.RightNum = arr[2].length;
- item.WrongNum = arr[0].length + arr[1].length;
- delete item.JSONData;
- } else {
- item.TestTime += " 已封存";
- }
- }
- }
- ctx.body = { errcode: 10000, result };
- }
- export async function InsertTestReport2(ctx) {
- const param = ctx.request.body || {};
- param.UserID = ctx.query.UserID || 0;
- param.TestTime = moment().format("YYYY-MM-DD HH:mm:ss");
- const list = await miaoguo.GetMiaoguoTestReport(param);
- if (list && list.length > 0) {
- param.ID = list[0].ID;
- await miaoguo.UpdateMiaoguoTestReport(param);
- } else {
- await miaoguo.AddMiaoguoTestReport(param);
- }
- ctx.body = { errcode: 10000 };
- }
- export async function GetMiaoguoTestReportByID(ctx) {
- const param = {
- ID: ctx.query.ID || 0,
- UserID: ctx.query.UserID || 0,
- };
- let result = null;
- const info = await miaoguo.GetMiaoguoTestExamineReport2(param);
- if (info && info.length > 0) {
- result = info[0];
- if (result.IsTestRead)
- result.TestType = "read";
- else if (result.IsTestWrite)
- result.TestType = "write";
- result.List = JSON.parse(result.JSONData);
- delete result.JSONData;
- result.TestTime = moment(result.TestTime).format("YYYY-MM-DD HH:mm:ss");
- }
- ctx.body = { errcode: 10000, result };
- }
- export async function InsertTestReport(ctx) {
- const param = ctx.request.body || {};
- param.UserID = ctx.query.UserID || 0;
- if (param.ID) {
- const param2 = {
- ID: param.ID,
- UserID: param.UserID,
- TestRightStr: param.TestRightStr,
- TestWrongStr: param.TestWrongStr,
- TestSkipStr: param.TestSkipStr,
- UpdateTime: moment().format("YYYY-MM-DD HH:mm:ss"),
- };
- if (param.TestTotal)
- param2.TestTotal = param.TestTotal;
- if (param.IsFinished == 1)
- param2.IsFinished = 1;
- if (param.IsFinished === 0)
- param2.IsFinished = 0;
- if (param.TestExistStr)
- param2.TestExistStr = param.TestExistStr;
- if (param.BookID)
- param2.BookID = param.BookID;
- await miaoguo.UpdateTestReport(param2);
- } else {
- param.UpdateTime = moment().format("YYYY-MM-DD HH:mm:ss");
- const result = await miaoguo.InsertTestReport(param);
- param.ID = result.insertId;
- }
- ctx.body = { errcode: 10000, result: param.ID };
- }
- export async function GetTestGradeArr(ctx) {
- const bufferMemoryUrl = "GetTestGradeArr";
- let result = globalCache.get(bufferMemoryUrl);
- if (result === 0) {
- const arr = [];
- let param = { Type: "TestMenuMain" };
- let listName = await hanzi.GetHanziBooks(param);
- param.Type = "TestMenu";
- let list = await hanzi.GetHanziBooks(param);
- for (const nameItem of listName) {
- const obj = {
- Name: nameItem.Category,
- Name2: nameItem.Category,
- Type: "CHN",
- Select: "",
- List: [],
- };
- for (const item of list) {
- if (nameItem.Category == item.Category) {
- obj.List.push({
- ID: item.ID,
- Type: item.HanziType,
- Name: item.Name1,
- Name2: item.Name2,
- Finish: 0,
- Total: item.Total,
- Image: item.Image,
- });
- }
- }
- arr.push(obj);
- }
- param = { FieldType: "Name1" };
- listName = await miaoguo.GetWordBooks(param);
- list = await miaoguo.GetWordBooks(null);
- for (const nameItem of listName) {
- const obj = {
- Name: nameItem.Category,
- Name2: nameItem.Category,
- Type: "ENG",
- Select: "",
- List: [],
- };
- for (const item of list) {
- if (nameItem.Category == item.Category) {
- obj.List.push({
- ID: item.ID,
- Type: "Word",
- Name: item.Name,
- Name2: item.Name2,
- Finish: 0,
- Total: item.Total,
- Image: item.Image,
- });
- }
- }
- arr.push(obj);
- }
- result = arr;
- if (result)
- globalCache.set(bufferMemoryUrl, result, config.BufferMemoryTimeHigher);
- }
- ctx.body = { errcode: 10000, result };
- }
- export async function GetTestReportList(ctx) {
- const param = {
- UserID: ctx.query.UserID || 0,
- };
- const list = await miaoguo.GetTestReportList(param);
- for (const item of list) {
- item.CreateTime = moment(item.CreateTime).format('MM月DD日');
- item.UpdateTime = moment(item.UpdateTime).format('MM月DD日');
- item.Name = item.Name.split("#");
- if (item.wName1 && item.wFlag >= 0) {
- item.Name[0] = item.wName1 + " " + item.wName2 + " " + item.wName3;
- delete item.wName1;
- delete item.wName2;
- delete item.wName3;
- delete item.wFlag;
- }
- if (item.hName1 && item.hFlag >= 0) {
- item.Name[0] = item.hName1 + " " + item.hName2 + " " + item.hName3;
- delete item.hName1;
- delete item.hName2;
- delete item.hName3;
- delete item.hFlag;
- }
- }
- ctx.body = { errcode: 10000, result: list };
- }
- export async function GetTestAncientPoetryList(ctx) {
- const param = {
- UserID: ctx.query.UserID || 0,
- BookID: ctx.query.BookID || 0,
- };
- const list = await hanzi.GetAncientPoetryList(param);
- const result = [];
- for (const item of list) {
- const peomContent = JSON.parse(item.PeomContent);
- let str2 = item.Dynasty + " " + item.Author + "\n\n";
- if (param.BookID >= 74 && item.Category == 1)
- str2 = "\n\n";
- for (const content of peomContent) {
- if (stringUtils.IsArray(content)) {
- for (const line of content)
- str2 += line + "\n";
- } else {
- str2 += content + "\n";
- }
- }
- let str3 = "";
- if (item.Translation) {
- const translation = JSON.parse(item.Translation);
- for (const content of translation) {
- if (stringUtils.IsArray(content)) {
- for (const line of content)
- str3 += line;
- } else {
- str3 += content;
- }
- }
- }
- const obj = {
- ID: item.ID,
- Word: item.Title,
- Content: [],
- };
- obj.Content.push({ ContentType: 0, Content: item.Tag });
- let str4 = "";
- if (param.BookID >= 74 && item.Category == 1)
- str4 = item.Title;
- else
- str4 = "《" + item.Title + "》";
- if (item.ImgUrl)
- str4 += "\n\n[图]" + item.ImgUrl + "[/图]";
- obj.Content.push({ ContentType: 1, Content: str4 });
- obj.Content.push({ ContentType: 2, Content: str2 });
- obj.Content.push({ ContentType: 3, Content: str3 });
- result.push(obj);
- }
- ctx.body = { errcode: 10000, result };
- }
- export async function GetTestEnglishWords(ctx) {
- const param = {
- UserID: ctx.query.UserID || 0,
- Words: ctx.query.Words || "",
- BookID: ctx.query.BookID || 0,
- LessonID: ctx.query.LessonID || 0,
- TestType: ctx.query.TestType || "read",
- };
- let list = [];
- if (param.BookID && ((Number(param.BookID) > 120 && Number(param.BookID) < 169) || (Number(param.BookID) >= 184 && Number(param.BookID) <= 186) || (Number(param.BookID) > 190 && Number(param.BookID) <= 211))) {
- list = await miaoguo.GetTestEnglishNewConceptWords(param);
- for (const item of list) {
- let question = "";
- let answer = "";
- let tags = "";
- let soundmark = "";
- const sound = item.Word.replace("ˈ", "%27");
- let readString = "https://sp0.baidu.com/-rM1hT4a2gU2pMbgoY3K/gettts?lan=uk&text=" + sound + "&spd=3&source=alading";
- if (item.Word == "our" || item.Word == "stomachache")
- readString = readString.replace("lan=uk", "lan=en");
- else if (item.Word == "Mr=mister")
- readString = readString.replace("text=Mr=mister", "text=mister");
- else if (item.Word == "(a) round the clock")
- readString = readString.replace("text=(a) round the clock", "text=a round the clock");
- else if (item.Word == "in favo(u)r of")
- readString = readString.replace("text=in favo(u)r of", "text=in favor of");
- if (param.TestType == "read") {
- if ((param.BookID > 140 && param.BookID < 149) || (param.BookID > 160 && param.BookID < 165)) {
- question = "[特]" + item.Word + "[/特]";
- question += "\n\n\n\n" + item.ExampleSentence;
- if (!item.Soundmark || item.Soundmark == "")
- item.Soundmark = "发音";
- soundmark = "[读 src='" + readString + "']" + item.Soundmark + "[/读]\n";
- answer = soundmark + "\n\n";
- answer += item.Translate;
- tags = "发音,释义";
- item.FontSize = 48;
- } else {
- question = item.Word;
- if (!item.Soundmark || item.Soundmark == "")
- item.Soundmark = "发音";
- soundmark = "[读 src='" + readString + "']" + item.Soundmark + "[/读]\n";
- answer = soundmark + "\n\n";
- if (param.BookID > 190 && param.BookID <= 211)
- answer += item.Translate;
- else
- answer += "[光]" + item.Translate + "[/光]";
- tags = "发音,释义";
- item.FontSize = 108;
- if (param.BookID >= 199 && param.BookID < 207)
- item.FontSize = 54;
- }
- } else if (param.TestType == "write") {
- if ((param.BookID > 140 && param.BookID < 149) || (param.BookID > 160 && param.BookID < 165)) {
- soundmark = "[读 src='" + readString + "']发音[/读]\n";
- question = soundmark + "\n\n";
- question += item.Translate;
- answer = "[特]" + item.Word + "[/特]";
- answer += "\n\n\n\n" + item.ExampleSentence;
- tags = "默写单词";
- item.FontSize = 48;
- } else {
- soundmark = "[读 src='" + readString + "']发音[/读]\n";
- question = soundmark + "\n\n";
- question += item.Translate;
- if (param.BookID == 135 || param.BookID == 184 || param.BookID == 185 || param.BookID == 186)
- tags = "默写词组";
- if (param.BookID >= 199 && param.BookID < 207)
- tags = "默写句子";
- else
- tags = "默写单词";
- answer = "[特]" + item.Word + "[/特]";
- if (param.BookID >= 199 && param.BookID < 207)
- answer = item.Word;
- item.FontSize = 48;
- }
- }
- item.ReadString = readString;
- item.Content = [
- { ContentType: 0, Content: tags },
- { ContentType: 1, Content: question },
- { ContentType: 2, Content: answer },
- { ContentType: 3, Content: "" },
- ];
- delete item.Soundmark;
- delete item.Translate;
- }
- } else if (param.BookID && Number(param.BookID) > 100 && Number(param.BookID) < 110) {
- list = constantClass.GetPhonetic();
- const arr = [];
- for (const item of list) {
- if (item.LessonID == param.LessonID)
- arr.push(item);
- }
- list = arr;
- } else if ((Number(param.BookID) >= 169 && Number(param.BookID) <= 183) || (Number(param.BookID) >= 212 && Number(param.BookID) <= 217)) {
- if (Number(param.BookID) >= 169 && Number(param.BookID) <= 172)
- param.Type = "GaoKao";
- else if (Number(param.BookID) >= 173 && Number(param.BookID) <= 177)
- param.Type = "GET4";
- else if (Number(param.BookID) >= 178 && Number(param.BookID) <= 183)
- param.Type = "GET6";
- else if (Number(param.BookID) >= 212 && Number(param.BookID) <= 217)
- param.Type = "GET6";
- list = await miaoguo.GetTestEnglishWords(param);
- const listTextbook = await miaoguo.GetTestEnglishWords({
- ...param,
- Type: "textbook",
- Words: list.map(item => item.Word),
- });
- for (const item of list) {
- if (!item.JSONString) {
- const soundFallback = item.Word.replace("ˈ", "%27");
- const readStringFallback = "https://sp0.baidu.com/-rM1hT4a2gU2pMbgoY3K/gettts?lan=uk&text=" + soundFallback + "&spd=3&source=alading";
- if (param.TestType == "write") {
- item.Content = [
- { ContentType: 0, Content: "默写单词" },
- { ContentType: 1, Content: "[读 src='" + readStringFallback + "']发音[/读]\n\n[光]" + item.Translate + "[/光]" },
- { ContentType: 2, Content: "[特]" + item.Word + "[/特]" },
- { ContentType: 3, Content: "" },
- ];
- item.FontSize = 48;
- } else {
- item.Content = [
- { ContentType: 0, Content: "发音,释义" },
- { ContentType: 1, Content: item.Word },
- { ContentType: 2, Content: "[读 src='" + readStringFallback + "']" + (item.Soundmark || "发音") + "[/读]\n\n[光]" + item.Translate + "[/光]" },
- { ContentType: 3, Content: "" },
- ];
- item.FontSize = 108;
- }
- item.ReadString = readStringFallback;
- continue;
- }
- const json = JSON.parse(item.JSONString);
- item.Data = json.ENG;
- let question = "";
- let answer = "";
- let tags = "";
- let soundmark = "";
- let paraphrase = "";
- if (item.Data.Soundmark && item.Data.Soundmark.EngSound && item.Data.Soundmark.Eng)
- soundmark = "[读 src='" + item.Data.Soundmark.EngSound + "']" + item.Data.Soundmark.Eng + "[/读]\n \n";
- if (item.Data.Paraphrase && item.Data.Paraphrase.length > 0) {
- for (const p of item.Data.Paraphrase) {
- paraphrase += p.PartOfSpeech;
- paraphrase += " " + p.ParaphraseList.join(" ") + "\n\n";
- }
- }
- let paraphraseBasic = "";
- let paraphraseBasicEng = "";
- if (listTextbook && listTextbook.length > 0) {
- for (const textBook of listTextbook) {
- if (textBook.Word == item.Data.Word)
- paraphraseBasicEng = textBook.Translate;
- }
- }
- paraphraseBasic = item.Translate;
- if (param.Words.substr(0, 8) == "\"A\",\"B\",") {
- question = item.Data.Word + " " + item.Data.Word.toString().toLowerCase();
- answer = soundmark.substr(0, soundmark.length - 3);
- answer += "[图]" + json.CHN.BiShunArr2[0] + "[/图]";
- answer += "\n[图]" + json.CHN.BiShunArr2[1] + "[/图]";
- tags = "发音,书写";
- item.FontSize = 108;
- } else if (param.TestType == "read") {
- question = item.Data.Word;
- answer = soundmark;
- if (paraphraseBasic) {
- answer += item.Data.Word + " 的基本中文释义\n\n";
- answer += "[光]" + paraphraseBasic + "[/光]\n\n";
- }
- if (paraphraseBasicEng) {
- answer += item.Data.Word + " 的基本英文释义\n\n";
- answer += "[光]" + paraphraseBasicEng + "[/光]\n\n";
- }
- if (Number(param.BookID) >= 169 && Number(param.BookID) <= 172) {
- answer += item.Data.Word + " 的更多中文释义\n\n";
- answer += paraphrase;
- }
- tags = "发音,释义";
- item.FontSize = 108;
- } else if (param.TestType == "write") {
- if (item.Data.Soundmark && item.Data.Soundmark.Eng)
- soundmark = soundmark.replace(item.Data.Soundmark.Eng, "发音");
- else
- soundmark = "";
- question = soundmark;
- if (paraphraseBasic)
- question += "[光]" + paraphraseBasic + "[/光]\n\n";
- if (paraphraseBasicEng)
- question += "[光]" + paraphraseBasicEng + "[/光]\n\n";
- if (Number(param.BookID) >= 169 && Number(param.BookID) <= 172) {
- paraphrase = stringUtils.ReplaceAllString(paraphrase, item.Data.Word, "[光]~[/光]");
- question += paraphrase;
- }
- answer = "[特]" + item.Data.Word + "[/特]";
- tags = "默写单词";
- item.FontSize = 48;
- }
- item.Word = item.Data.Word;
- if (item.Data.Soundmark && item.Data.Soundmark.EngSound)
- item.ReadString = item.Data.Soundmark.EngSound;
- else
- item.ReadString = "";
- item.Content = [
- { ContentType: 0, Content: tags },
- { ContentType: 1, Content: question },
- { ContentType: 2, Content: answer },
- { ContentType: 3, Content: "" },
- ];
- delete item.JSONString;
- delete item.Data;
- }
- } else {
- param.Words = param.Words.split(",");
- param.Words = JSON.stringify(param.Words);
- param.Words = param.Words.substr(1, param.Words.length - 2);
- list = await miaoguo.GetTestEnglishWords(param);
- param.Type = "textbook";
- const listTextbook = await miaoguo.GetTestEnglishWords(param);
- for (const item of list) {
- const json = JSON.parse(item.JSONString);
- item.Data = json.ENG;
- let question = "";
- let answer = "";
- let tags = "";
- let soundmark = "";
- let paraphrase = "";
- if (item.Data.Soundmark && item.Data.Soundmark.EngSound && item.Data.Soundmark.Eng)
- soundmark = "[读 src='" + item.Data.Soundmark.EngSound + "']" + item.Data.Soundmark.Eng + "[/读]\n \n";
- if (item.Data.Paraphrase && item.Data.Paraphrase.length > 0) {
- for (const p of item.Data.Paraphrase) {
- paraphrase += p.PartOfSpeech;
- paraphrase += " " + p.ParaphraseList.join(" ") + "\n\n";
- }
- }
- let paraphraseBasic = "";
- let paraphraseBasicEng = "";
- let exampleSentence = "";
- if (listTextbook && listTextbook.length > 0) {
- for (const textBook of listTextbook) {
- if (textBook.Word == item.Data.Word && textBook.BookID < 160)
- paraphraseBasic = textBook.Translate;
- if (textBook.Word == item.Data.Word && textBook.BookID > 160) {
- paraphraseBasicEng = textBook.Translate;
- exampleSentence = textBook.ExampleSentence;
- }
- }
- }
- if (param.Words.substr(0, 8) == "\"A\",\"B\",") {
- question = item.Data.Word + " " + item.Data.Word.toString().toLowerCase();
- answer = soundmark.substr(0, soundmark.length - 3);
- answer += "[图]" + json.CHN.BiShunArr2[0] + "[/图]";
- answer += "\n[图]" + json.CHN.BiShunArr2[1] + "[/图]";
- tags = "发音,书写";
- item.FontSize = 108;
- } else if (param.TestType == "read") {
- question = item.Data.Word;
- answer = soundmark;
- if (paraphraseBasic) {
- answer += item.Data.Word + " 的基本中文释义\n\n";
- answer += "[光]" + paraphraseBasic + "[/光]\n\n";
- }
- if (paraphraseBasicEng) {
- answer += item.Data.Word + " 的基本英文释义\n\n";
- answer += "[光]" + paraphraseBasicEng + "[/光]\n\n";
- }
- answer += item.Data.Word + " 的更多中文释义\n\n";
- answer += paraphrase;
- tags = "发音,释义";
- item.FontSize = 108;
- } else if (param.TestType == "write") {
- if (item.Data.Soundmark && item.Data.Soundmark.Eng)
- soundmark = soundmark.replace(item.Data.Soundmark.Eng, "发音");
- else
- soundmark = "";
- question = soundmark;
- if (paraphraseBasic)
- question += "[光]" + paraphraseBasic + "[/光]\n\n";
- if (paraphraseBasicEng)
- question += "[光]" + paraphraseBasicEng + "[/光]\n\n";
- paraphrase = stringUtils.ReplaceAllString(paraphrase, item.Data.Word, "[光]~[/光]");
- question += paraphrase;
- answer = "[特]" + item.Data.Word + "[/特]";
- tags = "默写单词";
- item.FontSize = 48;
- }
- item.Word = item.Data.Word;
- if (item.Data.Soundmark && item.Data.Soundmark.EngSound)
- item.ReadString = item.Data.Soundmark.EngSound;
- else
- item.ReadString = "";
- item.Content = [
- { ContentType: 0, Content: tags },
- { ContentType: 1, Content: question },
- { ContentType: 2, Content: answer },
- { ContentType: 3, Content: "" },
- ];
- delete item.JSONString;
- delete item.Data;
- if (param.TestType == "read" && param.Words.substr(0, 8) != "\"A\",\"B\",") {
- if (exampleSentence || (json.ENG.ExamplesSentences && json.ENG.ExamplesSentences.length > 0)) {
- const temp = json.ENG.ExamplesSentences;
- item.Content[2].Content = item.Content[2].Content + "\n例句:";
- let index = 0;
- if (exampleSentence)
- item.Content[2].Content = item.Content[2].Content + "\n\n(" + (++index) + ") " + exampleSentence + "\n\n";
- const len = temp.length > 5 ? 5 : temp.length;
- for (let j = 0; j < len; j++) {
- const num = "(" + (++index) + ")";
- item.Content[2].Content = item.Content[2].Content + "\n\n" + num + " " + temp[j][0] + "\n" + temp[j][1];
- }
- }
- }
- }
- }
- ctx.body = { errcode: 10000, result: list };
- }
- export async function GetMiaoguoTestExamine(ctx) {
- const param = {
- BookID: ctx.query.BookID || 0,
- UnitName: ctx.query.UnitName || "",
- UnitID: ctx.query.UnitID || 0,
- TestType: ctx.query.TestType || "read",
- IsBuild: ctx.query.IsBuild || false,
- };
- const cacheKey = "GetMiaoguoTestExamine?BookID=" + param.BookID + "&UnitName=" + param.UnitName + "&UnitID=" + param.UnitID + "&TestType=" + param.TestType + "&IsBuild=" + param.IsBuild;
- let result = globalCache.get(cacheKey);
- if (result === 0) {
- const info = await miaoguo.GetMiaoguoPackage(param);
- param.Category = info[0].Category;
- param.BookID = info[0].BookIDOld;
- if (param.Category == "语文") {
- if (param.BookID == "43" || param.BookID == "44") {
- const list = await fetchLocalResult('/api/GetPinyinUnitWords?TestType=' + param.TestType + '&BookID=' + param.BookID + '&UnitID=' + param.UnitID + '&Word=' + param.UnitName);
- const arr = [];
- for (const item of list) {
- const obj = {};
- if (param.IsBuild)
- obj.Content = item.Content;
- obj.ContentNew = changeStringToView(item.Content);
- obj.TagWidth = 230;
- obj.FontSize = 108;
- obj.Word = item.Word;
- obj.ReadString = item.ReadString;
- arr.push(obj);
- }
- result = arr;
- } else if (param.UnitName == "古诗文" || param.UnitName == "日积月累") {
- const list = await fetchLocalResult('/api/GetTestAncientPoetryList?BookID=' + param.BookID);
- const arr = [];
- for (const item of list) {
- const obj = {};
- if (param.IsBuild)
- obj.Content = item.Content;
- obj.ContentNew = changeStringToView(item.Content);
- obj.TagWidth = 306;
- if (param.BookID >= "74")
- obj.TagWidth = 520;
- if (item.Word.length > 8)
- obj.FontSize = 48;
- else
- obj.FontSize = 64;
- obj.Word = item.Word;
- arr.push(obj);
- }
- result = arr;
- } else {
- const unitInfo = await hanzi.GetHanziUnitInfo(param);
- if (unitInfo && unitInfo.length > 0 && unitInfo[0].UnitType == 2) {
- const words = await hanzi.GetHanziUnitByID(param);
- if (words[0] && words[0].Example) {
- param.Words = words[0].Example.split(",").join("','");
- result = await hanzi.GetMiaoguoLiteracyWords(param);
- let temp = "";
- const arrTemp = [];
- for (const item of result) {
- if (temp != item.Word && item.JSONString) {
- const json = JSON.parse(item.JSONString);
- const obj = { ID: arrTemp.length + 1 };
- let qustion;
- let answer;
- let tags;
- if (param.TestType == "read") {
- qustion = item.Word;
- answer = "[读 src='" + item.Word + "']" + json.CHN.PinYin[0].pinyin + "[/读]\n\n";
- answer += json.CHN.PinYin[0].explain;
- tags = "怎么念";
- obj.FontSize = 108;
- } else {
- qustion = "[读 src='" + item.Word + "']" + json.CHN.PinYin[0].pinyin + "[/读]\n";
- answer = item.Word + "\n\n";
- if (json.CHN.KaitiArr) {
- for (const kaiti of json.CHN.KaitiArr)
- answer += "[图 w='650' h='650']" + kaiti + "[/图]\n";
- }
- answer += json.CHN.PinYin[0].explain;
- tags = "怎么写";
- }
- obj.Word = item.Word;
- obj.ReadString = item.Word;
- obj.Content = [
- { ContentType: 0, Content: tags },
- { ContentType: 1, Content: qustion },
- { ContentType: 2, Content: answer },
- { ContentType: 3, Content: "" },
- ];
- obj.ContentNew = changeStringToView(obj.Content);
- obj.TagWidth = 136;
- if (!param.IsBuild)
- delete obj.Content;
- arrTemp.push(obj);
- }
- temp = item.Word;
- }
- result = arrTemp;
- }
- } else if (unitInfo && unitInfo.length > 0 && unitInfo[0].UnitType == 4) {
- const words = await hanzi.GetHanziUnitByID(param);
- const arrAncientList = await hanzi.GetAncientChineseProse({ IsList: 0 });
- result = [];
- if (words[0] && words[0].Name) {
- for (const ancient of arrAncientList) {
- if (ancient.Word == words[0].Name) {
- let qustion = ancient.ExampleSentence;
- qustion = stringUtils.ReplaceAllString(qustion, ancient.Word, "[光]" + ancient.Word + "[/光]");
- const readString = "“" + ancient.Word + "”字在这里的意思是" + ancient.Definitions;
- let answer = "[读 src='" + readString + "']" + ancient.Definitions + "[/读]\n\n";
- if (ancient.ExampleDefinitions.indexOf("译文") < 0)
- answer += "译文:";
- answer += ancient.ExampleDefinitions;
- const obj = {
- Word: "【" + ancient.Word + "】" + ancient.Definitions,
- ReadString: readString,
- Content: [
- { ContentType: 0, Content: "文言文字释义" },
- { ContentType: 1, Content: qustion },
- { ContentType: 2, Content: answer },
- { ContentType: 3, Content: "" },
- ],
- TagWidth: 270,
- };
- obj.ContentNew = changeStringToView(obj.Content);
- if (!param.IsBuild)
- delete obj.Content;
- result.push(obj);
- }
- }
- }
- } else if (unitInfo && unitInfo.length > 0 && unitInfo[0].UnitType == 3) {
- const words = await hanzi.GetHanziUnitByID(param);
- const resultList = await hanzi.GetAncientChineseProseSentence({ Unit: words[0].Name });
- result = [];
- if (words[0] && words[0].Name) {
- for (const item of resultList) {
- let qustion;
- let answer;
- let tags;
- if (param.TestType == "read") {
- qustion = item.Question;
- answer = "[光]" + item.Sentence + "[/光]\n\n";
- answer += "含义\n• " + item.Paraphrase + "\n\n";
- if (item.Explain)
- answer += "详解\n• " + item.Explain + "\n\n";
- if (item.Idiom)
- answer += "句中包含的成语\n• " + item.Idiom + "\n\n";
- if (item.SentenceFragment)
- answer += "原文片段\n• " + item.SentenceFragment + "\n\n";
- if (item.Source) {
- answer += "出自\n• 《" + item.Source + "》 ";
- if (item.Author)
- answer += item.Author + " ";
- if (item.Dynasty)
- answer += "(" + item.Dynasty + ")";
- answer += "\n\n";
- }
- tags = "接下文";
- } else {
- qustion = item.Paraphrase;
- answer = "[光]" + item.Sentence + "[/光]\n\n";
- if (item.Explain)
- answer += "详解\n• " + item.Explain + "\n\n";
- if (item.Idiom)
- answer += "句中包含的成语\n• " + item.Idiom + "\n\n";
- if (item.SentenceFragment)
- answer += "原文片段\n• " + item.SentenceFragment + "\n\n";
- if (item.Source) {
- answer += "出自\n• 《" + item.Source + "》 ";
- if (item.Author)
- answer += item.Author + " ";
- if (item.Dynasty)
- answer += "(" + item.Dynasty + ")";
- answer += "\n\n";
- }
- tags = "说古文";
- }
- const obj = {
- Word: item.Sentence,
- Content: [
- { ContentType: 0, Content: tags },
- { ContentType: 1, Content: qustion },
- { ContentType: 2, Content: answer },
- { ContentType: 3, Content: "" },
- ],
- TagWidth: 136,
- };
- obj.ContentNew = changeStringToView(obj.Content);
- if (!param.IsBuild)
- delete obj.Content;
- result.push(obj);
- }
- }
- } else {
- if ((param.UnitID > 93 && param.UnitID <= 358) || (param.UnitID >= 561)) {
- const words = await hanzi.GetHanziUnitByID(param);
- param.Words = words[0].Example.split("").join("','");
- result = await hanzi.GetHanziUnitWords(param);
- } else if (param.UnitID <= 93) {
- result = await hanzi.GetHanziUnitWords(param);
- }
- for (const item of result) {
- if (item.Pinyin) {
- item.Pinyin = item.Pinyin.split(",")[0];
- item.CombineWords2 = stringUtils.ReplaceAllString(item.CombineWords, item.Name, item.Pinyin);
- if (item.CombineWords.length == 2 && item.CombineWords[0] == item.CombineWords[1]) {
- switch (item.CombineWords) {
- case "妈妈":
- item.CombineWords2 = "māma";
- break;
- case "爸爸":
- item.CombineWords2 = "bàba";
- break;
- case "叔叔":
- item.CombineWords2 = "shūshu";
- break;
- case "弟弟":
- item.CombineWords2 = "dìdi";
- break;
- case "爷爷":
- item.CombineWords2 = "yéye";
- break;
- case "哥哥":
- item.CombineWords2 = "gēge";
- break;
- case "玲玲":
- item.CombineWords2 = "língling";
- break;
- }
- }
- if (item.CombineWords.length == 2) {
- switch (item.CombineWords) {
- case "倔强":
- item.CombineWords2 = "jué强";
- item.Pinyin = "jué";
- break;
- case "搂住":
- item.CombineWords2 = "lǒu住";
- item.Pinyin = "lǒu";
- break;
- }
- }
- }
- }
- result = getWordJSON(param, result);
- }
- }
- } else if (param.Category == "English") {
- let unitsid = "";
- let words = "";
- const bookid = param.BookID;
- if (bookid > 100 && bookid < 110 && param.UnitName)
- unitsid = Number(param.UnitName);
- else if (bookid >= 111 && bookid <= 119) {
- const engList = await miaoguo.GetWordFrequencyList({ Limit: 3000 });
- const idStart = (Number(param.UnitName.replace("单元", "")) - 1) * 10;
- words = "&Words=";
- for (let j = idStart; j < idStart + 10; j++)
- words += engList[j].Word + ",";
- words = words.substr(0, words.length - 1);
- } else if ((bookid > 120 && bookid <= 124) || (bookid >= 169 && bookid <= 186))
- unitsid = Number(param.UnitName.replace("Lesson ", ""));
- else if (bookid > 130 && bookid <= 168 && param.UnitName)
- unitsid = Number(param.UnitName);
- else if (bookid == 100) {
- param.TestType = "read";
- words = "&Words=A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z";
- } else if (info[0].LibraryName1.indexOf("剑桥") >= 0 && info[0].LibraryName2 == "分类词汇") {
- unitsid = param.UnitID;
- param.UnitID = param.BookID;
- param.BookID = 133;
- if (info[0].LibraryName1 == "剑桥PET")
- param.BookID = 134;
- else if (info[0].LibraryName1 == "剑桥FCE")
- param.BookID = 136;
- } else if (bookid > 190 && bookid <= 211)
- unitsid = param.UnitID;
- const list = await fetchLocalResult('/api/GetTestEnglishWords?TestType=' + param.TestType + '&BookID=' + param.BookID + '&LessonID=' + param.UnitID + words);
- const arr = [];
- for (let i = 0; i < list.length; i++) {
- const obj = {};
- if (param.IsBuild)
- obj.Content = list[i].Content;
- if (list[i].ExampleSentence && list[i].ExampleSentence.substring(0, 1) == "{") {
- const arrTemp = ["\n\n例句:"];
- const jsonSentence = JSON.parse(list[i].ExampleSentence);
- const arrSentence = jsonSentence.Sentences;
- const count = arrSentence.length > 2 ? 2 : arrSentence.length;
- for (let k = 0; k < count; k++) {
- let sentence1 = arrSentence[k].Sentence;
- const word2 = list[i].Word;
- sentence1 = stringUtils.ReplaceAllString(sentence1, word2, "[线]" + word2 + "[/线]");
- if (sentence1.substring(0, word2.length).toLowerCase() == word2.toLowerCase()) {
- const word1 = sentence1.substring(0, word2.length);
- sentence1 = sentence1.replace(word1, "[线]" + word1 + "[/线]");
- }
- arrTemp.push(sentence1);
- arrTemp.push(arrSentence[k].Translate);
- arrTemp.push("\n");
- }
- list[i].Content[2].Content += arrTemp.join("\n");
- }
- obj.ContentNew = changeStringToView(list[i].Content);
- obj.Word = list[i].Word;
- obj.ReadString = list[i].ReadString;
- if (param.TestType == "read") {
- obj.TagWidth = 212;
- obj.FontSize = 108;
- if ((param.BookID >= 140 && param.BookID <= 149) || (param.BookID >= 160 && param.BookID <= 164))
- obj.FontSize = 48;
- else if ((param.BookID == 135) || (param.BookID >= 184 && param.BookID <= 186))
- obj.FontSize = 72;
- if (obj.Word.length > 10)
- obj.FontSize = 84;
- if (param.BookID >= 199 && param.BookID < 207)
- obj.FontSize = 54;
- } else if (param.TestType == "write") {
- obj.TagWidth = 186;
- obj.FontSize = 42;
- }
- if (info[0].LibraryName1.indexOf("剑桥") >= 0 && info[0].LibraryName2 == "分类词汇") {
- if (i >= (unitsid - 1) * 10 && i < unitsid * 10)
- arr.push(obj);
- } else {
- arr.push(obj);
- }
- }
- result = arr;
- }
- globalCache.set(cacheKey, result, config.BufferMemoryTimeHigh);
- }
- ctx.body = { errcode: 10000, result };
- }
- export async function AddMiaoguoCard(ctx) {
- const param = ctx.request.body || {};
- let createSource = "app";
- if (param.VisitType) {
- createSource = Decrypt(param.VisitType, config.urlSecrets.aes_key, config.urlSecrets.aes_iv);
- if (createSource == "web") {
- param.ID = Decrypt(param.ID, config.urlSecrets.aes_key, config.urlSecrets.aes_iv);
- delete param.VisitType;
- ctx.query.Type = param.Type;
- delete param.Type;
- }
- }
- param.UserID = ctx.query.UserID;
- const field1 = param.Field1 || "";
- const field2 = param.Field2 || "";
- const field3 = param.Field3 || "";
- let tags = "";
- if (param.Tags && param.Tags.length > 0)
- tags = stringUtils.IsArray(param.Tags) ? param.Tags.join(",") : param.Tags;
- delete param.Field1;
- delete param.Field2;
- delete param.Field3;
- delete param.Tags;
- let isExist = false;
- if (ctx.query.Type == "IsExist") {
- const param2 = {
- UserID: ctx.query.UserID,
- FolderID: param.FolderID,
- Content: stringUtils.ReplaceAllString(field1, "'", "''"),
- IsTest: 1,
- };
- param2.Content = stringUtils.ReplaceAllString(param2.Content, "\n", "");
- const miaoguoCardID = await miaoguo.GetCardIDByContent(param2);
- if (miaoguoCardID && miaoguoCardID.length > 0) {
- param2.MiaoguoCardID = miaoguoCardID[0].MiaoguoCardID;
- param2.Type = "TestReset";
- await miaoguo.ResetCard(param2);
- globalCache.delete("GetMiaoguoCard###UserID=" + param.UserID);
- isExist = true;
- }
- }
- if (!isExist && (ctx.query.Type == "edit" || ctx.query.Type == "edit1" || ctx.query.Type == "edit2" || ctx.query.Type == "edit3")) {
- param.MiaoguoCardID = param.ID;
- delete param.ID;
- let obj = {
- MiaoguoCardID: param.MiaoguoCardID,
- ContentType: 1,
- Content: updateSoundError(field1, createSource),
- };
- await miaoguo.UpdateCardContent(obj);
- obj.ContentType = 2;
- obj.Content = updateSoundError(field2, createSource);
- await miaoguo.UpdateCardContent(obj);
- obj.ContentType = 3;
- obj.Content = updateSoundError(field3, createSource);
- await miaoguo.UpdateCardContent(obj);
- if (tags || tags.length == 0) {
- obj.ContentType = 0;
- obj.Content = tags;
- await miaoguo.UpdateCardContent(obj);
- }
- if (param.IsTodayStudy || param.LimitTime) {
- obj = {
- MiaoguoCardID: param.MiaoguoCardID,
- IsTodayStudy: param.IsTodayStudy,
- IsCollect: param.IsCollect || 0,
- FolderID: param.FolderID || 0,
- FontSize: param.FontSize || 48,
- };
- if (param.LimitTime) {
- if (param.LimitTime.indexOf("/") >= 0)
- param.LimitTime = stringUtils.ReplaceAllString(param.LimitTime.toString(), "/", "-");
- obj.LimitTime = moment(param.LimitTime).format('YYYY-MM-DD HH:mm:ss');
- }
- if (param.IsTodayStudy == 1)
- obj.LimitTime = moment().format('YYYY-MM-DD HH:mm:ss');
- obj.UpdateTime = moment().format('YYYY-MM-DD HH:mm:ss');
- const cardInfo = await miaoguo.GetCardInfo(param);
- await miaoguo.UpdateCard(obj);
- const param2 = {
- UserID: param.UserID,
- MiaoguoCardID: param.MiaoguoCardID,
- CardType: param.CardType || 0,
- LimitTime: obj.LimitTime,
- };
- if (param2.LimitTime === "" || param2.LimitTime == "undefined")
- delete param2.LimitTime;
- else if (cardInfo && cardInfo.length > 0) {
- const limittime = moment(cardInfo[0].LimitTime).format('YYYY-MM-DD HH:mm:ss');
- if (param2.LimitTime == limittime)
- delete param2.LimitTime;
- }
- if (cardInfo && cardInfo.length > 0 && param2.CardType != cardInfo[0].CardType)
- await miaoguo.UpdateCardType(param2);
- miaoguo.AddMiaoguoLog({
- UserID: ctx.query.UserID,
- LogID: 298,
- Content: JSON.stringify({ Content1: obj, Content2: param2 }),
- }).catch(err => console.error('AddMiaoguoLog failed:', err));
- }
- } else if (!isExist) {
- delete param.ID;
- param.CreateTime = moment().format('YYYY-MM-DD HH:mm:ss');
- if (!param.LimitTime)
- param.LimitTime = param.CreateTime;
- param.UpdateTime = param.CreateTime;
- param.CreateSource = createSource;
- let canSave = true;
- if (field1 && (field1.indexOf("]undefined[/图]") > 0 || field1.indexOf("][/图]") > 0 || field2.indexOf("]undefined[/图]") > 0 || field2.indexOf("][/图]") > 0 || field3.indexOf("]undefined[/图]") > 0 || field3.indexOf("][/图]") > 0))
- canSave = false;
- if (canSave) {
- const insertResult = await miaoguo.AddCard(param);
- const obj = {
- MiaoguoCardID: insertResult.insertId,
- ContentType: 0,
- Content: tags,
- };
- await miaoguo.AddCardContent(obj);
- obj.ContentType = 1;
- obj.Content = updateSoundError(field1, createSource);
- await miaoguo.AddCardContent(obj);
- obj.ContentType = 2;
- obj.Content = updateSoundError(field2, createSource);
- await miaoguo.AddCardContent(obj);
- obj.ContentType = 3;
- obj.Content = updateSoundError(field3, createSource);
- await miaoguo.AddCardContent(obj);
- miaoguo.AddMiaoguoLog({
- UserID: ctx.query.UserID,
- LogID: 297,
- Content: JSON.stringify(param),
- }).catch(err => console.error('AddMiaoguoLog failed:', err));
- }
- }
- globalCache.delete("GetMiaoguoCard###UserID=" + param.UserID);
- ctx.body = { errcode: 10000 };
- function updateSoundError(content, source) {
- if (source == "web" && content) {
- const arr = constantClass.GetSoundErrorArr();
- let str = content;
- while (str.indexOf("[读 src=") >= 0) {
- str = str.substr(str.indexOf("[读 src=") + 8);
- const sound = str.substr(0, str.indexOf("'"));
- for (const item of arr) {
- if (sound.indexOf(item.Word) >= 0 && sound.indexOf(item.Sound) < 0) {
- const sound2 = sound.replace(item.Word, item.Sound);
- content = content.replace("[读 src='" + sound, "[读 src=''" + sound2);
- break;
- }
- }
- }
- }
- return content;
- }
- }
- export async function BuildMiaoguoTestCard(ctx) {
- const param = ctx.request.body || {};
- param.UserID = ctx.query.UserID || 0;
- if (param.FolderID == -1) {
- const arrColor = constantClass.getFolderColor;
- const arrFolderIcon = constantClass.getFolderIcon;
- const numColor = stringUtils.Random(0, arrColor.length - 1);
- const numIcon = stringUtils.Random(0, arrFolderIcon.length - 1);
- const obj2 = {
- UserID: param.UserID || 0,
- Name: param.UnitName + "_" + moment().format("MMDDHHmm"),
- FolderType: 0,
- ColorName: arrColor[numColor].Color,
- IconName: arrFolderIcon[numIcon],
- UpdateTime: moment().format("YYYY-MM-DD HH:mm:ss"),
- Flag: 0,
- };
- const insertID = await miaoguo.AddFolderInfo(obj2);
- param.FolderID = insertID.insertId;
- } else if (param.FolderID > 0) {
- await miaoguo.UpdateFolderInfo({
- ID: param.FolderID,
- UserID: param.UserID,
- UpdateTime: moment().format("YYYY-MM-DD HH:mm:ss"),
- });
- }
- const list = await fetchLocalResult("/api/GetMiaoguoTestExamine?BookID=" + param.BookID + "&UnitName=" + param.UnitName + "&UnitID=" + param.UnitID + "&TestType=" + param.TestType + "&IsBuild=1");
- if (param.WordList.length > 0) {
- for (let i = 0; i < param.WordList.length; i++) {
- if (param.WordList[i] && param.WordList[i].Word)
- param.WordList[i] = param.WordList[i].Word;
- }
- }
- const arr = [];
- for (const word of param.WordList) {
- for (const item of list) {
- if (word == item.Word) {
- const obj = {
- Field1: item.Content[1].Content,
- Field2: item.Content[2].Content,
- Field3: item.Content[3] && item.Content[3].Content ? item.Content[3].Content : "",
- Tags: item.Content[0].Content,
- ID: 0,
- FolderID: param.FolderID,
- LimitTime: moment().format("YYYY-MM-DD HH:mm:ss"),
- FontSize: item.FontSize,
- };
- if (!stringUtils.CheckIsArray(obj.Tags))
- obj.Tags = obj.Tags.split(",");
- arr.push(obj);
- break;
- }
- }
- }
- for (const postJSON of arr)
- await fetchLocalPost("/api/AddMiaoguoCard?Type=IsExist&UserID=" + param.UserID, postJSON);
- ctx.body = { errcode: 10000 };
- }
- export async function BuildMiaoguoCardByYJBDC(ctx) {
- const param = ctx.request.body || {};
- param.UserID = ctx.query.UserID || 0;
- let folderID = 0;
- const folderInfo = await miaoguo.GetMiaoguoFolderCount({ UserID: param.UserID, FolderType: 2 });
- if (!folderInfo || folderInfo.length == 0) {
- const insertID = await miaoguo.AddFolderInfo({
- UserID: ctx.query.UserID || 0,
- Name: "语境背单词",
- FolderType: 2,
- ColorName: "#7C63DC",
- IconName: "cardlist_paper_white_48x62",
- UpdateTime: moment().format("YYYY-MM-DD HH:mm:ss"),
- Flag: 0,
- });
- folderID = insertID.insertId;
- } else if (folderInfo.length > 0) {
- folderID = folderInfo[0].ID;
- }
- const arrWords = param.Words.split(",");
- for (let i = 0; i < arrWords.length; i++)
- arrWords[i] = "'" + arrWords[i].replace(/'/g, "''") + "'";
- const list = await miaoguo.RunSql(null, "select * from Words where BookID=110 and Word in (" + arrWords.join(",") + ");");
- const arr = [];
- for (const item of list) {
- const question = "[特]" + item.Word + "[/特]";
- let answer = "";
- if (item.Soundmark)
- answer = "[读 src='https://sp0.baidu.com/-rM1hT4a2gU2pMbgoY3K/gettts?lan=uk&text=" + item.Word + "&spd=3&source=alading']" + item.Soundmark + "[/读]\n \n";
- answer += "[光]" + item.Translate + "[/光]\n \n";
- if (item.ExampleSentence) {
- answer += "例句:\n";
- const json = JSON.parse(item.ExampleSentence);
- const sentences = json.Sentences;
- const count = sentences.length > 3 ? 3 : sentences.length;
- for (let j = 0; j < count; j++) {
- answer += "(" + (j + 1) + ")" + sentences[j].Sentence + "\n";
- answer += sentences[j].Translate + "\n\n";
- }
- }
- arr.push({
- Field1: question,
- Field2: answer,
- Field3: "",
- Tags: ["语境", "单词"],
- ID: 0,
- FolderID: folderID,
- LimitTime: moment().format("YYYY-MM-DD HH:mm:ss"),
- });
- }
- for (const postJSON of arr)
- await fetchLocalPost("/api/AddMiaoguoCard?Type=IsExist&UserID=" + param.UserID, postJSON);
- ctx.body = { errcode: 10000 };
- }
- export async function UpdateMiaoguoCardTodayAll(ctx) {
- const paramBody = ctx.request.body || {};
- let currentTime = moment().format('YYYY-MM-DD HH:mm:ss');
- const logInfo = await miaoguo.GetMiaoguoLogInfo({ UserID: ctx.query.UserID, LogID: 304 });
- if (logInfo && logInfo.length > 0) {
- const today = moment().format('YYYY-MM-DD');
- const startDate = moment(logInfo[0].CreateTime).format('YYYY-MM-DD');
- if (startDate < today)
- currentTime = startDate + " 23:59:59";
- }
- for (const item of paramBody.List || []) {
- const param = {
- MiaoguoCardID: item.MiaoguoCardID,
- UserID: ctx.query.UserID,
- IntervalTime: item.IntervalTime || "1d",
- BtnNumber: item.BtnNumber || 4,
- FontSize: item.FontSize || 48,
- Duration: item.Duration || 0,
- LearningType: item.LearningType || 0,
- IsUndo: item.IsUndo || 0,
- LastTime: item.LastTime || currentTime,
- };
- if (param.LastTime > currentTime)
- param.LastTime = currentTime;
- if (param.Duration == "undefined")
- param.Duration = 0;
- let info = await miaoguo.GetCardInfo(param);
- if (info && info.length > 0) {
- info = info[0];
- if (param.BtnNumber != 1 && param.BtnNumber != -1) {
- info.LastTime = param.LastTime;
- info.FirstTime = moment(info.FirstTime).format('YYYY-MM-DD HH:mm:ss');
- if (info.FirstTime < "1900-01-02 00:00:00")
- info.FirstTime = info.LastTime;
- info.LearnNumber = info.LearnNumber + 1;
- let btnNumber = param.BtnNumber;
- if (param.LearningType == 0 && btnNumber < 4)
- btnNumber = 4;
- if (info.RepetitionCoefficient > 1.3)
- info.RepetitionCoefficient = getEF(info.RepetitionCoefficient, btnNumber);
- else
- info.RepetitionCoefficient = 1.5;
- }
- if (param.BtnNumber == 1) {
- info.LastTime = param.LastTime;
- const days = Number(param.IntervalTime.replace("d", ""));
- info.LimitTime = moment().add(days, "days").format('YYYY-MM-DD HH:mm:ss');
- } else if (param.IntervalTime) {
- const intervalTime = param.IntervalTime;
- if (intervalTime.indexOf("m") > 0) {
- const minute = Number(intervalTime.replace("m", ""));
- info.LimitTime = moment().add(minute, "minute").format('YYYY-MM-DD HH:mm:ss');
- info.IntervalDay = 0;
- } else if (intervalTime.indexOf("d") > 0) {
- const days = Number(intervalTime.replace("d", ""));
- info.LimitTime = moment().add(days, "days").format('YYYY-MM-DD HH:mm:ss');
- info.IntervalDay = days;
- }
- }
- if (param.FontSize)
- info.FontSize = param.FontSize;
- if (param.BtnNumber == -1) {
- info.IsTodayStudy = 1;
- info.LimitTime = moment().format('YYYY-MM-DD HH:mm:ss');
- info.IntervalDay = 0;
- } else if (info.IsTodayStudy == 1 && param.BtnNumber > 0) {
- info.IsTodayStudy = 0;
- }
- await miaoguo.UpdateCard(info);
- const obj = {
- CardID: param.MiaoguoCardID,
- CardType: info.CardType,
- CreateTime: param.LastTime,
- LearningType: param.LearningType,
- BtnNumber: Number(param.BtnNumber),
- RepetitionCoefficient: info.RepetitionCoefficient,
- };
- if (param.IntervalTime) {
- if (param.BtnNumber == 1)
- obj.IntervalTime = "1d";
- else
- obj.IntervalTime = param.IntervalTime;
- }
- if (param.Duration) {
- obj.Duration = param.Duration;
- if (param.Duration > 1800)
- obj.Duration = 1800;
- }
- const learningRecord = await miaoguo.GetLearningRecordInfoNew(obj);
- if (!learningRecord || learningRecord.length == 0)
- await miaoguo.AddLearningRecord(obj);
- }
- }
- ctx.body = { errcode: 10000, result: 1 };
- miaoguo.AddMiaoguoLog({
- UserID: ctx.query.UserID,
- LogID: 312,
- Content: JSON.stringify(paramBody),
- }).catch(err => console.error('AddMiaoguoLog failed:', err));
- globalCache.delete("GetMiaoguoCard###UserID=" + ctx.query.UserID);
- }
- export async function UpdateMiaoguoCardInfo(ctx) {
- const param = {
- UserID: ctx.query.UserID || "0",
- MiaoguoCardID: ctx.query.MiaoguoCardID || "0",
- IsCollect: ctx.query.IsCollect,
- };
- const info = await miaoguo.GetCardInfo(param);
- if (info && info.length > 0) {
- const obj = {
- MiaoguoCardID: param.MiaoguoCardID,
- };
- if (param.IsCollect)
- obj.IsCollect = param.IsCollect;
- await miaoguo.UpdateCard(obj);
- const log = {
- UserID: param.UserID,
- LogID: 298,
- Content: JSON.stringify(obj),
- };
- miaoguo.AddMiaoguoLog(log).catch(err => console.error('AddMiaoguoLog failed:', err));
- }
- ctx.body = { errcode: 10000 };
- }
- export async function UpdateCardImageUrl(ctx) {
- const param = {
- MiaoguoCardID: ctx.query.MiaoguoCardID,
- };
- const list = await miaoguo.GetCardContentList(param.MiaoguoCardID);
- if (list && list.length > 0) {
- for (let i = 1; i < list.length; i++) {
- let temp = list[i].Content;
- if (!temp) continue;
- let changed = false;
- const startTime = Date.now();
- while (temp.indexOf("[图") >= 0) {
- temp = temp.substr(temp.indexOf("[图 url='"));
- const oldUrl = temp.substring(temp.indexOf("[图 url='") + 8, temp.indexOf("']"));
- const newUrl = temp.substring(temp.indexOf("']") + 2, temp.indexOf("[/图]"));
- if (newUrl) {
- changed = true;
- list[i].Content = list[i].Content.replace(newUrl, "");
- list[i].Content = list[i].Content.replace(oldUrl, newUrl);
- }
- temp = temp.substr(temp.indexOf("[/图]") + 4);
- try {
- stringUtils.loopBreaker(startTime);
- } catch {
- break;
- }
- }
- if (changed) {
- await miaoguo.UpdateCardContent({
- MiaoguoCardID: param.MiaoguoCardID,
- ContentType: list[i].ContentType,
- Content: list[i].Content,
- });
- }
- }
- }
- ctx.body = { errcode: 10000 };
- }
- export async function GetBiShunByKaitiUrl(ctx) {
- const param = ctx.request.body || {};
- let result = param.Url;
- const arr = globalCache.get("HanziWordsAll");
- if (arr !== 0) {
- for (const item of arr) {
- if (param.Url === item.KaitiUrl && param.DataType == "bishun") {
- result = item.BiShunUrl;
- break;
- } else if (param.Url === item.BiShunUrl && param.DataType == "kaiti") {
- result = item.KaitiUrl;
- break;
- }
- }
- }
- ctx.body = { errcode: 10000, result };
- }
- async function fetchLocalResult(path) {
- const response = await fetch('http://localhost:' + config.port + encodeURI(path));
- const json = await response.json();
- return json.result;
- }
- async function fetchLocalPost(path, body) {
- const response = await fetch('http://localhost:' + config.port + encodeURI(path), {
- method: 'POST',
- headers: { 'content-type': 'application/json' },
- body: JSON.stringify(body),
- });
- return await response.json();
- }
- function changeStringToView(field) {
- const result = {
- Field: [[]],
- Images: [],
- };
- for (let j = 0; j < field.length; j++) {
- if (j == 0) {
- if (field[j].ContentType == 0 && field[j].Content && field[j].Content.length > 0)
- result.Tags = field[j].Content.toString().split(",");
- else
- result.Tags = [];
- } else {
- if (field[j].ContentType == j && field[j].Content && field[j].Content.length > 0) {
- const arrResult = [];
- let str = field[j].Content.toString();
- str = decryptUrl(str);
- if (str.indexOf("[读") > 0)
- str = str.replace(/\[读/g, "\n[读");
- str = str.replace(/\[图/g, "\n[图");
- if (str.indexOf("[音") > 0)
- str = str.replace(/\[音/g, "\n[音");
- str = str.replace(/\[\/读\]/g, "[/读]\n");
- str = str.replace(/\[\/图\]/g, "[/图]\n");
- str = str.replace(/\[\/音\]/g, "[/音]\n");
- str = str.replace(/\n\n\n/g, "\n\n");
- const arr = str.split("\n");
- for (let k = 0; k < arr.length; k++) {
- if (arr[k].indexOf("[图") >= 0 && arr[k].indexOf("[/图]") > 0) {
- const obj = { Type: "image" };
- obj.ContentServer = arr[k].substring(arr[k].indexOf("[图") + 3, arr[k].indexOf("[/图]"));
- const w = 650;
- if (obj.ContentServer.indexOf("w='") >= 0 && obj.ContentServer.indexOf("h='") >= 0) {
- obj.Width = obj.ContentServer.substring(obj.ContentServer.indexOf("w='") + 3, obj.ContentServer.indexOf("h='") - 2);
- obj.Height = obj.ContentServer.substring(obj.ContentServer.indexOf("h='") + 3, obj.ContentServer.indexOf("']"));
- obj.Height = Math.round((w * Number(obj.Height)) / Number(obj.Width));
- obj.Width = w;
- } else {
- obj.Width = "";
- obj.Height = "";
- }
- obj.ContentServer = obj.ContentServer.substring(obj.ContentServer.indexOf("]") + 1);
- obj.Content = obj.ContentServer;
- if (obj.Content.lastIndexOf("fm=58") >= 0)
- obj.IsShowBishun = true;
- else if (obj.Content.indexOf("hanyu-word-gif") > 0)
- obj.IsShowKaiti = true;
- result.Images.push(obj.Content);
- arrResult.push(obj);
- } else if (arr[k].indexOf("[特]") >= 0 && arr[k].indexOf("[/特]") > 0) {
- arrResult.push({
- Type: "bigword",
- Content: arr[k].substring(arr[k].indexOf("[特]") + 3, arr[k].indexOf("[/特]")),
- });
- } else if ((arr[k].indexOf("[线]") >= 0 && arr[k].indexOf("[/线]") > 0) || (arr[k].indexOf("[光]") >= 0 && arr[k].indexOf("[/光]") > 0)) {
- const content = [];
- let temp = arr[k];
- do {
- const num1 = temp.indexOf("[线]");
- const num2 = temp.indexOf("[光]");
- if (num1 >= 0 || num2 >= 0) {
- if ((num1 < num2 && num1 >= 0 && num2 >= 0) || (num1 >= 0 && num2 < 0)) {
- const temp1 = temp.substring(0, temp.indexOf("[线]"));
- if (temp1)
- content.push({ key: "normal", value: temp1 });
- else if (temp && temp.indexOf("[线]") < 0) {
- content.push({ key: "normal", value: temp });
- temp = "";
- }
- } else if ((num1 > num2 && num1 >= 0 && num2 >= 0) || (num1 < 0 && num2 >= 0)) {
- const temp1 = temp.substring(0, temp.indexOf("[光]"));
- if (temp1)
- content.push({ key: "normal", value: temp1 });
- else if (temp && temp.indexOf("[光]") < 0) {
- content.push({ key: "normal", value: temp });
- temp = "";
- }
- } else {
- content.push({ key: "normal", value: temp });
- temp = "";
- }
- } else {
- content.push({ key: "normal", value: temp });
- temp = "";
- }
- if (temp.length > 0 && (num1 >= 0 || num2 >= 0)) {
- if ((num1 < num2 && num1 >= 0 && num2 >= 0) || (num1 >= 0 && num2 < 0)) {
- temp = temp.substr(temp.indexOf("[线]") + 3);
- const temp1 = temp.substring(0, temp.indexOf("[/线]"));
- if (temp1)
- content.push({ key: "line", value: temp1 });
- temp = temp.substr(temp.indexOf("[/线]") + 4);
- } else if ((num1 > num2 && num1 >= 0 && num2 >= 0) || (num1 < 0 && num2 >= 0)) {
- temp = temp.substr(temp.indexOf("[光]") + 3);
- const temp1 = temp.substring(0, temp.indexOf("[/光]"));
- if (temp1)
- content.push({ key: "highlighter", value: temp1 });
- temp = temp.substr(temp.indexOf("[/光]") + 4);
- } else {
- temp = "";
- }
- } else {
- temp = "";
- }
- } while (temp.length > 0);
- arrResult.push({ Type: "line", Content: content });
- } else if (arr[k].indexOf("[读") >= 0 && arr[k].indexOf("[/读]") > 0) {
- const obj = { Type: "sound" };
- if (arr[k].indexOf("[读]") >= 0) {
- obj.Content = arr[k].substring(arr[k].indexOf("[读]") + 3, arr[k].indexOf("[/读]"));
- } else {
- const tempIndex = arr[k].indexOf("']") + 2;
- obj.Content = arr[k].substring(tempIndex, arr[k].indexOf("[/读]"));
- obj.SoundMark = arr[k].substring(arr[k].indexOf("src='") + 5, arr[k].indexOf("']"));
- }
- arrResult.push(obj);
- } else if (arr[k].indexOf("[音") >= 0 && arr[k].indexOf("[/音]") > 0) {
- const obj = { Type: "recorder" };
- obj.SoundMark = arr[k].substring(arr[k].indexOf("url='") + 5, arr[k].indexOf("']"));
- arrResult.push(obj);
- } else if (arr[k] != "") {
- arrResult.push({ Type: "normal", Content: arr[k] });
- } else if (k > 0 && arr[k] == "") {
- arrResult.push({ Type: "br", Content: "" });
- }
- arrResult.push({ Type: "return" });
- }
- for (let i = arrResult.length - 1; i >= 0; i--) {
- if (arrResult[i].Type == "return" || arrResult[i].Type == "br")
- arrResult.pop();
- else
- break;
- }
- result.Field.push(arrResult);
- } else {
- result.Field.push([]);
- }
- }
- }
- return result;
- }
- function decryptUrl(str) {
- if (str && str.constructor == Array) {
- if (str.length > 0)
- str = str.join(",");
- else
- str = "";
- }
- if (str) {
- str = str.replace(/#####1#####/g, "baidu.com");
- str = str.replace(/#####2#####/g, "iciba.com");
- str = str.replace(/#####3#####/g, "https://pinyin.kylx365.com/sounds");
- str = str.replace(/#####4#####/g, "https://miaguo-1253256735.file.myqcloud.com");
- }
- return str;
- }
- function getPinyinNormal(pinyin) {
- let result = "";
- const arr = constantClass.getPinyinArray();
- for (const item of arr) {
- if (item[1] == pinyin) {
- result = item[0];
- break;
- }
- }
- return result;
- }
- function getEF(EF, Q) {
- if (Q < 3)
- Q = 3;
- let result = Math.round(1000 * (EF + (0.1 - (5 - Q) * (0.08 + (5 - Q) * 0.02)))) / 1000;
- if (result < 1.6)
- result = 1.6;
- if (EF < 1.8 && Q == 4)
- result = 1.8;
- if (EF < 2 && Q == 5)
- result = 2;
- return result;
- }
- function getWordJSON(param, words) {
- const taskList = [];
- if (words[0].Pinyin) {
- for (const word of words) {
- const taskInfo = {
- FontSize: 144,
- TagWidth: 136,
- Content: [
- { ContentType: 0, Content: [] },
- { ContentType: 1, Content: [] },
- { ContentType: 2, Content: [] },
- ],
- };
- taskInfo.Word = word.Name;
- const pinyinNormal = "(" + getPinyinNormal(word.Pinyin) + ")";
- const combineWords = stringUtils.ReplaceAllString(word.CombineWords, word.Name, word.Name + pinyinNormal);
- taskInfo.ReadString = word.Name + pinyinNormal + "," + combineWords + "的" + word.Name + pinyinNormal;
- if (param.TestType == "read") {
- taskInfo.Content[0].Content = ["怎么念"];
- let question = word.CombineWords;
- question = stringUtils.ReplaceAllString(question, word.Name, "(" + word.Name + ")");
- taskInfo.Content[1].Content = question;
- taskInfo.Content[2].Content = "[读 src='" + taskInfo.ReadString + "']" + word.Pinyin + "[/读]";
- if (word.CombineWords.length > 6) {
- taskInfo.FontSize = 108;
- if (word.CombineWords.length > 10)
- taskInfo.FontSize = 68;
- }
- } else if (param.TestType == "write") {
- taskInfo.Content[0].Content = ["怎么写"];
- const question2 = word.CombineWords2;
- taskInfo.Content[1].Content = "[读 src='" + taskInfo.ReadString + "']" + question2 + "[/读]";
- taskInfo.Content[2].Content = word.Name + "[图 w='650' h='650']" + word.KaitiUrl + "[/图]";
- if (question2.length > 6) {
- taskInfo.FontSize = 108;
- if (question2.length > 10) {
- taskInfo.FontSize = 68;
- if (question2.length > 14)
- taskInfo.FontSize = 48;
- }
- }
- }
- taskInfo.ContentNew = changeStringToView(taskInfo.Content);
- if (!param.IsBuild)
- delete taskInfo.Content;
- taskList.push(taskInfo);
- }
- }
- return taskList;
- }
|