ActivityController.cs 309 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433
  1. using Azure.Cosmos;
  2. using Microsoft.AspNetCore.Http;
  3. using Microsoft.AspNetCore.Mvc;
  4. using Microsoft.Extensions.Options;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Linq;
  8. using System.Text;
  9. using System.Text.Json;
  10. using System.Threading.Tasks;
  11. using TEAMModelOS.Models;
  12. using TEAMModelOS.SDK.Models;
  13. using TEAMModelOS.SDK.DI;
  14. using TEAMModelOS.SDK.Extension;
  15. using Azure;
  16. using Microsoft.Extensions.Configuration;
  17. using TEAMModelOS.Filter;
  18. using HTEXLib.COMM.Helpers;
  19. using TEAMModelOS.SDK;
  20. using StackExchange.Redis;
  21. using System.IdentityModel.Tokens.Jwt;
  22. using Microsoft.AspNetCore.Routing;
  23. using Pipelines.Sockets.Unofficial.Arenas;
  24. using static TEAMModelOS.SDK.CoreAPIHttpService;
  25. using System.Net;
  26. using TEAMModelOS.SDK.Models.Service;
  27. using TEAMModelOS.Services;
  28. using Azure.Storage.Sas;
  29. using Microsoft.IdentityModel.Tokens;
  30. using System.Net.Http;
  31. using IHttpClientFactory = System.Net.Http.IHttpClientFactory;
  32. using SDK.Helpers;
  33. using Microsoft.Azure.Amqp.Framing;
  34. using Microsoft.AspNetCore.Authorization;
  35. using DocumentFormat.OpenXml.Drawing.Charts;
  36. using static SKIT.FlurlHttpClient.Wechat.TenpayV3.Models.CreateApplyForSubjectApplymentRequest.Types;
  37. using static TEAMModelOS.Controllers.FixDataController;
  38. using DocumentFormat.OpenXml.Spreadsheet;
  39. using DocumentFormat.OpenXml.Office2013.Drawing.ChartStyle;
  40. using static TEAMModelOS.SDK.Models.Cosmos.Student.StudentAnalysis;
  41. using System.Net.NetworkInformation;
  42. namespace TEAMModelOS.Controllers
  43. {
  44. [ProducesResponseType(StatusCodes.Status200OK)]
  45. [ProducesResponseType(StatusCodes.Status400BadRequest)]
  46. [Route("activity")]
  47. [ApiController]
  48. public class ActivityController : ControllerBase
  49. {
  50. private AzureCosmosFactory _azureCosmos;
  51. private readonly DingDing _dingDing;
  52. private readonly CoreAPIHttpService _coreAPIHttpService;
  53. private readonly Option _option;
  54. private readonly AzureServiceBusFactory _serviceBus;
  55. private readonly AzureStorageFactory _azureStorage;
  56. private readonly AzureRedisFactory _azureRedis;
  57. private readonly HttpTrigger _httpTrigger;
  58. private readonly IPSearcher _searcher;
  59. public IConfiguration _configuration { get; set; }
  60. private IHttpClientFactory _httpClientFactory;
  61. public ActivityController(AzureRedisFactory azureRedis, AzureCosmosFactory azureCosmos, DingDing dingDing, IOptionsSnapshot<Option> option, CoreAPIHttpService coreAPIHttpService, AzureServiceBusFactory serviceBus, AzureStorageFactory azureStorage, IConfiguration configuration, HttpTrigger httpTrigger, IPSearcher searcher, IHttpClientFactory httpClientFactory)
  62. {
  63. _azureCosmos = azureCosmos;
  64. _dingDing = dingDing;
  65. _option = option?.Value;
  66. _serviceBus = serviceBus;
  67. _configuration = configuration;
  68. _azureStorage = azureStorage;
  69. _azureRedis = azureRedis;
  70. _coreAPIHttpService = coreAPIHttpService;
  71. _httpTrigger=httpTrigger;
  72. _searcher=searcher;
  73. _httpClientFactory=httpClientFactory;
  74. }
  75. /// <summary>
  76. /// 分站管理
  77. /// </summary>
  78. /// <param name="request"></param>
  79. /// <returns></returns>
  80. [ProducesDefaultResponseType]
  81. [AuthToken(Roles = "admin,area")]
  82. [HttpPost("website-manage")]
  83. #if !DEBUG
  84. [Authorize(Roles = "IES")]
  85. #endif
  86. public async Task<IActionResult> WebsiteManage(JsonElement request)
  87. {
  88. (string tmdid, _, _, string school) = HttpContext.GetAuthTokenInfo();
  89. if (!request.TryGetProperty("grant_type", out JsonElement grant_type)) return BadRequest();
  90. {
  91. switch (true)
  92. {
  93. case bool when $"{grant_type}".Equals("update", StringComparison.OrdinalIgnoreCase):
  94. {
  95. request.TryGetProperty("areaId", out JsonElement _areaId);
  96. if (!request.TryGetProperty("website", out JsonElement _website)) return BadRequest();
  97. ActivityWebsite website = _website.ToObject<ActivityWebsite>();
  98. Azure.Response teammodelResponse = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).ReadItemStreamAsync(website.id, new PartitionKey("ActivityWebsite"));
  99. if (teammodelResponse.Status == 200)
  100. {
  101. ActivityWebsite activityWebsite = JsonDocument.Parse(teammodelResponse.Content).RootElement.ToObject<ActivityWebsite>();
  102. website.route=activityWebsite.route;
  103. website.pk=activityWebsite.pk;
  104. website.code=activityWebsite.code;
  105. website.scope=activityWebsite.scope;
  106. //不是醍摩豆学区的,不能修改是否有公开办活动权限
  107. if (!(string.IsNullOrWhiteSpace($"{_areaId}")&& _areaId.Equals("02944f32-f534-3397-ea56-e6f1fc6c3714")))
  108. {
  109. website.allowPublic=activityWebsite.allowPublic;
  110. }
  111. }
  112. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).UpsertItemAsync(website, new PartitionKey("ActivityWebsite"));
  113. return Ok(new { website, code = 200 });
  114. }
  115. case bool when $"{grant_type}".Equals("list", StringComparison.OrdinalIgnoreCase):
  116. {
  117. List<ActivityWebsite> websites = new List<ActivityWebsite>();
  118. if (!request.TryGetProperty("websiteId", out JsonElement _websiteId)) return BadRequest();
  119. string websiteId = _websiteId.GetString();
  120. if (websiteId.Equals("02944f32-f534-3397-ea56-e6f1fc6c3714", StringComparison.OrdinalIgnoreCase))
  121. {
  122. Azure.Response teammodelResponse = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).ReadItemStreamAsync("teammodel", new PartitionKey("ActivityWebsite"));
  123. if (teammodelResponse.Status == 200)
  124. {
  125. ActivityWebsite activityWebsite = JsonDocument.Parse(teammodelResponse.Content).RootElement.ToObject<ActivityWebsite>();
  126. websites.Add(activityWebsite);
  127. }
  128. else
  129. {
  130. ActivityWebsite website = new ActivityWebsite
  131. {
  132. id="teammodel",
  133. pk="ActivityWebsite",
  134. code="ActivityWebsite",
  135. route="teammodel",
  136. scope="public",
  137. allowPublic=1,
  138. };
  139. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).UpsertItemAsync(website, new PartitionKey(website.code));
  140. websites.Add(website);
  141. }
  142. //返回其他区的。
  143. string sqlArea = "select value c from c ";
  144. var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).GetList<Area>(sqlArea, "Base-Area");
  145. if (result.list.IsNotEmpty())
  146. {
  147. string sqlWebsite = $"select value c from c where c.id in ({string.Join(",", result.list.Select(z => $"'{z.id}'"))})";
  148. var resultWebsite = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).GetList<ActivityWebsite>(sqlWebsite, "ActivityWebsite");
  149. foreach (var item in result.list)
  150. {
  151. var website = resultWebsite.list.Find(z => z.id.Equals(item.id));
  152. if (website!=null)
  153. {
  154. if (!string.IsNullOrWhiteSpace(item.shortCode))
  155. {
  156. bool change = false;
  157. if (string.IsNullOrWhiteSpace(website.route))
  158. {
  159. website.route=item.shortCode;
  160. change = true;
  161. }
  162. else
  163. {
  164. if (!website.route.Equals(item.shortCode))
  165. {
  166. website.route=item.shortCode;
  167. change = true;
  168. }
  169. }
  170. if (change)
  171. {
  172. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).UpsertItemAsync(website, new PartitionKey(website.code));
  173. }
  174. }
  175. }
  176. else
  177. {
  178. website= new ActivityWebsite
  179. {
  180. id= item.id,
  181. code="ActivityWebsite",
  182. pk="ActivityWebsite",
  183. route=item.shortCode,
  184. scope="area",
  185. allowPublic=0,
  186. };
  187. }
  188. websites.Add(website);
  189. }
  190. }
  191. }
  192. else
  193. {
  194. Azure.Response activityWebsiteResponse = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).ReadItemStreamAsync(websiteId, new PartitionKey("ActivityWebsite"));
  195. if (activityWebsiteResponse.Status == 200)
  196. {
  197. ActivityWebsite activityWebsite = JsonDocument.Parse(activityWebsiteResponse.Content).RootElement.ToObject<ActivityWebsite>();
  198. Area area = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).ReadItemAsync<Area>(websiteId, new PartitionKey("Base-Area"));
  199. if (!string.IsNullOrWhiteSpace(area.shortCode))
  200. {
  201. bool change = false;
  202. if (string.IsNullOrWhiteSpace(activityWebsite.route))
  203. {
  204. activityWebsite.route=area.shortCode;
  205. change = true;
  206. }
  207. else
  208. {
  209. if (!activityWebsite.route.Equals(area.shortCode))
  210. {
  211. activityWebsite.route=area.shortCode;
  212. change = true;
  213. }
  214. }
  215. if (change)
  216. {
  217. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).UpsertItemAsync(activityWebsite, new PartitionKey(activityWebsite.code));
  218. }
  219. }
  220. websites.Add(activityWebsite);
  221. }
  222. else
  223. {
  224. string route = string.Empty;
  225. string scope = string.Empty;
  226. Azure.Response responseArea = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).ReadItemStreamAsync(websiteId, new PartitionKey("Base-Area"));
  227. if (responseArea.Status==200)
  228. {
  229. Area area = JsonDocument.Parse(responseArea.Content).RootElement.ToObject<Area>();
  230. if (!string.IsNullOrWhiteSpace(area.shortCode))
  231. {
  232. route=area.shortCode;
  233. }
  234. scope="area";
  235. }
  236. if (!string.IsNullOrWhiteSpace(scope))
  237. {
  238. Azure.Response responseSchool = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemStreamAsync(websiteId, new PartitionKey("Base"));
  239. if (responseSchool.Status==200)
  240. {
  241. scope="school";
  242. route = websiteId;
  243. }
  244. }
  245. if (!string.IsNullOrWhiteSpace(scope))
  246. {
  247. if (!string.IsNullOrWhiteSpace(route))
  248. {
  249. ActivityWebsite website = new ActivityWebsite
  250. {
  251. id=websiteId,
  252. pk="ActivityWebsite",
  253. code="ActivityWebsite",
  254. route=route,
  255. scope=scope,
  256. allowPublic=0
  257. };
  258. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).UpsertItemAsync(website, new PartitionKey(website.code));
  259. websites.Add(website);
  260. }
  261. else
  262. {
  263. ActivityWebsite website = new ActivityWebsite
  264. {
  265. id=websiteId,
  266. pk="ActivityWebsite",
  267. code="ActivityWebsite",
  268. route=route,
  269. scope=scope,
  270. allowPublic=0
  271. };
  272. websites.Add(website);
  273. }
  274. }
  275. }
  276. }
  277. return Ok(new { code = 200, websites });
  278. }
  279. }
  280. }
  281. return Ok();
  282. }
  283. /// <summary>
  284. /// 添加活动参与对象,学校,教师
  285. /// </summary>
  286. /// <param name="request"></param>
  287. /// <returns></returns>
  288. [ProducesDefaultResponseType]
  289. [AuthToken(Roles = "admin,area")]
  290. [HttpPost("invite-target")]
  291. #if !DEBUG
  292. [Authorize(Roles = "IES")]
  293. #endif
  294. public async Task<IActionResult> InviteTarget(JsonElement request)
  295. {
  296. (string tmdid, _, _, string school) = HttpContext.GetAuthTokenInfo();
  297. if (!request.TryGetProperty("grant_type", out JsonElement grant_type)) return BadRequest();
  298. switch (true)
  299. {
  300. case bool when $"{grant_type}".Equals("schools", StringComparison.OrdinalIgnoreCase):
  301. {
  302. if (!request.TryGetProperty("scope", out JsonElement _scope)) return BadRequest();
  303. if (!request.TryGetProperty("areaId", out JsonElement _areaId)) return BadRequest();
  304. string sql = string.Empty;
  305. int allowPublic = 0;
  306. if (_scope.GetString().Equals("public", StringComparison.OrdinalIgnoreCase))
  307. {
  308. if (_areaId.GetString().Equals("02944f32-f534-3397-ea56-e6f1fc6c3714"))
  309. {
  310. allowPublic=1;
  311. }
  312. else
  313. {
  314. Azure.Response activityWebsiteResponse = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).ReadItemStreamAsync(_areaId.GetString(), new PartitionKey("ActivityWebsite"));
  315. if (activityWebsiteResponse.Status==200)
  316. {
  317. ActivityWebsite website = JsonDocument.Parse(activityWebsiteResponse.Content).RootElement.ToObject<ActivityWebsite>();
  318. allowPublic=website.allowPublic;
  319. }
  320. }
  321. }
  322. if (allowPublic==1)
  323. {
  324. sql = "select c.id,c.name ,c.picture,c.region,c.province,c.city,c.areaId from c where c.code='Base' ";
  325. }
  326. else
  327. {
  328. sql = $"select c.id,c.name ,c.picture,c.region,c.province,c.city,c.areaId from c where c.code='Base' and c.areaId='{_areaId}' ";
  329. }
  330. var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).GetList<School>(sql, "Base");
  331. var sc = result.list.FindAll(z => !string.IsNullOrWhiteSpace(z.areaId));
  332. List<dynamic> schools = new List<dynamic>();
  333. if (sc.IsNotEmpty())
  334. {
  335. string areaSql = $"select value c from c where c.id in ({string.Join(",", sc.Select(z => $"'{z.areaId}'").ToHashSet())})";
  336. var areaResult = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).GetList<Area>(areaSql, "Base-Area");
  337. if (areaResult.list.IsNotEmpty())
  338. {
  339. foreach (var item in result.list)
  340. {
  341. if (!string.IsNullOrWhiteSpace(item.areaId))
  342. {
  343. var area = areaResult.list.Find(z => z.id.Equals(item.areaId));
  344. schools.Add(new { item.id, item.name, item.picture, item.region, item.province, item.city, item.areaId, areaName = area?.name });
  345. }
  346. else
  347. {
  348. schools.Add(new { item.id, item.name, item.picture, item.region, item.province, item.city, item.areaId, areaName = string.Empty });
  349. }
  350. }
  351. }
  352. }
  353. return Ok(new { code = 200, schools });
  354. }
  355. case bool when $"{grant_type}".Equals("teachers", StringComparison.OrdinalIgnoreCase):
  356. {
  357. if (!string.IsNullOrWhiteSpace(school))
  358. {
  359. School schoolbase = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemAsync<School>(school, new PartitionKey("Base"));
  360. string sql = $"select c.id,c.name ,c.picture from c where c.code='Teacher-{school}' ";
  361. var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).GetList<SchoolTeacher>(sql, $"Teacher-{school}");
  362. return Ok(new { code = 200, teachers = result.list.Select(z => new { z.id, z.name, z.picture, school, schooName = schoolbase.name }) });
  363. }
  364. else
  365. {
  366. return Ok(new { code = 1, msg = "没有学校信息" });
  367. }
  368. }
  369. }
  370. return Ok(new { code = 400 });
  371. }
  372. /// <summary>
  373. /// 管理
  374. /// </summary>
  375. /// <param name="request"></param>
  376. /// <returns></returns>
  377. [ProducesDefaultResponseType]
  378. [AuthToken(Roles = "teacher,admin,area,expert")]
  379. [HttpPost("manage")]
  380. #if !DEBUG
  381. [Authorize(Roles = "IES")]
  382. #endif
  383. public async Task<IActionResult> Manage(JsonElement request)
  384. {
  385. try
  386. {
  387. (string tmdid, _, _, string school) = HttpContext.GetAuthTokenInfo();
  388. if (!request.TryGetProperty("grant_type", out JsonElement grant_type)) return BadRequest();
  389. var client = _azureCosmos.GetCosmosClient();
  390. switch (true)
  391. {
  392. //修改赛课活动信息
  393. case bool when $"{grant_type}".Equals("update-contest-base", StringComparison.OrdinalIgnoreCase):
  394. {
  395. if (!request.TryGetProperty("activityId", out JsonElement _activityId)) return BadRequest();
  396. if (!request.TryGetProperty("contestUpdate", out JsonElement _contestUpdate)) return BadRequest();
  397. Azure.Response responseContest = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("Contest"));
  398. if (responseContest.Status==200)
  399. {
  400. Contest contest = JsonDocument.Parse(responseContest.Content).RootElement.ToObject<Contest>();
  401. long now = DateTimeOffset.Now.ToUnixTimeMilliseconds();
  402. ContestUpdate contestUpdate = new ContestUpdate() {
  403. signStime= contest.sign?.stime,
  404. signEtime= contest.sign?.etime,
  405. uploadStime= contest.upload?.stime,
  406. uploadEtime= contest.upload?.etime,
  407. reviewStime= contest.review?.stime,
  408. reviewEtime= contest.review?.etime,
  409. scoreStime= contest.score?.stime,
  410. scoreEtime= contest.score?.etime,
  411. };
  412. if (_contestUpdate.TryGetProperty("signStime", out JsonElement signStime) && signStime.ValueKind.Equals(JsonValueKind.Number)) {
  413. contestUpdate.signStime=signStime.GetInt64();
  414. }
  415. if (_contestUpdate.TryGetProperty("signEtime", out JsonElement signEtime) && signEtime.ValueKind.Equals(JsonValueKind.Number))
  416. {
  417. contestUpdate.signEtime=signEtime.GetInt64();
  418. }
  419. if (_contestUpdate.TryGetProperty("uploadStime", out JsonElement uploadStime) && uploadStime.ValueKind.Equals(JsonValueKind.Number))
  420. {
  421. contestUpdate.uploadStime=uploadStime.GetInt64();
  422. }
  423. if (_contestUpdate.TryGetProperty("uploadEtime", out JsonElement uploadEtime) && uploadEtime.ValueKind.Equals(JsonValueKind.Number))
  424. {
  425. contestUpdate.uploadEtime=uploadEtime.GetInt64();
  426. }
  427. if (_contestUpdate.TryGetProperty("reviewStime", out JsonElement reviewStime) && reviewStime.ValueKind.Equals(JsonValueKind.Number))
  428. {
  429. contestUpdate.reviewStime=reviewStime.GetInt64();
  430. }
  431. if (_contestUpdate.TryGetProperty("reviewEtime", out JsonElement reviewEtime) && reviewEtime.ValueKind.Equals(JsonValueKind.Number))
  432. {
  433. contestUpdate.reviewEtime=reviewEtime.GetInt64();
  434. }
  435. if (_contestUpdate.TryGetProperty("scoreStime", out JsonElement scoreStime) && scoreStime.ValueKind.Equals(JsonValueKind.Number))
  436. {
  437. contestUpdate.scoreStime=scoreStime.GetInt64();
  438. }
  439. if (_contestUpdate.TryGetProperty("scoreEtime", out JsonElement scoreEtime) && scoreEtime.ValueKind.Equals(JsonValueKind.Number))
  440. {
  441. contestUpdate.scoreEtime=scoreEtime.GetInt64();
  442. }
  443. if (_contestUpdate.TryGetProperty("addModules", out JsonElement addModules) && addModules.ValueKind.Equals(JsonValueKind.Array))
  444. {
  445. contestUpdate.addModules = addModules.ToObject<List<string>>();
  446. }
  447. if (contest.modules.Contains("sign") && contest.sign!= null )
  448. {
  449. if (contestUpdate.signStime.HasValue &&contestUpdate.signEtime.HasValue) {
  450. if (contestUpdate.reviewStime.HasValue)
  451. {
  452. if (contestUpdate.signEtime.Value<contestUpdate.reviewStime.Value)
  453. {
  454. contest.sign.etime=contestUpdate.signEtime.Value;
  455. }
  456. else
  457. {
  458. return Ok(new { code = 1, msg = "报名结束时间不能晚于评审开始时间!" });
  459. }
  460. }
  461. else
  462. {
  463. contest.sign.etime=contestUpdate.signEtime.Value;
  464. }
  465. if (contestUpdate.signEtime.Value> contestUpdate.signStime.Value)
  466. {
  467. contest.sign.stime=contestUpdate.signStime.Value;
  468. }
  469. else {
  470. return Ok(new { code = 2, msg = "报名开始时间不能早于报名结束时间!" });
  471. }
  472. }
  473. if (_contestUpdate.TryGetProperty("limit", out JsonElement limit) && limit.ValueKind.Equals(JsonValueKind.Number))
  474. {
  475. contest.sign.limit=limit.GetInt32();
  476. }
  477. }
  478. if (contest.modules.Contains("upload") && contest.upload!= null)
  479. {
  480. if (contestUpdate.uploadStime.HasValue &&contestUpdate.uploadEtime.HasValue)
  481. {
  482. if (contestUpdate.reviewStime.HasValue)
  483. {
  484. if (contestUpdate.uploadEtime.Value<contestUpdate.reviewStime.Value)
  485. {
  486. contest.upload.etime=contestUpdate.uploadEtime.Value;
  487. }
  488. else
  489. {
  490. return Ok(new { code =3, msg = "报名结束时间不能晚于评审开始时间!" });
  491. }
  492. }
  493. else
  494. {
  495. contest.upload.etime=contestUpdate.uploadEtime.Value;
  496. }
  497. if (contestUpdate.uploadEtime.Value> contestUpdate.uploadStime.Value)
  498. {
  499. contest.upload.stime=contestUpdate.uploadStime.Value;
  500. }
  501. else
  502. {
  503. return Ok(new { code = 4, msg = "报名开始时间不能早于报名结束时间!" });
  504. }
  505. }
  506. if (_contestUpdate.TryGetProperty("updateDesc", out JsonElement desc) && desc.ValueKind.Equals(JsonValueKind.String))
  507. {
  508. contest.upload.desc=desc.GetString();
  509. }
  510. if (_contestUpdate.TryGetProperty("fileType", out JsonElement fileType) && fileType.ValueKind.Equals(JsonValueKind.Array))
  511. {
  512. if (contest.upload.fileType.IsNotEmpty())
  513. {
  514. contest.upload.fileType=fileType.ToObject<List<string>>();
  515. }
  516. }
  517. }
  518. if (contest.modules.Contains("review") && contest.review!= null)
  519. {
  520. if (contestUpdate.reviewStime.HasValue &&contestUpdate.reviewEtime.HasValue)
  521. {
  522. if (contestUpdate.scoreStime.HasValue)
  523. {
  524. if (contestUpdate.reviewEtime.Value<contestUpdate.scoreStime.Value)
  525. {
  526. contest.review.etime=contestUpdate.reviewEtime.Value;
  527. }
  528. else
  529. {
  530. return Ok(new { code = 5, msg = "评审结束时间不能晚于成绩公布开始时间!" });
  531. }
  532. }
  533. else
  534. {
  535. contest.review.etime=contestUpdate.reviewEtime.Value;
  536. }
  537. if (contestUpdate.reviewEtime.Value> contestUpdate.reviewStime.Value)
  538. {
  539. contest.review.stime=contestUpdate.reviewStime.Value;
  540. }
  541. else
  542. {
  543. return Ok(new { code = 6, msg = "评审开始时间不能早于评审结束时间!" });
  544. }
  545. }
  546. }
  547. if (contest.modules.Contains("score") && contest.score!= null)
  548. {
  549. if (contestUpdate.scoreStime.HasValue &&contestUpdate.scoreEtime.HasValue)
  550. {
  551. if (contestUpdate.reviewEtime.HasValue)
  552. {
  553. if (contestUpdate.reviewEtime.Value<contestUpdate.scoreStime.Value)
  554. {
  555. contest.score.stime=contestUpdate.scoreStime.Value;
  556. }
  557. else
  558. {
  559. return Ok(new { code = 7, msg = "成绩公布开始时间不能早于评审结束时间!" });
  560. }
  561. }
  562. else
  563. {
  564. contest.score.stime=contestUpdate.scoreStime.Value;
  565. }
  566. if (contestUpdate.scoreEtime.Value> contestUpdate.scoreStime.Value)
  567. {
  568. contest.score.etime=contestUpdate.scoreEtime.Value;
  569. }
  570. else
  571. {
  572. return Ok(new { code = 8, msg = "成绩公布结束时间不能晚于成绩公布开始时间!" });
  573. }
  574. }
  575. }
  576. else {
  577. //增加公示成绩模块
  578. if (contestUpdate.addModules.Contains("score") )
  579. {
  580. if (contestUpdate.scoreStime.HasValue &&contestUpdate.scoreEtime.HasValue)
  581. {
  582. if (!contest.modules.Contains("score"))
  583. {
  584. contest.modules.Add("score");
  585. }
  586. if (contest.score==null)
  587. {
  588. contest.score= new ContestScore
  589. {
  590. scoreStatus=0,
  591. showType=0,
  592. showDetail=0,
  593. levelType=0,
  594. top=-1
  595. };
  596. }
  597. if (contestUpdate.reviewEtime.HasValue)
  598. {
  599. if (contestUpdate.reviewEtime.Value<contestUpdate.scoreStime.Value)
  600. {
  601. contest.score.stime=contestUpdate.scoreStime.Value;
  602. }
  603. else
  604. {
  605. return Ok(new { code = 7, msg = "成绩公布开始时间不能早于评审结束时间!" });
  606. }
  607. }
  608. else
  609. {
  610. contest.score.stime=contestUpdate.scoreStime.Value;
  611. }
  612. if (contestUpdate.scoreEtime.Value> contestUpdate.scoreStime.Value)
  613. {
  614. contest.score.etime=contestUpdate.scoreEtime.Value;
  615. }
  616. else
  617. {
  618. return Ok(new { code = 8, msg = "成绩公布结束时间不能晚于成绩公布开始时间!" });
  619. }
  620. }
  621. }
  622. }
  623. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).UpsertItemAsync(contest, new PartitionKey("Contest"));
  624. return Ok(new { code = 200, contest });
  625. }
  626. else
  627. {
  628. return Ok(new { code = 9, msg = "赛课模块信息未完善!" });
  629. }
  630. }
  631. //修改活动基本信息
  632. case bool when $"{grant_type}".Equals("update-activity-base", StringComparison.OrdinalIgnoreCase):
  633. {
  634. if (!request.TryGetProperty("activityId", out JsonElement _activityId)) return BadRequest();
  635. if (!request.TryGetProperty("activityUpdate", out JsonElement _activityUpdate)) return BadRequest();
  636. Azure.Response response = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("Activity"));
  637. if (response.Status==200)
  638. {
  639. Activity activity = JsonDocument.Parse(response.Content).RootElement.ToObject<Activity>();
  640. _activityUpdate.CopyToSameProperty<ActivityUpdate, Activity>(activity,
  641. filter: new List<string>() { "name", "subject", "description", "address", "stime", "etime", "poster", "attachment", "zb", "cb", "mzsm" });
  642. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).UpsertItemAsync(activity, new PartitionKey("Activity"));
  643. return Ok(new { activity, code = 200 });
  644. }
  645. else
  646. {
  647. return Ok(new { code = 1, msg = "活动不存在!" });
  648. }
  649. }
  650. //创建活动
  651. case bool when $"{grant_type}".Equals("create", StringComparison.OrdinalIgnoreCase):
  652. {
  653. if (!request.TryGetProperty("Activity", out JsonElement _activity)) return Ok(new { code = 1, msg = "活动信息参数错误" });
  654. Activity activity = _activity.ToObject<Activity>();
  655. activity.id=!string.IsNullOrWhiteSpace(activity.id) ? activity.id : Guid.NewGuid().ToString();
  656. activity.code="Activity";
  657. activity.pk="Activity";
  658. //如果是区级活动,enroll报名制,则学校的确认状态默认为1 。
  659. //if (activity.scope.Equals("area", StringComparison.OrdinalIgnoreCase) && activity.joinMode.Equals("enroll", StringComparison.OrdinalIgnoreCase))
  660. //{
  661. // activity.schools.ForEach(z => z.status=1);
  662. //}
  663. ActivityWebsite website = null;
  664. {
  665. string websiteId = activity.owner;
  666. string route = string.Empty;
  667. if (activity.owner.Equals("02944f32-f534-3397-ea56-e6f1fc6c3714", StringComparison.OrdinalIgnoreCase) && activity.scope.Equals("public", StringComparison.OrdinalIgnoreCase))
  668. {
  669. websiteId="teammodel";
  670. route="teammodel";
  671. }
  672. Azure.Response activityWebsiteResponse = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).ReadItemStreamAsync(websiteId, new PartitionKey("ActivityWebsite"));
  673. if (activityWebsiteResponse.Status!=200)
  674. {
  675. if (activity.scope.Equals("area", StringComparison.OrdinalIgnoreCase))
  676. {
  677. Area area = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).ReadItemAsync<Area>(activity.owner, new PartitionKey("Base-Area"));
  678. if (!string.IsNullOrWhiteSpace(area.shortCode))
  679. {
  680. route=area.shortCode;
  681. }
  682. }
  683. if (activity.scope.Equals("school", StringComparison.OrdinalIgnoreCase))
  684. {
  685. route=activity.owner;
  686. }
  687. if (!string.IsNullOrWhiteSpace(route))
  688. {
  689. website = new ActivityWebsite
  690. {
  691. id=websiteId,
  692. pk="ActivityWebsite",
  693. code="ActivityWebsite",
  694. route=route,
  695. scope=activity.scope,
  696. };
  697. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).UpsertItemAsync(website, new PartitionKey(website.code));
  698. }
  699. }
  700. else
  701. {
  702. website =JsonDocument.Parse(activityWebsiteResponse.Content).RootElement.ToObject<ActivityWebsite>();
  703. }
  704. }
  705. //醍摩豆智慧学区
  706. if (activity.scope.Equals("public", StringComparison.OrdinalIgnoreCase))
  707. {
  708. if (website.allowPublic==0)
  709. {
  710. return Ok(new { code = 2, msg = "暂无创建公开活动权限!" });
  711. }
  712. }
  713. Contest contest = null;
  714. ValidResult validResult = activity.Valid();
  715. if (validResult.isVaild)
  716. {
  717. activity.creatorId=tmdid;
  718. activity.createTime= DateTimeOffset.Now.ToUnixTimeMilliseconds();
  719. activity.year=DateTimeOffset.Now.Year;
  720. foreach (var module in activity.modules)
  721. {
  722. switch (true)
  723. {
  724. //赛课
  725. case bool when module.Equals("Contest"):
  726. {
  727. if (!request.TryGetProperty("Contest", out JsonElement _contest))
  728. {
  729. return Ok(new { code = 3, msg = "赛课信息参数错误" });
  730. }
  731. contest = _contest.ToObject<Contest>();
  732. if (contest!=null)
  733. {
  734. contest.id=activity.id;
  735. contest.code="Contest";
  736. contest.pk="Contest";
  737. ValidResult validResultContest = contest.Valid();
  738. if (validResultContest.isVaild)
  739. {
  740. if (contest.modules.Contains("review"))
  741. {
  742. if (!request.TryGetProperty("reviewConfig", out JsonElement _reviewConfig))
  743. {
  744. return Ok(new { code = 4, msg = "评审未配置" });
  745. }
  746. if (contest.review== null)
  747. {
  748. return Ok(new { code = 4, msg = "评审未配置" });
  749. }
  750. ReviewRuleTree ruleTree = _reviewConfig.ToObject<ReviewRuleTree>();
  751. var reviewRuleResult = await ActivityService.UpsertReviewRule(ruleTree, activity, contest, _azureCosmos);
  752. if (reviewRuleResult.invalidCode!=200)
  753. {
  754. return Ok(new { code = reviewRuleResult.invalidCode, msg = reviewRuleResult.msg });
  755. }
  756. contest.review.ruleId =reviewRuleResult.reviewRule.id;
  757. contest.review.ruleName = reviewRuleResult.reviewRule.name;
  758. }
  759. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).UpsertItemAsync(contest, new PartitionKey(contest.code));
  760. break;
  761. }
  762. else
  763. {
  764. return Ok(validResult);
  765. }
  766. }
  767. else
  768. {
  769. return Ok(validResult);
  770. }
  771. }
  772. //培训
  773. case bool when module.Equals("Training"):
  774. {
  775. break;
  776. }
  777. //教研
  778. case bool when module.Equals("Research"):
  779. {
  780. break;
  781. }
  782. }
  783. }
  784. //保存活动基础信息
  785. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).UpsertItemAsync(activity, new PartitionKey(activity.code));
  786. return Ok(new { activity, contest, code = 200 });
  787. }
  788. else
  789. {
  790. return Ok(validResult);
  791. }
  792. }
  793. //删除活动
  794. case bool when $"{grant_type}".Equals("delete", StringComparison.OrdinalIgnoreCase):
  795. {
  796. if (!request.TryGetProperty("activityId", out JsonElement _activityId)) return BadRequest();
  797. if (!request.TryGetProperty("owner", out JsonElement _owner)) return BadRequest();
  798. if (!request.TryGetProperty("scope", out JsonElement _scope)) return BadRequest();
  799. Azure.Response response = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("Activity"));
  800. if (response.Status==200)
  801. {
  802. Activity activity = JsonDocument.Parse(response.Content).RootElement.ToObject<Activity>();
  803. if (_scope.GetString().Equals("school") && _owner.GetString().Equals(school))
  804. {
  805. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).DeleteItemStreamAsync(activity.id, new PartitionKey("Activity"));
  806. await ActivityService.DeleteActivityRelated(_azureCosmos, activity);
  807. return Ok(new { code = 201, activity }); //删除成功
  808. }
  809. else
  810. {
  811. if ((_scope.GetString().Equals("area") || _scope.GetString().Equals("public")) && !_owner.GetString().Equals(school))
  812. {
  813. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).DeleteItemStreamAsync(activity.id, new PartitionKey("Activity"));
  814. await ActivityService.DeleteActivityRelated(_azureCosmos, activity);
  815. return Ok(new { code = 201, activity });//删除成功
  816. }
  817. }
  818. return Ok(new { code = 200, activity });//未删除掉
  819. }
  820. else
  821. {
  822. return Ok(new { code = 1, msg = "活动不存在" });
  823. }
  824. }
  825. //区级活动列表
  826. case bool when $"{grant_type}".Equals("list-area", StringComparison.OrdinalIgnoreCase):
  827. {
  828. if (!request.TryGetProperty("areaId", out JsonElement _areaId)) return BadRequest();
  829. var activities = await ActivityService.AreaActivityList(_azureCosmos, _azureStorage, request, _areaId.GetString());
  830. return Ok(new { activities = activities });
  831. }
  832. //校级活动列表
  833. case bool when $"{grant_type}".Equals("list-school", StringComparison.OrdinalIgnoreCase):
  834. {
  835. if (!string.IsNullOrWhiteSpace(school))
  836. {
  837. var activities = await ActivityService.SchoolActivityList(_azureCosmos, _azureStorage, request, school);
  838. return Ok(new { code = 200, activities = activities.OrderByDescending(z => z.stime) });
  839. }
  840. else
  841. {
  842. return Ok(new { code = 1, msg = "没有学校信息" });
  843. }
  844. }
  845. //教师活动列表
  846. case bool when $"{grant_type}".Equals("list-teacher", StringComparison.OrdinalIgnoreCase):
  847. {
  848. List<TeacherActivityDto> activities = await ActivityService.TeacherActivityList(_azureCosmos, _azureStorage, request, tmdid);
  849. return Ok(new { activities = activities.OrderByDescending(z => z.stime) });
  850. }
  851. case bool when $"{grant_type}".Equals("list-year", StringComparison.OrdinalIgnoreCase):
  852. {
  853. if (!request.TryGetProperty("type", out JsonElement _type)) return BadRequest();
  854. if (!request.TryGetProperty("ownerId", out JsonElement ownerId)) return BadRequest();
  855. if ($"{_type}".Equals("teacher"))
  856. {
  857. var data = await ActivityService.TeacherActivityList(_azureCosmos, _azureStorage, request, ownerId.GetString(),1);
  858. var countYear = data.GroupBy(z => z.year).Select(z => new { year = z.Key, count = z.ToList().Count() });
  859. return Ok(new { code = 200, countYear });
  860. }
  861. else if ($"{_type}".Equals("school"))
  862. {
  863. var data = await ActivityService.SchoolActivityList(_azureCosmos, _azureStorage, request, ownerId.GetString(),1);
  864. var countYear = data.GroupBy(z => z.year).Select(z => new { year = z.Key, count = z.ToList().Count() });
  865. return Ok(new { code = 200, countYear });
  866. }
  867. else if ($"{_type}".Equals("area"))
  868. {
  869. var data = await ActivityService.AreaActivityList(_azureCosmos, _azureStorage, request, ownerId.GetString(), 1);
  870. var countYear = data.GroupBy(z => z.year).Select(z => new { year = z.Key, count = z.ToList().Count() });
  871. return Ok(new { code = 200, countYear });
  872. }
  873. else
  874. {
  875. return BadRequest("类型错误!");
  876. }
  877. }
  878. case bool when $"{grant_type}".Equals("read-activity", StringComparison.OrdinalIgnoreCase):
  879. {
  880. if (!request.TryGetProperty("activityId", out JsonElement _activityId)) return BadRequest();
  881. Azure.Response response = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("Activity"));
  882. if (response.Status==200)
  883. {
  884. ActivityDto activity = JsonDocument.Parse(response.Content).RootElement.ToObject<ActivityDto>();
  885. Contest contest = null;
  886. ReviewRuleTree reviewRule = null;
  887. Azure.Response responseContest = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("Contest"));
  888. if (responseContest.Status==200)
  889. {
  890. contest= JsonDocument.Parse(responseContest.Content).RootElement.ToObject<Contest>();
  891. if (contest.modules.Contains("review"))
  892. {
  893. Azure.Response reviewRuleResponse = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("ReviewRule-disposable"));
  894. if (reviewRuleResponse.Status==200)
  895. {
  896. ReviewRule reviewRuleDB = JsonDocument.Parse(reviewRuleResponse.Content).RootElement.ToObject<ReviewRule>();
  897. var tree = ActivityService.ListToTree(reviewRuleDB.configs);
  898. reviewRule=new ReviewRuleTree
  899. {
  900. id=reviewRuleDB.id,
  901. name= reviewRuleDB.name,
  902. owner= reviewRuleDB.owner,
  903. sourceName= reviewRuleDB.sourceName,
  904. trees=tree,
  905. desc=reviewRuleDB.desc,
  906. scoreDetail=reviewRuleDB.scoreDetail,
  907. scoreRule=reviewRuleDB.scoreRule,
  908. distribute=reviewRuleDB.distribute,
  909. taskCount=reviewRuleDB.taskCount,
  910. };
  911. }
  912. }
  913. }
  914. Training training = null;
  915. TEAMModelOS.SDK.Models.Research research = null;
  916. var (blob_uri, blob_sas) = _azureStorage.GetBlobContainerSAS(activity.owner, BlobContainerSasPermissions.Read | BlobContainerSasPermissions.List);
  917. activity.sas=blob_sas;
  918. activity.url=blob_uri;
  919. long now = DateTimeOffset.Now.ToUnixTimeMilliseconds();
  920. activity.publish=now>activity.etime ? 2 : activity.publish;
  921. return Ok(new { code = 200, activity, contest, reviewRule, training, research });
  922. }
  923. else
  924. {
  925. return Ok(new { code = 2, msg = "活动不存在" });
  926. }
  927. }
  928. //读取优课评选模块及评审规则
  929. case bool when $"{grant_type}".Equals("read-Contest", StringComparison.OrdinalIgnoreCase):
  930. {
  931. Contest contest = null;
  932. ReviewRuleTree reviewRule = null;
  933. if (!request.TryGetProperty("activityId", out JsonElement _activityId)) return BadRequest();
  934. Azure.Response response = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("Contest"));
  935. if (response.Status==200)
  936. {
  937. contest= JsonDocument.Parse(response.Content).RootElement.ToObject<Contest>();
  938. if (contest.modules.Contains("review"))
  939. {
  940. Azure.Response reviewRuleResponse = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("ReviewRule-disposable"));
  941. if (reviewRuleResponse.Status==200)
  942. {
  943. ReviewRule reviewRuleDB = JsonDocument.Parse(reviewRuleResponse.Content).RootElement.ToObject<ReviewRule>();
  944. var tree = ActivityService.ListToTree(reviewRuleDB.configs);
  945. reviewRule= new ReviewRuleTree
  946. {
  947. id=reviewRuleDB.id,
  948. name= reviewRuleDB.name,
  949. owner= reviewRuleDB.owner,
  950. sourceName= reviewRuleDB.sourceName,
  951. trees=tree,
  952. desc=reviewRuleDB.desc,
  953. distribute=reviewRuleDB.distribute,
  954. taskCount=reviewRuleDB.taskCount,
  955. scoreDetail=reviewRuleDB.scoreDetail,
  956. scoreRule=reviewRuleDB.scoreRule,
  957. };
  958. }
  959. }
  960. }
  961. return Ok(new { code = 200, contest, reviewRule });
  962. }
  963. //获取评审的模板列表
  964. case bool when $"{grant_type}".Equals("rule-list", StringComparison.OrdinalIgnoreCase):
  965. {
  966. if (!request.TryGetProperty("owner", out JsonElement _owner)) return BadRequest();
  967. var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).GetList<ReviewRule>($"select value c from c where c.owner='{_owner}'", "ReviewRule-template");
  968. List<ReviewRuleTree> reviewRules = new List<ReviewRuleTree>();
  969. foreach (var item in result.list)
  970. {
  971. var tree = ActivityService.ListToTree(item.configs);
  972. ReviewRuleTree reviewRule = new ReviewRuleTree
  973. {
  974. id=item.id,
  975. desc=item.desc,
  976. name= item.name,
  977. owner= item.owner,
  978. sourceName= item.sourceName,
  979. trees=tree,
  980. upsertAsTemplate=1,
  981. taskCount=item.taskCount,
  982. scoreRule=item.scoreRule,
  983. distribute=item.distribute,
  984. scoreDetail=item.scoreDetail
  985. };
  986. reviewRules.Add(reviewRule);
  987. }
  988. return Ok(new { reviewRules });
  989. }
  990. //编辑当前活动评审规则
  991. case bool when $"{grant_type}".Equals("rule-update", StringComparison.OrdinalIgnoreCase):
  992. {
  993. if (!request.TryGetProperty("reviewConfig", out JsonElement _reviewConfig))
  994. {
  995. return Ok(new { code = 4, msg = "评审未配置" });
  996. }
  997. ReviewRuleTree ruleTree = _reviewConfig.ToObject<ReviewRuleTree>();
  998. if (!string.IsNullOrWhiteSpace(ruleTree.id))
  999. {
  1000. Activity activity = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemAsync<Activity>(ruleTree.id, new PartitionKey("Activity"));
  1001. Contest contest = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemAsync<Contest>(ruleTree.id, new PartitionKey("Contest"));
  1002. var reviewRuleResult = await ActivityService.UpsertReviewRule(ruleTree, activity, contest, _azureCosmos);
  1003. if (reviewRuleResult.invalidCode!=200)
  1004. {
  1005. return Ok(new { code = reviewRuleResult.invalidCode, msg = reviewRuleResult.msg });
  1006. }
  1007. var tree = ActivityService.ListToTree(reviewRuleResult.reviewRule.configs);
  1008. var reviewRule = new ReviewRuleTree
  1009. {
  1010. id=reviewRuleResult.reviewRule.id,
  1011. name= reviewRuleResult.reviewRule.name,
  1012. owner= reviewRuleResult.reviewRule.owner,
  1013. sourceName= reviewRuleResult.reviewRule.sourceName,
  1014. trees=tree,
  1015. desc=reviewRuleResult.reviewRule.desc,
  1016. distribute=reviewRuleResult.reviewRule.distribute,
  1017. scoreDetail=reviewRuleResult.reviewRule.scoreDetail,
  1018. scoreRule=reviewRuleResult.reviewRule.scoreRule,
  1019. taskCount=reviewRuleResult.reviewRule.taskCount,
  1020. };
  1021. return Ok(new { reviewRule });
  1022. }
  1023. else
  1024. {
  1025. return Ok(new { code = 5, msg = "规则不存在" });
  1026. }
  1027. }
  1028. //删除评审规则模板
  1029. case bool when $"{grant_type}".Equals("rule-delete", StringComparison.OrdinalIgnoreCase):
  1030. {
  1031. if (!request.TryGetProperty("ruleId", out JsonElement _ruleId))
  1032. {
  1033. return BadRequest();
  1034. }
  1035. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).DeleteItemStreamAsync(_ruleId.GetString(), new PartitionKey("ReviewRule-template"));
  1036. return Ok(new { code = 200 });
  1037. }
  1038. case bool when $"{grant_type}".Equals("invite-remove-school", StringComparison.OrdinalIgnoreCase):
  1039. {
  1040. if (!request.TryGetProperty("activityId", out JsonElement _activityId)) return BadRequest();
  1041. if (!request.TryGetProperty("invitedSchools", out JsonElement _invitedSchools)) return BadRequest();
  1042. Azure.Response response = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("Activity"));
  1043. if (response.Status==200)
  1044. {
  1045. List<ActivityInvitedSchool> invitedSchools = _invitedSchools.ToObject<List<ActivityInvitedSchool>>();
  1046. Activity activity = JsonDocument.Parse(response.Content).RootElement.ToObject<Activity>();
  1047. foreach (var invitedSchool in invitedSchools)
  1048. {
  1049. if (!activity.invitedSchools.Exists(z => z.id.Equals(invitedSchool.id)))
  1050. {
  1051. activity.invitedSchools.Add(invitedSchool);
  1052. }
  1053. }
  1054. return Ok(new { code = 200, activity });
  1055. }
  1056. else
  1057. {
  1058. return Ok(new { code = 1, msg = "活动不存在" });
  1059. }
  1060. }
  1061. //学校确认参加本次活动
  1062. case bool when $"{grant_type}".Equals("school-confirm", StringComparison.OrdinalIgnoreCase):
  1063. {
  1064. if (!request.TryGetProperty("activityId", out JsonElement _activityId)) return BadRequest();
  1065. if (!request.TryGetProperty("confirm", out JsonElement _confirm)) return BadRequest();
  1066. if (!string.IsNullOrWhiteSpace(school))
  1067. {
  1068. Azure.Response response = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("Activity"));
  1069. if (response.Status==200)
  1070. {
  1071. Activity activity = JsonDocument.Parse(response.Content).RootElement.ToObject<Activity>();
  1072. if (_confirm.GetInt32()==1 ||_confirm.GetInt32()==0)
  1073. {
  1074. var invitedSchool = activity.invitedSchools.Find(z => z.id.Equals(school));
  1075. if (invitedSchool!=null ||
  1076. //如果是区级,且没选择学校,也需要确认
  1077. (activity.scope.Equals("area") && !activity.invitedSchools.IsNotEmpty()))
  1078. {
  1079. var confirmedSchool = activity.confirmedSchools.Find(z => z.id.Equals(school));
  1080. if (confirmedSchool!=null)
  1081. {
  1082. confirmedSchool.status=_confirm.GetInt32();
  1083. }
  1084. else
  1085. {
  1086. School schoolbase = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemAsync<School>(school, new PartitionKey("Base"));
  1087. if (activity.scope.Equals("area"))
  1088. {
  1089. if (string.IsNullOrWhiteSpace(schoolbase.areaId) || !schoolbase.areaId.Equals(activity.owner))
  1090. {
  1091. return Ok(new { code = 5, msg = "学校的区级与活动所属区级不一致!" });
  1092. }
  1093. }
  1094. activity.confirmedSchools= new List<ActivityConfirmedSchool>() { new ActivityConfirmedSchool { id=school, status=_confirm.GetInt32(), name=schoolbase.name, picture= schoolbase.picture } };
  1095. }
  1096. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).UpsertItemAsync(activity, new PartitionKey("Activity"));
  1097. return Ok(new { code = 200, activity });
  1098. }
  1099. else
  1100. {
  1101. return Ok(new { code = 1, msg = "该学校未被邀请!" });
  1102. }
  1103. }
  1104. else
  1105. {
  1106. return Ok(new { code = 2, msg = "活动发布状态错误!" });
  1107. }
  1108. }
  1109. else
  1110. {
  1111. return Ok(new { code = 4, msg = "活动不存在!" });
  1112. }
  1113. }
  1114. else
  1115. {
  1116. return Ok(new { code = 3, msg = "没有学校信息!" });
  1117. }
  1118. }
  1119. //发布或取消发布活动
  1120. case bool when $"{grant_type}".Equals("update-publish", StringComparison.OrdinalIgnoreCase):
  1121. {
  1122. if (!request.TryGetProperty("activityId", out JsonElement _activityId)) return BadRequest();
  1123. if (!request.TryGetProperty("publish", out JsonElement _publish)) return BadRequest();
  1124. Azure.Response response = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("Activity"));
  1125. if (response.Status==200)
  1126. {
  1127. Activity activity = JsonDocument.Parse(response.Content).RootElement.ToObject<Activity>();
  1128. if (_publish.GetInt32()==1 ||_publish.GetInt32()==0)
  1129. {
  1130. activity.publish=_publish.GetInt32();
  1131. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).UpsertItemAsync(activity, new PartitionKey("Activity"));
  1132. return Ok(new { code = 200, activity });
  1133. }
  1134. else
  1135. {
  1136. return Ok(new { code = 2, msg = "活动发布状态错误!" });
  1137. }
  1138. }
  1139. else
  1140. {
  1141. return Ok(new { code = 1, msg = "活动不存在" });
  1142. }
  1143. }
  1144. //邀请教师参加本次活动或移除教师参加活动
  1145. case bool when $"{grant_type}".Equals("invite-remove-teachers", StringComparison.OrdinalIgnoreCase):
  1146. {
  1147. if (!request.TryGetProperty("activityId", out JsonElement _activityId)) return BadRequest();
  1148. request.TryGetProperty("invite", out JsonElement _invite);
  1149. request.TryGetProperty("remove", out JsonElement _remove);
  1150. Azure.Response response = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("Activity"));
  1151. if (response.Status==200)
  1152. {
  1153. Activity activity = JsonDocument.Parse(response.Content).RootElement.ToObject<Activity>();
  1154. if (activity.joinMode.Equals("invite"))
  1155. {
  1156. var confirmedSchool = activity.confirmedSchools.Find(z => z.id.Equals(school) && z.status==1);
  1157. if (confirmedSchool!= null || activity.scope.Equals("school", StringComparison.OrdinalIgnoreCase))
  1158. {
  1159. List<InviteTeachers> inviteTeachersInvalid = new List<InviteTeachers>();
  1160. List<InviteTeachers> removeTeachersInvalid = new List<InviteTeachers>();
  1161. ActivityTeacher activityTeacher = null;
  1162. Azure.Response activityTeacherResponse = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemStreamAsync(school, new PartitionKey($"ActivityTeacher-{activity.id}"));
  1163. if (activityTeacherResponse.Status==200)
  1164. {
  1165. activityTeacher = JsonDocument.Parse(activityTeacherResponse.Content).RootElement.ToObject<ActivityTeacher>();
  1166. }
  1167. if (activityTeacher==null)
  1168. {
  1169. activityTeacher= new ActivityTeacher() { activityId=_activityId.GetString(), schoolName= activity.scope.Equals("school") && confirmedSchool== null ? activity.ownerName : confirmedSchool.name, id=school, code=$"ActivityTeacher-{_activityId}", pk="ActivityTeacher" };
  1170. }
  1171. if (_invite.ValueKind.Equals(JsonValueKind.Array))
  1172. {
  1173. List<InviteTeachers> inviteTeachers = _invite.ToObject<List<InviteTeachers>>();
  1174. foreach (var invite in inviteTeachers)
  1175. {
  1176. if (string.IsNullOrWhiteSpace(invite.school) || !invite.school.Equals(school))
  1177. {
  1178. inviteTeachersInvalid.Add(invite);
  1179. continue;
  1180. }
  1181. var inviteTeacher = activityTeacher.inviteTeachers.Find(z => z.id.Equals(invite.id));
  1182. if (inviteTeacher==null)
  1183. {
  1184. activityTeacher.inviteTeachers.Add(invite);
  1185. }
  1186. else
  1187. {
  1188. inviteTeacher=invite;
  1189. }
  1190. }
  1191. }
  1192. if (_remove.ValueKind.Equals(JsonValueKind.Array))
  1193. {
  1194. List<InviteTeachers> removeTeachers = _remove.ToObject<List<InviteTeachers>>();
  1195. foreach (var remove in removeTeachers)
  1196. {
  1197. if (string.IsNullOrWhiteSpace(remove.school) || !remove.school.Equals(school))
  1198. {
  1199. removeTeachersInvalid.Add(remove);
  1200. continue;
  1201. }
  1202. activityTeacher.inviteTeachers.RemoveAll(z => remove.id.Equals(z.id));
  1203. }
  1204. }
  1205. var teachers = activityTeacher.inviteTeachers.FindAll(z => z.school.Equals(school));
  1206. activityTeacher.activityId=$"{_activityId}";
  1207. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).UpsertItemAsync(activityTeacher, new PartitionKey($"ActivityTeacher-{_activityId}"));
  1208. return Ok(new { inviteTeachers = teachers, inviteTeachersInvalid, removeTeachersInvalid });
  1209. }
  1210. else
  1211. {
  1212. return Ok(new { code = 2, msg = "学校未确认,暂不能邀请教师" });
  1213. }
  1214. }
  1215. else
  1216. {
  1217. return Ok(new { code = 3, msg = "活动不是邀请制。" });
  1218. }
  1219. }
  1220. else
  1221. {
  1222. return Ok(new { code = 1, msg = "活动不存在" });
  1223. }
  1224. }
  1225. //获取单个教师的报名数据
  1226. case bool when $"{grant_type}".Equals("get-teacher-enroll", StringComparison.OrdinalIgnoreCase):
  1227. {
  1228. if (!request.TryGetProperty("teacherId", out JsonElement _teacherId)) return BadRequest();
  1229. if (!request.TryGetProperty("activityId", out JsonElement _activityId)) return BadRequest();
  1230. ActivityEnroll enroll = null;
  1231. Azure.Response responseActivityEnroll = await client.GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemStreamAsync($"{_teacherId}", new PartitionKey($"ActivityEnroll-{_activityId.GetString()}"));
  1232. if (responseActivityEnroll.Status==200)
  1233. {
  1234. enroll= JsonDocument.Parse(responseActivityEnroll.Content).RootElement.ToObject<ActivityEnroll>();
  1235. return Ok(new { code = 200, enroll });
  1236. }
  1237. return Ok(new { code = 1, msg = "暂无报名数据!", });
  1238. }
  1239. //获取邀请的教师列表
  1240. case bool when $"{grant_type}".Equals("invited-teachers", StringComparison.OrdinalIgnoreCase)
  1241. || $"{grant_type}".Equals("invited-and-enroll-teachers", StringComparison.OrdinalIgnoreCase):
  1242. {
  1243. string owner = string.Empty;
  1244. if (!request.TryGetProperty("activityId", out JsonElement _activityId)) return BadRequest();
  1245. request.TryGetProperty("activityOwner", out JsonElement _activityOwner);
  1246. if (string.IsNullOrWhiteSpace($"{_activityOwner}"))
  1247. {
  1248. if (!string.IsNullOrWhiteSpace(school))
  1249. {
  1250. owner=school;
  1251. }
  1252. }
  1253. else
  1254. {
  1255. owner=$"{_activityOwner}";
  1256. }
  1257. Activity activity = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemAsync<Activity>(_activityId.GetString(), new PartitionKey("Activity"));
  1258. int isAll = 0;
  1259. if (!string.IsNullOrWhiteSpace(owner))
  1260. {
  1261. if (activity.owner.Equals(owner))
  1262. {
  1263. isAll = 1;
  1264. }
  1265. }
  1266. List<InviteTeachers> inviteTeachers = new List<InviteTeachers>();
  1267. string activityTeacherSQL = $"select value c from c where c.pk='ActivityTeacher'";
  1268. if (isAll!=1 && !string.IsNullOrWhiteSpace(school))
  1269. {
  1270. activityTeacherSQL=$"{activityTeacherSQL} and c.id='{school}'";
  1271. }
  1272. var activityTeacherResult = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<ActivityTeacher>(activityTeacherSQL, $"ActivityTeacher-{_activityId}");
  1273. foreach (var activityTeacher in activityTeacherResult.list)
  1274. {
  1275. inviteTeachers.AddRange(activityTeacher.inviteTeachers);
  1276. }
  1277. if ($"{grant_type}".Equals("invited-and-enroll-teachers", StringComparison.OrdinalIgnoreCase))
  1278. {
  1279. string enrollSQL = $"select value c from c where c.activityId='{_activityId.GetString()}' ";
  1280. //不是自己的,且学校不为空,则查询指定学校的,否则获取所有报名的数据
  1281. if (isAll!=1 && !string.IsNullOrWhiteSpace(school))
  1282. {
  1283. enrollSQL=$"{enrollSQL} and c.schoolId='{school}'";
  1284. }
  1285. var enrollResult = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<ActivityEnroll>(enrollSQL, $"ActivityEnroll-{_activityId}");
  1286. List<InviteEnrollTeacherDto> inviteEnrollTeachers = new List<InviteEnrollTeacherDto>();
  1287. Contest contest = null;
  1288. Azure.Response contestResponse = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("Contest"));
  1289. if (contestResponse.Status==200)
  1290. {
  1291. contest = JsonDocument.Parse(contestResponse.Content).RootElement.ToObject<Contest>();
  1292. }
  1293. long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  1294. int uploadStatus = -1;
  1295. int contestStatus = -1;
  1296. if (contest?.sign!=null)
  1297. {
  1298. if (contest?.sign.stime>now)
  1299. {
  1300. contestStatus=-2;
  1301. }
  1302. else
  1303. {
  1304. contestStatus = 0;
  1305. }
  1306. }
  1307. if (contest?.upload!=null)
  1308. {
  1309. if (contest?.upload.stime>now)
  1310. {
  1311. uploadStatus=-2;
  1312. }
  1313. else
  1314. {
  1315. uploadStatus=0;
  1316. }
  1317. }
  1318. foreach (var inviteTeacher in inviteTeachers)
  1319. {
  1320. inviteEnrollTeachers.Add(new InviteEnrollTeacherDto
  1321. {
  1322. id= inviteTeacher.id,
  1323. name= inviteTeacher.name,
  1324. picture= inviteTeacher.picture,
  1325. school= inviteTeacher.school,
  1326. schoolName=inviteTeacher.schoolName,
  1327. inviteStatus=inviteTeacher.status,
  1328. signContestStatus=contestStatus,
  1329. uploadContestStatus=uploadStatus
  1330. });
  1331. }
  1332. foreach (var activityEnroll in enrollResult.list)
  1333. {
  1334. var inviteEnrollTeacher = inviteEnrollTeachers.Find(z => z.id.Equals(activityEnroll.id) && !string.IsNullOrWhiteSpace(z.school) && !string.IsNullOrEmpty(activityEnroll.schoolId) && z.school.Equals(activityEnroll.schoolId));
  1335. if (inviteEnrollTeacher==null)
  1336. {
  1337. inviteEnrollTeacher= new InviteEnrollTeacherDto
  1338. {
  1339. id= activityEnroll.id,
  1340. name= activityEnroll.tmdName,
  1341. picture= activityEnroll.tmdPicture,
  1342. school= activityEnroll.schoolId,
  1343. schoolName=activityEnroll.schoolName,
  1344. signContestStatus=contestStatus,
  1345. uploadContestStatus=uploadStatus
  1346. };
  1347. inviteEnrollTeachers.Add(inviteEnrollTeacher);
  1348. }
  1349. if (activityEnroll.contest!= null)
  1350. {
  1351. inviteEnrollTeacher.signContestStatus = 1;
  1352. inviteEnrollTeacher.signContestTime = activityEnroll.contest.enrollTime;
  1353. inviteEnrollTeacher.signContestType = activityEnroll.contest.type;
  1354. inviteEnrollTeacher.teamCipherContest=activityEnroll.contest.cipher;
  1355. inviteEnrollTeacher.teamLeaderContest=activityEnroll.contest.leader;
  1356. inviteEnrollTeacher.teamNameContest=activityEnroll.contest.teamName;
  1357. }
  1358. if (activityEnroll.upload!=null)
  1359. {
  1360. inviteEnrollTeacher.uploadContestId=activityEnroll.upload.uploadId;
  1361. //inviteEnrollTeacher.uploadContestType=activityEnroll.upload.type;
  1362. inviteEnrollTeacher.uploadContestTypes= activityEnroll.upload.uploadType;
  1363. inviteEnrollTeacher.uploadContestStatus=1;
  1364. inviteEnrollTeacher.uploadContestTime= activityEnroll.upload.uploadTime;
  1365. inviteEnrollTeacher.uploadContestScore=activityEnroll.upload.score;
  1366. }
  1367. }
  1368. //进入评审环节
  1369. if (contest.review!= null && now > contest.review.stime)
  1370. {
  1371. HashSet<string> uploadContestIds = inviteEnrollTeachers.Where(x => !string.IsNullOrWhiteSpace(x.uploadContestId)).Select(z => z.uploadContestId).ToHashSet();
  1372. if (uploadContestIds!= null && uploadContestIds.Count>0)
  1373. {
  1374. // List<ActivityExpertTask> expertTasks = new List<ActivityExpertTask>();
  1375. string taskSQL = $"select distinct value c from c join s in c.contestTasks where c.pk='ActivityExpertTask' and s.uploadId in ({string.Join(",", uploadContestIds.Select(z => $"'{z}'"))})";
  1376. List<ExpertContestTaskDto> worksDB = new List<ExpertContestTaskDto>();
  1377. var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<ActivityExpertTask>(taskSQL, $"ActivityExpertTask-{_activityId}");
  1378. if (result.list.IsNotEmpty())
  1379. {
  1380. List<ActivityExpertTask> change = new List<ActivityExpertTask>();
  1381. var experts = await ActivityService.ListExperts(_azureCosmos, _coreAPIHttpService, _dingDing, _option, $"{_activityId}");
  1382. foreach (var item in result.list)
  1383. {
  1384. var expert= experts.Find(x => !string.IsNullOrWhiteSpace(x.id) && x.id.Equals(item.id));
  1385. if (expert!=null)
  1386. {
  1387. foreach (var task in item.contestTasks)
  1388. {
  1389. var teachers = inviteEnrollTeachers.FindAll(z => !string.IsNullOrWhiteSpace(z.uploadContestId) && z.uploadContestId.Equals(task.uploadId));
  1390. if (teachers!=null)
  1391. {
  1392. teachers.ForEach(z => {
  1393. z.reviewContestAssignCount+=1;
  1394. z.reviewContestExperts.Add(new ExpertUploadScore
  1395. {
  1396. score=task.score,
  1397. detailScore=task.detailScore,
  1398. id= item.id,
  1399. name=item.name,
  1400. nickname=item.tmdname,
  1401. picture=item.picture
  1402. });
  1403. });
  1404. }
  1405. }
  1406. }
  1407. else
  1408. {
  1409. change.Add(item);
  1410. }
  1411. }
  1412. if (change.IsNotEmpty()) {
  1413. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).DeleteItemsAsync<ActivityExpertTask>(change.Select(x=>x.id).ToList(),$"ActivityExpertTask-{_activityId}");
  1414. }
  1415. }
  1416. }
  1417. }
  1418. return Ok(new { code = 200, inviteEnrollTeachers });
  1419. }
  1420. else
  1421. {
  1422. return Ok(new { code = 200, inviteTeachers });
  1423. }
  1424. }
  1425. //导入评审专家
  1426. case bool when $"{grant_type}".Equals("add-remove-experts", StringComparison.OrdinalIgnoreCase):
  1427. {
  1428. if (!request.TryGetProperty("activityId", out JsonElement _activityId)) return BadRequest();
  1429. List<Expert> upsert_experts = new List<Expert>();
  1430. List<Expert> remove_experts = new List<Expert>();
  1431. if (request.TryGetProperty("upsert_experts", out JsonElement _upsert_experts) && _upsert_experts.ValueKind.Equals(JsonValueKind.Array))
  1432. {
  1433. upsert_experts = _upsert_experts.ToObject<List<Expert>>();
  1434. }
  1435. if (request.TryGetProperty("remove_experts", out JsonElement _remove_experts) && _remove_experts.ValueKind.Equals(JsonValueKind.Array))
  1436. {
  1437. remove_experts = _remove_experts.ToObject<List<Expert>>();
  1438. }
  1439. ActivityExpert activityExpert = null;
  1440. if (upsert_experts.IsNotEmpty())
  1441. {
  1442. var tmdids = upsert_experts.Where(x => !string.IsNullOrWhiteSpace(x.tmdid)).Select(z => z.tmdid);
  1443. var phones = upsert_experts.Where(x => !string.IsNullOrWhiteSpace(x.mobile)).Select(z => z.mobile);
  1444. var emails = upsert_experts.Where(x => !string.IsNullOrWhiteSpace(x.email)).Select(z => z.email);
  1445. List<string> keys = new List<string>();
  1446. if (tmdids.Any())
  1447. {
  1448. keys.AddRange(tmdids);
  1449. }
  1450. if (phones.Any())
  1451. {
  1452. keys.AddRange(phones);
  1453. }
  1454. if (emails.Any())
  1455. {
  1456. keys.AddRange(emails);
  1457. }
  1458. upsert_experts.ForEach(x => { x.status = 0; x.iname = x.name; x.name = null; });
  1459. List<CoreUser> coreUsers = new List<CoreUser>();
  1460. if (keys.Any())
  1461. {
  1462. try
  1463. {
  1464. var content = new StringContent(keys.ToJsonString(), Encoding.UTF8, "application/json");
  1465. string json = await _coreAPIHttpService.GetUserInfos(content);
  1466. if (!string.IsNullOrWhiteSpace(json))
  1467. {
  1468. coreUsers = json.ToObject<List<CoreUser>>();
  1469. }
  1470. }
  1471. catch (Exception ex)
  1472. {
  1473. await _dingDing.SendBotMsg($"{_option.Location},导入名单时,查验key信息错误{ex.Message}\n{ex.StackTrace}\n\n{keys.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
  1474. }
  1475. }
  1476. if (coreUsers.IsNotEmpty())
  1477. {
  1478. foreach (var t in upsert_experts)
  1479. {
  1480. if (!string.IsNullOrWhiteSpace(t.tmdid))
  1481. {
  1482. CoreUser coreUser = coreUsers.Find(x => x.id.Equals(t.tmdid));
  1483. if (coreUser != null)
  1484. {
  1485. t.id = coreUser.id;
  1486. t.name = coreUser.name;
  1487. t.picture = coreUser.picture;
  1488. t.tmdid = coreUser.id;
  1489. if (!string.IsNullOrWhiteSpace(coreUser.mobile))
  1490. {
  1491. t.mobile = coreUser.mobile;
  1492. }
  1493. if (!string.IsNullOrWhiteSpace(coreUser.mail))
  1494. {
  1495. t.email = coreUser.mail;
  1496. }
  1497. }
  1498. }
  1499. if (string.IsNullOrWhiteSpace(t.id))
  1500. {
  1501. if (!string.IsNullOrWhiteSpace(t.mobile))
  1502. {
  1503. CoreUser coreUser = coreUsers.Find(x => !string.IsNullOrWhiteSpace(x.mobile) && x.mobile.Equals(t.mobile));
  1504. if (coreUser != null)
  1505. {
  1506. t.id = coreUser.id;
  1507. t.name = coreUser.name;
  1508. t.picture = coreUser.picture;
  1509. t.tmdid = coreUser.id;
  1510. if (!string.IsNullOrWhiteSpace(coreUser.mobile))
  1511. {
  1512. t.mobile = coreUser.mobile;
  1513. }
  1514. if (!string.IsNullOrWhiteSpace(coreUser.mail))
  1515. {
  1516. t.email = coreUser.mail;
  1517. }
  1518. }
  1519. }
  1520. }
  1521. if (string.IsNullOrWhiteSpace(t.id))
  1522. {
  1523. if (!string.IsNullOrWhiteSpace(t.email))
  1524. {
  1525. CoreUser coreUser = coreUsers.Find(x => !string.IsNullOrWhiteSpace(x.mail) && x.mail.Equals(t.email));
  1526. if (coreUser != null)
  1527. {
  1528. t.id = coreUser.id;
  1529. t.name = coreUser.name;
  1530. t.picture = coreUser.picture;
  1531. t.tmdid = coreUser.id;
  1532. if (!string.IsNullOrWhiteSpace(coreUser.mobile))
  1533. {
  1534. t.mobile = coreUser.mobile;
  1535. }
  1536. if (!string.IsNullOrWhiteSpace(coreUser.mail))
  1537. {
  1538. t.email = coreUser.mail;
  1539. }
  1540. }
  1541. }
  1542. }
  1543. }
  1544. Azure.Response response = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemStreamAsync($"{_activityId}", new PartitionKey("ActivityExpert"));
  1545. if (response.Status == 200)
  1546. {
  1547. activityExpert = JsonDocument.Parse(response.Content).RootElement.Deserialize<ActivityExpert>();
  1548. upsert_experts.ForEach(x =>
  1549. {
  1550. Expert tch = null;
  1551. if (string.IsNullOrWhiteSpace(x.id))
  1552. {
  1553. tch = activityExpert.experts.Find(t => !string.IsNullOrWhiteSpace(t.iname) && t.iname.Equals(x.iname));
  1554. }
  1555. else
  1556. {
  1557. tch = activityExpert.experts.Find(t => !string.IsNullOrWhiteSpace(x.id) && !string.IsNullOrWhiteSpace(t.id) && t.id.Equals(x.id));
  1558. }
  1559. if (tch != null)
  1560. {
  1561. tch.status = x.status;
  1562. tch.name = x.name;
  1563. tch.iname = x.iname;
  1564. tch.picture = x.picture;
  1565. tch.mobile = x.mobile;
  1566. tch.tmdid = x.tmdid;
  1567. tch.email = x.email;
  1568. tch.id = x.id;
  1569. tch.school = x.school;
  1570. //直接替换更新
  1571. tch.modules=x.modules;
  1572. tch.subjects=x.subjects;
  1573. // x.modules.ForEach(y => {
  1574. // if (!tch.modules.Contains(y))
  1575. // {
  1576. // tch.modules.Add(y);
  1577. // }
  1578. // });
  1579. // x.subjects.ForEach(r => {
  1580. // if (!string.IsNullOrWhiteSpace(r.subject) && !string.IsNullOrWhiteSpace(r.period))
  1581. // {
  1582. // var sub = tch.subjects.Find(x => !string.IsNullOrWhiteSpace(x.subject) && !string.IsNullOrWhiteSpace(x.period) && x.subject.Equals(r.subject) && x.period.Equals(r.period));
  1583. // if (sub == null)
  1584. // {
  1585. // tch.subjects.Add(r);
  1586. // }
  1587. // }
  1588. // if (!string.IsNullOrWhiteSpace(r.subject) && string.IsNullOrWhiteSpace(r.period))
  1589. // {
  1590. // var sub = tch.subjects.Find(a => !string.IsNullOrWhiteSpace(a.subject) && string.IsNullOrWhiteSpace(a.period) && a.subject.Equals(r.subject));
  1591. // if (sub == null)
  1592. // {
  1593. // tch.subjects.Add(r);
  1594. // }
  1595. // }
  1596. // });
  1597. }
  1598. else
  1599. {
  1600. activityExpert.experts.Add(new Expert
  1601. {
  1602. status = x.status,
  1603. name = x.name,
  1604. iname = x.iname,
  1605. picture = x.picture,
  1606. mobile = x.mobile,
  1607. tmdid = x.tmdid,
  1608. email = x.email,
  1609. id = x.id,
  1610. title = x.title,
  1611. subjects = x.subjects,
  1612. modules = x.modules,
  1613. school=x.school,
  1614. });
  1615. }
  1616. });
  1617. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).UpsertItemAsync(activityExpert, new PartitionKey("ActivityExpert"));
  1618. }
  1619. else
  1620. {
  1621. activityExpert = new ActivityExpert { id = $"{_activityId}", code = "ActivityExpert", pk = "ActivityExpert", experts = upsert_experts };
  1622. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).UpsertItemAsync(activityExpert, new PartitionKey("ActivityExpert"));
  1623. }
  1624. }
  1625. else
  1626. {
  1627. activityExpert = new ActivityExpert { id = $"{_activityId}", code = "ActivityExpert", pk = "ActivityExpert", experts = upsert_experts };
  1628. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).UpsertItemAsync(activityExpert, new PartitionKey("ActivityExpert"));
  1629. }
  1630. }
  1631. if (remove_experts.IsNotEmpty())
  1632. {
  1633. if (activityExpert == null)
  1634. {
  1635. Azure.Response response = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemStreamAsync($"{_activityId}", new PartitionKey("ActivityExpert"));
  1636. if (response.Status == 200)
  1637. {
  1638. activityExpert = JsonDocument.Parse(response.Content).RootElement.Deserialize<ActivityExpert>();
  1639. }
  1640. }
  1641. if (activityExpert!=null)
  1642. {
  1643. remove_experts.ForEach(z => {
  1644. if (!string.IsNullOrWhiteSpace(z.id))
  1645. {
  1646. activityExpert.experts.RemoveAll(x => !string.IsNullOrWhiteSpace(x.id) && x.id.Equals(z.id));
  1647. }
  1648. else
  1649. {
  1650. if (!string.IsNullOrWhiteSpace(z.mobile))
  1651. {
  1652. activityExpert.experts.RemoveAll(x => !string.IsNullOrWhiteSpace(x.mobile) && x.mobile.Equals(z.mobile));
  1653. }
  1654. if (!string.IsNullOrWhiteSpace(z.email))
  1655. {
  1656. activityExpert.experts.RemoveAll(x => !string.IsNullOrWhiteSpace(x.email) && x.email.Equals(z.email));
  1657. }
  1658. if (!string.IsNullOrWhiteSpace(z.tmdid))
  1659. {
  1660. activityExpert.experts.RemoveAll(x => !string.IsNullOrWhiteSpace(x.tmdid) && x.tmdid.Equals(z.tmdid));
  1661. }
  1662. }
  1663. });
  1664. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).UpsertItemAsync(activityExpert, new PartitionKey("ActivityExpert"));
  1665. }
  1666. }
  1667. return Ok(new { activityExpert, code = 200 });
  1668. }
  1669. //评审专家列表
  1670. case bool when $"{grant_type}".Equals("list-experts", StringComparison.OrdinalIgnoreCase):
  1671. {
  1672. if (!request.TryGetProperty("activityId", out JsonElement _activityId)) return BadRequest();
  1673. var expertTasks = await ActivityService.ListExperts(_azureCosmos, _coreAPIHttpService, _dingDing, _option, $"{_activityId}");
  1674. return Ok(new { expertTasks, code = 200 });
  1675. }
  1676. case bool when $"{grant_type}".Equals("update-reviewStatus", StringComparison.OrdinalIgnoreCase):
  1677. {
  1678. if (!request.TryGetProperty("activityId", out JsonElement _activityId)) return BadRequest();
  1679. if (!request.TryGetProperty("reviewStatus", out JsonElement _reviewStatus)) return BadRequest();
  1680. Azure.Response responseContest = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("Contest"));
  1681. if (responseContest.Status == 200)
  1682. {
  1683. long now = DateTimeOffset.Now.ToUnixTimeMilliseconds();
  1684. Contest contest = JsonDocument.Parse(responseContest.Content).RootElement.ToObject<Contest>();
  1685. if (contest.modules.Contains("review") && contest.review != null)
  1686. {
  1687. //只有开启评审的时候才去检查评审时间, 取消评审不用检查。
  1688. if ($"{_reviewStatus}".Equals("1") && (now < contest.review.stime || now > contest.review.etime))
  1689. {
  1690. return Ok(new { code = 1, msg = "不在评审时间范围内!" });
  1691. }
  1692. }
  1693. else
  1694. {
  1695. return Ok(new { code = 2, msg = "未配置评审模块!" });
  1696. }
  1697. if (int.TryParse($"{_reviewStatus}", out int reviewStatus))
  1698. {
  1699. contest.review.reviewStatus = reviewStatus;
  1700. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).UpsertItemAsync(contest, new PartitionKey("Contest"));
  1701. return Ok(new { code = 200, msg = "操作成功!" });
  1702. }
  1703. else
  1704. {
  1705. return Ok(new { code = 4, msg = "评审参数错误!" });
  1706. }
  1707. }
  1708. else {
  1709. return Ok(new { code = 3, msg = "活动不存在!" });
  1710. }
  1711. }
  1712. //分配评审作品任务-检查,自动分配
  1713. case bool when $"{grant_type}".Equals("allocation-task-auto-assign", StringComparison.OrdinalIgnoreCase):
  1714. {
  1715. if (!request.TryGetProperty("activityId", out JsonElement _activityId)) return BadRequest();
  1716. Azure.Response responseReviewRule = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("ReviewRule-disposable"));
  1717. if (responseReviewRule.Status == 200)
  1718. {
  1719. ReviewRule reviewRule = JsonDocument.Parse(responseReviewRule.Content).RootElement.ToObject<ReviewRule>();
  1720. Azure.Response responseContest = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("Contest"));
  1721. if (responseContest.Status == 200)
  1722. {
  1723. long now = DateTimeOffset.Now.ToUnixTimeMilliseconds();
  1724. Contest contest = JsonDocument.Parse(responseContest.Content).RootElement.ToObject<Contest>();
  1725. if (contest.modules.Contains("review") && contest.review != null)
  1726. {
  1727. if (now < contest.review.stime || now > contest.review.etime)
  1728. {
  1729. return Ok(new { code = 12, msg = "不在评审时间范围内!" });
  1730. }
  1731. }
  1732. else
  1733. {
  1734. return Ok(new { code = 11, msg = "未配置评审模块!" });
  1735. }
  1736. var result = ActivityService.CheckReviewRule(reviewRule, contest);
  1737. if (result.invalidCode == 200)
  1738. {
  1739. Azure.Response responseActivityExpert = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemStreamAsync($"{_activityId}", new PartitionKey("ActivityExpert"));
  1740. if (responseActivityExpert.Status == 200)
  1741. {
  1742. ActivityExpert activityExpert = JsonDocument.Parse(responseActivityExpert.Content).RootElement.ToObject<ActivityExpert>();
  1743. HashSet<string> periodSubjectKey = new HashSet<string>();
  1744. List<dynamic> distributeInvalid = new List<dynamic>();
  1745. string allocationTaskKey = $"Contest:Allocation:{_activityId}";
  1746. switch (reviewRule.distribute)
  1747. {
  1748. case "period":
  1749. {
  1750. List<ExpertPeriodSubjectDto> expertPeriodSubjects = new List<ExpertPeriodSubjectDto>();
  1751. var fieldPeriod = contest.sign.fields.Find(z => z.field.Equals("period"));
  1752. if (fieldPeriod == null)
  1753. {
  1754. return Ok(new { code = 5, msg = "评审规则匹配学段,但赛课表单未配置学段。" });
  1755. }
  1756. else
  1757. {
  1758. foreach (string item in fieldPeriod.item)
  1759. {
  1760. periodSubjectKey.Add($"{item}-");
  1761. var periodExperts = activityExpert.experts.Where(z => z.modules.Contains("Contest") && z.subjects != null && z.subjects.Where(v => !string.IsNullOrWhiteSpace(v.period)).Select(c => c.period).Contains(item));
  1762. if (periodExperts.Count() < reviewRule.taskCount)
  1763. {
  1764. distributeInvalid.Add(new { name = item, expertCount = periodExperts.Count(), needCount = reviewRule.taskCount });
  1765. }
  1766. expertPeriodSubjects.AddRange(periodExperts.Select(z => new ExpertPeriodSubjectDto { expertId = z.id, periodSubjects = z.subjects.Select(x => $"{x.period}-")?.ToList() }));
  1767. }
  1768. }
  1769. if (distributeInvalid.Count > 0)
  1770. {
  1771. return Ok(new { code = 6, msg = "学段匹配的专家数量不足。", distributeInvalid });
  1772. }
  1773. else
  1774. {
  1775. IEnumerable<ExpertPeriodSubjectDto> experts = activityExpert.experts.Where(z => !string.IsNullOrWhiteSpace(z.id))//处理
  1776. .Select(z => new ExpertPeriodSubjectDto { expertId = z.id, expertName=z.iname, expertPicture=z.picture, expertTmdname=z.name, periodSubjects = z.subjects.Select(v => $"{v.period}-") });
  1777. var allocationResult = await ActivityService.AllocationTask(_azureCosmos, experts, contest, periodSubjectKey, reviewRule.distribute, reviewRule.taskCount);
  1778. if (allocationResult.expertContestTasks.IsNotEmpty())
  1779. {
  1780. await _azureRedis.GetRedisClient(8).StringSetAsync(allocationTaskKey, allocationResult.expertContestTasks.ToJsonString(), expiry: new TimeSpan(0, 5, 0));
  1781. }
  1782. else
  1783. {
  1784. allocationTaskKey = string.Empty;
  1785. }
  1786. return Ok(new { taskKey = allocationTaskKey, code = 200, tasksDb = allocationResult.expertContestTasksDB, tasksAdd = allocationResult.expertContestTasks, invalid = allocationResult.activityEnrollsInvalid });
  1787. }
  1788. }
  1789. case "subject":
  1790. {
  1791. List<ExpertPeriodSubjectDto> expertPeriodSubjects = new List<ExpertPeriodSubjectDto>();
  1792. var fieldSubject = contest.sign.fields.Find(z => z.field.Equals("subject"));
  1793. if (fieldSubject == null)
  1794. {
  1795. return Ok(new { code = 7, msg = "评审规则匹配学科,但赛课表单未配置学科。" });
  1796. }
  1797. else
  1798. {
  1799. foreach (string item in fieldSubject.item)
  1800. {
  1801. periodSubjectKey.Add($"-{item}");
  1802. var subjectExperts = activityExpert.experts.Where(z => z.modules.Contains("Contest") && z.subjects != null && z.subjects.Where(v => !string.IsNullOrWhiteSpace(v.subject)).Select(c => c.subject).Contains(item));
  1803. if (subjectExperts.Count() < reviewRule.taskCount)
  1804. {
  1805. distributeInvalid.Add(new { name = item, expertCount = subjectExperts.Count(), needCount = reviewRule.taskCount });
  1806. }
  1807. expertPeriodSubjects.AddRange(subjectExperts.Select(z => new ExpertPeriodSubjectDto { expertId = z.id, periodSubjects = z.subjects.Select(x => $"-{x.subject}")?.ToList() }));
  1808. }
  1809. }
  1810. if (distributeInvalid.Count > 0)
  1811. {
  1812. return Ok(new { code = 8, msg = "学科匹配的专家数量不足。", distributeInvalid });
  1813. }
  1814. else
  1815. {
  1816. IEnumerable<ExpertPeriodSubjectDto> experts = activityExpert.experts.Where(z => !string.IsNullOrWhiteSpace(z.id))//处理
  1817. .Select(z => new ExpertPeriodSubjectDto { expertId = z.id, expertName=z.iname, expertPicture=z.picture, expertTmdname=z.name, periodSubjects = z.subjects.Select(v => $"-{v.subject}") });
  1818. var allocationResult = await ActivityService.AllocationTask(_azureCosmos, experts, contest, periodSubjectKey, reviewRule.distribute, reviewRule.taskCount);
  1819. if (allocationResult.expertContestTasks.IsNotEmpty())
  1820. {
  1821. await _azureRedis.GetRedisClient(8).StringSetAsync(allocationTaskKey, allocationResult.expertContestTasks.ToJsonString(), expiry: new TimeSpan(0, 5, 0));
  1822. }
  1823. else
  1824. {
  1825. allocationTaskKey = string.Empty;
  1826. }
  1827. return Ok(new { taskKey = allocationTaskKey, code = 200, tasksDb = allocationResult.expertContestTasksDB, tasksAdd = allocationResult.expertContestTasks, invalid = allocationResult.activityEnrollsInvalid });
  1828. }
  1829. }
  1830. case "periodAndSubject":
  1831. {
  1832. List<ExpertPeriodSubjectDto> expertPeriodSubjects = new List<ExpertPeriodSubjectDto>();
  1833. var fieldPeriod = contest.sign.fields.Find(z => z.field.Equals("period"));
  1834. if (fieldPeriod == null)
  1835. {
  1836. return Ok(new { code = 9, msg = "评审规则匹配学段和学科,但赛课表单未配置学段。" });
  1837. }
  1838. var fieldSubject = contest.sign.fields.Find(z => z.field.Equals("subject"));
  1839. if (fieldSubject == null)
  1840. {
  1841. return Ok(new { code = 10, msg = "评审规则匹配学段和学科,但赛课表单未配置学科。" });
  1842. }
  1843. foreach (var period in fieldPeriod.item)
  1844. {
  1845. foreach (var subject in fieldSubject.item)
  1846. {
  1847. periodSubjectKey.Add($"{period}-{subject}");
  1848. var periodSubjectExperts = activityExpert.experts.FindAll(z => z.modules.Contains("Contest") && z.subjects != null && z.subjects.Where(v => !string.IsNullOrWhiteSpace(v.period) && !string.IsNullOrWhiteSpace(v.subject))
  1849. .Select(c => $"{c.period}-{c.subject}").Contains($"{period}-{subject}"));
  1850. if (periodSubjectExperts.Count() < reviewRule.taskCount)
  1851. {
  1852. distributeInvalid.Add(new { name = $"{period}-{subject}", expertCount = periodSubjectExperts.Count(), needCount = reviewRule.taskCount });
  1853. }
  1854. expertPeriodSubjects.AddRange(periodSubjectExperts.Select(z => new ExpertPeriodSubjectDto { expertId = z.id, periodSubjects = z.subjects.Select(x => $"{x.period}-{x.subject}")?.ToList() }));
  1855. }
  1856. }
  1857. if (distributeInvalid.Count > 0)
  1858. {
  1859. return Ok(new { code = 13, msg = "学段和学科匹配的专家数量不足。", distributeInvalid });
  1860. }
  1861. else
  1862. {
  1863. IEnumerable<ExpertPeriodSubjectDto> experts = activityExpert.experts.Where(z => !string.IsNullOrWhiteSpace(z.id))//处理
  1864. .Select(z => new ExpertPeriodSubjectDto { expertId = z.id, expertName=z.iname, expertPicture=z.picture, expertTmdname=z.name, periodSubjects = z.subjects.Select(v => $"{v.period}-{v.subject}") });
  1865. var allocationResult = await ActivityService.AllocationTask(_azureCosmos, experts, contest, periodSubjectKey, reviewRule.distribute, reviewRule.taskCount);
  1866. if (allocationResult.expertContestTasks.IsNotEmpty())
  1867. {
  1868. await _azureRedis.GetRedisClient(8).StringSetAsync(allocationTaskKey, allocationResult.expertContestTasks.ToJsonString(), expiry: new TimeSpan(0, 5, 0));
  1869. }
  1870. else
  1871. {
  1872. allocationTaskKey = string.Empty;
  1873. }
  1874. return Ok(new { taskKey = allocationTaskKey, code = 200, tasksDb = allocationResult.expertContestTasksDB, tasksAdd = allocationResult.expertContestTasks, invalid = allocationResult.activityEnrollsInvalid });
  1875. }
  1876. }
  1877. default:
  1878. //distribute=none
  1879. {
  1880. if (activityExpert.experts.Count() >= reviewRule.taskCount)
  1881. {
  1882. periodSubjectKey.Add($"-"); IEnumerable<ExpertPeriodSubjectDto> experts = activityExpert.experts.Where(z => !string.IsNullOrWhiteSpace(z.id))//处理
  1883. .Select(z => new ExpertPeriodSubjectDto { expertId = z.id, expertName=z.iname, expertPicture=z.picture, expertTmdname=z.name, periodSubjects = z.subjects.Select(v => $"-") });
  1884. var allocationResult = await ActivityService.AllocationTask(_azureCosmos, experts, contest, periodSubjectKey, reviewRule.distribute, reviewRule.taskCount);
  1885. if (allocationResult.expertContestTasks.IsNotEmpty())
  1886. {
  1887. await _azureRedis.GetRedisClient(8).StringSetAsync(allocationTaskKey, allocationResult.expertContestTasks.ToJsonString(), expiry: new TimeSpan(0, 5, 0));
  1888. }
  1889. else
  1890. {
  1891. allocationTaskKey = string.Empty;
  1892. }
  1893. return Ok(new { taskKey = allocationTaskKey, code = 200, tasksDb = allocationResult.expertContestTasksDB, tasksAdd = allocationResult.expertContestTasks, invalid = allocationResult.activityEnrollsInvalid });
  1894. }
  1895. else
  1896. {
  1897. return Ok(new { code = 4, msg = "评审专家人数不应少于作品分配次数。" });
  1898. }
  1899. }
  1900. }
  1901. }
  1902. else
  1903. {
  1904. return Ok(new { code = 3, msg = "未配置评审专家!" });
  1905. }
  1906. }
  1907. else
  1908. {
  1909. return Ok(new { code = result.invalidCode, msg = result.msg });
  1910. }
  1911. }
  1912. else
  1913. {
  1914. return Ok(new { code = 2, msg = "没有赛课模块!" });
  1915. }
  1916. //专家人数>=每个作品分配次数,同一作品才不会多次被分配到分配给同一个专家。
  1917. }
  1918. else
  1919. {
  1920. return Ok(new { code = 1, msg = "未配置评审规则!" });
  1921. }
  1922. }
  1923. //分配评审作品任务-自动
  1924. case bool when $"{grant_type}".Equals("allocation-task-auto-save", StringComparison.OrdinalIgnoreCase):
  1925. {
  1926. if (!request.TryGetProperty("activityId", out JsonElement _activityId)) return BadRequest();
  1927. if (!request.TryGetProperty("taskKey", out JsonElement _taskKey)) return BadRequest();
  1928. var value = await _azureRedis.GetRedisClient(8).StringGetAsync(_taskKey.GetString());
  1929. if (value.HasValue)
  1930. {
  1931. List<ExpertContestTaskDto> contestTasks = value.ToString().ToObject<List<ExpertContestTaskDto>>();
  1932. List<ActivityExpertTask> expertTasks = new List<ActivityExpertTask>();
  1933. var expertIds = contestTasks.Where(x => !string.IsNullOrWhiteSpace(x.expertId)).Select(z => z.expertId).ToHashSet();
  1934. if (expertIds != null && expertIds.Count > 0)
  1935. {
  1936. string taskSQL = $"select value c from c where c.pk='ActivityExpertTask' and c.id in ({string.Join(",", expertIds.Select(z => $"'{z}'"))})";
  1937. var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<ActivityExpertTask>(taskSQL, $"ActivityExpertTask-{_activityId}");
  1938. if (result.list.IsNotEmpty())
  1939. {
  1940. expertTasks.AddRange(result.list);
  1941. }
  1942. }
  1943. HashSet<ActivityExpertTask> expertTasksChange = new HashSet<ActivityExpertTask>();
  1944. Azure.Response responseContest = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("Contest"));
  1945. Contest contest = null;
  1946. if (responseContest.Status == 200)
  1947. {
  1948. long now = DateTimeOffset.Now.ToUnixTimeMilliseconds();
  1949. contest= JsonDocument.Parse(responseContest.Content).RootElement.ToObject<Contest>();
  1950. if (contest.modules.Contains("review") && contest.review != null)
  1951. {
  1952. if (now < contest.review.stime || now > contest.review.etime)
  1953. {
  1954. return Ok(new { code = 12, msg = "不在评审时间范围内!" });
  1955. }
  1956. }
  1957. }
  1958. foreach (var contestTask in contestTasks)
  1959. {
  1960. ExpertContestTask expertContestTask = contestTask.ToJsonString().ToObject<ExpertContestTask>();
  1961. var expertTask = expertTasks.Find(z => z.id.Equals(contestTask.expertId));
  1962. if (expertTask != null)
  1963. {
  1964. var task = expertTask.contestTasks.Find(z => z.uploadId.Equals(contestTask.uploadId));
  1965. if (task == null)
  1966. {
  1967. expertTask.contestTasks.Add(expertContestTask);
  1968. expertTasksChange.Add(expertTask);
  1969. }
  1970. }
  1971. else
  1972. {
  1973. ActivityExpertTask activityExpertTask = new ActivityExpertTask()
  1974. {
  1975. id = contestTask.expertId,
  1976. code = $"ActivityExpertTask-{_activityId}",
  1977. pk = "ActivityExpertTask",
  1978. activityId=_activityId.GetString(),
  1979. picture=contestTask.expertPicture,
  1980. name=contestTask.expertName,
  1981. tmdname=contestTask.expertTmdname,
  1982. contestTasks = new List<ExpertContestTask> { expertContestTask }
  1983. };
  1984. expertTasksChange.Add(activityExpertTask);
  1985. expertTasks.Add(activityExpertTask);
  1986. }
  1987. }
  1988. List<Task<ItemResponse<ActivityExpertTask>>> responses = new List<Task<ItemResponse<ActivityExpertTask>>>();
  1989. foreach (var contestTask in expertTasksChange)
  1990. {
  1991. responses.Add(_azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).UpsertItemAsync(contestTask, new PartitionKey($"ActivityExpertTask-{_activityId}")));
  1992. }
  1993. if (responses.IsNotEmpty())
  1994. {
  1995. await responses.TaskPage(10);
  1996. //await Task.WhenAll(responses);
  1997. }
  1998. await _azureRedis.GetRedisClient(8).KeyDeleteAsync(_taskKey.GetString());
  1999. List<ExpertContestTaskDto> tasksDb = new List<ExpertContestTaskDto>();
  2000. foreach (var item in expertTasks)
  2001. {
  2002. tasksDb.AddRange(item.contestTasks.Select(z =>
  2003. new ExpertContestTaskDto
  2004. {
  2005. expertName=item.name,
  2006. expertPicture=item.picture,
  2007. expertTmdname=item.tmdname,
  2008. expertId = item.id,
  2009. available = 1,
  2010. uploadId = z.uploadId,
  2011. name = z.name,
  2012. uploadTypes = z.uploadTypes,
  2013. count = z.count,
  2014. cipher=z.cipher,
  2015. type=z.type,
  2016. leader=z.leader,
  2017. members=z.members,
  2018. tmdid=z.tmdid,
  2019. score=z.score,
  2020. status=z.status,
  2021. detailScore=z.detailScore,
  2022. activityId=_activityId.GetString()
  2023. }));
  2024. }
  2025. return Ok(new { code = 200, tasksDb = tasksDb });
  2026. }
  2027. else { return Ok(new { code = 1, msg = "作品分配Token异常!" }); }
  2028. }
  2029. //分配评审作品任务-手动
  2030. case bool when $"{grant_type}".Equals("allocation-task-manual-save", StringComparison.OrdinalIgnoreCase):
  2031. {
  2032. if (!request.TryGetProperty("activityId", out JsonElement _activityId)) return BadRequest();
  2033. if (!request.TryGetProperty("uploadId", out JsonElement _uploadId)) return BadRequest();
  2034. if (!request.TryGetProperty("expertId", out JsonElement _expertId)) return BadRequest();
  2035. request.TryGetProperty("expertIdOld", out JsonElement _expertIdOld);
  2036. Azure.Response responseContest = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("Contest"));
  2037. if (responseContest.Status == 200) {
  2038. long now = DateTimeOffset.Now.ToUnixTimeMilliseconds();
  2039. Contest contest = JsonDocument.Parse(responseContest.Content).RootElement.ToObject<Contest>();
  2040. if (contest.modules.Contains("review") && contest.review != null)
  2041. {
  2042. if (now < contest.review.stime || now > contest.review.etime)
  2043. {
  2044. return Ok(new { code = 12, msg = "不在评审时间范围内!" });
  2045. }
  2046. }
  2047. else
  2048. {
  2049. return Ok(new { code = 11, msg = "未配置评审模块!" });
  2050. }
  2051. }
  2052. else
  2053. {
  2054. return Ok(new { code = 13, msg = "没有赛课模块!" });
  2055. }
  2056. string sql = $"select value c from c where c.upload.uploadId='{_uploadId}' and c.pk='ActivityEnroll'";
  2057. var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<ActivityEnroll>(sql, $"ActivityEnroll-{_activityId}");
  2058. if (result.list.IsNotEmpty())
  2059. {
  2060. ActivityExpertTask expertTask = null;
  2061. ExpertContestTask contestTask = new ExpertContestTask
  2062. {
  2063. uploadId=_uploadId.GetString(),
  2064. };
  2065. string name = string.Empty;
  2066. int count = 0;
  2067. if (result.list.Count>1)
  2068. {
  2069. var leaders = result.list.FindAll(z => z.contest.leader == 1);
  2070. var leader = leaders?.First();
  2071. if (leader!=null)
  2072. {
  2073. name = leader?.contest?.teamName;
  2074. if (string.IsNullOrEmpty(name))
  2075. {
  2076. name = $"{leader?.contest?.enrollInfos?.Find(z => z.code.Equals("name"))?.val}({result.list.Count})";
  2077. }
  2078. if (leader?.upload != null && leader.upload.sokrates.IsNotEmpty())
  2079. {
  2080. count += leader.upload.sokrates.Count;
  2081. }
  2082. if (leader?.upload != null && leader.upload.files.IsNotEmpty())
  2083. {
  2084. count += leader.upload.files.Count;
  2085. }
  2086. if (leader?.upload != null && leader.upload.lessons.IsNotEmpty())
  2087. {
  2088. count += leader.upload.lessons.Count;
  2089. }
  2090. if (leader?.upload!=null && leader.upload.complexes.IsNotEmpty())
  2091. {
  2092. count+= leader.upload.complexes.Count();
  2093. }
  2094. List<IdNameCode> members = result.list.Select(z => new IdNameCode { id = z.id, code = z.schoolId, picture = z.tmdPicture, nickname = z.tmdName, name = z.contest?.enrollInfos?.Find(e => e.code.Equals("name")).val }).ToList();
  2095. var period = leader?.contest?.enrollInfos?.Find(z => z.code.Equals("period"));
  2096. var subject = leader?.contest?.enrollInfos?.Find(z => z.code.Equals("subject"));
  2097. contestTask.name= $"{leader?.schoolName}-{name}";
  2098. //contestTask.uploadTypes=new List<string> { leader.upload?.type };
  2099. contestTask.uploadTypes =leader.upload.uploadType;
  2100. contestTask.count=count;
  2101. contestTask.cipher=leader.contest?.cipher;
  2102. contestTask.type=leader.contest.type;
  2103. contestTask.leader=leader.contest.leader;
  2104. contestTask.members= members;
  2105. contestTask.tmdid=leader.id;
  2106. contestTask.period=period?.val;
  2107. contestTask.subject=subject?.val;
  2108. }
  2109. else
  2110. {
  2111. return Ok(new { code = 3, msg = "该队伍没有队长!" });
  2112. }
  2113. }
  2114. else if (result.list.Count==1)
  2115. {
  2116. var leader = result.list[0];
  2117. name = leader?.contest?.enrollInfos?.Find(z => z.code.Equals("name"))?.val;
  2118. if (leader?.upload != null && leader.upload.sokrates.IsNotEmpty())
  2119. {
  2120. count += leader.upload.sokrates.Count;
  2121. }
  2122. if (leader?.upload != null && leader.upload.files.IsNotEmpty())
  2123. {
  2124. count += leader.upload.files.Count;
  2125. }
  2126. if (leader?.upload != null && leader.upload.lessons.IsNotEmpty())
  2127. {
  2128. count += leader.upload.lessons.Count;
  2129. }
  2130. var period = leader?.contest?.enrollInfos?.Find(z => z.code.Equals("period"));
  2131. var subject = leader?.contest?.enrollInfos?.Find(z => z.code.Equals("subject"));
  2132. contestTask.name= $"{leader?.schoolName}-{name}";
  2133. contestTask.uploadTypes= leader.upload.uploadType;
  2134. contestTask.count=count;
  2135. contestTask.type=leader.contest.type;
  2136. contestTask.tmdid=leader.id;
  2137. contestTask.period=period?.val;
  2138. contestTask.subject=subject?.val;
  2139. }
  2140. ActivityExpert activityExpert = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemAsync<ActivityExpert>(_activityId.GetString(), new PartitionKey("ActivityExpert"));
  2141. Expert expert= activityExpert.experts.Find(z => !string.IsNullOrWhiteSpace(z.id) && z.id.Equals(_expertId.GetString()));
  2142. if (expert!=null) {
  2143. //作品是否有分配过
  2144. string taskSQL = $"select value c from c join b in c.contestTasks where b.uploadId='{_uploadId}' and c.pk='ActivityExpertTask' " ;
  2145. var resultTask = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<ActivityExpertTask>(taskSQL, $"ActivityExpertTask-{_activityId}");
  2146. if (resultTask.list.IsNotEmpty())
  2147. {
  2148. if (!string.IsNullOrWhiteSpace($"{_expertIdOld}")) {
  2149. if (!expert.id.Equals(_expertIdOld.GetString()))
  2150. {
  2151. //从旧的分配中移除
  2152. var oldTaskExpert = resultTask.list.Find(z => z.id.Equals(_expertIdOld.GetString()));
  2153. if (oldTaskExpert!=null)
  2154. {
  2155. var changeCount = oldTaskExpert.contestTasks.RemoveAll(z => z.uploadId.Equals(_uploadId.GetString()));
  2156. if (changeCount>0)
  2157. {
  2158. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).UpsertItemAsync(oldTaskExpert, new PartitionKey(oldTaskExpert.code));
  2159. }
  2160. }
  2161. else
  2162. {
  2163. return Ok(new { code = 2, msg = "未找到该作品已经分配的专家!" });
  2164. }
  2165. }
  2166. else {
  2167. return Ok(new { code = 4, msg = "作品变更评审专家,调整后的专家不能与已分配的专家相同!" });
  2168. }
  2169. }
  2170. // 除去被调整的专家(oldExpert),(resultTask)可能还有别的专家已分配的,但是不影响该作品继续被分配到新的专家, 可以理解为,作品分配次数+1,
  2171. //作品未被分配的情况、
  2172. string expTaskSQL = $"select value c from c where c.id='{expert.id}' and c.pk='ActivityExpertTask' ";
  2173. var resultExpTask = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<ActivityExpertTask>(expTaskSQL, $"ActivityExpertTask-{_activityId}");
  2174. if (resultExpTask.list.IsNotEmpty())
  2175. {
  2176. var task = resultExpTask.list[0].contestTasks.Find(z => z.uploadId.Equals(_uploadId.GetString()));
  2177. if (task!=null)
  2178. {
  2179. task=contestTask;
  2180. }
  2181. else
  2182. {
  2183. resultExpTask.list[0].contestTasks.Add(contestTask);
  2184. }
  2185. expertTask=resultExpTask.list[0];
  2186. expertTask.activityId=_activityId.GetString();
  2187. }
  2188. else
  2189. {
  2190. //专家没有任何被分配的作品
  2191. expertTask = new ActivityExpertTask()
  2192. {
  2193. id= expert.id,
  2194. code=$"ActivityExpertTask-{_activityId}",
  2195. pk="ActivityExpertTask",
  2196. ttl=-1,
  2197. activityId=_activityId.GetString(),
  2198. name=expert.iname,
  2199. tmdname=expert.name,
  2200. picture=expert.picture,
  2201. contestTasks= new List<ExpertContestTask> { contestTask }
  2202. };
  2203. }
  2204. if (expertTask!=null) {
  2205. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).UpsertItemAsync(expertTask, new PartitionKey(expertTask.code));
  2206. }
  2207. }
  2208. else {
  2209. //旧专家,和作品没有匹配的情况,未分配过,不能调整。
  2210. if (!string.IsNullOrWhiteSpace($"{_expertIdOld}"))
  2211. {
  2212. return Ok(new { code = 2, msg = "未找到该作品已经分配的专家!" });
  2213. }
  2214. //作品未被分配的情况、
  2215. string expTaskSQL = $"select value c from c where c.id='{expert.id}' and c.pk='ActivityExpertTask' ";
  2216. var resultExpTask = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<ActivityExpertTask>(expTaskSQL, $"ActivityExpertTask-{_activityId}");
  2217. if (resultExpTask.list.IsNotEmpty())
  2218. {
  2219. var task = resultExpTask.list[0].contestTasks.Find(z => z.uploadId.Equals(_uploadId.GetString()));
  2220. if (task!=null)
  2221. {
  2222. task=contestTask;
  2223. }
  2224. else {
  2225. resultExpTask.list[0].contestTasks.Add(contestTask);
  2226. }
  2227. expertTask=resultExpTask.list[0];
  2228. expertTask.activityId=_activityId.GetString();
  2229. }
  2230. else {
  2231. //专家没有任何被分配的作品
  2232. expertTask = new ActivityExpertTask()
  2233. {
  2234. id= expert.id,
  2235. code=$"ActivityExpertTask-{_activityId}",
  2236. pk="ActivityExpertTask",
  2237. ttl=-1,
  2238. activityId=_activityId.GetString(),
  2239. name=expert.iname,
  2240. tmdname=expert.name,
  2241. picture=expert.picture,
  2242. contestTasks= new List<ExpertContestTask> { contestTask }
  2243. };
  2244. }
  2245. if (expertTask!=null)
  2246. {
  2247. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).UpsertItemAsync(expertTask, new PartitionKey(expertTask.code));
  2248. }
  2249. }
  2250. }
  2251. return Ok(new { code = 200, expertTask });
  2252. }
  2253. else {
  2254. return Ok(new { code=1,msg ="作品不存在!"});
  2255. }
  2256. }
  2257. //修改活动成绩公示状态
  2258. case bool when $"{grant_type}".Equals("update-scoreStatus", StringComparison.OrdinalIgnoreCase):
  2259. {
  2260. if (!request.TryGetProperty("activityId", out JsonElement _activityId)) return BadRequest();
  2261. if (!request.TryGetProperty("scoreStatus", out JsonElement _scoreStatus)) return BadRequest();
  2262. Azure.Response responseContest = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("Contest"));
  2263. if (responseContest.Status == 200)
  2264. {
  2265. long now = DateTimeOffset.Now.ToUnixTimeMilliseconds();
  2266. Contest contest = JsonDocument.Parse(responseContest.Content).RootElement.ToObject<Contest>();
  2267. if (contest.modules.Contains("score") && contest.score != null)
  2268. {
  2269. if (now < contest.score.stime || now > contest.score.etime)
  2270. {
  2271. return Ok(new { code = 1, msg = "不在成绩公布时间范围内!" });
  2272. }
  2273. }
  2274. else
  2275. {
  2276. return Ok(new { code = 2, msg = "未配置成绩公布模块!" });
  2277. }
  2278. if (int.TryParse($"{_scoreStatus}", out int scoreStatus))
  2279. {
  2280. contest.score.scoreStatus = scoreStatus;
  2281. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).UpsertItemAsync(contest, new PartitionKey("Contest"));
  2282. return Ok(new { code = 200, msg = "操作成功!" });
  2283. }
  2284. else
  2285. {
  2286. return Ok(new { code = 4, msg = "成绩公布参数错误!" });
  2287. }
  2288. }
  2289. else
  2290. {
  2291. return Ok(new { code = 3, msg = "活动不存在!" });
  2292. }
  2293. }
  2294. //修改活动成绩公布类型或等级
  2295. case bool when $"{grant_type}".Equals("update-scoreShowTypeOrLevel", StringComparison.OrdinalIgnoreCase):
  2296. {
  2297. if (!request.TryGetProperty("activityId", out JsonElement _activityId)) return BadRequest();
  2298. if (!request.TryGetProperty("showType", out JsonElement _showType)) return BadRequest();
  2299. request.TryGetProperty("attention", out JsonElement _attention);
  2300. request.TryGetProperty("top", out JsonElement _top);
  2301. request.TryGetProperty("showDetail", out JsonElement _showDetail);
  2302. List<ScoreLevel> scoreLevels = new List<ScoreLevel>();
  2303. bool ok = true;
  2304. string msg = string.Empty;
  2305. int code = 200;
  2306. //全部
  2307. int showDetail = 0;
  2308. int top = -1;
  2309. int levelType = -1;
  2310. if (int.TryParse($"{_top}", out int topReq) && topReq>0)
  2311. {
  2312. top=topReq;
  2313. }
  2314. if (int.TryParse($"{_showDetail}", out int showDetailReq))
  2315. {
  2316. showDetail=showDetailReq;
  2317. }
  2318. if (int.TryParse($"{_showType}", out int showType))
  2319. {
  2320. if (showType==1)
  2321. {
  2322. // int levelType = 0;
  2323. if (!request.TryGetProperty("levelType", out JsonElement _levelType) ||!int.TryParse($"{_levelType}", out levelType)||!(levelType==0 ||levelType==1))
  2324. {
  2325. code=7;
  2326. ok = false;
  2327. msg="等级类型参数错误";
  2328. }
  2329. else {
  2330. if (!request.TryGetProperty("scoreLevels", out JsonElement _scoreLevels))
  2331. {
  2332. code=1;
  2333. ok = false;
  2334. msg="等级设置参数错误";
  2335. }
  2336. else
  2337. {
  2338. scoreLevels= _scoreLevels.ToObject<List<ScoreLevel>>();
  2339. if (scoreLevels.IsNotEmpty())
  2340. {
  2341. scoreLevels= scoreLevels.OrderBy(z => z.min).ToList();
  2342. double max = scoreLevels.First().min;
  2343. foreach (ScoreLevel scoreLevel in scoreLevels)
  2344. {
  2345. if (levelType==0)
  2346. {
  2347. //检查当前值最大大于最小
  2348. if (scoreLevel.max>scoreLevel.min)
  2349. { //当前最小大于上一轮的最大值
  2350. if (scoreLevel.min==max)
  2351. {
  2352. max = scoreLevel.max;
  2353. }
  2354. else
  2355. {
  2356. ok=false;
  2357. code=3;
  2358. msg=$"相邻等级的分数设置错误";
  2359. break;
  2360. }
  2361. }
  2362. else
  2363. {
  2364. ok=false;
  2365. code=4;
  2366. msg=$"等级的最大值小于最小值";
  2367. break;
  2368. }
  2369. }
  2370. else {
  2371. if (scoreLevel.top<=0) {
  2372. ok=false;
  2373. code=8;
  2374. msg=$"等级人数必须大于0";
  2375. break;
  2376. }
  2377. }
  2378. }
  2379. }
  2380. else
  2381. {
  2382. code=2;
  2383. ok = false;
  2384. msg="分数等级未设置!";
  2385. }
  2386. }
  2387. }
  2388. }
  2389. else if (showType==0)
  2390. {
  2391. ok=true;
  2392. code=200;
  2393. }
  2394. else
  2395. {
  2396. code=1;
  2397. ok = false;
  2398. msg="参数错误";
  2399. }
  2400. }
  2401. else
  2402. {
  2403. code=1;
  2404. ok = false;
  2405. msg="参数错误";
  2406. }
  2407. if (code==200 && ok==true)
  2408. {
  2409. Azure.Response responseContest = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("Contest"));
  2410. if (responseContest.Status == 200)
  2411. {
  2412. long now = DateTimeOffset.Now.ToUnixTimeMilliseconds();
  2413. Contest contest = JsonDocument.Parse(responseContest.Content).RootElement.ToObject<Contest>();
  2414. if (contest.modules.Contains("score") && contest.score != null)
  2415. {
  2416. contest.score.showType=showType;
  2417. contest.score.scoreLevels=scoreLevels;
  2418. contest.score.attention=$"{_attention}";
  2419. contest.score.top=top;
  2420. contest.score.levelType=levelType;
  2421. contest.score.showDetail=showDetail;
  2422. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).UpsertItemAsync(contest, new PartitionKey("Contest"));
  2423. return Ok(new { code = 200, msg = "操作成功" });
  2424. }
  2425. else
  2426. {
  2427. return Ok(new { code = 5, msg = "未配置成绩公布模块!" });
  2428. }
  2429. }
  2430. else
  2431. {
  2432. return Ok(new { code = 6, msg = "活动不存在!" });
  2433. }
  2434. }
  2435. else {
  2436. return Ok(new { code, msg });
  2437. }
  2438. }
  2439. //修改分数,在作品公布环节才能调整
  2440. case bool when $"{grant_type}".Equals("update-maskScore", StringComparison.OrdinalIgnoreCase):
  2441. {
  2442. if (!request.TryGetProperty("activityId", out JsonElement _activityId)) return BadRequest();
  2443. if (!request.TryGetProperty("maskScoreDatas", out JsonElement _maskScoreDatas)) return BadRequest();
  2444. List<MaskScoreDto> maskScores = _maskScoreDatas.ToObject<List<MaskScoreDto>>();
  2445. if (maskScores.IsNotEmpty())
  2446. {
  2447. Azure.Response responseContest = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("Contest"));
  2448. if (responseContest.Status == 200)
  2449. {
  2450. long now = DateTimeOffset.Now.ToUnixTimeMilliseconds();
  2451. Contest contest = JsonDocument.Parse(responseContest.Content).RootElement.ToObject<Contest>();
  2452. if (contest.score?.stime<now && contest.score?.etime>now)
  2453. {
  2454. string sql = $"select value c from c where c.upload.uploadId in ({string.Join(",", maskScores.Select(z => $"'{z.uploadId}'"))}) and c.pk='ActivityEnroll' ";
  2455. var reslut = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<ActivityEnroll>(sql, $"ActivityEnroll-{_activityId}");
  2456. foreach (var item in maskScores)
  2457. {
  2458. var enrolls = reslut.list.FindAll(z => z.upload.uploadId.Equals(item.uploadId));
  2459. if (enrolls.IsNotEmpty())
  2460. {
  2461. foreach (var enroll in enrolls)
  2462. {
  2463. if (item.showScore==1 && item.maskScore>=0)
  2464. {
  2465. enroll.upload.showScore=item.showScore;
  2466. enroll.upload.maskScore=item.maskScore;
  2467. }
  2468. else
  2469. {
  2470. enroll.upload.showScore=0;
  2471. }
  2472. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).UpsertItemAsync(enroll, new PartitionKey(enroll.code));
  2473. }
  2474. item.hasError=0;
  2475. }
  2476. else
  2477. {
  2478. item.hasError=1;
  2479. }
  2480. }
  2481. }
  2482. else
  2483. {
  2484. return Ok(new { code = 1, msg = "不在作品公布时间范围内!" });
  2485. }
  2486. }
  2487. else
  2488. {
  2489. return Ok(new { code = 2, msg = "活动不存在!" });
  2490. }
  2491. }
  2492. else {
  2493. return Ok(new { code = 2, msg = "活动不存在!" });
  2494. }
  2495. return Ok(new { code = 200, maskScores });
  2496. }
  2497. case bool when $"{grant_type}".Equals("get-scores", StringComparison.OrdinalIgnoreCase):
  2498. {
  2499. if (!request.TryGetProperty("activityId", out JsonElement _activityId)) return BadRequest();
  2500. Azure.Response responseContest = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("Contest"));
  2501. if (responseContest.Status == 200)
  2502. {
  2503. List<ActivityTeacherScoreMask> teacherScores = new List<ActivityTeacherScoreMask>();
  2504. long now = DateTimeOffset.Now.ToUnixTimeMilliseconds();
  2505. Contest contest = JsonDocument.Parse(responseContest.Content).RootElement.ToObject<Contest>();
  2506. if (contest.score?.stime<now)
  2507. {
  2508. string sql = $"select value c from c where c.pk='ActivityEnroll' ";
  2509. var reslut = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<ActivityEnroll>(sql, $"ActivityEnroll-{_activityId}");
  2510. if (contest.sign.type==1)
  2511. {
  2512. var teams = reslut.list.Where(x => !string.IsNullOrEmpty(x.contest?.cipher)).GroupBy(z => z.contest.cipher);
  2513. foreach (var team in teams)
  2514. {
  2515. var members = team.ToList();
  2516. var leader = members.FindAll(z => z.contest.leader==1)?.FirstOrDefault();
  2517. if (leader==null)
  2518. {
  2519. leader=members.First();
  2520. }
  2521. teacherScores.Add(new ActivityTeacherScoreMask
  2522. {
  2523. uploadId=leader.upload?.uploadId,
  2524. uploadName=!string.IsNullOrWhiteSpace(leader.upload?.name) ? leader.upload?.name : $"{leader.contest.teamName}",
  2525. score=leader.upload?.score??-1,
  2526. maskScore=leader.upload?.maskScore??-1,
  2527. showScore=leader.upload?.showScore??0,
  2528. tmdid=leader.id,
  2529. nickname=leader.tmdName,
  2530. name=leader.contest.enrollInfos.Find(z => z.code.Equals("name"))?.val,
  2531. picture=leader.tmdPicture,
  2532. school=leader.schoolId,
  2533. schoolName=leader.schoolName,
  2534. schoolPicture=leader.schoolPicture,
  2535. cipher=leader.contest.cipher,
  2536. teamName=leader.contest.teamName,
  2537. type=leader.contest.type,
  2538. members=members.Select(z => new IdNameCode { id=z.id, name=z.contest.enrollInfos.Find(x => x.code.Equals("name"))?.val, picture=z.tmdPicture, nickname=z.tmdName }).ToList(),
  2539. });
  2540. }
  2541. }
  2542. else
  2543. {
  2544. ///个人组
  2545. foreach (var item in reslut.list)
  2546. {
  2547. teacherScores.Add(new ActivityTeacherScoreMask
  2548. {
  2549. uploadId=item.upload?.uploadId,
  2550. uploadName=!string.IsNullOrWhiteSpace(item.upload?.name) ? item.upload?.name : $"{item.contest.enrollInfos.Find(z => z.code.Equals("name"))?.val}",
  2551. score=item.upload?.score??-1,
  2552. maskScore=item.upload?.maskScore??-1,
  2553. showScore=item.upload?.showScore??0,
  2554. tmdid=item.id,
  2555. nickname=item.tmdName,
  2556. name=item.contest.enrollInfos.Find(z => z.code.Equals("name"))?.val,
  2557. picture=item.tmdPicture,
  2558. school=item.schoolId,
  2559. schoolName=item.schoolName,
  2560. schoolPicture=item.schoolPicture,
  2561. type=item.contest.type,
  2562. });
  2563. }
  2564. }
  2565. }
  2566. return Ok(new { code = 200, teacherScores });
  2567. }
  2568. else {
  2569. return Ok(new { code = 1, msg = "活动不存在" });
  2570. }
  2571. }
  2572. case bool when $"{grant_type}".Equals("preview-scores", StringComparison.OrdinalIgnoreCase):
  2573. {
  2574. if (!request.TryGetProperty("activityId", out JsonElement _activityId)) return BadRequest();
  2575. List<ActivityScoreLevel> contestScores = await ActivityService.ActivityScores(_azureCosmos,_activityId);
  2576. return Ok(new { code = 200, contestScores });
  2577. }
  2578. }
  2579. }
  2580. catch (Exception ex)
  2581. {
  2582. await _dingDing.SendBotMsg($"{ex.Message}\n{ex.StackTrace}\n{request.ToJsonString()}", GroupNames.成都开发測試群組);
  2583. return Ok(new { code = 500, msg = ex.Message });
  2584. }
  2585. return Ok();
  2586. }
  2587. /// <summary>
  2588. /// portal站的
  2589. /// </summary>
  2590. /// <param name="request"></param>
  2591. /// <returns></returns>
  2592. [ProducesDefaultResponseType]
  2593. [HttpPost("login-portal")]
  2594. public async Task<IActionResult> LoginPortal(JsonElement request)
  2595. {
  2596. int timezone = 8;
  2597. if (HttpContext.Request.Headers.TryGetValue("Time-Zone", out var Time_Zone) && int.TryParse(Time_Zone, out int tz))
  2598. {
  2599. timezone=tz;
  2600. }
  2601. string tmdid = null;
  2602. if (!request.TryGetProperty("route", out JsonElement _route)) return BadRequest();
  2603. request.TryGetProperty("ticket", out JsonElement _ticket);
  2604. request.TryGetProperty("token", out JsonElement _token);
  2605. TeacherInfo teacherInfo = null;
  2606. object name = null, picture = null;
  2607. string head_lang = "";
  2608. (string ip, string region) = await LoginService.LoginIp(HttpContext, _searcher);
  2609. if (!string.IsNullOrWhiteSpace($"{_ticket}"))
  2610. {
  2611. var clientID = _configuration.GetValue<string>("HaBookAuth:CoreService:clientID");
  2612. (HttpStatusCode statusCode, CoreAPIToken token) = await _coreAPIHttpService.GetCoreAPIoAuth2Token(
  2613. new Dictionary<string, object> { { "client_id", clientID }, { "grant_type", "authorization_code" }, { "code", _ticket.GetString() } }, _option.Location, _configuration, _dingDing);
  2614. if (statusCode.Equals(HttpStatusCode.OK))
  2615. {
  2616. var jwt = new JwtSecurityToken(token.id_token);
  2617. tmdid = jwt.Payload.Sub;
  2618. if (HttpContext.Request.Headers.TryGetValue("lang", out var _lang))
  2619. {
  2620. head_lang = $"{_lang}";
  2621. }
  2622. jwt.Payload.TryGetValue("name", out name);
  2623. jwt.Payload.TryGetValue("picture", out picture);
  2624. jwt.Payload.TryGetValue("lang", out object _jwtlang);
  2625. head_lang = !string.IsNullOrWhiteSpace($"{_jwtlang}") ? $"{_jwtlang}" : head_lang;
  2626. }
  2627. }
  2628. if (tmdid == null)
  2629. {
  2630. if (!string.IsNullOrWhiteSpace($"{_token}"))
  2631. {
  2632. var jwt = new JwtSecurityToken(_token.GetString());
  2633. if (JwtAuthExtension.ValidateAuthTokenRefresh(_token.GetString(), _option.JwtSecretKey))
  2634. {
  2635. tmdid = jwt.Payload.Sub;
  2636. if (HttpContext.Request.Headers.TryGetValue("lang", out var _lang))
  2637. {
  2638. head_lang = $"{_lang}";
  2639. }
  2640. jwt.Payload.TryGetValue("name", out name);
  2641. jwt.Payload.TryGetValue("picture", out picture);
  2642. jwt.Payload.TryGetValue("lang", out object _jwtlang);
  2643. head_lang = !string.IsNullOrWhiteSpace($"{_jwtlang}") ? $"{_jwtlang}" : head_lang;
  2644. }
  2645. else { return Ok(new { code = 2, msg = "Token验证失败" }); }
  2646. }
  2647. else { return Ok(new { code = 3, msg = "凭证验证失败" }); }
  2648. }
  2649. teacherInfo = await TeacherService.TeacherInfoLite(_azureCosmos, $"{name}", $"{picture}", tmdid, _azureStorage, _option, _azureRedis, ip, _httpTrigger, head_lang,timezone);
  2650. string sql = $"select value c from c where c.route='{_route}'";
  2651. var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).GetList<ActivityWebsite>(sql, "ActivityWebsite");
  2652. ActivityWebsite website = null;
  2653. if (result.list.Count>1)
  2654. {
  2655. return Ok(new { code = 1, msg = "路由匹配多个区校" });
  2656. }
  2657. else
  2658. {
  2659. if (result.list.Count==1)
  2660. {
  2661. website= result.list[0];
  2662. }
  2663. }
  2664. List<string> roles = new List<string>() { "teacher" };
  2665. CoreUser coreUser = await _coreAPIHttpService.GetUserInfo(new Dictionary<string, string> { { "key", teacherInfo.teacher.id } }, _option.Location, _configuration);
  2666. string sqlExpert = $"select value c from c join e in c.experts where e.id='{teacherInfo.teacher.id}'";
  2667. if (!string.IsNullOrWhiteSpace(coreUser.mobile))
  2668. {
  2669. sqlExpert=$" {sqlExpert} or e.mobile='{coreUser.mobile}' ";
  2670. }
  2671. var resultActivityExpert = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<ActivityExpert>(sqlExpert, "ActivityExpert", pageSize: 1);
  2672. if (resultActivityExpert.list.IsNotEmpty())
  2673. {
  2674. roles.Add("expert");
  2675. }
  2676. var payload = new JwtPayload {
  2677. { JwtRegisteredClaimNames.Iss, _option.HostName }, //發行者
  2678. { JwtRegisteredClaimNames.Sub, teacherInfo.teacher.id }, // 用戶ID
  2679. { JwtRegisteredClaimNames.Exp,DateTimeOffset.UtcNow.AddHours(2).ToUnixTimeSeconds()}, // 到期的時間,必須為數字
  2680. { "name",name}, // 用戶的顯示名稱
  2681. { "picture",picture}, // 用戶頭像
  2682. { "roles", roles.ToArray()}, // 登入者的角色,角色類型 (Admin、Teacher、Student)
  2683. { JwtRegisteredClaimNames.Website,website?.route},
  2684. };
  2685. var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_option.JwtSecretKey));
  2686. //var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);
  2687. var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
  2688. var header = new JwtHeader(signingCredentials);
  2689. var secToken = new JwtSecurityToken(header, payload);
  2690. // 產出所需要的 JWT securityToken 物件,並取得序列化後的 Token 結果(字串格式)
  2691. var tokenHandler = new JwtSecurityTokenHandler();
  2692. var serializeToken = tokenHandler.WriteToken(secToken);
  2693. var core_clientID = _configuration.GetValue<string>("HaBookAuth:CoreService:clientID");
  2694. var core_clientSecret = _configuration.GetValue<string>("HaBookAuth:CoreService:clientSecret");
  2695. string location = _option.Location;
  2696. if (location.Contains("China"))
  2697. {
  2698. location = "China";
  2699. }
  2700. else if (location.Contains("Global"))
  2701. {
  2702. location = "Global";
  2703. }
  2704. var access_token = await CoreTokenExtensions.CreateAccessToken(core_clientID, core_clientSecret, location);
  2705. return Ok(new { auth_token = new { access_token = access_token.AccessToken, token_type = access_token.TokenType, expires_in = access_token.ExpiresOn }, code = 200, token = serializeToken, schools = teacherInfo.teacher.schools.Where(z => z.status.Equals("join")) });
  2706. }
  2707. [ProducesDefaultResponseType]
  2708. [HttpPost("get-website")]
  2709. public async Task<IActionResult> GetWebsite(JsonElement request)
  2710. {
  2711. if (!request.TryGetProperty("route", out JsonElement _route)) return BadRequest();
  2712. string sql = $"select value c from c where c.route='{_route}'";
  2713. var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).GetList<ActivityWebsiteDto>(sql, "ActivityWebsite");
  2714. ActivityWebsiteDto website = null;
  2715. if (result.list.Count>1)
  2716. {
  2717. return Ok(new { code = 1, msg = "路由匹配多个区校" });
  2718. }
  2719. else
  2720. {
  2721. if (result.list.Count==1)
  2722. {
  2723. website= result.list[0];
  2724. }
  2725. if (result.list.Count==0) {
  2726. try {
  2727. Azure.Response responseSchool = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemStreamAsync($"{_route}", new PartitionKey("Base"));
  2728. if (responseSchool.Status==200)
  2729. {
  2730. ActivityWebsite websiteDB = new ActivityWebsite
  2731. {
  2732. id=$"{_route}",
  2733. pk="ActivityWebsite",
  2734. code="ActivityWebsite",
  2735. route=$"{_route}",
  2736. scope="school",
  2737. allowPublic=0,
  2738. };
  2739. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).UpsertItemAsync(websiteDB, new PartitionKey(websiteDB.code));
  2740. website=new ActivityWebsiteDto(websiteDB);
  2741. }
  2742. } catch (Exception ex ) { }
  2743. }
  2744. }
  2745. if (website!= null)
  2746. {
  2747. List<ActivityWebsiteDto> websites = new List<ActivityWebsiteDto>();
  2748. if (website.route.Equals("teammodel"))
  2749. {
  2750. string sqlAll = $"select value c from c where IS_DEFINED(c.route) = true and c.route<> null and c.route<>'' ";
  2751. var resultAll = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).GetList<ActivityWebsiteDto>(sqlAll, "ActivityWebsite");
  2752. websites=resultAll.list;
  2753. }
  2754. websites.ForEach(z => {
  2755. string cnt = z.id;
  2756. if (z.id.Equals("teammodel"))
  2757. {
  2758. cnt="02944f32-f534-3397-ea56-e6f1fc6c3714";
  2759. }
  2760. var it = _azureStorage.GetBlobContainerSAS(cnt, BlobContainerSasPermissions.Read);
  2761. z.sas= it.sas;
  2762. z.url=it.uri;
  2763. });
  2764. string cnt = website.id;
  2765. if (website.id.Equals("teammodel"))
  2766. {
  2767. cnt="02944f32-f534-3397-ea56-e6f1fc6c3714";
  2768. }
  2769. var blob = _azureStorage.GetBlobContainerSAS(cnt, BlobContainerSasPermissions.Read);
  2770. website.sas= blob.sas;
  2771. website.url=blob.uri;
  2772. string blobUrl = blob.uri;
  2773. return Ok(new { code = 200, website, websites, blobUrl });
  2774. }
  2775. else
  2776. {
  2777. return Ok(new { code = 2, msg = "未匹配分站" });
  2778. }
  2779. }
  2780. /// <summary>
  2781. ///
  2782. /// </summary>
  2783. /// <param name="request"></param>
  2784. /// <returns></returns>
  2785. [ProducesDefaultResponseType]
  2786. [HttpPost("read-activity")]
  2787. public async Task<IActionResult> ReadActivity(JsonElement request)
  2788. {
  2789. if (!request.TryGetProperty("activityId", out JsonElement _activityId)) return BadRequest();
  2790. Azure.Response response = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("Activity"));
  2791. if (response.Status==200)
  2792. {
  2793. ActivityDto activity = JsonDocument.Parse(response.Content).RootElement.ToObject<ActivityDto>();
  2794. if (activity.publish!=1 && activity.publish!=2)
  2795. {
  2796. return Ok(new { code = 1, msg = "活动未发布!" });
  2797. }
  2798. Contest contest = null;
  2799. ReviewRuleTree reviewRule = null;
  2800. Azure.Response responseContest = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("Contest"));
  2801. if (responseContest.Status==200)
  2802. {
  2803. contest= JsonDocument.Parse(responseContest.Content).RootElement.ToObject<Contest>();
  2804. if (contest.modules.Contains("review"))
  2805. {
  2806. Azure.Response reviewRuleResponse = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("ReviewRule-disposable"));
  2807. if (reviewRuleResponse.Status==200)
  2808. {
  2809. ReviewRule reviewRuleDB = JsonDocument.Parse(reviewRuleResponse.Content).RootElement.ToObject<ReviewRule>();
  2810. var tree = ActivityService.ListToTree(reviewRuleDB.configs);
  2811. reviewRule=new ReviewRuleTree
  2812. {
  2813. id=reviewRuleDB.id,
  2814. name= reviewRuleDB.name,
  2815. owner= reviewRuleDB.owner,
  2816. sourceName= reviewRuleDB.sourceName,
  2817. trees=tree,
  2818. desc=reviewRuleDB.desc,
  2819. scoreDetail=reviewRuleDB.scoreDetail,
  2820. scoreRule=reviewRuleDB.scoreRule,
  2821. distribute=reviewRuleDB.distribute,
  2822. taskCount=reviewRuleDB.taskCount,
  2823. };
  2824. }
  2825. }
  2826. }
  2827. Training training = null;
  2828. TEAMModelOS.SDK.Models.Research research = null;
  2829. var (blob_uri, blob_sas) = _azureStorage.GetBlobContainerSAS(activity.owner, BlobContainerSasPermissions.Read | BlobContainerSasPermissions.List);
  2830. activity.sas=blob_sas;
  2831. activity.url=blob_uri;
  2832. long now = DateTimeOffset.Now.ToUnixTimeMilliseconds();
  2833. activity.publish=now>activity.etime ? 2 : activity.publish;
  2834. List<ActivityScoreLevel> contestScores = null;
  2835. if (contest.score!=null && contest.score.scoreStatus==1 && now>contest.score?.stime && now<contest.score.etime)
  2836. {
  2837. contestScores = await ActivityService.ActivityScores(_azureCosmos, _activityId);
  2838. }
  2839. return Ok(new { code = 200, activity, contest, reviewRule, training, research, contestScores });
  2840. }
  2841. else
  2842. {
  2843. return Ok(new { code = 2, msg = "活动不存在" });
  2844. }
  2845. }
  2846. /// <summary>
  2847. /// 获取活动的站点
  2848. /// </summary>
  2849. /// <param name="request"></param>
  2850. /// <returns></returns>
  2851. [ProducesDefaultResponseType]
  2852. [HttpPost("get-activity-website")]
  2853. public async Task<IActionResult> GetActivityWebsite(JsonElement request)
  2854. {
  2855. if (!request.TryGetProperty("activityId", out JsonElement _activityId)) return BadRequest();
  2856. Azure.Response response = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("Activity"));
  2857. if (response.Status==200)
  2858. {
  2859. Activity activity = JsonDocument.Parse(response.Content).RootElement.ToObject<Activity>();
  2860. if (activity.publish!=1 && activity.publish!=2)
  2861. {
  2862. return Ok(new { code = 1, msg = "活动未发布!" });
  2863. }
  2864. string routeId = "";
  2865. if (activity.scope.Equals("public"))
  2866. {
  2867. routeId="";
  2868. }
  2869. else
  2870. {
  2871. routeId=activity.owner;
  2872. }
  2873. Azure.Response responseActivityWebsite = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).ReadItemStreamAsync(routeId, new PartitionKey("ActivityWebsite"));
  2874. ActivityWebsiteDto website = null;
  2875. if (responseActivityWebsite.Status==200)
  2876. {
  2877. website=JsonDocument.Parse(responseActivityWebsite.Content).RootElement.ToObject<ActivityWebsiteDto>();
  2878. }
  2879. if (website!= null)
  2880. {
  2881. string cnt = website.id;
  2882. if (website.id.Equals("teammodel"))
  2883. {
  2884. cnt="02944f32-f534-3397-ea56-e6f1fc6c3714";
  2885. }
  2886. var blob = _azureStorage.GetBlobContainerSAS(cnt, BlobContainerSasPermissions.Read);
  2887. website.sas= blob.sas;
  2888. website.url=blob.uri;
  2889. return Ok(new { code = 200, website });
  2890. }
  2891. else
  2892. {
  2893. return Ok(new { code = 2, msg = "未匹配分站" });
  2894. }
  2895. }
  2896. else
  2897. {
  2898. return Ok(new { code = 3, msg = "活动不存在" });
  2899. }
  2900. }
  2901. /// <summary>
  2902. /// 教师在赛课模块的操作
  2903. /// </summary>
  2904. /// <param name="request"></param>
  2905. /// <returns></returns>
  2906. [ProducesDefaultResponseType]
  2907. [HttpPost("expert-contest")]
  2908. [AuthToken(Roles = "expert")]
  2909. #if !DEBUG
  2910. [Authorize(Roles = "IES")]
  2911. #endif
  2912. public async Task<IActionResult> ExpertContest(JsonElement request)
  2913. {
  2914. (string tmdid, string name, string picture, _) = HttpContext.GetAuthTokenInfo();
  2915. if (!request.TryGetProperty("grant_type", out JsonElement grant_type)) return BadRequest();
  2916. var client = _azureCosmos.GetCosmosClient();
  2917. switch (true)
  2918. { //获取分配的任务
  2919. case bool when $"{grant_type}".Equals("get-enroll-by-uploadId", StringComparison.OrdinalIgnoreCase):
  2920. {
  2921. if (!request.TryGetProperty("activityId", out JsonElement _activityId)) return BadRequest();
  2922. if (!request.TryGetProperty("uploadId", out JsonElement _uploadId)) return BadRequest();
  2923. string enrollSQL = $"select value c from c where c.activityId='{_activityId.GetString()}' and c.upload.uploadId='{_uploadId}' ";
  2924. //不是自己的,且学校不为空,则查询指定学校的,否则获取所有报名的数据
  2925. var enrollResult = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<ActivityEnroll>(enrollSQL, $"ActivityEnroll-{_activityId}");
  2926. EnrollUpload upload = null;
  2927. if (enrollResult.list.IsNotEmpty()) {
  2928. upload= enrollResult.list[0].upload;
  2929. }
  2930. return Ok(new { upload });
  2931. }
  2932. //获取分配的任务
  2933. case bool when $"{grant_type}".Equals("list-task", StringComparison.OrdinalIgnoreCase):
  2934. {
  2935. List<ActivityExpertDto> activities = new List<ActivityExpertDto>();
  2936. long now = DateTimeOffset.Now.ToUnixTimeMilliseconds();
  2937. //在时间内正在进入评审阶段的活动。
  2938. string contestSQL = $"select value c from c where c.review.stime<={now} and c.review.etime>={now} and c.review.reviewStatus=1";
  2939. var contestResult = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).GetList<Contest>(contestSQL, "Contest");
  2940. if (contestResult.list.IsNotEmpty())
  2941. {
  2942. string baseSQL = $"select value c from c where c.id in ({string.Join(",", contestResult.list.Select(z => $"'{z.id}'"))}) ";
  2943. var activityResult = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).GetList<Activity>(baseSQL, "Activity");
  2944. string sql = $"select value c from c where c.activityId in ({string.Join(",", contestResult.list.Select(z => $"'{z.id}'"))}) and c.id='{tmdid}' and c.pk='ActivityExpertTask'";
  2945. var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<ActivityExpertTask>(sql);
  2946. foreach (var item in result.list)
  2947. {
  2948. var contest = contestResult.list.Find(z => z.id.Equals(item.activityId));
  2949. var activity = activityResult.list.Find(z => z.id.Equals(item.activityId));
  2950. var (blob_uri, blob_sas) = _azureStorage.GetBlobContainerSAS(activity.owner, BlobContainerSasPermissions.Read | BlobContainerSasPermissions.List);
  2951. activities.Add(new ActivityExpertDto
  2952. {
  2953. activityId=item.activityId,
  2954. activityName=activity?.name,
  2955. stime=contest?.review?.stime??0,
  2956. etime=contest?.review?.etime??0,
  2957. taskCount=item.contestTasks.Count(),
  2958. completeCount=item.contestTasks.Where(z => z.status==1).Count(),
  2959. contestTasks=item.contestTasks,
  2960. sas=blob_sas,
  2961. url=blob_uri
  2962. }) ;
  2963. }
  2964. }
  2965. return Ok(new { activities,code=200 });
  2966. }
  2967. ///评分
  2968. case bool when $"{grant_type}".Equals("decide-score", StringComparison.OrdinalIgnoreCase):
  2969. {
  2970. if (!request.TryGetProperty("activityId", out JsonElement _activityId)) return BadRequest();
  2971. if (!request.TryGetProperty("scoreData", out JsonElement _scoreData)) return BadRequest();
  2972. Azure.Response response = await client.GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("Contest"));
  2973. if (response.Status==200)
  2974. {
  2975. long now = DateTimeOffset.Now.ToUnixTimeMilliseconds();
  2976. Contest contest = JsonDocument.Parse(response.Content).RootElement.ToObject<Contest>();
  2977. if (contest.review!= null &&contest.review.stime<now &&contest.review.etime>now)
  2978. {
  2979. if (contest.review.reviewStatus==1)
  2980. {
  2981. //作品安分配次数,如果分数全部打完成,自动汇算
  2982. ReviewScoreData scoreData= _scoreData.ToObject<ReviewScoreData>();
  2983. var ruleResponse= await client.GetContainer(Constant.TEAMModelOS, Constant.Normal).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("ReviewRule-disposable"));
  2984. ReviewRule reviewRule = JsonDocument.Parse(ruleResponse.Content).RootElement.ToObject<ReviewRule>();
  2985. if (reviewRule.scoreDetail==1) {
  2986. if (!scoreData.detailScore.IsNotEmpty())
  2987. {
  2988. return Ok(new { code = 5, msg = "需要进行细项评分!" });
  2989. }
  2990. }
  2991. if (scoreData.score<0) {
  2992. return Ok(new { code = 6, msg = "分数不能小于0!" });
  2993. }
  2994. if (!string.IsNullOrWhiteSpace(scoreData.uploadId))
  2995. {
  2996. ActivityExpertTask expertTask = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemAsync<ActivityExpertTask>(tmdid, new PartitionKey($"ActivityExpertTask-{_activityId}"));
  2997. var task = expertTask.contestTasks.Find(x => x.uploadId.Equals(scoreData.uploadId));
  2998. task.score = scoreData.score;
  2999. task.status=1;
  3000. task.detailScore = ActivityService.TreeToList(scoreData.detailScore, new List<RuleConfig>()) ;
  3001. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).UpsertItemAsync(expertTask, new PartitionKey($"ActivityExpertTask-{_activityId}"));
  3002. //检查作品是否完成评审自动结算
  3003. {
  3004. string sql = $"select distinct value c from c join b in c.contestTasks where c.activityId='{_activityId}' and b.uploadId='{scoreData.uploadId}'";
  3005. var uploadAllResult = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<ActivityExpertTask>(sql, $"ActivityExpertTask-{_activityId}");
  3006. if (uploadAllResult.list.IsNotEmpty())
  3007. {
  3008. var unfinish = uploadAllResult.list.SelectMany(x=>x.contestTasks).Where(z => z.status!=1 && z.uploadId.Equals(scoreData.uploadId));
  3009. if (!(unfinish!=null && unfinish.Count()>0)) {
  3010. //没有未完成的评审作品自动结算、
  3011. string enrollSQL =$"select value c from c where c.upload.uploadId='{scoreData.uploadId}'and c.pk ='ActivityEnroll' ";
  3012. var enrollResult = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<ActivityEnroll>(enrollSQL, $"ActivityEnroll-{_activityId}");
  3013. foreach (var item in enrollResult.list)
  3014. {
  3015. bool change = false;
  3016. List<ExpertUploadScore> expertScores= new List<ExpertUploadScore>();
  3017. foreach (var expertScore in uploadAllResult.list)
  3018. {
  3019. var taskScore = expertScore.contestTasks.Find(z => z.uploadId.Equals(item.upload.uploadId));
  3020. if (taskScore!= null) {
  3021. expertScores.Add(new ExpertUploadScore {
  3022. id= expertScore.id,
  3023. name=expertScore.name,
  3024. score=taskScore.score,
  3025. detailScore=taskScore.detailScore
  3026. });
  3027. }
  3028. }
  3029. switch (reviewRule.scoreRule)
  3030. {
  3031. case "only":
  3032. if (expertScores.IsNotEmpty() && expertScores.Count==1)
  3033. {
  3034. item.upload.score= expertScores.First().score;
  3035. change=true;
  3036. }
  3037. break;
  3038. case "avg":
  3039. if (expertScores.IsNotEmpty() && expertScores.Count>=2)
  3040. {
  3041. item.upload.score= expertScores.Average(z => z.score);
  3042. change=true;
  3043. }
  3044. break;
  3045. case "top":
  3046. if (expertScores.IsNotEmpty() && expertScores.Count>2) {
  3047. item.upload.score= expertScores.Max(z => z.score);
  3048. change=true;
  3049. }
  3050. break;
  3051. case "rmLowAvg":
  3052. if (expertScores.IsNotEmpty() && expertScores.Count>=3)
  3053. {
  3054. expertScores.Remove(expertScores.Min());
  3055. if (expertScores.IsNotEmpty()) {
  3056. item.upload.score= expertScores.Average(z => z.score);
  3057. change=true;
  3058. }
  3059. }
  3060. break;
  3061. case "rmTopAvg":
  3062. if (expertScores.IsNotEmpty() && expertScores.Count>=3)
  3063. {
  3064. expertScores.Remove(expertScores.Max());
  3065. if (expertScores.IsNotEmpty())
  3066. {
  3067. item.upload.score= expertScores.Average(z => z.score);
  3068. change=true;
  3069. }
  3070. }
  3071. break;
  3072. case "rmLowTopAvg":
  3073. if (expertScores.IsNotEmpty() && expertScores.Count>=4)
  3074. {
  3075. expertScores.Remove(expertScores.Max());
  3076. expertScores.Remove(expertScores.Min());
  3077. if (expertScores.IsNotEmpty())
  3078. {
  3079. item.upload.score= expertScores.Average(z => z.score);
  3080. change=true;
  3081. }
  3082. }
  3083. break;
  3084. }
  3085. if (change)
  3086. {
  3087. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).UpsertItemAsync(item, new PartitionKey($"ActivityEnroll-{_activityId}"));
  3088. }
  3089. }
  3090. }
  3091. }
  3092. }
  3093. return Ok(new { code = 200, completeCount = expertTask.contestTasks.Where(z => z.status==1).Count(), contestTasks = expertTask.contestTasks });
  3094. }
  3095. else
  3096. {
  3097. return Ok(new { code = 4, msg = "参数错误!" });
  3098. }
  3099. }
  3100. else
  3101. {
  3102. return Ok(new { code = 2, msg = "评审已关闭!" });
  3103. }
  3104. }
  3105. else
  3106. {
  3107. return Ok(new { code = 1, msg = "已过评审时间!" });
  3108. }
  3109. }
  3110. else {
  3111. return Ok(new { code = 3, msg = "活动不存在!" });
  3112. }
  3113. }
  3114. }
  3115. return Ok();
  3116. }
  3117. /// <summary>
  3118. /// 教师在赛课模块的操作
  3119. /// </summary>
  3120. /// <param name="request"></param>
  3121. /// <returns></returns>
  3122. [ProducesDefaultResponseType]
  3123. [HttpPost("teacher-contest")]
  3124. [AuthToken(Roles = "teacher")]
  3125. #if !DEBUG
  3126. [Authorize(Roles = "IES")]
  3127. #endif
  3128. public async Task<IActionResult> TeacherContest(JsonElement request)
  3129. {
  3130. (string tmdid, string name, string picture, _) = HttpContext.GetAuthTokenInfo();
  3131. if (!request.TryGetProperty("grant_type", out JsonElement grant_type)) return BadRequest();
  3132. if ($"{grant_type}".Equals("update-teacher-enroll"))
  3133. {
  3134. if (!request.TryGetProperty("teacherEnroll", out JsonElement _teacherEnroll))
  3135. {
  3136. return Ok(new { code = 0, msg = "报名信息未完善!" });
  3137. };
  3138. TeacherEnroll teacherEnroll = _teacherEnroll.ToObject<TeacherEnroll>();
  3139. teacherEnroll.id=tmdid;
  3140. teacherEnroll.code="TeacherEnroll";
  3141. teacherEnroll.pk="TeacherEnroll";
  3142. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).UpsertItemAsync(teacherEnroll, new PartitionKey("TeacherEnroll"));
  3143. return Ok(new { code = 200, teacherEnroll });
  3144. }
  3145. if ($"{grant_type}".Equals("get-teacher-enroll"))
  3146. {
  3147. TeacherEnroll teacherEnroll = null;
  3148. Azure.Response responseTeacherEnroll= await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemStreamAsync(tmdid, new PartitionKey("TeacherEnroll"));
  3149. if (responseTeacherEnroll.Status==200)
  3150. {
  3151. teacherEnroll= JsonDocument.Parse(responseTeacherEnroll.Content).RootElement.ToObject<TeacherEnroll>();
  3152. return Ok(new { code = 200, teacherEnroll });
  3153. }
  3154. else {
  3155. return Ok(new { code = 1, msg="未填写" });
  3156. }
  3157. }
  3158. if (!request.TryGetProperty("activityId", out JsonElement _activityId)) return BadRequest();
  3159. var client = _azureCosmos.GetCosmosClient();
  3160. Azure.Response response = await client.GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("Activity"));
  3161. Azure.Response responseContest = await client.GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("Contest"));
  3162. try
  3163. {
  3164. if (response.Status==200)
  3165. {
  3166. int code = -1;
  3167. long now = DateTimeOffset.Now.ToUnixTimeMilliseconds();
  3168. Activity activity = JsonDocument.Parse(response.Content).RootElement.ToObject<Activity>();
  3169. Contest contest = null;
  3170. if (responseContest.Status==200)
  3171. {
  3172. contest=JsonDocument.Parse(responseContest.Content).RootElement.ToObject<Contest>();
  3173. }
  3174. else
  3175. {
  3176. return Ok(new { code = 33, msg = "未设置赛课模块!" });
  3177. }
  3178. if (!activity.modules.Contains("Contest"))
  3179. {
  3180. return Ok(new { code = 33, msg = "未设置赛课模块!" });
  3181. }
  3182. if (activity.publish>=1)
  3183. {
  3184. //如果包含了评审模块
  3185. if (contest.modules.Contains("review"))
  3186. {
  3187. if (contest.review!=null)
  3188. {
  3189. if (now>= contest.review?.stime && !$"{grant_type}".Equals("get-enroll", StringComparison.OrdinalIgnoreCase))
  3190. {
  3191. //只能查看报名信息
  3192. return Ok(new { code = 35, msg = "已到截至日期,不能操作!" });
  3193. }
  3194. }
  3195. else
  3196. {
  3197. return Ok(new { code = 34, msg = "评审模块信息未完善!" });
  3198. }
  3199. }
  3200. switch (true)
  3201. {
  3202. //移除队员
  3203. case bool when $"{grant_type}".Equals("remove-member", StringComparison.OrdinalIgnoreCase):
  3204. {
  3205. if (!request.TryGetProperty("removeMember", out JsonElement _removeMember)) return BadRequest();
  3206. if (tmdid.Equals(_removeMember.GetString()))
  3207. {
  3208. return Ok(new { code = 5, msg = "不能移除自己!" });
  3209. }
  3210. Azure.Response responseActivityEnroll = await client.GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemStreamAsync(tmdid, new PartitionKey($"ActivityEnroll-{_activityId.GetString()}"));
  3211. if (responseActivityEnroll.Status==200)
  3212. {
  3213. ActivityEnroll enrollOld = JsonDocument.Parse(responseActivityEnroll.Content).RootElement.ToObject<ActivityEnroll>();
  3214. if (enrollOld!=null && enrollOld?.contest?.leader==1 && enrollOld?.contest?.type==1)
  3215. {
  3216. Azure.Response responseActivityEnrollRemove = await client.GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemStreamAsync(_removeMember.GetString(), new PartitionKey($"ActivityEnroll-{_activityId.GetString()}"));
  3217. if (responseActivityEnrollRemove.Status==200)
  3218. {
  3219. ActivityEnroll enrollRemove = JsonDocument.Parse(responseActivityEnrollRemove.Content).RootElement.ToObject<ActivityEnroll>();
  3220. if (enrollRemove!=null && enrollRemove?.contest!=null && enrollOld?.contest?.type==1)
  3221. {
  3222. if (enrollOld.contest.cipher.Equals(enrollRemove.contest.cipher))
  3223. {
  3224. enrollRemove.contest.cipher=null;
  3225. //string cipher = await ActivityService.GenCipher(client, _dingDing, _option, _activityId.GetString());
  3226. await client.GetContainer(Constant.TEAMModelOS, Constant.Teacher).UpsertItemAsync(enrollRemove, new PartitionKey(enrollRemove.code));
  3227. return Ok(new { code = 200, msg = "移除成功!" });
  3228. }
  3229. else
  3230. {
  3231. return Ok(new { code = 4, msg = "指定的队长不是同一团队人员!" });
  3232. }
  3233. }
  3234. else
  3235. {
  3236. return Ok(new { code = 3, msg = "指定的队长未参加本次活动!" });
  3237. }
  3238. }
  3239. else
  3240. {
  3241. return Ok(new { code = 3, msg = "指定的队长未参加本次活动!" });
  3242. }
  3243. }
  3244. else
  3245. {
  3246. return Ok(new { code = 1, msg = "你不是队长!" });
  3247. }
  3248. }
  3249. else
  3250. {
  3251. return Ok(new { code = 2, msg = "你未参加本次活动!" });
  3252. }
  3253. }
  3254. ///移交队长
  3255. case bool when $"{grant_type}".Equals("change-team-leader", StringComparison.OrdinalIgnoreCase):
  3256. {
  3257. if (!request.TryGetProperty("targetLeader", out JsonElement _targetLeader)) return BadRequest();
  3258. if (tmdid.Equals(_targetLeader.GetString()))
  3259. {
  3260. return Ok(new { code = 5, msg = "不能将队长移交给自己!" });
  3261. }
  3262. Azure.Response responseActivityEnroll = await client.GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemStreamAsync(tmdid, new PartitionKey($"ActivityEnroll-{_activityId.GetString()}"));
  3263. if (responseActivityEnroll.Status==200)
  3264. {
  3265. ActivityEnroll enrollOld = JsonDocument.Parse(responseActivityEnroll.Content).RootElement.ToObject<ActivityEnroll>();
  3266. if (enrollOld!=null && enrollOld?.contest?.leader==1 && enrollOld?.contest?.type==1)
  3267. {
  3268. Azure.Response responseActivityEnrollNew = await client.GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemStreamAsync(_targetLeader.GetString(), new PartitionKey($"ActivityEnroll-{_activityId.GetString()}"));
  3269. if (responseActivityEnrollNew.Status==200)
  3270. {
  3271. ActivityEnroll enrollNew = JsonDocument.Parse(responseActivityEnrollNew.Content).RootElement.ToObject<ActivityEnroll>();
  3272. if (enrollNew!=null && enrollNew?.contest!=null && enrollOld?.contest?.type==1)
  3273. {
  3274. if (enrollOld.contest.cipher.Equals(enrollNew.contest.cipher))
  3275. {
  3276. enrollOld.contest.leader=0;
  3277. enrollNew.contest.leader=1;
  3278. await client.GetContainer(Constant.TEAMModelOS, Constant.Teacher).UpsertItemAsync(enrollNew, new PartitionKey(enrollNew.code));
  3279. await client.GetContainer(Constant.TEAMModelOS, Constant.Teacher).UpsertItemAsync(enrollOld, new PartitionKey(enrollOld.code));
  3280. return Ok(new { code = 200, msg = "移交成功!" });
  3281. }
  3282. else
  3283. {
  3284. return Ok(new { code = 4, msg = "指定的队长不是同一团队人员!" });
  3285. }
  3286. }
  3287. else
  3288. {
  3289. return Ok(new { code = 3, msg = "指定的队长未参加本次活动!" });
  3290. }
  3291. }
  3292. else
  3293. {
  3294. return Ok(new { code = 3, msg = "指定的队长未参加本次活动!" });
  3295. }
  3296. }
  3297. else
  3298. {
  3299. return Ok(new { code = 1, msg = "你不是队长!" });
  3300. }
  3301. }
  3302. else
  3303. {
  3304. return Ok(new { code = 2, msg = "你未参加本次活动!" });
  3305. }
  3306. }
  3307. ///取消报名
  3308. case bool when $"{grant_type}".Equals("cancel-enroll", StringComparison.OrdinalIgnoreCase):
  3309. {
  3310. ActivityEnroll enroll = null;
  3311. Azure.Response responseActivityEnroll = await client.GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemStreamAsync(tmdid, new PartitionKey($"ActivityEnroll-{_activityId.GetString()}"));
  3312. if (responseActivityEnroll.Status==200)
  3313. {
  3314. enroll= JsonDocument.Parse(responseActivityEnroll.Content).RootElement.ToObject<ActivityEnroll>();
  3315. if (enroll.contest!=null && enroll.contest.leader==1)
  3316. {
  3317. // 如果没有其他队员,则可以直接退出
  3318. //检查是否还有其他成员
  3319. string cipherSQL = $"select value c.id from c where c.contest!=null and c.activityId='{_activityId.GetString()}' and c.contest.type=1 and c.contest.cipher='{enroll.contest.cipher}' and c.id<>'{tmdid}' ";
  3320. var cipherResult = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<string>(cipherSQL, $"ActivityEnroll-{_activityId}");
  3321. if (cipherResult.list.Count>0)
  3322. {
  3323. return Ok(new { code = 3, msg = "队伍中还有其他参赛队员,请移交队长后或移除队员后再退出参赛!" });
  3324. }
  3325. }
  3326. Azure.Response responseActivityEnrollDel = await client.GetContainer(Constant.TEAMModelOS, Constant.Teacher).DeleteItemStreamAsync(enroll.id, new PartitionKey($"ActivityEnroll-{_activityId.GetString()}"));
  3327. if (activity.joinMode.Equals("invite"))
  3328. {
  3329. string sqlInvite = $"select value c from c join t in c.inviteTeachers where t.id='{tmdid}' and c.pk='ActivityTeacher'";
  3330. var activityTeacherResult = await client.GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<ActivityTeacher>(sqlInvite, $"ActivityTeacher-{_activityId}");
  3331. foreach (var activityTeacher in activityTeacherResult.list)
  3332. {
  3333. activityTeacher.inviteTeachers.ForEach(z =>
  3334. {
  3335. if (z.id.Equals(tmdid))
  3336. {
  3337. z.status=0;
  3338. }
  3339. });
  3340. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).UpsertItemAsync(activityTeacher, new PartitionKey($"ActivityTeacher-{_activityId}"));
  3341. }
  3342. }
  3343. //已分配作品,强制删除。
  3344. if (!string.IsNullOrWhiteSpace(enroll.upload?.uploadId))
  3345. {
  3346. string sql = $"select value c from c join t in c.contestTasks where t.uploadId='{enroll.upload.uploadId}' and c.pk='ActivityExpertTask' ";
  3347. var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<ActivityExpertTask>(sql, $"ActivityExpertTask-{_activityId}");
  3348. if (result.list.IsNotEmpty())
  3349. {
  3350. foreach (var activityExpertTask in result.list)
  3351. {
  3352. await client.GetContainer(Constant.TEAMModelOS, Constant.Teacher).DeleteItemStreamAsync(activityExpertTask.id, new PartitionKey(activityExpertTask.code));
  3353. }
  3354. }
  3355. }
  3356. if (responseActivityEnrollDel.Status==204)
  3357. {
  3358. return Ok(new { code = 204, msg = "退出成功!" });
  3359. }
  3360. else
  3361. {
  3362. return Ok(new { code = 2, msg = "退出失败!" });
  3363. }
  3364. }
  3365. return Ok(new { code = 1, msg = "暂无报名数据!", });
  3366. }
  3367. ///获取报名
  3368. case bool when $"{grant_type}".Equals("get-enroll", StringComparison.OrdinalIgnoreCase):
  3369. {
  3370. ActivityEnroll enroll = null;
  3371. Azure.Response responseActivityEnroll = await client.GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemStreamAsync(tmdid, new PartitionKey($"ActivityEnroll-{_activityId.GetString()}"));
  3372. if (responseActivityEnroll.Status==200)
  3373. {
  3374. //更新邀请状态
  3375. if (activity.joinMode.Equals("invite"))
  3376. {
  3377. string sqlInvite = $"select value c from c join t in c.inviteTeachers where t.id='{tmdid}' and c.pk='ActivityTeacher' and t.status=0 ";
  3378. var activityTeacherResult = await client.GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<ActivityTeacher>(sqlInvite, $"ActivityTeacher-{_activityId}");
  3379. foreach (var activityTeacher in activityTeacherResult.list)
  3380. {
  3381. activityTeacher.inviteTeachers.ForEach(z =>
  3382. {
  3383. if (z.id.Equals(tmdid))
  3384. {
  3385. z.status=1;
  3386. }
  3387. });
  3388. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).UpsertItemAsync(activityTeacher, new PartitionKey($"ActivityTeacher-{_activityId}"));
  3389. }
  3390. }
  3391. enroll= JsonDocument.Parse(responseActivityEnroll.Content).RootElement.ToObject<ActivityEnroll>();
  3392. double score = -1;
  3393. int levelStatus = -1;
  3394. string scoreLevel = string.Empty;
  3395. int showType = -1;
  3396. //是否已经分配作品 0未分配 1 已分配
  3397. int allotStatus = 0;
  3398. List<dynamic> detailScore = new List<dynamic>();
  3399. if (contest.score!=null && contest.score.scoreStatus==1 && now>contest.score?.stime && now<contest.score.etime && enroll.upload!=null)
  3400. {
  3401. score=enroll.upload.score;
  3402. if (enroll.upload.showScore==1) {
  3403. score=enroll.upload.maskScore;
  3404. }
  3405. List<ActivityScoreLevel> contestScores = await ActivityService.ActivityScores(_azureCosmos, _activityId, enroll.id);
  3406. var levels = contestScores.SelectMany(x => x.scores).Where(x => x.tmdid.Equals(enroll.id));
  3407. ActivityTeacherScoreLevel level = null;
  3408. if (level!=null && levels.Count()>0)
  3409. {
  3410. level=levels.First();
  3411. levelStatus=1;
  3412. scoreLevel=level.scoreLevel;
  3413. score= level.score;
  3414. }
  3415. else {
  3416. levelStatus=0;
  3417. }
  3418. showType=contest.score.showType;
  3419. }
  3420. if (!string.IsNullOrWhiteSpace(enroll.upload?.uploadId))
  3421. {
  3422. string sql = $"select value c from c join t in c.contestTasks where t.uploadId='{enroll.upload.uploadId}' and c.pk='ActivityExpertTask' ";
  3423. var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<ActivityExpertTask>(sql, $"ActivityExpertTask-{_activityId}");
  3424. if (result.list.IsNotEmpty())
  3425. {
  3426. if (contest.score!=null && contest.score.showDetail==1)
  3427. {
  3428. result.list.ForEach(x => {
  3429. var upload = x.contestTasks.Find(z => z.uploadId.Equals(enroll.upload.uploadId));
  3430. if (upload!= null)
  3431. {
  3432. detailScore.Add(new { upload.detailScore, x.id, name = "***" });
  3433. }
  3434. });
  3435. }
  3436. allotStatus=1;
  3437. }
  3438. }
  3439. if (enroll.upload!=null) {
  3440. enroll.upload.score=-1;
  3441. enroll.upload.maskScore=-1;
  3442. }
  3443. return Ok(new { code = 200, enroll,scoreData=new { allotStatus, levelStatus , score, scoreLevel, showType, detailScore } });
  3444. }
  3445. return Ok(new { code = 1, msg = "暂无报名数据!", });
  3446. }
  3447. //生成组队口令
  3448. case bool when $"{grant_type}".Equals("gen-cipher", StringComparison.OrdinalIgnoreCase):
  3449. {
  3450. //Azure.Response responseContest = await client.GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("Contest"));
  3451. //if (responseContest.Status==200 && activity.modules.Contains("Contest"))
  3452. //{
  3453. // Contest contest = JsonDocument.Parse(responseContest.Content).RootElement.ToObject<Contest>();
  3454. //}
  3455. if (contest.modules.Contains("sign") && contest.sign!=null && contest.sign.type==1)
  3456. {
  3457. string cipher = await ActivityService.GenCipher(client, _dingDing, _option, _activityId.GetString());
  3458. return Ok(new { code = 200, cipher });
  3459. }
  3460. return Ok(new { code = 1, msg = "组队口令生成失败!" });
  3461. }
  3462. //根据口令获取团队和队员信息
  3463. case bool when $"{grant_type}".Equals("search-team-by-cipher", StringComparison.OrdinalIgnoreCase):
  3464. {
  3465. if (!request.TryGetProperty("cipher", out JsonElement _cipher)) return BadRequest();
  3466. //Azure.Response responseContest = await client.GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("Contest"));
  3467. //if (responseContest.Status==200 && activity.modules.Contains("Contest"))
  3468. //{
  3469. // Contest contest = JsonDocument.Parse(responseContest.Content).RootElement.ToObject<Contest>();
  3470. //}
  3471. if (contest.modules.Contains("sign") && contest.sign!=null && contest.sign.type==1)
  3472. {
  3473. string cipherSQL = $"select value c from c where c.contest!=null and c.activityId='{_activityId}' and c.contest.type=1 and c.contest.cipher='{_cipher}' ";
  3474. var cipherResult = await client.GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<ActivityEnroll>(cipherSQL, $"ActivityEnroll-{_activityId}");
  3475. List<TeacherEnrollContestDto> teamMembers = new List<TeacherEnrollContestDto>();
  3476. teamMembers= cipherResult.list.Select(z => new TeacherEnrollContestDto
  3477. {
  3478. tmdid= z.id,
  3479. tmdPicture= z.tmdPicture,
  3480. tmdName= z.tmdName,
  3481. schoolName=z.schoolName,
  3482. schoolPicture= z.schoolPicture,
  3483. schoolId= z.schoolId,
  3484. cipher= z.contest.cipher,
  3485. enrollTime= z.contest.enrollTime,
  3486. leader= z.contest.leader,
  3487. teamName= z.contest.teamName,
  3488. type=z.contest.type,
  3489. enrollInfos= z.contest.enrollInfos
  3490. }).ToList();
  3491. return Ok(new
  3492. {
  3493. code = 200,
  3494. teamMembers = teamMembers.Select(z => new
  3495. {
  3496. z.tmdid,
  3497. z.tmdPicture,
  3498. z.tmdName,
  3499. z.schoolName,
  3500. z.schoolPicture,
  3501. z.schoolId,
  3502. z.cipher,
  3503. z.enrollTime,
  3504. z.leader,
  3505. z.teamName,
  3506. z.type,
  3507. z.enrollInfos
  3508. })
  3509. });
  3510. }
  3511. return Ok(new { code = 1, msg = "未找到团队!" });
  3512. }
  3513. //教师报名参加
  3514. case bool when $"{grant_type}".Equals("sign-contest", StringComparison.OrdinalIgnoreCase):
  3515. {
  3516. request.TryGetProperty("mock", out JsonElement _mock);
  3517. if (!request.TryGetProperty("enrollData", out JsonElement _enrollData))
  3518. {
  3519. return Ok(new { code = 0, msg = "报名信息未完善!" });
  3520. };
  3521. TeacherEnrollContestDto enrollData = _enrollData.ToObject<TeacherEnrollContestDto>();
  3522. if (!string.IsNullOrWhiteSpace($"{_mock}")) {
  3523. tmdid= enrollData.tmdid;
  3524. }
  3525. ActivityEnroll enroll = null;
  3526. Azure.Response responseActivityEnroll = await client.GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemStreamAsync(tmdid, new PartitionKey($"ActivityEnroll-{_activityId.GetString()}"));
  3527. if (responseActivityEnroll.Status==200)
  3528. {
  3529. enroll= JsonDocument.Parse(responseActivityEnroll.Content).RootElement.ToObject<ActivityEnroll>();
  3530. }
  3531. //邀请制
  3532. List<ActivityTeacher> activityTeachers = new List<ActivityTeacher>();
  3533. if (activity.joinMode.Equals("invite"))
  3534. {
  3535. string sqlInvite = $"select value c from c join t in c.inviteTeachers where t.id='{tmdid}' and c.pk='ActivityTeacher'";
  3536. var activityTeacherResult = await client.GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<ActivityTeacher>(sqlInvite, $"ActivityTeacher-{_activityId}");
  3537. if (activityTeacherResult.list.IsNotEmpty())
  3538. {
  3539. activityTeachers.AddRange(activityTeacherResult.list);
  3540. var exsit = activityTeacherResult.list.Exists(z => z.id.Equals(enrollData.schoolId));
  3541. if (!exsit)
  3542. {
  3543. code=16;
  3544. return Ok(new { code, msg = "填报的学校与邀请的学校不一致!" });
  3545. }
  3546. else
  3547. {
  3548. code=200;
  3549. }
  3550. }
  3551. else
  3552. {
  3553. code=1;
  3554. return Ok(new { code, msg = "教师未被邀请" });
  3555. }
  3556. }
  3557. //如果邀请制没有检查通过,则检查其他模式
  3558. if (code!=200)
  3559. {
  3560. //如果是 活动主办方设置了 部分学校参加(包含区级以及公开,选择了学校的)
  3561. if (activity.invitedSchools.IsNotEmpty() && activity.confirmedSchools.IsNotEmpty())
  3562. {
  3563. if (!string.IsNullOrWhiteSpace(enrollData.schoolId))
  3564. {
  3565. if (!activity.invitedSchools.Exists(z => z.id.Equals(enrollData.schoolId)))
  3566. {
  3567. return Ok(new { code = 3, msg = "学校未被邀请参与本次活动!" });
  3568. }
  3569. if (!activity.confirmedSchools.Exists(z => z.id.Equals(enrollData.schoolId) && z.status==1))
  3570. {
  3571. return Ok(new { code = 4, msg = "学校未确认参与本次活动!" });
  3572. }
  3573. code=200;
  3574. }
  3575. else
  3576. {
  3577. return Ok(new { code = 2, msg = "请以学校教师身份参加本次活动!" });
  3578. }
  3579. }
  3580. //完全开放的
  3581. else if (activity.scope.Equals("public") && activity.invitedSchools.IsEmpty())
  3582. {
  3583. code=200;
  3584. }
  3585. else if (activity.scope.Equals("school"))
  3586. {
  3587. if (!string.IsNullOrWhiteSpace(enrollData.schoolId))
  3588. {
  3589. if (activity.owner.Equals(enrollData.schoolId))
  3590. {
  3591. code=200;
  3592. }
  3593. else
  3594. {
  3595. return Ok(new { code = 5, msg = "不是本校的教师不能参加本次活动!" });
  3596. }
  3597. }
  3598. else { return Ok(new { code = 2, msg = "请以学校教师身份参加本次活动!" }); }
  3599. }
  3600. else if (activity.scope.Equals("area") && activity.confirmedSchools.IsNotEmpty()) {
  3601. if (!string.IsNullOrWhiteSpace(enrollData.schoolId))
  3602. {
  3603. if (!activity.confirmedSchools.Exists(z => z.id.Equals(enrollData.schoolId) && z.status==1))
  3604. {
  3605. return Ok(new { code = 4, msg = "学校未确认参与本次活动!" });
  3606. }
  3607. else {
  3608. code=200;
  3609. }
  3610. }
  3611. else { return Ok(new { code = 2, msg = "请以学校教师身份参加本次活动!" }); }
  3612. }
  3613. else
  3614. {
  3615. await _dingDing.SendBotMsg($"{_option.Location},活动类型错误:{activity.id}", GroupNames.成都开发測試群組);
  3616. return Ok(new { code = 6, msg = "活动类型错误!" });
  3617. }
  3618. }
  3619. if (code==200)
  3620. {
  3621. ///检查被报名的活动是是否符合
  3622. if (activity.publish==1)
  3623. {
  3624. //Azure.Response responseContest = await client.GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("Contest"));
  3625. //if (responseContest.Status==200 && activity.modules.Contains("Contest"))
  3626. //{
  3627. // Contest contest = JsonDocument.Parse(responseContest.Content).RootElement.ToObject<Contest>();
  3628. //}
  3629. //else
  3630. //{
  3631. // return Ok(new { code = 14, msg = "活动未设置赛课模块!" });
  3632. //}
  3633. if (contest.modules.Contains("sign") && contest.sign!=null)
  3634. {
  3635. //报名时间检查
  3636. if (contest.sign.stime<=now && contest.sign.etime>=now)
  3637. {
  3638. code=200;
  3639. }
  3640. else
  3641. {
  3642. return Ok(new { code = 7, msg = "不在报名时间范围内!" });
  3643. }
  3644. //检查报名人数
  3645. if (contest.sign.limit>0)
  3646. {
  3647. //报名人数,除去自己
  3648. string countEnrollSQL = $"select value c.id from c where c.contest!=null and c.activityId='{_activityId.GetString()}' and c.id<>'{tmdid}' ";
  3649. var countEnrollResult = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<string>(countEnrollSQL, $"ActivityEnroll-{_activityId.GetString()}");
  3650. if (countEnrollResult.list.Count+1>contest.sign.limit)
  3651. {
  3652. return Ok(new { code = 8, msg = "已超过报名人数限制!" });
  3653. }
  3654. else { code=200; }
  3655. }
  3656. //检查团队组,检查口令
  3657. int checkTeam = -1;
  3658. int cipherChange = -1;
  3659. if (contest.sign.type==1)
  3660. {
  3661. if (enrollData.type==1 && !string.IsNullOrWhiteSpace(enrollData.cipher))
  3662. {
  3663. //检查组队口令
  3664. string cipherSQL = $"select value c from c where c.contest!=null and c.activityId='{_activityId.GetString()}' and c.contest.type=1 and c.contest.cipher='{enrollData.cipher}' and c.contest.leader=1 ";
  3665. var cipherResult = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<ActivityEnroll>(cipherSQL, $"ActivityEnroll-{_activityId}");
  3666. if (cipherResult.list.IsNotEmpty())
  3667. {
  3668. //如果队伍存在
  3669. if (!cipherResult.list.First().schoolId.Equals(enrollData.schoolId))
  3670. {
  3671. return Ok(new { code = 18, msg = "报名选择的学校与组队学校不一致!" });
  3672. }
  3673. enrollData.teamName= cipherResult.list.First().contest?.teamName;
  3674. }
  3675. if (enrollData.leader==1)
  3676. {
  3677. //队长
  3678. if (cipherResult.list.IsNotEmpty())
  3679. {
  3680. //组队口令已被其他团队使用,此处已顺便处理成员篡位的逻辑
  3681. var otherTeam = cipherResult.list.FindAll(z => !z.id.Equals(tmdid));
  3682. if (otherTeam.IsNotEmpty())
  3683. {
  3684. return Ok(new { code = 10, msg = "组队口令已被其他团队使用!" });
  3685. }
  3686. else
  3687. {
  3688. //队长更改信息。
  3689. //检查 更新信息的 组队口令是否有变化,如果有变化则队员的组队口令也跟着变化
  3690. if (!string.IsNullOrWhiteSpace(enroll?.contest?.cipher) && !enroll.contest.cipher.Equals(enrollData.cipher))
  3691. {
  3692. cipherChange=1;
  3693. }
  3694. checkTeam=1;
  3695. }
  3696. }
  3697. else
  3698. {
  3699. //队长更改信息。
  3700. //检查 更新信息的 组队口令是否有变化,如果有变化则队员的组队口令也跟着变化
  3701. if (!string.IsNullOrWhiteSpace(enroll?.contest?.cipher) && !enroll.contest.cipher.Equals(enrollData.cipher))
  3702. {
  3703. cipherChange=1;
  3704. }
  3705. checkTeam=1;
  3706. }
  3707. }
  3708. else
  3709. {
  3710. //队长跑路
  3711. if (enroll!=null && enroll.contest!=null && enroll.contest.leader==1 && enrollData.leader==0)
  3712. {
  3713. return Ok(new { code = 17, msg = "你是队长,不能变更身份!" });
  3714. }
  3715. //队员
  3716. if (cipherResult.list.IsNotEmpty())
  3717. {
  3718. if (cipherResult.list.Count==1)
  3719. {
  3720. checkTeam=1;
  3721. }
  3722. else
  3723. {
  3724. await _dingDing.SendBotMsg($"{_option.Location},组队口令重复:{enrollData.cipher}", GroupNames.成都开发測試群組);
  3725. return Ok(new { code = 12, msg = "组队口令重复!" });
  3726. }
  3727. }
  3728. else
  3729. {
  3730. return Ok(new { code = 11, msg = "队伍未组建或不存在!" });
  3731. }
  3732. }
  3733. }
  3734. else
  3735. {
  3736. return Ok(new { code = 9, msg = "参加组别不一致!" });
  3737. }
  3738. }
  3739. else
  3740. {
  3741. //个人组
  3742. if (contest.sign.type== enrollData.type)
  3743. {
  3744. checkTeam=1;
  3745. }
  3746. else
  3747. {
  3748. return Ok(new { code = 9, msg = "参加组别不一致!" });
  3749. }
  3750. }
  3751. if (checkTeam==1)
  3752. {
  3753. if (enroll!=null)
  3754. {
  3755. //更新组队信息
  3756. enroll.contest.teamName= enrollData.teamName;
  3757. enroll.contest.cipher=enrollData.cipher;
  3758. enroll.contest.type=enrollData.type;
  3759. enroll.contest.leader=enrollData.leader;
  3760. enroll.contest.enrollInfos=enrollData.enrollInfos;
  3761. enroll.contest.enrollTime=now;
  3762. enroll.schoolPicture=enrollData.schoolPicture;
  3763. enroll.schoolId=enrollData.schoolId;
  3764. enroll.schoolName=enrollData.schoolName;
  3765. enroll.tmdName=enrollData.tmdName;
  3766. enroll.tmdPicture=enrollData.tmdPicture;
  3767. }
  3768. else
  3769. {
  3770. enroll= new ActivityEnroll
  3771. {
  3772. id=tmdid,
  3773. schoolName=enrollData.schoolName,
  3774. schoolId=enrollData.schoolId,
  3775. schoolPicture=enrollData.schoolPicture,
  3776. activityId=_activityId.GetString(),
  3777. code=$"ActivityEnroll-{_activityId}",
  3778. pk="ActivityEnroll",
  3779. tmdName=enrollData.tmdName,
  3780. tmdPicture=enrollData.tmdPicture,
  3781. contest=new EnrollContest
  3782. {
  3783. cipher=enrollData.cipher,
  3784. leader=enrollData.leader,
  3785. teamName=enrollData.teamName,
  3786. type=enrollData.type,
  3787. enrollTime=now,
  3788. enrollInfos=enrollData.enrollInfos
  3789. }
  3790. };
  3791. }
  3792. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).UpsertItemAsync(enroll, new PartitionKey(enroll.code));
  3793. List<TeacherEnrollContestDto> teamMembers = new List<TeacherEnrollContestDto>();
  3794. //获取组队队员信息
  3795. if (enrollData.type==1 && !string.IsNullOrWhiteSpace(enrollData.cipher))
  3796. {
  3797. //获取队员报名信息
  3798. string cipherSQL = $"select value c from c where c.contest!=null and c.activityId='{_activityId.GetString()}' and c.contest.type=1 and c.contest.cipher='{enrollData.cipher}' ";
  3799. var cipherResult = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<ActivityEnroll>(cipherSQL, $"ActivityEnroll-{_activityId}");
  3800. if (cipherChange==1)
  3801. {
  3802. //队长更新其他队员的组队口令
  3803. cipherResult.list.RemoveAll(z => z.contest.leader==1);
  3804. foreach (var z in cipherResult.list)
  3805. {
  3806. z.contest.cipher=enrollData.cipher;
  3807. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).UpsertItemAsync(z, new PartitionKey(z.code));
  3808. }
  3809. }
  3810. teamMembers= cipherResult.list.Select(z => new TeacherEnrollContestDto
  3811. {
  3812. tmdid= z.id,
  3813. tmdPicture= z.tmdPicture,
  3814. tmdName= z.tmdName,
  3815. schoolName=z.schoolName,
  3816. schoolPicture= z.schoolPicture,
  3817. schoolId= z.schoolId,
  3818. cipher= z.contest.cipher,
  3819. enrollTime= z.contest.enrollTime,
  3820. leader= z.contest.leader,
  3821. teamName= z.contest.teamName,
  3822. type=z.contest.type,
  3823. enrollInfos= z.contest.enrollInfos,
  3824. }).ToList();
  3825. }
  3826. foreach (var activityTeacher in activityTeachers)
  3827. {
  3828. //反向更新邀请状态
  3829. activityTeacher.inviteTeachers.ForEach(z => { if (z.id.Equals(enrollData.tmdid)) { z.status=1; } });
  3830. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).UpsertItemAsync(activityTeacher, new PartitionKey($"ActivityTeacher-{_activityId}"));
  3831. }
  3832. return Ok(new
  3833. {
  3834. code = 200,
  3835. enroll,
  3836. teamMembers = teamMembers.Select(z => new
  3837. {
  3838. z.tmdid,
  3839. z.tmdPicture,
  3840. z.tmdName,
  3841. z.schoolName,
  3842. z.schoolPicture,
  3843. z.schoolId,
  3844. z.cipher,
  3845. z.enrollTime,
  3846. z.leader,
  3847. z.teamName,
  3848. z.type,
  3849. z.enrollInfos
  3850. })
  3851. });
  3852. }
  3853. else
  3854. {
  3855. return Ok(new { code = 12, msg = "报名组别检查未通过!" });
  3856. }
  3857. }
  3858. else
  3859. {
  3860. return Ok(new { code = 15, msg = "活动未设置信息填报模块!" });
  3861. }
  3862. }
  3863. else
  3864. {
  3865. return Ok(new { code = 13, msg = "活动未发布!" });
  3866. }
  3867. }
  3868. else
  3869. {
  3870. return Ok(new { code = 6, msg = "活动类型错误!" });
  3871. }
  3872. }
  3873. //作品上传
  3874. case bool when $"{grant_type}".Equals("upload-contest", StringComparison.OrdinalIgnoreCase):
  3875. {
  3876. request.TryGetProperty("mock", out JsonElement _mock);
  3877. if (!request.TryGetProperty("uploadData", out JsonElement _uploadData))
  3878. {
  3879. return Ok(new { code = 0, msg = "上传信息未完善!" });
  3880. };
  3881. TeacherUploadContestDto uploadContest = _uploadData.ToObject<TeacherUploadContestDto>();
  3882. if (!string.IsNullOrWhiteSpace($"{_mock}"))
  3883. {
  3884. tmdid= uploadContest.tmdid;
  3885. }
  3886. if (contest.modules.Contains("upload") && contest.upload!=null)
  3887. {
  3888. int check = -1;
  3889. //作品上传时间
  3890. if (!(contest.upload.stime<=now && contest.upload.etime>=now))
  3891. {
  3892. return Ok(new { code = 4, msg = "未到上传作品时间!" });
  3893. }
  3894. ActivityEnroll enroll = null;
  3895. int captainUpload = -1;
  3896. Azure.Response responseActivityEnroll = await client.GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemStreamAsync(tmdid, new PartitionKey($"ActivityEnroll-{_activityId.GetString()}"));
  3897. if (responseActivityEnroll.Status==200)
  3898. {
  3899. enroll= JsonDocument.Parse(responseActivityEnroll.Content).RootElement.ToObject<ActivityEnroll>();
  3900. if (contest.modules.Contains("sign"))
  3901. {
  3902. if (enroll.contest==null)
  3903. {
  3904. return Ok(new { code = 2, msg = "请先报名后再上传作品!" });
  3905. }
  3906. else
  3907. {
  3908. if (contest.upload.captainUpload==1)
  3909. {
  3910. if (enroll.contest.type==1)
  3911. {
  3912. if (enroll.contest.leader!=1)
  3913. {
  3914. return Ok(new { code = 3, msg = "作品上传要求队长上传!" });
  3915. }
  3916. else
  3917. {
  3918. check=1;
  3919. captainUpload=1;
  3920. }
  3921. }
  3922. else
  3923. {
  3924. return Ok(new { code = 3, msg = "作品上传要求队长上传!" });
  3925. }
  3926. }
  3927. else
  3928. {
  3929. check=1;
  3930. }
  3931. }
  3932. }
  3933. else
  3934. {
  3935. //没有报名模块,直接上传
  3936. check=1;
  3937. }
  3938. }
  3939. else
  3940. {
  3941. if (contest.modules.Contains("sign"))
  3942. {
  3943. return Ok(new { code = 2, msg = "请先报名后再上传作品!" });
  3944. }
  3945. else
  3946. {
  3947. //没有报名模块,直接上传
  3948. check=1;
  3949. enroll= new ActivityEnroll
  3950. {
  3951. id=tmdid,
  3952. code=$"ActivityEnroll-{_activityId}",
  3953. pk="ActivityEnroll",
  3954. schoolId= uploadContest.schoolId,
  3955. schoolName=uploadContest.schoolName,
  3956. schoolPicture=uploadContest.schoolPicture,
  3957. activityId=_activityId.GetString()
  3958. };
  3959. }
  3960. }
  3961. if (check==1)
  3962. {
  3963. if (uploadContest.complexes.IsNotEmpty())
  3964. {
  3965. if (contest.upload.limit>0)
  3966. {
  3967. if (contest.upload.limit<contest.upload.uploadType.Count())
  3968. {
  3969. ///上传类型数量限制小于文件类型数量,表示可以上传任意N种类型的文件。
  3970. if (uploadContest.complexes.Count>=contest.upload.limit && uploadContest.complexes.Count<= contest.upload.uploadType.Count())
  3971. {
  3972. var types = uploadContest.complexes.Select(x => x.type).ToHashSet();
  3973. foreach (var type in types)
  3974. {
  3975. if (!contest.upload.uploadType.Contains(type))
  3976. {
  3977. return Ok(new { code = 7, msg = "上传的文件类型与活动要求的文件类型不符!" });
  3978. }
  3979. }
  3980. }
  3981. else
  3982. {
  3983. return Ok(new { code = 10, msg = "文件上传数量不满足活动要求上传的文件类型数量!" });
  3984. }
  3985. }
  3986. else
  3987. {
  3988. ///上传类型数量限制大于等于则表示需要上传所有类型的文件。
  3989. if (uploadContest.complexes.Count== contest.upload.uploadType.Count())
  3990. {
  3991. var types = uploadContest.complexes.Select(x => x.type).ToHashSet();
  3992. bool hasError = false;
  3993. foreach (var type in contest.upload.uploadType)
  3994. {
  3995. if (!contest.upload.uploadType.Contains(type))
  3996. {
  3997. hasError=true;
  3998. }
  3999. }
  4000. if (hasError)
  4001. {
  4002. return Ok(new { code = 7, msg = "上传的文件类型与活动要求的文件类型不符!" });
  4003. }
  4004. }
  4005. else
  4006. {
  4007. return Ok(new { code = 10, msg = "文件上传数量不满足活动要求上传的文件类型数量!" });
  4008. }
  4009. }
  4010. }
  4011. else
  4012. {
  4013. ///在上传类型范围内,不限制上传文件的种类和类型的数量。
  4014. var types = uploadContest.complexes.Select(x => x.type).ToHashSet();
  4015. foreach (var type in types)
  4016. {
  4017. if (!contest.upload.uploadType.Contains(type))
  4018. {
  4019. return Ok(new { code = 7, msg = "上传的文件类型与活动要求的文件类型不符!" });
  4020. }
  4021. }
  4022. }
  4023. ///检查必须上传的类型
  4024. if (contest.upload.uploadTypeNecessary!=null && contest.upload.uploadTypeNecessary.Count>0)
  4025. {
  4026. var types = uploadContest.complexes.Select(x => x.type).ToHashSet();
  4027. foreach (var type in contest.upload.uploadTypeNecessary)
  4028. {
  4029. if (!types.Contains(type))
  4030. {
  4031. return Ok(new { code = 9, msg = "没有上传活动要求必须上传的文件类型!" });
  4032. }
  4033. }
  4034. }
  4035. //覆盖更新
  4036. enroll.upload= new EnrollUpload
  4037. {
  4038. uploadTime=now,
  4039. complexes=uploadContest.complexes,
  4040. uploadType=uploadContest.complexes.Select(x => x.type).ToHashSet(),
  4041. //作品id变更,已经上传过不会发生变更。
  4042. uploadId=string.IsNullOrWhiteSpace(enroll?.upload?.uploadId) ? Guid.NewGuid().ToString(): enroll.upload.uploadId,
  4043. name=uploadContest.name,
  4044. };
  4045. await client.GetContainer(Constant.TEAMModelOS, Constant.Teacher).UpsertItemAsync(enroll, new PartitionKey($"ActivityEnroll-{_activityId.GetString()}"));
  4046. if (captainUpload==1&& !string.IsNullOrWhiteSpace(enroll.contest.cipher))
  4047. {
  4048. //获取队员报名信息
  4049. string cipherSQL = $"select value c from c where c.contest!=null and c.activityId='{_activityId.GetString()}' and c.contest.type=1 and c.contest.cipher='{enroll.contest.cipher}' ";
  4050. var cipherResult = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<ActivityEnroll>(cipherSQL, $"ActivityEnroll-{_activityId}");
  4051. //队长统一上传
  4052. cipherResult.list.RemoveAll(z => z.contest.leader==1);
  4053. foreach (var z in cipherResult.list)
  4054. {
  4055. z.upload=enroll.upload;
  4056. //队长统一上传的作品不需要单独生成作品id.
  4057. // z.upload.uploadId=Guid.NewGuid().ToString();
  4058. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).UpsertItemAsync(z, new PartitionKey(z.code));
  4059. }
  4060. }
  4061. return Ok(new { code = 200, });
  4062. }
  4063. else
  4064. {
  4065. return Ok(new { code = 6, msg = "未通过作品验证!" });
  4066. }
  4067. //if (contest.upload.type.Equals(uploadContest.type))
  4068. //{
  4069. // if (uploadContest.type.Equals("sokrates"))
  4070. // {
  4071. // //校验苏格拉底
  4072. // //var httpClient = _httpClientFactory.CreateClient();
  4073. // //if (!httpClient.DefaultRequestHeaders.Contains("x-functions-key"))
  4074. // //{
  4075. // // httpClient.DefaultRequestHeaders.Add("x-functions-key", "2BcXFR_hvzG1pZjqIkaM7Dx74Hcu6m0PwwOacFpDpq44AzFuHJBRXA==");
  4076. // //}
  4077. // //string paramJson = JsonConvert.SerializeObject(new { fmt = "0" });
  4078. // //var content = new StringContent(paramJson, Encoding.UTF8, "application/json");
  4079. // //HttpResponseMessage httpResponse = await httpClient.PostAsync("https://malearn.teammodel.cn/api/txtwc", content);
  4080. // //if (httpResponse.IsSuccessStatusCode)
  4081. // //{
  4082. // // string str = await httpResponse.Content.ReadAsStringAsync();
  4083. // //}
  4084. // // 处理队长统一上传
  4085. // return Ok(new { code = 200 });
  4086. // }
  4087. // else if (uploadContest.type.Equals("lesson"))
  4088. // {
  4089. // foreach (var ext in uploadContest.lessons.Select(z => z.extension).ToHashSet())
  4090. // {
  4091. // if (!contest.upload.fileType.Contains(ext))
  4092. // {
  4093. // return Ok(new { code = 7, msg = "上传的文件类型与活动要求的文件类型不符!" });
  4094. // }
  4095. // }
  4096. // //覆盖更新
  4097. // enroll.upload= new EnrollUpload
  4098. // {
  4099. // uploadTime=now,
  4100. // lessons=uploadContest.lessons,
  4101. // type=uploadContest.type,
  4102. // uploadId=Guid.NewGuid().ToString(),
  4103. // name=uploadContest.name,
  4104. // };
  4105. // await client.GetContainer(Constant.TEAMModelOS, Constant.Teacher).UpsertItemAsync(enroll, new PartitionKey($"ActivityEnroll-{_activityId.GetString()}"));
  4106. // if (captainUpload==1&& !string.IsNullOrWhiteSpace(enroll.contest.cipher))
  4107. // {
  4108. // //获取队员报名信息
  4109. // string cipherSQL = $"select value c from c where c.contest!=null and c.activityId='{_activityId.GetString()}' and c.contest.type=1 and c.contest.cipher='{enroll.contest.cipher}' ";
  4110. // var cipherResult = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<ActivityEnroll>(cipherSQL, $"ActivityEnroll-{_activityId}");
  4111. // //队长统一上传
  4112. // cipherResult.list.RemoveAll(z => z.contest.leader==1);
  4113. // foreach (var z in cipherResult.list)
  4114. // {
  4115. // z.upload=enroll.upload;
  4116. // //队长统一上传的作品不需要单独生成作品id.
  4117. // // z.upload.uploadId=Guid.NewGuid().ToString();
  4118. // await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).UpsertItemAsync(z, new PartitionKey(z.code));
  4119. // }
  4120. // }
  4121. // return Ok(new { code = 200, });
  4122. // }
  4123. // else if (uploadContest.type.Equals("file"))
  4124. // {
  4125. // foreach (var ext in uploadContest.files.Select(z => z.extension).ToHashSet())
  4126. // {
  4127. // if (!contest.upload.fileType.Contains(ext))
  4128. // {
  4129. // return Ok(new { code = 7, msg = "上传的文件类型与活动要求的文件类型不符!" });
  4130. // }
  4131. // }
  4132. // //覆盖更新
  4133. // enroll.upload= new EnrollUpload
  4134. // {
  4135. // uploadTime=now,
  4136. // files=uploadContest.files,
  4137. // type=uploadContest.type,
  4138. // uploadId=Guid.NewGuid().ToString(),
  4139. // name=uploadContest.name,
  4140. // };
  4141. // await client.GetContainer(Constant.TEAMModelOS, Constant.Teacher).UpsertItemAsync(enroll, new PartitionKey($"ActivityEnroll-{_activityId.GetString()}"));
  4142. // if (captainUpload==1&& !string.IsNullOrWhiteSpace(enroll.contest.cipher))
  4143. // {
  4144. // //获取队员报名信息
  4145. // string cipherSQL = $"select value c from c where c.contest!=null and c.activityId='{_activityId.GetString()}' and c.contest.type=1 and c.contest.cipher='{enroll.contest.cipher}' ";
  4146. // var cipherResult = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<ActivityEnroll>(cipherSQL, $"ActivityEnroll-{_activityId}");
  4147. // //队长统一上传
  4148. // cipherResult.list.RemoveAll(z => z.contest.leader==1);
  4149. // foreach (var z in cipherResult.list)
  4150. // {
  4151. // z.upload=enroll.upload;
  4152. // //队长统一上传的作品不需要单独生成作品id.
  4153. // // z.upload.uploadId=Guid.NewGuid().ToString();
  4154. // await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).UpsertItemAsync(z, new PartitionKey(z.code));
  4155. // }
  4156. // }
  4157. // return Ok(new { code = 200, });
  4158. // }
  4159. // else
  4160. // {
  4161. // return Ok(new { code = 8, msg = "上传类型不一致!" });
  4162. // }
  4163. //}
  4164. //else
  4165. //{
  4166. // return Ok(new { code = 5, msg = "上传的作品类型与活动要求的作品类型不符!" });
  4167. //}
  4168. }
  4169. else
  4170. {
  4171. return Ok(new { code = 6, msg = "未通过作品验证!" });
  4172. }
  4173. }
  4174. else
  4175. {
  4176. return Ok(new { code = 1, msg = "未设置上传模块!" });
  4177. }
  4178. //Azure.Response responseContest = await client.GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("Contest"));
  4179. //if (responseContest.Status==200 && activity.modules.Contains("Contest"))
  4180. //{
  4181. // Contest contest = JsonDocument.Parse(responseContest.Content).RootElement.ToObject<Contest>();
  4182. //}
  4183. //else { return Ok(new { code = 1, msg = "未设置上传模块!" }); }
  4184. }
  4185. }
  4186. }
  4187. else
  4188. {
  4189. return Ok(new { code = 31, msg = "活动未发布!" });
  4190. }
  4191. }
  4192. else { return Ok(new { code = 32, msg = "活动不存在!" }); }
  4193. }
  4194. catch (Exception ex)
  4195. {
  4196. await _dingDing.SendBotMsg($"{_option.Location},报名信息{ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  4197. return BadRequest(ex.Message);
  4198. }
  4199. return Ok();
  4200. }
  4201. /// <summary>
  4202. /// portal站的
  4203. /// </summary>
  4204. /// <param name="request"></param>
  4205. /// <returns></returns>
  4206. [ProducesDefaultResponseType]
  4207. [HttpPost("list-portal")]
  4208. public async Task<IActionResult> ListPortal(JsonElement request)
  4209. {
  4210. //var authtoken = HttpContext.GetXAuth("AuthToken");
  4211. //string userid = string.Empty;
  4212. //object schoolid = null;
  4213. //if (!string.IsNullOrWhiteSpace(authtoken)) {
  4214. // var jwt = new JwtSecurityToken(authtoken);
  4215. // //TODO 此驗證IdToken先簡單檢查,後面需向Core ID新API,驗證Token
  4216. // userid= jwt.Payload.Sub;
  4217. // jwt.Payload.TryGetValue("azp", out schoolid);
  4218. //}
  4219. if (!request.TryGetProperty("route", out JsonElement _route)) return BadRequest();
  4220. List<ActivityDto> activities = new List<ActivityDto>();
  4221. string sql = $"select value c from c where c.route='{_route}'";
  4222. var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).GetList<ActivityWebsite>(sql, "ActivityWebsite");
  4223. ActivityWebsite website = null;
  4224. if (result.list.Count>1)
  4225. {
  4226. return Ok(new { code = 1, msg = "路由匹配多个区校" });
  4227. }
  4228. else
  4229. {
  4230. if (result.list.Count==1)
  4231. {
  4232. website= result.list[0];
  4233. }
  4234. }
  4235. if (website!=null)
  4236. {
  4237. if (website.scope.Equals("area"))
  4238. {
  4239. //区级所有学校
  4240. string sqlOpen = $"select value c from c where c.scope='area' and (c.publish=1 or c.publish=2 ) and c.owner='{website.id}' ";
  4241. var resultOpen = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).GetList<ActivityDto>(sqlOpen, "Activity");
  4242. activities.AddRange(resultOpen.list);
  4243. }
  4244. if (website.scope.Equals("school"))
  4245. {
  4246. School schoolbase = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemAsync<School>(website.id, new PartitionKey("Base"));
  4247. //区级下放的
  4248. if (!string.IsNullOrWhiteSpace(schoolbase.areaId))
  4249. {
  4250. //区级所有学校
  4251. string sqlOpen = $"select value c from c join s in c.confirmedSchools where c.scope='area' and (c.publish=1 or c.publish=2 ) and c.owner='{schoolbase.areaId}' and( ARRAY_LENGTH(c.invitedSchools)=0 or IS_DEFINED(c.invitedSchools) = false) and s.id='{schoolbase.id}' and s.status=1 ";
  4252. var resultOpen = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).GetList<ActivityDto>(sqlOpen, "Activity");
  4253. activities.AddRange(resultOpen.list);
  4254. //区级部分学校
  4255. string sqlSchool = $"select value c from c join i in c.invitedSchools join s in c.confirmedSchools where c.scope='area'and (c.publish=1 or c.publish=2 ) and c.owner='{schoolbase.areaId}' and i.id='{schoolbase.id}' and s.id='{schoolbase.id}' and s.status=1 ";
  4256. var resultSchool = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).GetList<ActivityDto>(sqlSchool, "Activity");
  4257. activities.AddRange(resultSchool.list);
  4258. }
  4259. {
  4260. ///学校自己的
  4261. string sqlSchool = $"select value c from c where c.scope='school' and (c.publish=1 or c.publish=2 ) and c.owner='{schoolbase.id}' ";
  4262. var resultSchool = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).GetList<ActivityDto>(sqlSchool, "Activity");
  4263. activities.AddRange(resultSchool.list);
  4264. }
  4265. }
  4266. //获取开放的
  4267. {
  4268. //完全开放 所有的学校
  4269. string sqlOpen = $"select value c from c where c.scope='public' and (c.publish=1 or c.publish=2 ) ";
  4270. var resultOpen = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).GetList<ActivityDto>(sqlOpen, "Activity");
  4271. activities.AddRange(resultOpen.list);
  4272. }
  4273. }
  4274. long now = DateTimeOffset.Now.ToUnixTimeMilliseconds();
  4275. activities.ForEach(z =>
  4276. {
  4277. var (blob_uri, blob_sas) = _azureStorage.GetBlobContainerSAS(z.owner, BlobContainerSasPermissions.Read);
  4278. z.sas=blob_sas;
  4279. z.url=blob_uri;
  4280. if (z.etime<now) {
  4281. z.publish=2;
  4282. }
  4283. });
  4284. return Ok(new { activities, website });
  4285. }
  4286. }
  4287. }