ActivityController.cs 309 KB

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