ScoreCalcController.cs 147 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758
  1. using Azure;
  2. using Azure.Core;
  3. using Azure.Cosmos;
  4. using Azure.Messaging.ServiceBus;
  5. using Azure.Storage.Blobs.Models;
  6. using DinkToPdf.Contracts;
  7. using HTEXLib.COMM.Helpers;
  8. using Microsoft.AspNetCore.Authorization;
  9. using Microsoft.AspNetCore.Hosting;
  10. using Microsoft.AspNetCore.Mvc;
  11. using Microsoft.Extensions.Configuration;
  12. using Microsoft.Extensions.Options;
  13. using Newtonsoft.Json;
  14. using StackExchange.Redis;
  15. using System;
  16. using System.Collections.Generic;
  17. using System.Linq;
  18. using System.Net;
  19. using System.Net.Http;
  20. using System.Text;
  21. using System.Text.Json;
  22. using System.Threading.Tasks;
  23. using TEAMModelOS.Models;
  24. using TEAMModelOS.SDK;
  25. using TEAMModelOS.SDK.DI;
  26. using TEAMModelOS.SDK.Extension;
  27. using TEAMModelOS.SDK.Models;
  28. using TEAMModelOS.SDK.Models.Cosmos.School;
  29. using TEAMModelOS.SDK.Models.Service;
  30. namespace TEAMModelOS.Controllers
  31. {
  32. [Route("score")]
  33. [ApiController]
  34. public class ScoreCalcController : ControllerBase
  35. {
  36. private readonly IHttpClientFactory _httpClient;
  37. public IWebHostEnvironment _environment { get; set; }
  38. private readonly AzureStorageFactory _azureStorage;
  39. private readonly AzureRedisFactory _azureRedis;
  40. private readonly AzureCosmosFactory _azureCosmos;
  41. private readonly DingDing _dingDing;
  42. private readonly AzureServiceBusFactory _serviceBus;
  43. private readonly CoreAPIHttpService _coreAPIHttpService;
  44. private readonly Option _option;
  45. private readonly IPSearcher _searcher;
  46. public IConfiguration _configuration { get; set; }
  47. private readonly IConverter _converter;
  48. public ScoreCalcController(IConverter converter, IPSearcher searcher, IOptionsSnapshot<Option> option, CoreAPIHttpService coreAPIHttpService, IHttpClientFactory httpClient, IWebHostEnvironment environment, AzureCosmosFactory azureCosmos, AzureRedisFactory azureRedis, AzureStorageFactory azureStorage, IConfiguration configuration, AzureServiceBusFactory serviceBus, DingDing dingDing)
  49. {
  50. _converter = converter;
  51. _azureCosmos = azureCosmos;
  52. _azureRedis = azureRedis;
  53. _azureStorage = azureStorage;
  54. _dingDing = dingDing;
  55. _serviceBus = serviceBus; _configuration = configuration;
  56. _environment = environment;
  57. _httpClient = httpClient;
  58. _option = option.Value;
  59. _coreAPIHttpService = coreAPIHttpService;
  60. _searcher = searcher;
  61. }
  62. [ProducesDefaultResponseType]
  63. [Authorize(Roles = "IES")]
  64. [HttpPost("upsert-scorecalc")]
  65. //[Authorize(Roles = "IES")]
  66. //[AuthToken(Roles = "admin,teacher,student")]
  67. public async Task<IActionResult> UpsertScoreCalc(JsonElement json)
  68. {
  69. try
  70. {
  71. //var client = _azureCosmos.GetCosmosClient();
  72. ////總覽
  73. //ScoreCalcBase scoreCalcBase = new ScoreCalcBase();
  74. //string tmid = "1595321354";
  75. //scoreCalcBase.id = "8f25d7b4-79bd-4448-baaf-01b0d3d3efd9";
  76. //scoreCalcBase.name = "測試成績001";
  77. //scoreCalcBase.code = $"ScoreCalc-{tmid}";
  78. //scoreCalcBase.courseId = "a6d778e8-e4f0-46a3-850f-c15daedc5d94";
  79. //scoreCalcBase.classId = "b069d9d4-ef7e-4f3e-ac62-532b11f95b80";
  80. //ScoreCalcMember member1 = new ScoreCalcMember() { id = "20230001" , name = "學生1" , no = "1"};
  81. //ScoreCalcMember member2 = new ScoreCalcMember() { id = "20230002", name = "學生2", no = "2" };
  82. //scoreCalcBase.members.Add(member1);
  83. //scoreCalcBase.members.Add(member2);
  84. //scoreCalcBase.scores.Add(65.5);
  85. //scoreCalcBase.scores.Add(73.8);
  86. //scoreCalcBase.scoresOrg.Add(66.7);
  87. //scoreCalcBase.scoresOrg.Add(71.4);
  88. //scoreCalcBase.rateType = "percentage";
  89. //await client.GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync(scoreCalcBase, new PartitionKey($"ScoreCalc-{tmid}"));
  90. ////評量
  91. //ScoreCalcActivity scoreCalcActivity = new ScoreCalcActivity();
  92. //scoreCalcActivity.id = "bd492c0c-c6d5-472d-9b3a-93196d3a7010";
  93. //scoreCalcActivity.code = $"ScoreCalcAct-{tmid}";
  94. //scoreCalcActivity.scorecalcId = "8f25d7b4-79bd-4448-baaf-01b0d3d3efd9";
  95. //scoreCalcActivity.type = "exam";
  96. //ScoreCalcActivityItems exam1 = new ScoreCalcActivityItems(); //被選取的第一個評量
  97. //exam1.id = "af6cc80f-a4be-4a5f-94ff-12c1fd366a8f";
  98. //exam1.name = "第一次小考";
  99. //exam1.code = "Exam-1595321354";
  100. //exam1.scope = "school";
  101. //exam1.owner = "teacher";
  102. //exam1.progress = "finish";
  103. //exam1.sStatus = 1;
  104. //exam1.source = "1";
  105. //exam1.createTime = 1623919622766;
  106. //scoreCalcActivity.items.Add(exam1);
  107. //ScoreCalcActivityItems exam2 = new ScoreCalcActivityItems(); //被選取的第二個評量
  108. //exam2.id = "b3f95a17-b839-4b9a-84de-76c83d0e2845";
  109. //exam2.name = "第二次小考";
  110. //exam2.code = "Exam-1595321354";
  111. //exam2.scope = "private";
  112. //exam2.owner = "teacher";
  113. //exam2.progress = "finish";
  114. //exam2.sStatus = 1;
  115. //exam2.source = "1";
  116. //exam2.createTime = 1623204312794;
  117. //scoreCalcActivity.items.Add(exam2);
  118. //scoreCalcActivity.itemRates.Add(2); //第一個評量權重
  119. //scoreCalcActivity.itemRates.Add(1); //第二個評量權重
  120. //scoreCalcActivity.itemRateType = "count";
  121. //scoreCalcActivity.itemScores.Add(76.2);
  122. //scoreCalcActivity.itemScores.Add(81.1);
  123. //scoreCalcActivity.itemScoresOrg.Add(72.6);
  124. //scoreCalcActivity.itemScoresOrg.Add(80.7);
  125. ////scoreCalcActivity.score = 78.2;
  126. ////scoreCalcActivity.scoreOrg = 77.5;
  127. //scoreCalcActivity.rate = 40; //評量的總加權 = 40%
  128. //List<double> stuScores = new List<double>() { 70.1, 73.5 }; //第一個學生的所有評量總成績,第二個同學...
  129. //scoreCalcActivity.stuScores = stuScores;
  130. //List<double> examScore1 = new List<double>() { 73.2, 69.7 }; //第一個評量,第一位同學73.2 第二位同學69.7
  131. //scoreCalcActivity.stuActScores.Add(examScore1);
  132. //List<double> examScore2 = new List<double>() { 81.6, 58.1 }; //第二個評量
  133. //scoreCalcActivity.stuActScores.Add(examScore2);
  134. //List<double> examScore1Org = new List<double>() { 73.2, 69.7 };
  135. //scoreCalcActivity.stuActScoresOrg.Add(examScore1Org);
  136. //List<double> examScore2Org = new List<double>() { 81.6, 58.1 };
  137. //scoreCalcActivity.stuActScoresOrg.Add(examScore2Org);
  138. //await client.GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync(scoreCalcActivity, new PartitionKey($"ScoreCalcAct-{tmid}"));
  139. ////課堂紀錄
  140. //ScoreCalcLsRecord scoreCalcLsRecord = new ScoreCalcLsRecord();
  141. return Ok(new { status = 200 });
  142. }
  143. catch (Exception ex)
  144. {
  145. return BadRequest();
  146. }
  147. }
  148. /// <summary>
  149. /// (一)查詢成績統計列表
  150. /// </summary>
  151. /// <param name="request"></param>
  152. /// <returns></returns>
  153. [ProducesDefaultResponseType]
  154. [Authorize(Roles = "IES")]
  155. [HttpPost("get-scorecalc-list")]
  156. public async Task<IActionResult> GetSscoreCalcList(JsonElement request)
  157. {
  158. try
  159. {
  160. if (!request.TryGetProperty("courseId", out JsonElement courseId)) return BadRequest();
  161. bool ishaveClassId = request.TryGetProperty("classId", out JsonElement classId);
  162. bool ishaveGrouplistId = request.TryGetProperty("grouplistId", out JsonElement grouplistId);
  163. ishaveClassId = !string.IsNullOrWhiteSpace(classId + "");
  164. ishaveGrouplistId = !string.IsNullOrWhiteSpace(grouplistId + "");
  165. string sql = "";
  166. // classId 跟 grouplistId 兩個必須有一個必填
  167. if (!ishaveClassId)
  168. {
  169. if (!ishaveGrouplistId)
  170. {
  171. return BadRequest();
  172. }
  173. else
  174. {
  175. sql = $"SELECT c.id, c.name, c.sort, c.createTime FROM c where c.courseId = '{courseId}' and c.grouplistId = '{grouplistId}' order by c.sort Desc ";
  176. }
  177. }
  178. else
  179. {
  180. sql = $"SELECT c.id, c.name, c.sort, c.createTime FROM c where c.courseId = '{courseId}' and c.classId = '{classId}' order by c.sort Desc ";
  181. }
  182. var client = _azureCosmos.GetCosmosClient();
  183. #region ====資料取得===
  184. List<Calc> calcList = new List<Calc>();
  185. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetItemQueryIterator<Calc>(queryText: sql))
  186. {
  187. calcList.Add(item);
  188. }
  189. #endregion
  190. return Ok(calcList);
  191. }
  192. catch (Exception e)
  193. {
  194. //await _dingDing.SendBotMsg($"OS,{_option.Location},open-api/upsert()\n{e.Message}\n{e.StackTrace}\n{e.StackTrace}", GroupNames.醍摩豆服務運維群組);
  195. return BadRequest();
  196. }
  197. }
  198. /// <summary>
  199. /// (二)查詢成績統計首頁表資料
  200. /// </summary>
  201. /// <param name="request"></param>
  202. /// <returns></returns>
  203. [ProducesDefaultResponseType]
  204. [Authorize(Roles = "IES")]
  205. [HttpPost("get-scorecalc-All")]
  206. public async Task<IActionResult> GetSscoreCalcAll(JsonElement request)
  207. {
  208. try
  209. {
  210. if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
  211. request.TryGetProperty("classId", out JsonElement classId);
  212. request.TryGetProperty("grouplistId", out JsonElement grouplistId);
  213. bool ishaveClassId = !string.IsNullOrWhiteSpace(classId + "");
  214. bool ishaveGrouplistId = !string.IsNullOrWhiteSpace(grouplistId + "");
  215. request.TryGetProperty("scope", out JsonElement scope);
  216. bool ishaveScope = !string.IsNullOrWhiteSpace(scope + "");
  217. if (!ishaveScope) { return BadRequest(); }
  218. var clientStudent = _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Student);
  219. var clientSchool = _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School);
  220. var client = _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher);
  221. #region ====取得學生資料===
  222. string sql = $"select b.id, b.name, b.no from c join b in c.members where c.id = '{id}'";
  223. List<ScoreCalcMember> members = new List<ScoreCalcMember>();
  224. List<ScoreCalcMember> memberirs = new List<ScoreCalcMember>();
  225. List<Object> scoreCalcAct = new List<Object>();
  226. List<ScoreCalcFunc> scoreCalcFunc = new List<ScoreCalcFunc>();
  227. StringBuilder sb = new StringBuilder();
  228. await foreach (var item in client.GetItemQueryIterator<ScoreCalcMember>(queryText: sql))
  229. {
  230. members.Add(item);
  231. sb.Append($"'{item.id}',");
  232. }
  233. #region 取學生irs號碼
  234. string sql_members = "";
  235. if (ishaveClassId)
  236. {// 如果有classId 直接到student 取資料
  237. sql_members = $"SELECT c.id, c.irs FROM c WHERE c.id in ({sb.ToString().Remove(sb.Length - 1, 1)})";
  238. await foreach (var item in clientStudent.GetItemQueryIterator<ScoreCalcMember>(queryText: sql_members))
  239. {
  240. memberirs.Add(item);
  241. }
  242. }
  243. else if (scope.ToString() == "school")
  244. {// 選課班 撈School 取id irs
  245. if (ishaveGrouplistId)
  246. {
  247. sql_members = $"SELECT b.id, b.irs FROM c join b in c.members WHERE c.id= '{grouplistId}'";
  248. await foreach (var item in clientSchool.GetItemQueryIterator<ScoreCalcMember>(queryText: sql_members))
  249. {
  250. memberirs.Add(item);
  251. }
  252. }
  253. else { return BadRequest(); }
  254. }
  255. else if (scope.ToString() == "private")
  256. {// 私人班 撈Teacher 取id irs
  257. if (ishaveGrouplistId)
  258. {
  259. sql_members = $"SELECT b.id, b.irs FROM c join b in c.members WHERE c.id = '{grouplistId}'";
  260. await foreach (var item in client.GetItemQueryIterator<ScoreCalcMember>(queryText: sql_members))
  261. {
  262. memberirs.Add(item);
  263. }
  264. }
  265. else { return BadRequest(); }
  266. }
  267. else { return BadRequest(); }
  268. for (int i = 0; i < members.Count; i++)
  269. {
  270. for (int j = 0; j < memberirs.Count; j++)
  271. {
  272. if (members[i].id == memberirs[j].id)
  273. {
  274. members[i].irs = memberirs[j].irs;
  275. }
  276. }
  277. }
  278. #endregion
  279. #endregion
  280. #region ====取得非課堂紀錄的項目資料===
  281. string sql_Items = $"SELECT c.id, c.name, c.type, c.attendRate, c.pointRate, c.itactRate, c.rate, c.items, c.itemRates, c.itemRateType, c.score, c.scoreOrg, c.stuActScores, c.stuActScoresOrg, c.editScores, c.sort, c.custom FROM c where c.scorecalcId = '{id}' and c.type <> 'lessonrecord' ";
  282. List<ScoreCalcActivity> scoreCalcActivity = new List<ScoreCalcActivity>();
  283. await foreach (var item in client.GetItemQueryIterator<ScoreCalcActivity>(queryText: sql_Items))
  284. {
  285. scoreCalcActivity.Add(item);
  286. }
  287. #endregion
  288. #region ====取得課堂紀錄的項目資料===
  289. string sql_LessonRecordItems = $"SELECT c.id, c.code, c.name, c.type, c.attendRate, c.pointRate, c.itactRate, c.rate, c.items, c.itemRates, c.stuAttendFunctionId, c.stuPointFunctionId, c. stuItactFunctionId, c.stuActAttendOrgVals, c.stuActAttendScores, c.stuActPointOrgVals, c.stuActPointScores, c.stuActItactOrgVals, c.stuActItactScores, c.score, c.scoreOrg, c.stuActScores, c.stuActScoresOrg, c.editScores, c.sort, c.custom FROM c where c.scorecalcId = '{id}' and c.type = 'lessonrecord' ";
  290. List<ScoreCalcLsRecord> scoreCalcLsRecord = new List<ScoreCalcLsRecord>();
  291. await foreach (var item in client.GetItemQueryIterator<ScoreCalcLsRecord>(queryText: sql_LessonRecordItems))
  292. {
  293. scoreCalcLsRecord.Add(item);
  294. }
  295. #endregion
  296. #region ====取得公式的資料===
  297. string sql_FuncItems = $"SELECT c.id, c.code, c.name, c.scorecalcActId, c.type, c.method, c.template, c.keyvals, c.content from c where c.code = '{scoreCalcLsRecord[0].code.Replace("ScoreCalcAct", "ScoreCalcActFormula")}' and c.scorecalcActId = '{scoreCalcLsRecord[0].id}'";
  298. await foreach (var item in client.GetItemQueryIterator<ScoreCalcFunc>(queryText: sql_FuncItems))
  299. {
  300. scoreCalcFunc.Add(item);
  301. }
  302. #endregion
  303. #region====整理課堂紀錄回傳格式===
  304. ScoreCalcLsRecordActDto scoreCalcLsRecordActDto = new ScoreCalcLsRecordActDto();
  305. scoreCalcLsRecordActDto.id = scoreCalcLsRecord[0].id;
  306. scoreCalcLsRecordActDto.name = scoreCalcLsRecord[0].name;
  307. scoreCalcLsRecordActDto.type = scoreCalcLsRecord[0].type;
  308. scoreCalcLsRecordActDto.attendRate = scoreCalcLsRecord[0].attendRate;
  309. scoreCalcLsRecordActDto.pointRate = scoreCalcLsRecord[0].pointRate;
  310. scoreCalcLsRecordActDto.itactRate = scoreCalcLsRecord[0].itactRate;
  311. scoreCalcLsRecordActDto.rate = scoreCalcLsRecord[0].rate;
  312. scoreCalcLsRecordActDto.stuAttendFunctionId = scoreCalcLsRecord[0].stuAttendFunctionId;
  313. scoreCalcLsRecordActDto.stuPointFunctionId = scoreCalcLsRecord[0].stuPointFunctionId;
  314. scoreCalcLsRecordActDto.stuItactFunctionId = scoreCalcLsRecord[0].stuItactFunctionId;
  315. scoreCalcLsRecordActDto.sort = scoreCalcLsRecord[0].sort;
  316. #region====整理出席狀態資料===
  317. // 先塞入學生數量的出席狀態物件
  318. List<AttendStatesCalc> listAttendStatesCalc = new List<AttendStatesCalc>();
  319. for (int i = 0; i < members.Count; i++)
  320. {
  321. AttendStatesCalc attendStatesCalc = new AttendStatesCalc();
  322. attendStatesCalc.Absent = 0;
  323. attendStatesCalc.Absent_Sick = 0;
  324. attendStatesCalc.Absent_Personal = 0;
  325. attendStatesCalc.Absent_Official = 0;
  326. listAttendStatesCalc.Add(attendStatesCalc);
  327. }
  328. for (int i = 0; i < scoreCalcLsRecord[0].stuActAttendScores.Count; i++)
  329. {
  330. if (scoreCalcLsRecord[0].items[i].use)
  331. {// 如果是有勾選的才列入統計
  332. for (int j = 0; j < scoreCalcLsRecord[0].stuActAttendScores[i].Count; j++)
  333. {
  334. switch (scoreCalcLsRecord[0].stuActAttendScores[i][j])
  335. {
  336. //Absent,2(缺席)
  337. //DayOff,3(請假)
  338. //Absent_Sick,4(病假)
  339. //Absent_Personal,5(事假)
  340. //Absent_Official,6(公假)
  341. case 2:
  342. listAttendStatesCalc[j].Absent = listAttendStatesCalc[j].Absent + 1;
  343. break;
  344. case 4:
  345. listAttendStatesCalc[j].Absent_Sick = listAttendStatesCalc[j].Absent_Sick + 1;
  346. break;
  347. case 5:
  348. listAttendStatesCalc[j].Absent_Personal = listAttendStatesCalc[j].Absent_Personal + 1;
  349. break;
  350. case 6:
  351. listAttendStatesCalc[j].Absent_Official = listAttendStatesCalc[j].Absent_Official + 1;
  352. break;
  353. }
  354. }
  355. }
  356. }
  357. #endregion
  358. scoreCalcLsRecordActDto.attendStates = listAttendStatesCalc;
  359. for (int i = 0; i < scoreCalcLsRecord[0].items.Count; i++)
  360. {
  361. SubActLsRecord subActLsRecord = new SubActLsRecord();
  362. subActLsRecord.id = scoreCalcLsRecord[0].items[i].id;
  363. subActLsRecord.name = scoreCalcLsRecord[0].items[i].name;
  364. subActLsRecord.startTime = scoreCalcLsRecord[0].items[i].createTime;
  365. // 子項目比重由外層取得
  366. subActLsRecord.rate = scoreCalcLsRecord[0].itemRates[i];
  367. subActLsRecord.use = scoreCalcLsRecord[0].items[i].use;
  368. subActLsRecord.sort = scoreCalcLsRecord[0].items[i].sort;
  369. subActLsRecord.custom = scoreCalcLsRecord[0].items[i].custom;
  370. // 子項目 出席 / 記分板 / 互動 成績由外層取得
  371. subActLsRecord.stuActAttendScores = scoreCalcLsRecord[0].stuActAttendScores[i];
  372. subActLsRecord.stuActPointScores = scoreCalcLsRecord[0].stuActPointScores[i];
  373. subActLsRecord.stuActItactScores = scoreCalcLsRecord[0].stuActItactScores[i];
  374. scoreCalcLsRecordActDto.items.Add(subActLsRecord);
  375. }
  376. scoreCalcLsRecordActDto.editScores = scoreCalcLsRecord[0].editScores;
  377. scoreCalcAct.Add(scoreCalcLsRecordActDto);
  378. #endregion
  379. #region====整理非課堂紀錄回傳格式===
  380. for (int i = 0; i < scoreCalcActivity.Count; i++)
  381. {
  382. ScoreCalcActivityActDto scoreCalcActivityActDto = new ScoreCalcActivityActDto();
  383. scoreCalcActivityActDto.id = scoreCalcActivity[i].id;
  384. scoreCalcActivityActDto.name = scoreCalcActivity[i].name;
  385. scoreCalcActivityActDto.type = scoreCalcActivity[i].type;
  386. scoreCalcActivityActDto.rate = scoreCalcActivity[i].rate;
  387. scoreCalcActivityActDto.sort = scoreCalcActivity[i].sort;
  388. for (int j = 0; j < scoreCalcActivity[i].items.Count; j++)
  389. {
  390. SubActActivity subActActivity = new SubActActivity();
  391. subActActivity.id = scoreCalcActivity[i].items[j].id;
  392. subActActivity.name = scoreCalcActivity[i].items[j].name;
  393. subActActivity.startTime = scoreCalcActivity[i].items[j].createTime;
  394. // 子項目比重由外層取得
  395. subActActivity.rate = scoreCalcActivity[i].itemRates[j];
  396. subActActivity.use = scoreCalcActivity[i].items[j].use;
  397. subActActivity.sort = scoreCalcActivity[i].items[j].sort;
  398. subActActivity.custom = scoreCalcActivity[i].items[j].custom;
  399. subActActivity.scores = scoreCalcActivity[i].stuActScores[j];
  400. scoreCalcActivityActDto.items.Add(subActActivity);
  401. }
  402. scoreCalcActivityActDto.editScores = scoreCalcActivity[i].editScores;
  403. scoreCalcAct.Add(scoreCalcActivityActDto);
  404. }
  405. #endregion
  406. #region ====取得學生資料===
  407. string sql_editScores = $"select c.editScores from c where c.id = '{id}'";
  408. List<EditScores> editScores = new List<EditScores>();
  409. await foreach (var item in client.GetItemQueryIterator<EditScores>(queryText: sql_editScores))
  410. {
  411. editScores.Add(item);
  412. }
  413. if (editScores.Count == 0)
  414. {
  415. editScores.Add(new EditScores());
  416. }
  417. #endregion
  418. #region ====取得建立資料===
  419. string sql_createTime = $"select c.createTime from c where c.id = '{id}'";
  420. List<ScoreCalcBase> scoreCalcBase = new List<ScoreCalcBase>();
  421. await foreach (var item in client.GetItemQueryIterator<ScoreCalcBase>(queryText: sql_createTime))
  422. {
  423. scoreCalcBase.Add(item);
  424. }
  425. long? createTime = 0;
  426. if (scoreCalcBase.Count > 0)
  427. {
  428. createTime = scoreCalcBase[0].createTime;
  429. }
  430. #endregion
  431. var result = new
  432. {
  433. members = members,
  434. scoreCalcAct = scoreCalcAct,
  435. scoreCalcFunc = scoreCalcFunc,
  436. editScores = editScores[0].editScores,
  437. createTime = createTime
  438. };
  439. return Ok(result);
  440. }
  441. catch (Exception e)
  442. {
  443. //await _dingDing.SendBotMsg($"OS,{_option.Location},open-api/upsert()\n{e.Message}\n{e.StackTrace}\n{e.StackTrace}", GroupNames.醍摩豆服務運維群組);
  444. return BadRequest();
  445. }
  446. }
  447. /// <summary>
  448. /// (三)新增成績統計列(包含預設公式)
  449. /// </summary>
  450. /// <param name="request"></param>
  451. /// <returns></returns>
  452. [ProducesDefaultResponseType]
  453. [Authorize(Roles = "IES")]
  454. [HttpPost("add-scorecalc")]
  455. public async Task<IActionResult> AddSscoreCalc(JsonElement request)
  456. {
  457. try
  458. {
  459. if (!request.TryGetProperty("courseId", out JsonElement courseId)) return BadRequest();
  460. if (!request.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
  461. bool ishaveClassId = request.TryGetProperty("classId", out JsonElement classId);
  462. bool ishaveGrouplistId = request.TryGetProperty("grouplistId", out JsonElement grouplistId);
  463. ishaveClassId = !string.IsNullOrWhiteSpace(classId + "");
  464. ishaveGrouplistId = !string.IsNullOrWhiteSpace(grouplistId + "");
  465. bool ishaveTeammodelId = request.TryGetProperty("teammodelId", out JsonElement teammodelId);
  466. bool ishaveSchoolId = request.TryGetProperty("schoolId", out JsonElement schoolId);
  467. if ((schoolId + "") == "SYSTEM_NO_SCHOOL" || string.IsNullOrWhiteSpace(schoolId + ""))
  468. {
  469. ishaveSchoolId = false;
  470. }
  471. bool ishaveSubjectId = request.TryGetProperty("subjectId", out JsonElement subjectId);
  472. ishaveSubjectId = !string.IsNullOrWhiteSpace(subjectId + "");
  473. bool ishaveName = request.TryGetProperty("name", out JsonElement name);
  474. ishaveName = !string.IsNullOrWhiteSpace(name + "");
  475. request.TryGetProperty("year", out JsonElement _year);
  476. bool ishaveYear = !string.IsNullOrWhiteSpace(_year + "");
  477. string year = "0";
  478. request.TryGetProperty("copyid", out JsonElement copyid);
  479. bool ishaveCopyid = !string.IsNullOrWhiteSpace(copyid + "");
  480. // classId 跟 grouplistId 兩個必須有一個必填
  481. if (!ishaveClassId)
  482. {
  483. if (!ishaveGrouplistId)
  484. {
  485. return BadRequest();
  486. }
  487. else
  488. {
  489. if (!ishaveTeammodelId) return BadRequest();
  490. }
  491. }
  492. else
  493. {
  494. if (!ishaveSchoolId) return BadRequest();
  495. }
  496. if (ishaveSchoolId)
  497. {
  498. if (!ishaveYear) { return BadRequest(); }
  499. else { year = _year + ""; }
  500. }
  501. // 設定活動預設值
  502. ScoreCalcLsRecord scoreCalcLsRecord = new ScoreCalcLsRecord();
  503. ScoreCalcActivity scoreCalcActivity_eaxm = new ScoreCalcActivity();
  504. ScoreCalcActivity scoreCalcActivity_homework = new ScoreCalcActivity();
  505. ScoreCalcLsRecord scoreCalcLsRecord_copy = new ScoreCalcLsRecord();
  506. List<ScoreCalcActivity> scoreCalcActivity_copyList = new List<ScoreCalcActivity>();
  507. string lessonRecordid_copy = "";
  508. var clientTeacher = _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher);
  509. ////班級
  510. List<ScoreCalcMember> members = new List<ScoreCalcMember>();
  511. #region ==== 1~4. 取出系統資料====
  512. var isOKRequest = await getSystemScoresDate(courseId, scope, classId, grouplistId, teammodelId, schoolId, subjectId, ishaveClassId, ishaveGrouplistId, ishaveSubjectId, members, scoreCalcLsRecord, scoreCalcActivity_eaxm, scoreCalcActivity_homework);
  513. if (!isOKRequest) { return BadRequest(); }
  514. //// 根據學生數量設定加減分預設值陣列
  515. List<double> editScores = new List<double>();
  516. for (int j = 0; j < members.Count; j++)
  517. {
  518. editScores.Add(0);
  519. }
  520. #endregion
  521. #region ==== 5. 寫入成績統計資料====
  522. #region ==== 5.1 寫入成績統計主表 ScoreCalc====
  523. ScoreCalcBase scoreCalcBase = new ScoreCalcBase();
  524. scoreCalcBase.name = ishaveName ? (name + "") : "新成績表";
  525. scoreCalcBase.courseId = courseId.ToString();
  526. scoreCalcBase.classId = classId.ToString();
  527. scoreCalcBase.grouplistId = grouplistId.ToString();
  528. scoreCalcBase.members = members;
  529. scoreCalcBase.editScores = editScores;
  530. scoreCalcBase.rateType = "percentage";
  531. scoreCalcBase.id = Guid.NewGuid().ToString();
  532. scoreCalcBase.code = scoreCalcBase.pk + "-" + teammodelId;
  533. scoreCalcBase.year = Convert.ToInt32(year);
  534. scoreCalcBase.createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  535. //取得目前成績統計總數
  536. int count = 0;
  537. string sql = "";
  538. if (!ishaveClassId)
  539. {
  540. sql = $"SELECT c.id FROM c where c.courseId = '{courseId}' and c.grouplistId = '{grouplistId}' ";
  541. }
  542. else
  543. {
  544. sql = $"SELECT c.id FROM c where c.courseId = '{courseId}' and c.classId = '{classId}' ";
  545. }
  546. await foreach (var item in clientTeacher.GetItemQueryIterator<ItemId>(queryText: sql))
  547. {
  548. count++;
  549. }
  550. scoreCalcBase.sort = count + 1;
  551. scoreCalcBase = await clientTeacher.CreateItemAsync(scoreCalcBase, new PartitionKey($"{scoreCalcBase.code}"));
  552. #endregion
  553. #region ==== 5.2 用ScoreCalc的id 寫入成績統計項目表ScoreCalcAct====
  554. #region ==== 5.2.1 寫入課堂紀錄====
  555. scoreCalcLsRecord.id = Guid.NewGuid().ToString();
  556. scoreCalcLsRecord.scorecalcId = scoreCalcBase.id;
  557. scoreCalcLsRecord.name = "課堂紀錄";
  558. scoreCalcLsRecord.type = "lessonrecord";
  559. scoreCalcLsRecord.rate = 40;
  560. scoreCalcLsRecord.attendRate = 40;
  561. scoreCalcLsRecord.pointRate = 30;
  562. scoreCalcLsRecord.itactRate = 30;
  563. scoreCalcLsRecord.stuAttendFunctionId = Guid.NewGuid().ToString();
  564. scoreCalcLsRecord.stuPointFunctionId = Guid.NewGuid().ToString();
  565. scoreCalcLsRecord.stuItactFunctionId = Guid.NewGuid().ToString();
  566. for (int j = 0; j < scoreCalcLsRecord.items.Count; j++)
  567. {
  568. scoreCalcLsRecord.itemRates.Add(1);
  569. scoreCalcLsRecord.items[j].sort = j + 1;
  570. scoreCalcLsRecord.items[j].custom = false;
  571. }
  572. scoreCalcLsRecord.editScores = editScores;
  573. scoreCalcLsRecord.code = scoreCalcLsRecord.pk + "-" + teammodelId;
  574. scoreCalcLsRecord.sort = 1;
  575. //scoreCalcAct.Add(scoreCalcLsRecord);
  576. #endregion
  577. #region ==== 5.2.2 寫入評量活動====
  578. scoreCalcActivity_eaxm.id = Guid.NewGuid().ToString();
  579. scoreCalcActivity_eaxm.scorecalcId = scoreCalcBase.id;
  580. scoreCalcActivity_eaxm.name = "評量活動";
  581. scoreCalcActivity_eaxm.type = "exam";
  582. scoreCalcActivity_eaxm.rate = 30;
  583. scoreCalcActivity_eaxm.sort = 2;
  584. for (int j = 0; j < scoreCalcActivity_eaxm.items.Count; j++)
  585. {
  586. scoreCalcActivity_eaxm.itemRates.Add(1);
  587. scoreCalcActivity_eaxm.items[j].sort = j + 1;
  588. scoreCalcActivity_eaxm.items[j].custom = false;
  589. }
  590. scoreCalcActivity_eaxm.editScores = editScores;
  591. scoreCalcActivity_eaxm.code = scoreCalcActivity_eaxm.pk + "-" + teammodelId;
  592. //scoreCalcAct.Add(scoreCalcActivity_eaxm);
  593. #endregion
  594. #region ==== 5.2.3 寫入作業活動====
  595. scoreCalcActivity_homework.id = Guid.NewGuid().ToString();
  596. scoreCalcActivity_homework.scorecalcId = scoreCalcBase.id;
  597. scoreCalcActivity_homework.name = "作業活動";
  598. scoreCalcActivity_homework.type = "homework";
  599. scoreCalcActivity_homework.rate = 30;
  600. scoreCalcActivity_homework.sort = 3;
  601. for (int j = 0; j < scoreCalcActivity_homework.items.Count; j++)
  602. {
  603. scoreCalcActivity_homework.itemRates.Add(1);
  604. scoreCalcActivity_homework.items[j].sort = j + 1;
  605. scoreCalcActivity_homework.items[j].custom = false;
  606. }
  607. scoreCalcActivity_homework.editScores = editScores;
  608. scoreCalcActivity_homework.code = scoreCalcActivity_homework.pk + "-" + teammodelId;
  609. //scoreCalcAct.Add(scoreCalcActivity_homework);
  610. #endregion
  611. bool isCopyMode = true;
  612. /* 複製的邏輯
  613. 1. 大項目的百分比
  614. 2. 自訂項目
  615. 3. 自定子項目(不包含分數、比重)
  616. */
  617. if (ishaveCopyid)
  618. {
  619. // 如果有複製id,需要取指定id的成績統計來複製一些設定
  620. string sql_copy = $"SELECT * FROM c where c.scorecalcId = '{copyid}'";
  621. List<ScoreCalcActivityBase> scoreCalcActivityBaseList_copy = new List<ScoreCalcActivityBase>();
  622. await foreach (var item in clientTeacher.GetItemQueryIterator<ScoreCalcActivityBase>(queryText: sql_copy))
  623. {
  624. scoreCalcActivityBaseList_copy.Add(item);
  625. }
  626. if (scoreCalcActivityBaseList_copy.Count > 0)
  627. {
  628. // 如果有複製id 要複製目標的百分比
  629. // 根據學生數量設定預設值
  630. List<double> zeroScores = new List<double>();
  631. for (int j = 0; j < scoreCalcBase.members.Count; j++)
  632. {
  633. zeroScores.Add(0);
  634. }
  635. for (int k = 0; k < scoreCalcActivityBaseList_copy.Count; k++)
  636. {
  637. switch (scoreCalcActivityBaseList_copy[k].type)
  638. {
  639. case "lessonrecord":
  640. #region ===設定課堂記錄===
  641. lessonRecordid_copy = scoreCalcActivityBaseList_copy[k].id;
  642. scoreCalcLsRecord_copy = await clientTeacher.ReadItemAsync<ScoreCalcLsRecord>(lessonRecordid_copy, new PartitionKey($"ScoreCalcAct-{teammodelId}"));
  643. scoreCalcLsRecord.rate = scoreCalcLsRecord_copy.rate;
  644. scoreCalcLsRecord.attendRate = scoreCalcLsRecord_copy.attendRate;
  645. scoreCalcLsRecord.pointRate = scoreCalcLsRecord_copy.pointRate;
  646. scoreCalcLsRecord.itactRate = scoreCalcLsRecord_copy.itactRate;
  647. for (int i = 0; i < scoreCalcLsRecord_copy.items.Count; i++)
  648. {
  649. if (scoreCalcLsRecord_copy.items[i].custom == true)
  650. {// 如果複製的目標有自訂子項目 要多設定子項目的預設資料
  651. scoreCalcLsRecord_copy.items[i].sort = scoreCalcLsRecord.items.Count + 1;
  652. scoreCalcLsRecord_copy.items[i].id = Guid.NewGuid().ToString();
  653. scoreCalcLsRecord_copy.items[i].use = false;
  654. scoreCalcLsRecord_copy.items[i].createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  655. scoreCalcLsRecord.items.Add(scoreCalcLsRecord_copy.items[i]);
  656. scoreCalcLsRecord.stuActAttendOrgVals.Add(zeroScores);
  657. scoreCalcLsRecord.stuActAttendScores.Add(zeroScores);
  658. scoreCalcLsRecord.stuActPointOrgVals.Add(zeroScores);
  659. scoreCalcLsRecord.stuActPointScores.Add(zeroScores);
  660. scoreCalcLsRecord.stuActItactOrgVals.Add(zeroScores);
  661. scoreCalcLsRecord.stuActItactScores.Add(zeroScores);
  662. scoreCalcLsRecord.itemRates.Add(1);
  663. }
  664. }
  665. scoreCalcLsRecord = await clientTeacher.CreateItemAsync(scoreCalcLsRecord, new PartitionKey($"{scoreCalcLsRecord.code}"));
  666. #endregion
  667. break;
  668. case "homework":
  669. // ===設定作業活動===
  670. await setCopyAct(scoreCalcActivityBaseList_copy[k].id, teammodelId, scoreCalcActivity_homework, zeroScores);
  671. scoreCalcActivity_homework = await clientTeacher.CreateItemAsync(scoreCalcActivity_homework, new PartitionKey($"{scoreCalcActivity_homework.code}"));
  672. break;
  673. case "exam":
  674. // ===設定評量活動===
  675. await setCopyAct(scoreCalcActivityBaseList_copy[k].id, teammodelId, scoreCalcActivity_eaxm, zeroScores);
  676. scoreCalcActivity_eaxm = await clientTeacher.CreateItemAsync(scoreCalcActivity_eaxm, new PartitionKey($"{scoreCalcActivity_eaxm.code}"));
  677. break;
  678. case "custom":
  679. // ===自訂項目===
  680. ScoreCalcActivity scoreCalcActivity = new ScoreCalcActivity();
  681. scoreCalcActivity.id = Guid.NewGuid().ToString();
  682. scoreCalcActivity.scorecalcId = scoreCalcBase.id;
  683. scoreCalcActivity.name = scoreCalcActivityBaseList_copy[k].name;
  684. scoreCalcActivity.type = scoreCalcActivityBaseList_copy[k].type;
  685. scoreCalcActivity.rate = scoreCalcActivityBaseList_copy[k].rate;
  686. scoreCalcActivity.sort = scoreCalcActivityBaseList_copy[k].sort;
  687. scoreCalcActivity.editScores = editScores;
  688. scoreCalcActivity.code = scoreCalcActivityBaseList_copy[k].pk + "-" + teammodelId;
  689. await setCopyAct(scoreCalcActivityBaseList_copy[k].id, teammodelId, scoreCalcActivity, zeroScores);
  690. // 新增項目及子項目
  691. scoreCalcActivity = await clientTeacher.CreateItemAsync(scoreCalcActivity, new PartitionKey($"{scoreCalcActivity.pk + "-" + teammodelId}"));
  692. break;
  693. }
  694. }
  695. }
  696. else
  697. {// 沒有複製id的資料 走原本的新增動作
  698. isCopyMode = false;
  699. }
  700. }
  701. else
  702. {// 沒有複製id 走原本的新增動作
  703. isCopyMode = false;
  704. }
  705. if (!isCopyMode) // 不是複製模式 走原本的新增動作
  706. {
  707. scoreCalcLsRecord = await clientTeacher.CreateItemAsync(scoreCalcLsRecord, new PartitionKey($"{scoreCalcLsRecord.code}"));
  708. scoreCalcActivity_eaxm = await clientTeacher.CreateItemAsync(scoreCalcActivity_eaxm, new PartitionKey($"{scoreCalcActivity_eaxm.code}"));
  709. scoreCalcActivity_homework = await clientTeacher.CreateItemAsync(scoreCalcActivity_homework, new PartitionKey($"{scoreCalcActivity_homework.code}"));
  710. }
  711. #endregion
  712. #region ==== 5.3 用ScoreCalcAct的id 寫入課堂紀錄公式表ScoreCalcActFormula====
  713. if (ishaveCopyid)
  714. {// 如果有複製id 要用複製的成績統計的公式資料寫入DB
  715. string sql_FormulaCopy = $"SELECT * FROM c where c.scorecalcActId = '{lessonRecordid_copy}'";
  716. List<ScoreCalcFunc> scoreCalcFuncList_copy = new List<ScoreCalcFunc>();
  717. await foreach (var item in clientTeacher.GetItemQueryIterator<ScoreCalcFunc>(queryText: sql_FormulaCopy))
  718. {
  719. scoreCalcFuncList_copy.Add(item);
  720. }
  721. for (int i = 0; i < scoreCalcFuncList_copy.Count; i++)
  722. {
  723. switch (scoreCalcFuncList_copy[i].method)
  724. {
  725. case "attend":
  726. if (scoreCalcFuncList_copy[i].id == scoreCalcLsRecord_copy.stuAttendFunctionId)
  727. {// 如果此筆資料是複製目標之前指定的公式 就要指定成這次的使用公式
  728. scoreCalcFuncList_copy[i].id = scoreCalcLsRecord.stuAttendFunctionId;
  729. }
  730. else { scoreCalcFuncList_copy[i].id = Guid.NewGuid().ToString(); }
  731. break;
  732. case "point":
  733. if (scoreCalcFuncList_copy[i].id == scoreCalcLsRecord_copy.stuPointFunctionId)
  734. {// 如果此筆資料是複製目標之前指定的公式 就要指定成這次的使用公式
  735. scoreCalcFuncList_copy[i].id = scoreCalcLsRecord.stuPointFunctionId;
  736. }
  737. else { scoreCalcFuncList_copy[i].id = Guid.NewGuid().ToString(); }
  738. break;
  739. case "interaction":
  740. if (scoreCalcFuncList_copy[i].id == scoreCalcLsRecord_copy.stuItactFunctionId)
  741. {// 如果此筆資料是複製目標之前指定的公式 就要指定成這次的使用公式
  742. scoreCalcFuncList_copy[i].id = scoreCalcLsRecord.stuItactFunctionId;
  743. }
  744. else { scoreCalcFuncList_copy[i].id = Guid.NewGuid().ToString(); }
  745. break;
  746. }
  747. scoreCalcFuncList_copy[i].scorecalcActId = scoreCalcLsRecord.id;
  748. scoreCalcFuncList_copy[i] = await clientTeacher.CreateItemAsync(scoreCalcFuncList_copy[i], new PartitionKey($"{scoreCalcFuncList_copy[i].code}"));
  749. }
  750. }
  751. else
  752. {// 一般新增流程 新增公式
  753. #region ==== 出席-簡單出席計算法====
  754. ScoreCalcFunc scoreCalcFunc_simpleAttend = new ScoreCalcFunc();
  755. scoreCalcFunc_simpleAttend.code = scoreCalcFunc_simpleAttend.pk + "-" + teammodelId;
  756. scoreCalcFunc_simpleAttend.id = scoreCalcLsRecord.stuAttendFunctionId;
  757. scoreCalcFunc_simpleAttend.name = "簡單出席計算法";
  758. scoreCalcFunc_simpleAttend.scorecalcActId = scoreCalcLsRecord.id;
  759. scoreCalcFunc_simpleAttend.type = "lessonrecord";
  760. scoreCalcFunc_simpleAttend.method = "attend";
  761. scoreCalcFunc_simpleAttend.template = "simpleAttend";
  762. scoreCalcFunc_simpleAttend.keyvals.Add(new ScoreCalcFuncTemplateKeyval() { key = "一次扣幾分", val = "5" });
  763. scoreCalcFunc_simpleAttend.keyvals.Add(new ScoreCalcFuncTemplateKeyval() { key = "Absent_Sick", val = "true" });
  764. scoreCalcFunc_simpleAttend.keyvals.Add(new ScoreCalcFuncTemplateKeyval() { key = "Absent", val = "true" });
  765. scoreCalcFunc_simpleAttend.keyvals.Add(new ScoreCalcFuncTemplateKeyval() { key = "Absent_Personal", val = "true" });
  766. scoreCalcFunc_simpleAttend.keyvals.Add(new ScoreCalcFuncTemplateKeyval() { key = "Absent_Official", val = "true" });
  767. scoreCalcFunc_simpleAttend.content = " 100 - ( ( 病假次數 + 缺席次數 + 事假次數 + 公假次數 ) * 一次扣幾分 ) ";
  768. #endregion
  769. #region ==== 出席-出席率計算法====
  770. ScoreCalcFunc scoreCalcFunc_attendRate = new ScoreCalcFunc();
  771. scoreCalcFunc_attendRate.code = scoreCalcFunc_attendRate.pk + "-" + teammodelId;
  772. scoreCalcFunc_attendRate.id = Guid.NewGuid().ToString();
  773. scoreCalcFunc_attendRate.name = "出席率計算法";
  774. scoreCalcFunc_attendRate.scorecalcActId = scoreCalcLsRecord.id;
  775. scoreCalcFunc_attendRate.type = "lessonrecord";
  776. scoreCalcFunc_attendRate.method = "attend";
  777. scoreCalcFunc_attendRate.template = "attendRate";
  778. scoreCalcFunc_attendRate.keyvals.Add(new ScoreCalcFuncTemplateKeyval() { key = "每缺席1%扣幾分", val = "1" });
  779. scoreCalcFunc_attendRate.keyvals.Add(new ScoreCalcFuncTemplateKeyval() { key = "出席率超過%為滿分", val = "90" });
  780. scoreCalcFunc_attendRate.keyvals.Add(new ScoreCalcFuncTemplateKeyval() { key = "課堂總次數", val = "X" });
  781. scoreCalcFunc_attendRate.keyvals.Add(new ScoreCalcFuncTemplateKeyval() { key = "Absent_Sick", val = "true" });
  782. scoreCalcFunc_attendRate.keyvals.Add(new ScoreCalcFuncTemplateKeyval() { key = "Absent", val = "true" });
  783. scoreCalcFunc_attendRate.keyvals.Add(new ScoreCalcFuncTemplateKeyval() { key = "Absent_Personal", val = "true" });
  784. scoreCalcFunc_attendRate.keyvals.Add(new ScoreCalcFuncTemplateKeyval() { key = "Absent_Official", val = "true" });
  785. scoreCalcFunc_attendRate.content = " 100 - ( 出席率超過%為滿分 – ( ( 課堂總次數 - 病假次數 - 缺席次數 - 事假次數 - 公假次數 )/ 課堂總次數 * 100 ) ) * 每缺席1%扣幾分 ";
  786. #endregion
  787. #region ==== 記分板-標準化評分====
  788. ScoreCalcFunc scoreCalcFunc_standard = new ScoreCalcFunc();
  789. scoreCalcFunc_standard.code = scoreCalcFunc_standard.pk + "-" + teammodelId;
  790. scoreCalcFunc_standard.id = scoreCalcLsRecord.stuPointFunctionId;
  791. scoreCalcFunc_standard.name = "標準化評分";
  792. scoreCalcFunc_standard.scorecalcActId = scoreCalcLsRecord.id;
  793. scoreCalcFunc_standard.type = "lessonrecord";
  794. scoreCalcFunc_standard.method = "point";
  795. scoreCalcFunc_standard.template = "standard";
  796. scoreCalcFunc_standard.keyvals.Add(new ScoreCalcFuncTemplateKeyval() { key = "原始分數", val = "X" });
  797. scoreCalcFunc_standard.keyvals.Add(new ScoreCalcFuncTemplateKeyval() { key = "平均分數", val = "Y" });
  798. scoreCalcFunc_standard.keyvals.Add(new ScoreCalcFuncTemplateKeyval() { key = "平均數", val = "50" });
  799. scoreCalcFunc_standard.keyvals.Add(new ScoreCalcFuncTemplateKeyval() { key = "標準差", val = "50" });
  800. scoreCalcFunc_standard.content = " 10 * ( ( 原始分數 - 平均分數 ) / 標準差 ) + 平均數 ";
  801. #endregion
  802. #region ==== 記分板-百分比評分====
  803. ScoreCalcFunc scoreCalcFunc_percent = new ScoreCalcFunc();
  804. scoreCalcFunc_percent.code = scoreCalcFunc_percent.pk + "-" + teammodelId;
  805. scoreCalcFunc_percent.id = Guid.NewGuid().ToString();
  806. scoreCalcFunc_percent.name = "百分比評分";
  807. scoreCalcFunc_percent.scorecalcActId = scoreCalcLsRecord.id;
  808. scoreCalcFunc_percent.type = "lessonrecord";
  809. scoreCalcFunc_percent.method = "point";
  810. scoreCalcFunc_percent.template = "percent";
  811. scoreCalcFunc_percent.keyvals.Add(new ScoreCalcFuncTemplateKeyval() { key = "原始分數", val = "X" });
  812. scoreCalcFunc_percent.keyvals.Add(new ScoreCalcFuncTemplateKeyval() { key = "最高分數", val = "Y" });
  813. scoreCalcFunc_percent.content = " 100 * ( 原始分數 / 最高分數 )";
  814. #endregion
  815. #region ==== 互動-標準化評分====
  816. ScoreCalcFunc scoreCalcFunc_standard_interaction = new ScoreCalcFunc();
  817. scoreCalcFunc_standard_interaction.code = scoreCalcFunc_standard_interaction.pk + "-" + teammodelId;
  818. scoreCalcFunc_standard_interaction.id = scoreCalcLsRecord.stuItactFunctionId;
  819. scoreCalcFunc_standard_interaction.name = "標準化評分";
  820. scoreCalcFunc_standard_interaction.scorecalcActId = scoreCalcLsRecord.id;
  821. scoreCalcFunc_standard_interaction.type = "lessonrecord";
  822. scoreCalcFunc_standard_interaction.method = "interaction";
  823. scoreCalcFunc_standard_interaction.template = "standard";
  824. scoreCalcFunc_standard_interaction.keyvals.Add(new ScoreCalcFuncTemplateKeyval() { key = "原始分數", val = "X" });
  825. scoreCalcFunc_standard_interaction.keyvals.Add(new ScoreCalcFuncTemplateKeyval() { key = "平均分數", val = "Y" });
  826. scoreCalcFunc_standard_interaction.keyvals.Add(new ScoreCalcFuncTemplateKeyval() { key = "平均數", val = "50" });
  827. scoreCalcFunc_standard_interaction.keyvals.Add(new ScoreCalcFuncTemplateKeyval() { key = "標準差", val = "50" });
  828. scoreCalcFunc_standard_interaction.content = " 10 * ( ( 原始分數 - 平均分數 ) / 標準差 ) + 平均數 ";
  829. #endregion
  830. #region ==== 互動-百分比評分====
  831. ScoreCalcFunc scoreCalcFunc_percent_interaction = new ScoreCalcFunc();
  832. scoreCalcFunc_percent_interaction.code = scoreCalcFunc_percent_interaction.pk + "-" + teammodelId;
  833. scoreCalcFunc_percent_interaction.id = Guid.NewGuid().ToString();
  834. scoreCalcFunc_percent_interaction.name = "百分比評分";
  835. scoreCalcFunc_percent_interaction.scorecalcActId = scoreCalcLsRecord.id;
  836. scoreCalcFunc_percent_interaction.type = "lessonrecord";
  837. scoreCalcFunc_percent_interaction.method = "interaction";
  838. scoreCalcFunc_percent_interaction.template = "percent";
  839. scoreCalcFunc_percent_interaction.keyvals.Add(new ScoreCalcFuncTemplateKeyval() { key = "原始分數", val = "X" });
  840. scoreCalcFunc_percent_interaction.keyvals.Add(new ScoreCalcFuncTemplateKeyval() { key = "最高分數", val = "Y" });
  841. scoreCalcFunc_percent_interaction.content = " 100 * ( 原始分數 / 最高分數 )";
  842. #endregion
  843. scoreCalcFunc_simpleAttend = await clientTeacher.CreateItemAsync(scoreCalcFunc_simpleAttend, new PartitionKey($"{scoreCalcFunc_simpleAttend.code}"));
  844. scoreCalcFunc_attendRate = await clientTeacher.CreateItemAsync(scoreCalcFunc_attendRate, new PartitionKey($"{scoreCalcFunc_attendRate.code}"));
  845. scoreCalcFunc_standard = await clientTeacher.CreateItemAsync(scoreCalcFunc_standard, new PartitionKey($"{scoreCalcFunc_standard.code}"));
  846. scoreCalcFunc_percent = await clientTeacher.CreateItemAsync(scoreCalcFunc_percent, new PartitionKey($"{scoreCalcFunc_percent.code}"));
  847. scoreCalcFunc_standard_interaction = await clientTeacher.CreateItemAsync(scoreCalcFunc_standard_interaction, new PartitionKey($"{scoreCalcFunc_standard_interaction.code}"));
  848. scoreCalcFunc_percent_interaction = await clientTeacher.CreateItemAsync(scoreCalcFunc_percent_interaction, new PartitionKey($"{scoreCalcFunc_percent_interaction.code}"));
  849. }
  850. #endregion
  851. #endregion
  852. var result = new
  853. {
  854. id = scoreCalcBase.id
  855. };
  856. return Ok(result);
  857. }
  858. catch (Exception e)
  859. {
  860. //await _dingDing.SendBotMsg($"OS,{_option.Location},open-api/upsert()\n{e.Message}\n{e.StackTrace}\n{e.StackTrace}", GroupNames.醍摩豆服務運維群組);
  861. return BadRequest();
  862. }
  863. }
  864. private async Task<ScoreCalcActivity> setCopyAct(string id, JsonElement teammodelId, ScoreCalcActivity scoreCalcActivity, List<double> zeroScores)
  865. {
  866. var clientTeacher = _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher);
  867. ScoreCalcActivity scoreCalcActivity_copy = await clientTeacher.ReadItemAsync<ScoreCalcActivity>(id, new PartitionKey($"ScoreCalcAct-{teammodelId}"));
  868. scoreCalcActivity.rate = scoreCalcActivity_copy.rate;
  869. for (int i = 0; i < scoreCalcActivity_copy.items.Count; i++)
  870. {
  871. if (scoreCalcActivity_copy.items[i].custom == true)
  872. {// 如果複製的目標有自訂子項目 要多設定子項目的預設資料
  873. scoreCalcActivity_copy.items[i].sort = scoreCalcActivity.items.Count + 1;
  874. scoreCalcActivity_copy.items[i].id = Guid.NewGuid().ToString();
  875. scoreCalcActivity_copy.items[i].use = false;
  876. scoreCalcActivity_copy.items[i].createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  877. scoreCalcActivity.items.Add(scoreCalcActivity_copy.items[i]);
  878. scoreCalcActivity.stuActScores.Add(zeroScores);
  879. scoreCalcActivity.stuActScoresOrg.Add(zeroScores);
  880. scoreCalcActivity.itemRates.Add(1);
  881. }
  882. }
  883. return scoreCalcActivity;
  884. }
  885. /// <summary>
  886. /// (四)更新成績統計首頁表資料
  887. /// </summary>
  888. /// <param name="request"></param>
  889. /// <returns></returns>
  890. [ProducesDefaultResponseType]
  891. [Authorize(Roles = "IES")]
  892. [HttpPost("update-scorecalc")]
  893. public async Task<IActionResult> UpdateSscoreCalc(JsonElement request)
  894. {
  895. List<Object> scoreCalc = new List<object>();
  896. try
  897. {
  898. if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
  899. if (!request.TryGetProperty("teammodelId", out JsonElement teammodelId)) return BadRequest();
  900. var clientTeacher = _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher);
  901. UpdateSscoreCalcRq updateSscoreCalcRq = JsonConvert.DeserializeObject<UpdateSscoreCalcRq>(request.ToString());
  902. // 取主表資料
  903. ScoreCalcBase scoreCalcBase = await clientTeacher.ReadItemAsync<ScoreCalcBase>(id.ToString(), new PartitionKey($"ScoreCalc-{teammodelId}"));
  904. scoreCalc.Add(scoreCalcBase);
  905. #region 更新主表
  906. scoreCalcBase.name = updateSscoreCalcRq.name;
  907. scoreCalcBase.editScores = updateSscoreCalcRq.editScores;
  908. scoreCalcBase = await clientTeacher.ReplaceItemAsync(scoreCalcBase, $"{scoreCalcBase.id}", new PartitionKey(scoreCalcBase.code));
  909. #endregion
  910. #region 更新項目表
  911. for (int i = 0; i < updateSscoreCalcRq.ScoreCalcAct.Count; i++)
  912. {
  913. if (updateSscoreCalcRq.ScoreCalcAct[i].type == "lessonrecord")
  914. {
  915. // 取課堂紀錄資料
  916. ScoreCalcLsRecord scoreCalcLsRecord = await clientTeacher.ReadItemAsync<ScoreCalcLsRecord>(updateSscoreCalcRq.ScoreCalcAct[i].id, new PartitionKey($"ScoreCalcAct-{teammodelId}"));
  917. scoreCalcLsRecord.rate = updateSscoreCalcRq.ScoreCalcAct[i].rate;
  918. scoreCalcLsRecord.editScores = updateSscoreCalcRq.ScoreCalcAct[i].editScores;
  919. scoreCalcLsRecord.attendRate = updateSscoreCalcRq.ScoreCalcAct[i].attendRate;
  920. scoreCalcLsRecord.pointRate = updateSscoreCalcRq.ScoreCalcAct[i].pointRate;
  921. scoreCalcLsRecord.itactRate = updateSscoreCalcRq.ScoreCalcAct[i].itactRate;
  922. scoreCalcLsRecord = await clientTeacher.ReplaceItemAsync(scoreCalcLsRecord, $"{scoreCalcLsRecord.id}", new PartitionKey(scoreCalcLsRecord.code));
  923. }
  924. else
  925. {
  926. // 取其他活動資料
  927. ScoreCalcActivity scoreCalcActivity = await clientTeacher.ReadItemAsync<ScoreCalcActivity>(updateSscoreCalcRq.ScoreCalcAct[i].id, new PartitionKey($"ScoreCalcAct-{teammodelId}"));
  928. scoreCalcActivity.rate = updateSscoreCalcRq.ScoreCalcAct[i].rate;
  929. scoreCalcActivity.editScores = updateSscoreCalcRq.ScoreCalcAct[i].editScores;
  930. scoreCalcActivity = await clientTeacher.ReplaceItemAsync(scoreCalcActivity, $"{scoreCalcActivity.id}", new PartitionKey(scoreCalcActivity.code));
  931. }
  932. }
  933. #endregion
  934. var result = new
  935. {
  936. RtCode = "0",
  937. RtMsg = "OK"
  938. };
  939. return Ok(result);
  940. }
  941. catch (Exception e)
  942. {
  943. //await _dingDing.SendBotMsg($"OS,{_option.Location},open-api/upsert()\n{e.Message}\n{e.StackTrace}\n{e.StackTrace}", GroupNames.醍摩豆服務運維群組);
  944. return BadRequest();
  945. }
  946. }
  947. /// <summary>
  948. /// (五)刪除成績統計
  949. /// </summary>
  950. /// <param name="request"></param>
  951. /// <returns></returns>
  952. [ProducesDefaultResponseType]
  953. [Authorize(Roles = "IES")]
  954. [HttpPost("delete-scorecalc")]
  955. public async Task<IActionResult> DeleteSscoreCalc(JsonElement request)
  956. {
  957. try
  958. {
  959. if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
  960. if (!request.TryGetProperty("teammodelId", out JsonElement teammodelId)) return BadRequest();
  961. var clientTeacher = _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher);
  962. List<string> idslist = new List<string>();
  963. List<string> scorecalcIdslist = new List<string>();
  964. List<string> formulaIdslist = new List<string>();
  965. idslist.Add(id.ToString());
  966. // 取主表資料
  967. ScoreCalcBase scoreCalcBase = await clientTeacher.ReadItemAsync<ScoreCalcBase>(id.ToString(), new PartitionKey($"ScoreCalc-{teammodelId}"));
  968. if (string.IsNullOrWhiteSpace(scoreCalcBase.courseId)) { return BadRequest(); }
  969. // classId 跟 grouplistId 兩個必須有一個
  970. string sql_CalcList = "";
  971. if (string.IsNullOrWhiteSpace(scoreCalcBase.classId))
  972. {
  973. if (string.IsNullOrWhiteSpace(scoreCalcBase.grouplistId))
  974. {
  975. return BadRequest();
  976. }
  977. else
  978. {
  979. sql_CalcList = $"SELECT * FROM c where c.courseId = '{scoreCalcBase.courseId}' and c.grouplistId = '{scoreCalcBase.grouplistId}' order by c.sort ";
  980. }
  981. }
  982. else
  983. {
  984. sql_CalcList = $"SELECT * FROM c where c.courseId = '{scoreCalcBase.courseId}' and c.classId = '{scoreCalcBase.classId}' order by c.sort ";
  985. }
  986. #region 刪除流程
  987. // 取項目表的 Id
  988. string sql = $"SELECT c.id FROM c where c.scorecalcId = '{id}' ";
  989. await foreach (var item in clientTeacher.GetItemQueryIterator<ItemId>(queryText: sql))
  990. {
  991. scorecalcIdslist.Add(item.id);
  992. }
  993. StringBuilder sb = new StringBuilder();
  994. for (int i = 0; i < scorecalcIdslist.Count; i++)
  995. {
  996. sb.Append($"'{scorecalcIdslist[i]}',");
  997. }
  998. // 取公式表的 id
  999. string scorecalcActIdstr = "''";
  1000. if (sb.Length > 0)
  1001. {
  1002. scorecalcActIdstr = sb.ToString().Remove(sb.Length - 1, 1);
  1003. }
  1004. string sql_Formula = $"SELECT c.id FROM c where c.scorecalcActId in ({scorecalcActIdstr}) ";
  1005. await foreach (var item in clientTeacher.GetItemQueryIterator<ItemId>(queryText: sql_Formula))
  1006. {
  1007. formulaIdslist.Add(item.id);
  1008. }
  1009. //刪除主表 用傳進來的主表id 刪除資料
  1010. var response = await clientTeacher.DeleteItemStreamAsync(id.ToString(), new PartitionKey($"ScoreCalc-{teammodelId}"));
  1011. //await clientTeacher.DeleteItemsStreamAsync(idslist, $"ScoreCalc-{teammodelId}");
  1012. //刪除項目表
  1013. await clientTeacher.DeleteItemsStreamAsync(scorecalcIdslist, $"ScoreCalcAct-{teammodelId}");
  1014. //刪除公式表
  1015. await clientTeacher.DeleteItemsStreamAsync(formulaIdslist, $"ScoreCalcActFormula-{teammodelId}");
  1016. #endregion
  1017. #region 刪除後同時需要重新排序其他的成績統計 從1開始
  1018. // 取主表的資料
  1019. List<ScoreCalcBase> scoreCalcBases = new List<ScoreCalcBase>();
  1020. await foreach (var item in clientTeacher.GetItemQueryIterator<ScoreCalcBase>(queryText: sql_CalcList))
  1021. {
  1022. scoreCalcBases.Add(item);
  1023. }
  1024. for (int i = 0; i < scoreCalcBases.Count; i++)
  1025. {
  1026. scoreCalcBases[i].sort = i + 1;
  1027. //更新順序
  1028. scoreCalcBases[i] = await clientTeacher.ReplaceItemAsync(scoreCalcBases[i], $"{scoreCalcBases[i].id}", new PartitionKey(scoreCalcBases[i].code));
  1029. }
  1030. #endregion
  1031. var result = new
  1032. {
  1033. RtCode = "0",
  1034. RtMsg = "OK"
  1035. };
  1036. return Ok(result);
  1037. }
  1038. catch (Exception e)
  1039. {
  1040. //await _dingDing.SendBotMsg($"OS,{_option.Location},open-api/upsert()\n{e.Message}\n{e.StackTrace}\n{e.StackTrace}", GroupNames.醍摩豆服務運維群組);
  1041. return BadRequest();
  1042. }
  1043. }
  1044. /// <summary>
  1045. /// (六)更新公式設定(一次可以處理多個公式)
  1046. /// </summary>
  1047. /// <param name="request"></param>
  1048. /// <returns></returns>
  1049. [ProducesDefaultResponseType]
  1050. [Authorize(Roles = "IES")]
  1051. [HttpPost("update-formula")]
  1052. public async Task<IActionResult> UpdateFormula(JsonElement request)
  1053. {
  1054. try
  1055. {
  1056. if (!request.TryGetProperty("scoreCalcActId", out JsonElement scoreCalcActId)) return BadRequest();
  1057. if (!request.TryGetProperty("teammodelId", out JsonElement teammodelId)) return BadRequest();
  1058. var clientTeacher = _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher);
  1059. UpdateFormulaRq updateFormulaRq = JsonConvert.DeserializeObject<UpdateFormulaRq>(request.ToString());
  1060. List<ScoreCalcFunc> scoreCalcFuncs = new List<ScoreCalcFunc>();
  1061. // 取公式表的 資料
  1062. string sql = $"SELECT * FROM c where c.scorecalcActId = '{scoreCalcActId}' ";
  1063. await foreach (var item in clientTeacher.GetItemQueryIterator<ScoreCalcFunc>(queryText: sql))
  1064. {
  1065. scoreCalcFuncs.Add(item);
  1066. }
  1067. // 比對資料 決定哪些公式及項目表要更新
  1068. for (int i = 0; i < updateFormulaRq.scoreCalcFunc.Count; i++)
  1069. {
  1070. #region 更新 or 新增公式
  1071. for (int j = 0; j < scoreCalcFuncs.Count; j++)
  1072. {
  1073. if (updateFormulaRq.scoreCalcFunc[i].id == scoreCalcFuncs[j].id)
  1074. {// 如果公式Id有代入 則更新公式
  1075. // 取公式資料
  1076. scoreCalcFuncs[j].name = updateFormulaRq.scoreCalcFunc[i].name;
  1077. scoreCalcFuncs[j].keyvals = updateFormulaRq.scoreCalcFunc[i].keyvals;
  1078. scoreCalcFuncs[j].content = updateFormulaRq.scoreCalcFunc[i].content;
  1079. scoreCalcFuncs[j] = await clientTeacher.ReplaceItemAsync(scoreCalcFuncs[j], $"{scoreCalcFuncs[j].id}", new PartitionKey(scoreCalcFuncs[j].code));
  1080. }
  1081. }
  1082. if (updateFormulaRq.scoreCalcFunc[i].id == "")
  1083. {// 如果公式Id沒有代入 則新增公式
  1084. ScoreCalcFunc scoreCalcFunc = new ScoreCalcFunc();
  1085. scoreCalcFunc.code = $"ScoreCalcActFormula-{teammodelId}";
  1086. scoreCalcFunc.id = Guid.NewGuid().ToString();
  1087. updateFormulaRq.scoreCalcFunc[i].id = scoreCalcFunc.id;// 同時設定要新增的公式Id給Act
  1088. scoreCalcFunc.name = updateFormulaRq.scoreCalcFunc[i].name;
  1089. scoreCalcFunc.scorecalcActId = updateFormulaRq.scoreCalcActId;
  1090. // ToDo...以後可能需要其他活動也可以用公式
  1091. scoreCalcFunc.type = "lessonrecord";
  1092. scoreCalcFunc.method = updateFormulaRq.method;
  1093. scoreCalcFunc.template = updateFormulaRq.scoreCalcFunc[i].template;
  1094. scoreCalcFunc.keyvals = updateFormulaRq.scoreCalcFunc[i].keyvals;
  1095. scoreCalcFunc.content = updateFormulaRq.scoreCalcFunc[i].content;
  1096. scoreCalcFunc = await clientTeacher.CreateItemAsync(scoreCalcFunc, new PartitionKey($"{scoreCalcFunc.code}"));
  1097. }
  1098. #endregion
  1099. #region 更新項目表公式id
  1100. if (updateFormulaRq.scoreCalcFunc[i].use)
  1101. {
  1102. // 更新項目使用的公式id
  1103. // 取課堂紀錄資料
  1104. // ToDo...以後可能需要其他活動也可以用公式
  1105. ScoreCalcLsRecord scoreCalcLsRecord = await clientTeacher.ReadItemAsync<ScoreCalcLsRecord>(updateFormulaRq.scoreCalcActId, new PartitionKey($"ScoreCalcAct-{teammodelId}"));
  1106. switch (updateFormulaRq.method)
  1107. {
  1108. case "attend":
  1109. scoreCalcLsRecord.stuAttendFunctionId = updateFormulaRq.scoreCalcFunc[i].id;
  1110. break;
  1111. case "point":
  1112. scoreCalcLsRecord.stuPointFunctionId = updateFormulaRq.scoreCalcFunc[i].id;
  1113. break;
  1114. case "interaction":
  1115. scoreCalcLsRecord.stuItactFunctionId = updateFormulaRq.scoreCalcFunc[i].id;
  1116. break;
  1117. }
  1118. scoreCalcLsRecord = await clientTeacher.ReplaceItemAsync(scoreCalcLsRecord, $"{scoreCalcLsRecord.id}", new PartitionKey(scoreCalcLsRecord.code));
  1119. }
  1120. #endregion
  1121. }
  1122. var result = new
  1123. {
  1124. RtCode = "0",
  1125. RtMsg = "OK"
  1126. };
  1127. return Ok(result);
  1128. }
  1129. catch (Exception e)
  1130. {
  1131. //await _dingDing.SendBotMsg($"OS,{_option.Location},open-api/upsert()\n{e.Message}\n{e.StackTrace}\n{e.StackTrace}", GroupNames.醍摩豆服務運維群組);
  1132. return BadRequest();
  1133. }
  1134. }
  1135. /// <summary>
  1136. ///(七)新增自訂項目及其子項目資料
  1137. /// </summary>
  1138. /// <param name="request"></param>
  1139. /// <returns></returns>
  1140. [ProducesDefaultResponseType]
  1141. [Authorize(Roles = "IES")]
  1142. [HttpPost("add-scorecalcact")]
  1143. public async Task<IActionResult> AddScoreCalcAct(JsonElement request)
  1144. {
  1145. try
  1146. {
  1147. if (!request.TryGetProperty("scorecalcId", out JsonElement scorecalcId)) return BadRequest();
  1148. if (!request.TryGetProperty("teammodelId", out JsonElement teammodelId)) return BadRequest();
  1149. bool ishaveName = request.TryGetProperty("name", out JsonElement name);
  1150. ishaveName = !string.IsNullOrWhiteSpace(name + "");
  1151. bool ishavesubName = request.TryGetProperty("subName", out JsonElement subName);
  1152. ishavesubName = !string.IsNullOrWhiteSpace(subName + "");
  1153. var clientTeacher = _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher);
  1154. // 取主表資料
  1155. ScoreCalcBase scoreCalcBase = await clientTeacher.ReadItemAsync<ScoreCalcBase>(scorecalcId.ToString(), new PartitionKey($"ScoreCalc-{teammodelId}"));
  1156. #region 寫入DB 新增自訂項目及其子項目資料
  1157. // 設定預設值
  1158. ScoreCalcActivity scoreCalcActivity = new ScoreCalcActivity();
  1159. scoreCalcActivity.id = Guid.NewGuid().ToString();
  1160. scoreCalcActivity.code = $"ScoreCalcAct-{teammodelId}";
  1161. ScoreCalcActivityItems scoreCalcActivityItems = new ScoreCalcActivityItems();
  1162. scoreCalcActivityItems.id = Guid.NewGuid().ToString();
  1163. scoreCalcActivityItems.name = ishavesubName ? (subName + "") : "子項目";
  1164. scoreCalcActivityItems.use = true;
  1165. scoreCalcActivityItems.sort = 1;
  1166. scoreCalcActivityItems.custom = true;
  1167. scoreCalcActivityItems.createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  1168. scoreCalcActivity.items.Add(scoreCalcActivityItems);
  1169. // 根據學生數量設定預設值
  1170. List<double> zeroScores = new List<double>();
  1171. for (int j = 0; j < scoreCalcBase.members.Count; j++)
  1172. {
  1173. zeroScores.Add(0);
  1174. }
  1175. scoreCalcActivity.stuActScores.Add(zeroScores);
  1176. scoreCalcActivity.stuActScoresOrg.Add(zeroScores);
  1177. scoreCalcActivity.scorecalcId = scorecalcId.ToString();
  1178. scoreCalcActivity.name = ishaveName ? (name + "") : "新項目";
  1179. scoreCalcActivity.type = "custom";
  1180. scoreCalcActivity.rate = 0;
  1181. scoreCalcActivity.editScores = zeroScores;
  1182. scoreCalcActivity.itemRates = new List<double>() { 1 };
  1183. //取得目前項目總數
  1184. int count = 0;
  1185. string sql = $"SELECT c.id FROM c where c.scorecalcId = '{scorecalcId.ToString()}' ";
  1186. await foreach (var item in clientTeacher.GetItemQueryIterator<ItemId>(queryText: sql))
  1187. {
  1188. count++;
  1189. }
  1190. scoreCalcActivity.sort = count + 1;
  1191. // 新增項目及子項目
  1192. scoreCalcActivity = await clientTeacher.CreateItemAsync(scoreCalcActivity, new PartitionKey($"{scoreCalcActivity.code}"));
  1193. #endregion
  1194. #region 組合回傳格式
  1195. ScoreCalcActivityActDto scoreCalcActivityActDto = new ScoreCalcActivityActDto();
  1196. scoreCalcActivityActDto.id = scoreCalcActivity.id;
  1197. scoreCalcActivityActDto.name = scoreCalcActivity.name;
  1198. scoreCalcActivityActDto.type = scoreCalcActivity.type;
  1199. scoreCalcActivityActDto.rate = scoreCalcActivity.rate;
  1200. SubActActivity subActActivity = new SubActActivity();
  1201. subActActivity.id = scoreCalcActivity.items[0].id;
  1202. subActActivity.name = scoreCalcActivity.items[0].name;
  1203. // 子項目比重由外層取得
  1204. subActActivity.rate = scoreCalcActivity.itemRates[0];
  1205. subActActivity.use = scoreCalcActivity.items[0].use;
  1206. subActActivity.scores = scoreCalcActivity.stuActScores[0];
  1207. subActActivity.sort = scoreCalcActivity.items[0].sort;
  1208. subActActivity.custom = scoreCalcActivity.items[0].custom;
  1209. subActActivity.startTime = scoreCalcActivity.items[0].createTime;
  1210. scoreCalcActivityActDto.items.Add(subActActivity);
  1211. scoreCalcActivityActDto.editScores = scoreCalcActivity.editScores;
  1212. #endregion
  1213. return Ok(scoreCalcActivityActDto);
  1214. }
  1215. catch (Exception e)
  1216. {
  1217. //await _dingDing.SendBotMsg($"OS,{_option.Location},open-api/upsert()\n{e.Message}\n{e.StackTrace}\n{e.StackTrace}", GroupNames.醍摩豆服務運維群組);
  1218. return BadRequest();
  1219. }
  1220. }
  1221. /// <summary>
  1222. ///(八)新增子項目
  1223. /// </summary>
  1224. /// <param name="request"></param>
  1225. /// <returns></returns>
  1226. [ProducesDefaultResponseType]
  1227. [Authorize(Roles = "IES")]
  1228. [HttpPost("add-scorecalcact-item")]
  1229. public async Task<IActionResult> AddScoreCalcActItem(JsonElement request)
  1230. {
  1231. try
  1232. {
  1233. if (!request.TryGetProperty("scoreCalcActId", out JsonElement scoreCalcActId)) return BadRequest();
  1234. if (!request.TryGetProperty("teammodelId", out JsonElement teammodelId)) return BadRequest();
  1235. bool ishaveName = request.TryGetProperty("name", out JsonElement name);
  1236. ishaveName = !string.IsNullOrWhiteSpace(name + "");
  1237. var clientTeacher = _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher);
  1238. // 取項目表資料
  1239. ScoreCalcActivityBase scoreCalcActivityBase = await clientTeacher.ReadItemAsync<ScoreCalcActivityBase>(scoreCalcActId.ToString(), new PartitionKey($"ScoreCalcAct-{teammodelId}"));
  1240. // 取主表資料
  1241. ScoreCalcBase scoreCalcBase = await clientTeacher.ReadItemAsync<ScoreCalcBase>(scoreCalcActivityBase.scorecalcId.ToString(), new PartitionKey($"ScoreCalc-{teammodelId}"));
  1242. // 根據學生數量設定預設值
  1243. List<double> zeroScores = new List<double>();
  1244. for (int j = 0; j < scoreCalcBase.members.Count; j++)
  1245. {
  1246. zeroScores.Add(0);
  1247. }
  1248. // 設定子項目的預設值
  1249. ScoreCalcActivityItems scoreCalcActivityItems = new ScoreCalcActivityItems();
  1250. scoreCalcActivityItems.id = Guid.NewGuid().ToString();
  1251. scoreCalcActivityItems.name = ishaveName ? (name + "") : "子項目";
  1252. scoreCalcActivityItems.use = true;
  1253. scoreCalcActivityItems.custom = true;
  1254. scoreCalcActivityItems.createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  1255. // 先判斷是否為課堂紀錄 根據項目的類別寫入的欄位需要調整
  1256. if (scoreCalcActivityBase.type == "lessonrecord")
  1257. {
  1258. ScoreCalcLsRecord scoreCalcLsRecord = await clientTeacher.ReadItemAsync<ScoreCalcLsRecord>(scoreCalcActId.ToString(), new PartitionKey($"ScoreCalcAct-{teammodelId}"));
  1259. scoreCalcActivityItems.sort = scoreCalcLsRecord.items.Count + 1;
  1260. scoreCalcLsRecord.items.Add(scoreCalcActivityItems);
  1261. scoreCalcLsRecord.stuActAttendOrgVals.Add(zeroScores);
  1262. scoreCalcLsRecord.stuActAttendScores.Add(zeroScores);
  1263. scoreCalcLsRecord.stuActPointOrgVals.Add(zeroScores);
  1264. scoreCalcLsRecord.stuActPointScores.Add(zeroScores);
  1265. scoreCalcLsRecord.stuActItactOrgVals.Add(zeroScores);
  1266. scoreCalcLsRecord.stuActItactScores.Add(zeroScores);
  1267. scoreCalcLsRecord.itemRates.Add(1);
  1268. scoreCalcLsRecord = await clientTeacher.ReplaceItemAsync(scoreCalcLsRecord, $"{scoreCalcLsRecord.id}", new PartitionKey(scoreCalcLsRecord.code));
  1269. #region 組合回傳格式
  1270. SubActLsRecord subActLsRecord = new SubActLsRecord();
  1271. subActLsRecord.id = scoreCalcLsRecord.items[scoreCalcLsRecord.items.Count - 1].id;
  1272. subActLsRecord.name = scoreCalcLsRecord.items[scoreCalcLsRecord.items.Count - 1].name;
  1273. subActLsRecord.rate = scoreCalcLsRecord.itemRates[scoreCalcLsRecord.itemRates.Count - 1];
  1274. subActLsRecord.use = scoreCalcLsRecord.items[scoreCalcLsRecord.items.Count - 1].use;
  1275. subActLsRecord.startTime = scoreCalcLsRecord.items[scoreCalcLsRecord.items.Count - 1].createTime;
  1276. subActLsRecord.stuActAttendScores = scoreCalcLsRecord.stuActAttendScores[scoreCalcLsRecord.stuActAttendScores.Count - 1];
  1277. subActLsRecord.stuActPointScores = scoreCalcLsRecord.stuActPointScores[scoreCalcLsRecord.stuActPointScores.Count - 1];
  1278. subActLsRecord.stuActItactScores = scoreCalcLsRecord.stuActItactScores[scoreCalcLsRecord.stuActItactScores.Count - 1];
  1279. subActLsRecord.sort = scoreCalcActivityItems.sort;
  1280. subActLsRecord.custom = scoreCalcActivityItems.custom;
  1281. #endregion
  1282. return Ok(subActLsRecord);
  1283. }
  1284. else
  1285. {
  1286. ScoreCalcActivity scoreCalcActivity = await clientTeacher.ReadItemAsync<ScoreCalcActivity>(scoreCalcActId.ToString(), new PartitionKey($"ScoreCalcAct-{teammodelId}"));
  1287. scoreCalcActivityItems.sort = scoreCalcActivity.items.Count + 1;
  1288. scoreCalcActivity.items.Add(scoreCalcActivityItems);
  1289. scoreCalcActivity.stuActScores.Add(zeroScores);
  1290. scoreCalcActivity.stuActScoresOrg.Add(zeroScores);
  1291. scoreCalcActivity.itemRates.Add(1);
  1292. scoreCalcActivity = await clientTeacher.ReplaceItemAsync(scoreCalcActivity, $"{scoreCalcActivity.id}", new PartitionKey(scoreCalcActivity.code));
  1293. #region 組合回傳格式
  1294. SubActActivity subActActivity = new SubActActivity();
  1295. subActActivity.id = scoreCalcActivity.items[scoreCalcActivity.items.Count - 1].id;
  1296. subActActivity.name = scoreCalcActivity.items[scoreCalcActivity.items.Count - 1].name;
  1297. subActActivity.rate = scoreCalcActivity.itemRates[scoreCalcActivity.itemRates.Count - 1];
  1298. subActActivity.use = scoreCalcActivity.items[scoreCalcActivity.items.Count - 1].use;
  1299. subActActivity.startTime = scoreCalcActivity.items[scoreCalcActivity.items.Count - 1].createTime;
  1300. subActActivity.scores = scoreCalcActivity.stuActScores[scoreCalcActivity.stuActScores.Count - 1];
  1301. subActActivity.sort = scoreCalcActivityItems.sort;
  1302. subActActivity.custom = scoreCalcActivityItems.custom;
  1303. #endregion
  1304. return Ok(subActActivity);
  1305. }
  1306. }
  1307. catch (Exception e)
  1308. {
  1309. //await _dingDing.SendBotMsg($"OS,{_option.Location},open-api/upsert()\n{e.Message}\n{e.StackTrace}\n{e.StackTrace}", GroupNames.醍摩豆服務運維群組);
  1310. return BadRequest();
  1311. }
  1312. }
  1313. /// <summary>
  1314. /// (九)更新項目及子項目資料
  1315. /// </summary>
  1316. /// <param name="request"></param>
  1317. /// <returns></returns>
  1318. [ProducesDefaultResponseType]
  1319. [Authorize(Roles = "IES")]
  1320. [HttpPost("update-scorecalcact")]
  1321. public async Task<IActionResult> UpdateScoreCalcAct(JsonElement request)
  1322. {
  1323. try
  1324. {
  1325. if (!request.TryGetProperty("scoreCalcActId", out JsonElement scoreCalcActId)) return BadRequest();
  1326. if (!request.TryGetProperty("teammodelId", out JsonElement teammodelId)) return BadRequest();
  1327. var clientTeacher = _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher);
  1328. // 取項目表資料
  1329. ScoreCalcActivityBase scoreCalcActivityBase = await clientTeacher.ReadItemAsync<ScoreCalcActivityBase>(scoreCalcActId.ToString(), new PartitionKey($"ScoreCalcAct-{teammodelId}"));
  1330. UpdateActivityActRq updateActivityActRq = JsonConvert.DeserializeObject<UpdateActivityActRq>(request.ToString());
  1331. var result = new
  1332. {
  1333. RtCode = "0",
  1334. RtMsg = "OK"
  1335. };
  1336. // 先判斷是否為課堂紀錄 根據項目的類別要撈不同欄位的資料出來更新
  1337. if (scoreCalcActivityBase.type == "lessonrecord")
  1338. {
  1339. ScoreCalcLsRecord scoreCalcLsRecord = await clientTeacher.ReadItemAsync<ScoreCalcLsRecord>(scoreCalcActId.ToString(), new PartitionKey($"ScoreCalcAct-{teammodelId}"));
  1340. //設定需更新的欄位值
  1341. scoreCalcLsRecord.name = updateActivityActRq.name;
  1342. scoreCalcLsRecord.rate = updateActivityActRq.rate;
  1343. for (int i = 0; i < scoreCalcLsRecord.items.Count; i++)
  1344. {
  1345. for (int j = 0; j < updateActivityActRq.items.Count; j++)
  1346. {
  1347. if (scoreCalcLsRecord.items[i].id == updateActivityActRq.items[j].id)
  1348. {
  1349. scoreCalcLsRecord.items[i].name = updateActivityActRq.items[j].name;
  1350. scoreCalcLsRecord.items[i].use = updateActivityActRq.items[j].use;
  1351. scoreCalcLsRecord.itemRates[i] = updateActivityActRq.items[j].rate;
  1352. scoreCalcLsRecord.items[i].sort = updateActivityActRq.items[j].sort;
  1353. }
  1354. }
  1355. }
  1356. //更新
  1357. scoreCalcLsRecord = await clientTeacher.ReplaceItemAsync(scoreCalcLsRecord, $"{scoreCalcLsRecord.id}", new PartitionKey(scoreCalcLsRecord.code));
  1358. return Ok(result);
  1359. }
  1360. else
  1361. {
  1362. ScoreCalcActivity scoreCalcActivity = await clientTeacher.ReadItemAsync<ScoreCalcActivity>(scoreCalcActId.ToString(), new PartitionKey($"ScoreCalcAct-{teammodelId}"));
  1363. //設定需更新的欄位值
  1364. scoreCalcActivity.name = updateActivityActRq.name;
  1365. scoreCalcActivity.rate = updateActivityActRq.rate;
  1366. for (int i = 0; i < scoreCalcActivity.items.Count; i++)
  1367. {
  1368. for (int j = 0; j < updateActivityActRq.items.Count; j++)
  1369. {
  1370. if (scoreCalcActivity.items[i].id == updateActivityActRq.items[j].id)
  1371. {
  1372. scoreCalcActivity.items[i].name = updateActivityActRq.items[j].name;
  1373. scoreCalcActivity.items[i].use = updateActivityActRq.items[j].use;
  1374. scoreCalcActivity.itemRates[i] = updateActivityActRq.items[j].rate;
  1375. scoreCalcActivity.items[i].sort = updateActivityActRq.items[j].sort;
  1376. }
  1377. }
  1378. }
  1379. //更新
  1380. scoreCalcActivity = await clientTeacher.ReplaceItemAsync(scoreCalcActivity, $"{scoreCalcActivity.id}", new PartitionKey(scoreCalcActivity.code));
  1381. }
  1382. return Ok(result);
  1383. }
  1384. catch (Exception e)
  1385. {
  1386. //await _dingDing.SendBotMsg($"OS,{_option.Location},open-api/upsert()\n{e.Message}\n{e.StackTrace}\n{e.StackTrace}", GroupNames.醍摩豆服務運維群組);
  1387. return BadRequest();
  1388. }
  1389. }
  1390. /// <summary>
  1391. ///(十)刪除自訂項目
  1392. /// </summary>
  1393. /// <param name="request"></param>
  1394. /// <returns></returns>
  1395. [ProducesDefaultResponseType]
  1396. [Authorize(Roles = "IES")]
  1397. [HttpPost("delete-scorecalcact")]
  1398. public async Task<IActionResult> DeleteSscoreCalcAct(JsonElement request)
  1399. {
  1400. try
  1401. {
  1402. if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
  1403. if (!request.TryGetProperty("teammodelId", out JsonElement teammodelId)) return BadRequest();
  1404. if (!request.TryGetProperty("scorecalcId", out JsonElement scorecalcId)) return BadRequest();
  1405. var clientTeacher = _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher);
  1406. ScoreCalcActivityBase scoreCalcActivityBase = await clientTeacher.ReadItemAsync<ScoreCalcActivityBase>(id.ToString(), new PartitionKey($"ScoreCalcAct-{teammodelId}"));
  1407. // 先檢查 系統內建的成績項目不可以刪除
  1408. if (scoreCalcActivityBase.type == "lessonrecord" || scoreCalcActivityBase.type == "exam" || scoreCalcActivityBase.type == "homework")
  1409. {
  1410. return BadRequest();
  1411. }
  1412. else
  1413. {
  1414. //刪除項目表
  1415. var response = await clientTeacher.DeleteItemStreamAsync(id.ToString(), new PartitionKey($"ScoreCalcAct-{teammodelId}"));
  1416. #region 同時需要重新排序其他的項目 從1開始
  1417. List<ScoreCalcActivity> scoreCalcActivitys = new List<ScoreCalcActivity>();
  1418. // 取項目表的資料
  1419. string sql = $"SELECT * FROM c where c.type = 'custom' and c.scorecalcId = '{scorecalcId}' order by c.sort ";
  1420. await foreach (var item in clientTeacher.GetItemQueryIterator<ScoreCalcActivity>(queryText: sql))
  1421. {
  1422. scoreCalcActivitys.Add(item);
  1423. }
  1424. for (int i = 0; i < scoreCalcActivitys.Count; i++)
  1425. {
  1426. // 因為前面有三個系統項目為固定項目不能移動或是刪除所以從 4 開始排序
  1427. scoreCalcActivitys[i].sort = i + 4;
  1428. scoreCalcActivitys[i] = await clientTeacher.ReplaceItemAsync(scoreCalcActivitys[i], $"{scoreCalcActivitys[i].id}", new PartitionKey(scoreCalcActivitys[i].code));
  1429. }
  1430. #endregion
  1431. var result = new
  1432. {
  1433. RtCode = "0",
  1434. RtMsg = "OK"
  1435. };
  1436. return Ok(result);
  1437. }
  1438. }
  1439. catch (Exception e)
  1440. {
  1441. //await _dingDing.SendBotMsg($"OS,{_option.Location},open-api/upsert()\n{e.Message}\n{e.StackTrace}\n{e.StackTrace}", GroupNames.醍摩豆服務運維群組);
  1442. return BadRequest();
  1443. }
  1444. }
  1445. /// <summary>
  1446. ///(十一)刪除子項目
  1447. /// </summary>
  1448. /// <param name="request"></param>
  1449. /// <returns></returns>
  1450. [ProducesDefaultResponseType]
  1451. [Authorize(Roles = "IES")]
  1452. [HttpPost("delete-scorecalcactitem")]
  1453. public async Task<IActionResult> DeleteSscoreCalcItem(JsonElement request)
  1454. {
  1455. try
  1456. {
  1457. if (!request.TryGetProperty("scoreCalcActId", out JsonElement scoreCalcActId)) return BadRequest();
  1458. if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
  1459. if (!request.TryGetProperty("teammodelId", out JsonElement teammodelId)) return BadRequest();
  1460. var clientTeacher = _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher);
  1461. // 取項目表資料
  1462. ScoreCalcActivityBase scoreCalcActivityBase = await clientTeacher.ReadItemAsync<ScoreCalcActivityBase>(scoreCalcActId.ToString(), new PartitionKey($"ScoreCalcAct-{teammodelId}"));
  1463. var result = new
  1464. {
  1465. RtCode = "0",
  1466. RtMsg = "OK"
  1467. };
  1468. // 先判斷是否為課堂紀錄 根據項目的類別刪除的欄位需要調整
  1469. if (scoreCalcActivityBase.type == "lessonrecord")
  1470. {
  1471. ScoreCalcLsRecord scoreCalcLsRecord = await clientTeacher.ReadItemAsync<ScoreCalcLsRecord>(scoreCalcActId.ToString(), new PartitionKey($"ScoreCalcAct-{teammodelId}"));
  1472. // 先尋找要刪除的子項目
  1473. for (int i = 0; i < scoreCalcLsRecord.items.Count; i++)
  1474. {
  1475. if (scoreCalcLsRecord.items[i].id == id.ToString())
  1476. {// 比對中了 移除該項目
  1477. scoreCalcLsRecord.items.Remove(scoreCalcLsRecord.items[i]);
  1478. scoreCalcLsRecord.stuActAttendOrgVals.Remove(scoreCalcLsRecord.stuActAttendOrgVals[i]);
  1479. scoreCalcLsRecord.stuActAttendScores.Remove(scoreCalcLsRecord.stuActAttendScores[i]);
  1480. scoreCalcLsRecord.stuActPointOrgVals.Remove(scoreCalcLsRecord.stuActPointOrgVals[i]);
  1481. scoreCalcLsRecord.stuActPointScores.Remove(scoreCalcLsRecord.stuActPointScores[i]);
  1482. scoreCalcLsRecord.stuActItactOrgVals.Remove(scoreCalcLsRecord.stuActItactOrgVals[i]);
  1483. scoreCalcLsRecord.stuActItactScores.Remove(scoreCalcLsRecord.stuActItactScores[i]);
  1484. scoreCalcLsRecord.itemRates.Remove(scoreCalcLsRecord.itemRates[i]);
  1485. }
  1486. }
  1487. #region 同時需要重新排序其他的項目 從1開始
  1488. for (int i = 0; i < scoreCalcLsRecord.items.Count; i++)
  1489. {
  1490. scoreCalcLsRecord.items[i].sort = i + 1;
  1491. }
  1492. #endregion
  1493. scoreCalcLsRecord = await clientTeacher.ReplaceItemAsync(scoreCalcLsRecord, $"{scoreCalcLsRecord.id}", new PartitionKey(scoreCalcLsRecord.code));
  1494. return Ok(result);
  1495. }
  1496. else
  1497. {
  1498. ScoreCalcActivity scoreCalcActivity = await clientTeacher.ReadItemAsync<ScoreCalcActivity>(scoreCalcActId.ToString(), new PartitionKey($"ScoreCalcAct-{teammodelId}"));
  1499. // 先尋找要刪除的子項目
  1500. for (int i = 0; i < scoreCalcActivity.items.Count; i++)
  1501. {
  1502. if (scoreCalcActivity.items[i].id == id.ToString())
  1503. {// 比對中了 移除該項目
  1504. scoreCalcActivity.items.Remove(scoreCalcActivity.items[i]);
  1505. scoreCalcActivity.stuActScores.Remove(scoreCalcActivity.stuActScores[i]);
  1506. scoreCalcActivity.stuActScoresOrg.Remove(scoreCalcActivity.stuActScoresOrg[i]);
  1507. scoreCalcActivity.itemRates.Remove(scoreCalcActivity.itemRates[i]);
  1508. }
  1509. }
  1510. #region 同時需要重新排序其他的項目 從1開始
  1511. scoreCalcActivity.items = scoreCalcActivity.items.OrderBy(item => item.sort).ToList();
  1512. for (int i = 0; i < scoreCalcActivity.items.Count; i++)
  1513. {
  1514. scoreCalcActivity.items[i].sort = i + 1;
  1515. }
  1516. #endregion
  1517. scoreCalcActivity = await clientTeacher.ReplaceItemAsync(scoreCalcActivity, $"{scoreCalcActivity.id}", new PartitionKey(scoreCalcActivity.code));
  1518. return Ok(result);
  1519. }
  1520. }
  1521. catch (Exception e)
  1522. {
  1523. //await _dingDing.SendBotMsg($"OS,{_option.Location},open-api/upsert()\n{e.Message}\n{e.StackTrace}\n{e.StackTrace}", GroupNames.醍摩豆服務運維群組);
  1524. return BadRequest();
  1525. }
  1526. }
  1527. /// <summary>
  1528. ///(十二)登錄指定子項目成績
  1529. /// </summary>
  1530. /// <param name="request"></param>
  1531. /// <returns></returns>
  1532. [ProducesDefaultResponseType]
  1533. [Authorize(Roles = "IES")]
  1534. [HttpPost("update-itemscore")]
  1535. public async Task<IActionResult> UpdateItemScore(JsonElement request)
  1536. {
  1537. try
  1538. {
  1539. if (!request.TryGetProperty("scoreCalcActId", out JsonElement scoreCalcActId)) return BadRequest();
  1540. if (!request.TryGetProperty("teammodelId", out JsonElement teammodelId)) return BadRequest();
  1541. if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
  1542. var clientTeacher = _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher);
  1543. // 取項目表資料Base的部分
  1544. ScoreCalcActivityBase scoreCalcActivityBase = await clientTeacher.ReadItemAsync<ScoreCalcActivityBase>(scoreCalcActId.ToString(), new PartitionKey($"ScoreCalcAct-{teammodelId}"));
  1545. // 先判斷是否為課堂紀錄 根據項目的類別刪除的欄位需要調整
  1546. if (scoreCalcActivityBase.type == "lessonrecord")
  1547. {
  1548. UpdateScoreLessonRq updateScoreLessonRq = JsonConvert.DeserializeObject<UpdateScoreLessonRq>(request.ToString());
  1549. // 取課堂紀錄資料
  1550. ScoreCalcLsRecord scoreCalcLsRecord = await clientTeacher.ReadItemAsync<ScoreCalcLsRecord>(scoreCalcActId.ToString(), new PartitionKey($"ScoreCalcAct-{teammodelId}"));
  1551. for (int i = 0; i < scoreCalcLsRecord.items.Count; i++)
  1552. {
  1553. if (scoreCalcLsRecord.items[i].id == updateScoreLessonRq.id)
  1554. {
  1555. scoreCalcLsRecord.stuActAttendScores[i] = updateScoreLessonRq.stuActAttendScores;
  1556. scoreCalcLsRecord.stuActPointScores[i] = updateScoreLessonRq.stuActPointScores;
  1557. scoreCalcLsRecord.stuActItactScores[i] = updateScoreLessonRq.stuActItactScores;
  1558. }
  1559. }
  1560. //更新
  1561. scoreCalcLsRecord = await clientTeacher.ReplaceItemAsync(scoreCalcLsRecord, $"{scoreCalcLsRecord.id}", new PartitionKey(scoreCalcLsRecord.code));
  1562. }
  1563. else
  1564. {
  1565. UpdateScoreActivityRq updateScoreActivityRq = JsonConvert.DeserializeObject<UpdateScoreActivityRq>(request.ToString());
  1566. // 取其他活動資料
  1567. ScoreCalcActivity scoreCalcActivity = await clientTeacher.ReadItemAsync<ScoreCalcActivity>(scoreCalcActId.ToString(), new PartitionKey($"ScoreCalcAct-{teammodelId}"));
  1568. for (int i = 0; i < scoreCalcActivity.items.Count; i++)
  1569. {
  1570. if (scoreCalcActivity.items[i].id == updateScoreActivityRq.id)
  1571. {
  1572. scoreCalcActivity.stuActScores[i] = updateScoreActivityRq.scores;
  1573. }
  1574. }
  1575. //更新
  1576. scoreCalcActivity = await clientTeacher.ReplaceItemAsync(scoreCalcActivity, $"{scoreCalcActivity.id}", new PartitionKey(scoreCalcActivity.code));
  1577. }
  1578. var result = new
  1579. {
  1580. RtCode = "0",
  1581. RtMsg = "OK"
  1582. };
  1583. return Ok(result);
  1584. }
  1585. catch (Exception e)
  1586. {
  1587. //await _dingDing.SendBotMsg($"OS,{_option.Location},open-api/upsert()\n{e.Message}\n{e.StackTrace}\n{e.StackTrace}", GroupNames.醍摩豆服務運維群組);
  1588. return BadRequest();
  1589. }
  1590. }
  1591. /// <summary>
  1592. ///(十三)匯出原始成績資料
  1593. /// </summary>
  1594. /// <param name="request"></param>
  1595. /// <returns></returns>
  1596. [ProducesDefaultResponseType]
  1597. [Authorize(Roles = "IES")]
  1598. [HttpPost("export-orgscore")]
  1599. public async Task<IActionResult> ExportOrgScore(JsonElement request)
  1600. {
  1601. try
  1602. {
  1603. if (!request.TryGetProperty("courseId", out JsonElement courseId)) return BadRequest();
  1604. if (!request.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
  1605. bool ishaveClassId = request.TryGetProperty("classId", out JsonElement classId);
  1606. bool ishaveGrouplistId = request.TryGetProperty("grouplistId", out JsonElement grouplistId);
  1607. ishaveClassId = !string.IsNullOrWhiteSpace(classId + "");
  1608. ishaveGrouplistId = !string.IsNullOrWhiteSpace(grouplistId + "");
  1609. bool ishaveTeammodelId = request.TryGetProperty("teammodelId", out JsonElement teammodelId);
  1610. bool ishaveSchoolId = request.TryGetProperty("schoolId", out JsonElement schoolId);
  1611. bool ishaveSubjectId = request.TryGetProperty("subjectId", out JsonElement subjectId);
  1612. ishaveSubjectId = !string.IsNullOrWhiteSpace(subjectId + "");
  1613. // classId 跟 grouplistId 兩個必須有一個必填
  1614. if (!ishaveClassId)
  1615. {
  1616. if (!ishaveGrouplistId)
  1617. {
  1618. return BadRequest();
  1619. }
  1620. else
  1621. {
  1622. if (!ishaveTeammodelId) return BadRequest();
  1623. }
  1624. }
  1625. else
  1626. {
  1627. if (!ishaveSchoolId) return BadRequest();
  1628. }
  1629. //班級
  1630. List<ScoreCalcMember> members = new List<ScoreCalcMember>();
  1631. // 設定活動預設值
  1632. ScoreCalcLsRecord scoreCalcLsRecord = new ScoreCalcLsRecord();
  1633. ScoreCalcActivity scoreCalcActivity_eaxm = new ScoreCalcActivity();
  1634. ScoreCalcActivity scoreCalcActivity_homework = new ScoreCalcActivity();
  1635. var isOKRequest = await getSystemScoresDate(courseId, scope, classId, grouplistId, teammodelId, schoolId, subjectId, ishaveClassId, ishaveGrouplistId, ishaveSubjectId, members, scoreCalcLsRecord, scoreCalcActivity_eaxm, scoreCalcActivity_homework);
  1636. if (!isOKRequest) { return BadRequest(); }
  1637. #region 調整資料回傳格式
  1638. List<ExportOrgLsRecordData> exportlessonrecordData = new List<ExportOrgLsRecordData>();
  1639. List<ExportOrgActivityData> exporthomeworkData = new List<ExportOrgActivityData>();
  1640. List<ExportOrgActivityData> exportexamData = new List<ExportOrgActivityData>();
  1641. // 調整課程紀錄回傳格式
  1642. for (int i = 0; i < scoreCalcLsRecord.items.Count; i++)
  1643. {
  1644. ExportOrgLsRecordData exportOrgLsRecordData = new ExportOrgLsRecordData();
  1645. exportOrgLsRecordData.name = scoreCalcLsRecord.items[i].name;
  1646. for (int j = 0; j < members.Count; j++)
  1647. {
  1648. LessonScores lessonScores = new LessonScores();
  1649. lessonScores.id = members[j].id;
  1650. lessonScores.name = members[j].name;
  1651. lessonScores.no = members[j].no;
  1652. lessonScores.attend = scoreCalcLsRecord.stuActAttendOrgVals[i][j];
  1653. lessonScores.point = scoreCalcLsRecord.stuActPointOrgVals[i][j];
  1654. lessonScores.interaction = scoreCalcLsRecord.stuActItactOrgVals[i][j];
  1655. exportOrgLsRecordData.data.Add(lessonScores);
  1656. }
  1657. exportlessonrecordData.Add(exportOrgLsRecordData);
  1658. }
  1659. // 調整評量活動回傳格式
  1660. for (int i = 0; i < scoreCalcActivity_eaxm.items.Count; i++)
  1661. {
  1662. ExportOrgActivityData exportOrgActivityData = new ExportOrgActivityData();
  1663. exportOrgActivityData.name = scoreCalcActivity_eaxm.items[i].name;
  1664. for (int j = 0; j < members.Count; j++)
  1665. {
  1666. ActivityScores activityScores = new ActivityScores();
  1667. activityScores.id = members[j].id;
  1668. activityScores.name = members[j].name;
  1669. activityScores.no = members[j].no;
  1670. activityScores.score = scoreCalcActivity_eaxm.stuActScoresOrg[i][j];
  1671. exportOrgActivityData.data.Add(activityScores);
  1672. }
  1673. exportexamData.Add(exportOrgActivityData);
  1674. }
  1675. // 調整作業活動回傳格式
  1676. for (int i = 0; i < scoreCalcActivity_homework.items.Count; i++)
  1677. {
  1678. ExportOrgActivityData exportOrgActivityData = new ExportOrgActivityData();
  1679. exportOrgActivityData.name = scoreCalcActivity_homework.items[i].name;
  1680. for (int j = 0; j < members.Count; j++)
  1681. {
  1682. ActivityScores activityScores = new ActivityScores();
  1683. activityScores.id = members[j].id;
  1684. activityScores.name = members[j].name;
  1685. activityScores.no = members[j].no;
  1686. activityScores.score = scoreCalcActivity_homework.stuActScoresOrg[i][j];
  1687. exportOrgActivityData.data.Add(activityScores);
  1688. }
  1689. exporthomeworkData.Add(exportOrgActivityData);
  1690. }
  1691. #endregion
  1692. var orgData1 = new
  1693. {
  1694. lessonrecord = exportlessonrecordData,
  1695. homework = exporthomeworkData,
  1696. exam = exportexamData
  1697. };
  1698. return Ok(orgData1);
  1699. }
  1700. catch (Exception e)
  1701. {
  1702. //await _dingDing.SendBotMsg($"OS,{_option.Location},open-api/upsert()\n{e.Message}\n{e.StackTrace}\n{e.StackTrace}", GroupNames.醍摩豆服務運維群組);
  1703. return BadRequest();
  1704. }
  1705. }
  1706. private async Task<bool> getSystemScoresDate(JsonElement courseId, JsonElement scope, JsonElement classId, JsonElement grouplistId, JsonElement teammodelId, JsonElement schoolId, JsonElement subjectId, bool ishaveClassId, bool ishaveGrouplistId, bool ishaveSubjectId, List<ScoreCalcMember> members, ScoreCalcLsRecord scoreCalcLsRecord, ScoreCalcActivity scoreCalcActivity_eaxm, ScoreCalcActivity scoreCalcActivity_homework)
  1707. {
  1708. var clientStudent = _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Student);
  1709. var clientCommon = _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common);
  1710. var clientSchool = _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School);
  1711. var clientTeacher = _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher);
  1712. #region ==== 1~4. 取出系統資料====
  1713. //評量資料
  1714. List<ExamItem> examItem = new List<ExamItem>();
  1715. //評量名稱
  1716. List<ExamItem> examItemNameStartTime = new List<ExamItem>();
  1717. //作業資料
  1718. List<HomeworkItem> homeworkItems = new List<HomeworkItem>();
  1719. //作業分數
  1720. List<HomeworkItem> homeworkItemsScore = new List<HomeworkItem>();
  1721. #region ==== 1. 取此班級所有學生====
  1722. string sql_members = "";
  1723. if (ishaveClassId)
  1724. {// 如果有classId 直接到student 取資料
  1725. sql_members = $"SELECT c.id, c.no, c.name FROM c WHERE c.classId= '{classId}' and c.code = 'Base-{schoolId}'";
  1726. await foreach (var item in clientStudent.GetItemQueryIterator<ScoreCalcMember>(queryText: sql_members))
  1727. {
  1728. members.Add(item);
  1729. }
  1730. }
  1731. else if (scope.ToString() == "school")
  1732. {// 選課班 撈School 取id 撈student 取name no
  1733. sql_members = $"SELECT b.id FROM c join b in c.members WHERE c.id= '{grouplistId}' and c.code = 'GroupList-{schoolId}'";
  1734. StringBuilder sb = new StringBuilder();
  1735. await foreach (var item in clientSchool.GetItemQueryIterator<ScoreCalcMember>(queryText: sql_members))
  1736. {
  1737. sb.Append($"'{item.id}',");
  1738. }
  1739. if (sb.Length > 0)
  1740. {
  1741. sql_members = $"SELECT c.id, c.no, c.name FROM c WHERE c.id in ({sb.ToString().Remove(sb.Length - 1, 1)}) and c.code = 'Base-{schoolId}'";
  1742. await foreach (var item in clientStudent.GetItemQueryIterator<ScoreCalcMember>(queryText: sql_members))
  1743. {
  1744. members.Add(item);
  1745. }
  1746. }
  1747. }
  1748. else if (scope.ToString() == "private")
  1749. {// 私人班 撈Teacher 取c.id, c.no 撈student 取name
  1750. sql_members = $"SELECT b.id FROM c join b in c.members WHERE c.id= '{grouplistId}' and c.code = 'GroupList'";
  1751. StringBuilder sb = new StringBuilder();
  1752. await foreach (var item in clientTeacher.GetItemQueryIterator<ScoreCalcMember>(queryText: sql_members))
  1753. {
  1754. sb.Append($"'{item.id}',");
  1755. }
  1756. if (sb.Length > 0)
  1757. {
  1758. sql_members = $"SELECT c.id, c.no, c.name FROM c WHERE c.id in ({sb.ToString().Remove(sb.Length - 1, 1)})";
  1759. await foreach (var item in clientStudent.GetItemQueryIterator<ScoreCalcMember>(queryText: sql_members))
  1760. {
  1761. members.Add(item);
  1762. }
  1763. }
  1764. }
  1765. else { return false; }
  1766. //orgData.Add(members);
  1767. #endregion
  1768. #region ==== 2. 取系統課堂紀錄成績====
  1769. #region ==== 取得開課紀錄====
  1770. StringBuilder sql = new StringBuilder();
  1771. sql.Append("select value(c) from c ");
  1772. int pageCount = 1000;
  1773. string sgroupIds = "";
  1774. if (ishaveClassId)
  1775. {
  1776. sgroupIds = classId + "";
  1777. }
  1778. else
  1779. {
  1780. sgroupIds = grouplistId + "";
  1781. }
  1782. JsonElement rqt = System.Text.Json.JsonSerializer.SerializeToElement(new
  1783. {
  1784. courseId = courseId,
  1785. groupIds = new List<string> { sgroupIds + "" }
  1786. });
  1787. Dictionary<string, object> dict = LessonService.GetLessonCond(rqt);
  1788. string continuationToken = null;
  1789. AzureCosmosQuery cosmosDbQuery = SQLHelper.GetSQL(dict, sql);
  1790. string tbname = "";
  1791. string code = "";
  1792. string school = null;
  1793. //string sqlPrivate = "";
  1794. //List<string> autoTch = new List<string>();
  1795. // 如果是學校課程
  1796. if (scope.GetString().Equals("school"))
  1797. {
  1798. if (!string.IsNullOrEmpty($"{schoolId}"))// 如果有學校ID
  1799. {
  1800. code = $"LessonRecord-{schoolId}";// 組合區域碼
  1801. tbname = "School";
  1802. school = $"{schoolId}";
  1803. //只查询某个老师的课例
  1804. if (string.IsNullOrWhiteSpace($"{teammodelId}"))
  1805. {
  1806. return false;
  1807. }
  1808. }
  1809. else
  1810. {
  1811. return false;
  1812. }
  1813. }
  1814. else if ($"{scope}".Equals("private"))
  1815. {
  1816. code = $"LessonRecord";
  1817. tbname = "Teacher";
  1818. if (string.IsNullOrEmpty($"{teammodelId}"))
  1819. {
  1820. //如果不传tmdid, 则必须传递,课程id或者名单列表
  1821. // 如果不传递tmdid
  1822. if (!string.IsNullOrWhiteSpace($"{grouplistId}"))
  1823. {
  1824. return false;
  1825. }
  1826. }
  1827. }
  1828. else
  1829. {
  1830. return false;
  1831. }
  1832. List<LessonRecord> lessonRecords = new List<LessonRecord>();
  1833. try
  1834. {
  1835. string sql_status_managePage = "(c.status<>404 or IS_DEFINED(c.status) = false ) and ";
  1836. cosmosDbQuery.QueryText = cosmosDbQuery.QueryText.Replace("where", $" where {sql_status_managePage} array_length(c.groupIds)>0 and ");
  1837. await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, tbname)
  1838. .GetItemQueryStreamIterator(queryDefinition: cosmosDbQuery.CosmosQueryDefinition, continuationToken: continuationToken,
  1839. requestOptions: new QueryRequestOptions() { MaxItemCount = pageCount, PartitionKey = new PartitionKey(code) }))
  1840. {
  1841. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  1842. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  1843. {
  1844. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  1845. {
  1846. var rcd = obj.ToObject<LessonRecord>();
  1847. if (rcd.hitaClientCmpCount <= 0 && rcd.collateTaskCount > 0)
  1848. {
  1849. rcd.hitaClientCmpCount = rcd.collateTaskCount;
  1850. }
  1851. if (rcd.learningCategory == null)
  1852. {
  1853. rcd.learningCategory = new LearningCategory();
  1854. }
  1855. if (rcd.hitaClientCmpCount > 0)
  1856. {
  1857. rcd.learningCategory.cooperation = 1;
  1858. }
  1859. lessonRecords.Add(rcd);
  1860. }
  1861. continuationToken = item.GetContinuationToken();
  1862. break;
  1863. }
  1864. }
  1865. long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  1866. //查询时处理已经过期的课例。防止ServiceBus未触发的。
  1867. var expireRecords = lessonRecords.Where(x => x.expire > 0 && now > x.expire);
  1868. try
  1869. {
  1870. foreach (var item in expireRecords)
  1871. {
  1872. //item.status = 404;
  1873. //await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, tbname).ReplaceItemAsync(item, item.id, new PartitionKey(item.code));
  1874. var ActiveTask = _configuration.GetValue<string>("Azure:ServiceBus:ActiveTask");
  1875. var messageChange = new ServiceBusMessage(new { delete_id = item.id, tmdid = item.tmdid, scope = item.scope, opt = "delete", school = item.school }.ToJsonString());
  1876. messageChange.ApplicationProperties.Add("name", "LessonRecordEvent");
  1877. await _serviceBus.GetServiceBusClient().SendMessageAsync(ActiveTask, messageChange);
  1878. }
  1879. }
  1880. catch (Exception ex)
  1881. {
  1882. await _dingDing.SendBotMsg($"{_option.Location},ServiceBus ,LessonRecordEvent 发送消息失败,检查是否配置正常。", GroupNames.成都开发測試群組);
  1883. }
  1884. var tmdids = lessonRecords.Select(x => x.tmdid).ToHashSet();
  1885. if (tmdids != null && tmdids.Count > 0)
  1886. {
  1887. List<IdNameCode> codes = new List<IdNameCode>();
  1888. string sqltmd = $"select c.id,c.name,c.picture from c where c.id in ({string.Join(",", tmdids.Select(x => $"'{x}'"))})";
  1889. await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<IdNameCode>(queryText: sqltmd, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey("Base") }))
  1890. {
  1891. codes.Add(item);
  1892. }
  1893. if (codes.IsNotEmpty())
  1894. {
  1895. lessonRecords.ForEach(x =>
  1896. {
  1897. var tmd = codes.Find(z => z.id.Equals(x.tmdid));
  1898. if (tmd != null)
  1899. {
  1900. x.tmdname = tmd.name;
  1901. x.tmdpicture = tmd.picture;
  1902. }
  1903. });
  1904. }
  1905. }
  1906. var groupIds = lessonRecords.SelectMany(x => x.groupIds);
  1907. if (groupIds.Any())
  1908. {
  1909. List<GroupListDto> groupLists = await GroupListService.GetGroupListByListids(_azureCosmos.GetCosmosClient(), _dingDing, groupIds.ToList(), school);
  1910. lessonRecords.ForEach(x =>
  1911. {
  1912. List<string> groupNmae = new List<string>();
  1913. x.groupIds.ForEach(y =>
  1914. {
  1915. var dto = groupLists.Find(z => z.id.Equals(y));
  1916. string name = dto != null ? dto.name : "-";
  1917. groupNmae.Add(name);
  1918. });
  1919. x.groupNames = groupNmae;
  1920. });
  1921. }
  1922. //return Ok(new { currCount = lessonRecords.Count, continuationToken, lessonRecords });
  1923. }
  1924. catch (Exception)
  1925. {
  1926. continuationToken = null;
  1927. //return Ok(new { currCount = 0, continuationToken = continuationToken, lessonRecords });
  1928. }
  1929. #endregion
  1930. List<ScoreLessonBase> lessonBases = new List<ScoreLessonBase>();
  1931. string blobname = "";
  1932. foreach (var item in lessonRecords)
  1933. {// 先檢查課堂紀錄是否存在再取資料
  1934. if (item.scope.Equals("school"))
  1935. {// 學校課程 用學校id取blob
  1936. blobname = schoolId.GetString();
  1937. if (_azureStorage.GetBlobContainerClient(blobname).GetBlobClient($"/records/{item.id}/IES/base.json").Exists())
  1938. {
  1939. ScoreCalcActivityItems scoreCalcActivityItems = new ScoreCalcActivityItems();
  1940. scoreCalcActivityItems.id = item.id;
  1941. scoreCalcActivityItems.use = true;
  1942. scoreCalcLsRecord.items.Add(scoreCalcActivityItems);
  1943. BlobDownloadResult baseblobDownload = await _azureStorage.GetBlobContainerClient(blobname).GetBlobClient($"/records/{item.id}/IES/base.json").DownloadContentAsync();
  1944. ScoreLessonBase lessonBase = baseblobDownload.Content.ToObjectFromJson<ScoreLessonBase>();
  1945. if (lessonBase != null && lessonBase.summary != null)
  1946. {
  1947. lessonBases.Add(lessonBase);
  1948. }
  1949. }
  1950. }
  1951. else
  1952. { // 個人課程
  1953. List<CourseTask_ta> ctList = new();
  1954. // 檢查這個課程的助教跟教授裡面有沒有包含傳進來的teammodelId 有的話用教授取blob的資料
  1955. string sqlCourseTask = $"SELECT distinct b.teacherId, b.assistants FROM c join b in c.schedules where c.pk = 'CourseTask' and (ARRAY_CONTAINS(b.assistants, '{teammodelId}') or b.teacherId = '{teammodelId}') and b.groupId = '{grouplistId}' and c.code = 'CourseTask' and c.courseId = '{courseId}' AND ARRAY_LENGTH(b.assistants) > 0";
  1956. //string sqlCourseTask = $"SELECT s.groupId, s.assistants FROM c JOIN s IN c.schedules WHERE c.pk='CourseTask'AND c.courseId = '{courseId}' AND s.groupId = '{grouplistId}' AND ARRAY_LENGTH(s.assistants) > 0";
  1957. await foreach (var ctitem in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<CourseTask_ta>(queryText: sqlCourseTask))
  1958. {
  1959. ctList.Add(ctitem);
  1960. }
  1961. if (ctList.Count > 0)
  1962. {
  1963. blobname = ctList[0].teacherId;
  1964. if (_azureStorage.GetBlobContainerClient(blobname).GetBlobClient($"/records/{item.id}/IES/base.json").Exists())
  1965. {
  1966. ScoreCalcActivityItems scoreCalcActivityItems = new ScoreCalcActivityItems();
  1967. scoreCalcActivityItems.id = item.id;
  1968. scoreCalcActivityItems.use = true;
  1969. scoreCalcLsRecord.items.Add(scoreCalcActivityItems);
  1970. BlobDownloadResult baseblobDownload = await _azureStorage.GetBlobContainerClient(blobname).GetBlobClient($"/records/{item.id}/IES/base.json").DownloadContentAsync();
  1971. ScoreLessonBase lessonBase = baseblobDownload.Content.ToObjectFromJson<ScoreLessonBase>();
  1972. if (lessonBase != null && lessonBase.summary != null)
  1973. {
  1974. lessonBases.Add(lessonBase);
  1975. }
  1976. }
  1977. }
  1978. else { return false; }
  1979. }
  1980. }
  1981. List<ScoreLessonBase> lessonBasesCalcList = new List<ScoreLessonBase>();
  1982. // 重新比對資料以防 班級人數跟分數的數量對不上
  1983. for (int i = 0; i < lessonBases.Count; i++)
  1984. {
  1985. //因為有可能取出的JSON 學生人數對不準,所以需要另外建一個LessonBase接正確的資料
  1986. ScoreLessonBase lessonBaseCalc = new ScoreLessonBase();
  1987. lessonBaseCalc.summary = lessonBases[i].summary;
  1988. lessonBaseCalc.report = new ScoreReport();
  1989. lessonBaseCalc.report.clientSummaryList = new List<ScoreClientSummaryList>();
  1990. // 設定分數的預設值
  1991. for (int f = 0; f < members.Count; f++)
  1992. {
  1993. ScoreClientSummaryList clientSummaryList = new ScoreClientSummaryList();
  1994. clientSummaryList.attendState = 0;
  1995. clientSummaryList.score = 0;
  1996. clientSummaryList.interactScore = 0;
  1997. lessonBaseCalc.report.clientSummaryList.Add(clientSummaryList);
  1998. }
  1999. for (int j = 0; j < lessonBases[i].student.Count; j++)
  2000. {
  2001. for (int k = 0; k < members.Count; k++)
  2002. {
  2003. //如果有比對中學生id再把分數設定過來
  2004. if (lessonBases[i].student[j].id == members[k].id)
  2005. {
  2006. lessonBaseCalc.report.clientSummaryList[k] = lessonBases[i].report.clientSummaryList[j];
  2007. }
  2008. }
  2009. }
  2010. lessonBasesCalcList.Add(lessonBaseCalc);
  2011. }
  2012. for (int i = 0; i < lessonBasesCalcList.Count; i++)
  2013. {
  2014. // 補上寫進DB的子項目名稱欄位
  2015. scoreCalcLsRecord.items[i].name = lessonBasesCalcList[i].summary.meterialName;
  2016. for (int j = 0; j < lessonRecords.Count; j++)
  2017. {
  2018. if (scoreCalcLsRecord.items[i].id == lessonRecords[j].id)
  2019. {
  2020. scoreCalcLsRecord.items[i].createTime = lessonRecords[j].startTime;
  2021. }
  2022. }
  2023. List<double> stuActAttendScores = new List<double>();
  2024. List<double> stuActPointScores = new List<double>();
  2025. List<double> stuActItactScores = new List<double>();
  2026. if (lessonBasesCalcList[i].report.clientSummaryList.Count > 0)
  2027. {
  2028. for (int j = 0; j < lessonBasesCalcList[i].report.clientSummaryList.Count; j++)
  2029. {
  2030. stuActAttendScores.Add(lessonBasesCalcList[i].report.clientSummaryList[j].attendState);
  2031. stuActPointScores.Add(lessonBasesCalcList[i].report.clientSummaryList[j].score);
  2032. stuActItactScores.Add(lessonBasesCalcList[i].report.clientSummaryList[j].interactScore);
  2033. }
  2034. }
  2035. // 分數填入
  2036. scoreCalcLsRecord.stuActAttendScores.Add(stuActAttendScores);
  2037. scoreCalcLsRecord.stuActPointScores.Add(stuActPointScores);
  2038. scoreCalcLsRecord.stuActItactScores.Add(stuActItactScores);
  2039. scoreCalcLsRecord.stuActAttendOrgVals.Add(stuActAttendScores);
  2040. scoreCalcLsRecord.stuActPointOrgVals.Add(stuActPointScores);
  2041. scoreCalcLsRecord.stuActItactOrgVals.Add(stuActItactScores);
  2042. }
  2043. #endregion
  2044. #region ==== 3. 取系統評量活動成績====
  2045. string sql_exam = "";
  2046. // 取評量分數
  2047. if (ishaveClassId)
  2048. {
  2049. sql_exam = $"SELECT c.examId, c.studentIds, c.sum FROM c where c.info.id = '{classId}'";
  2050. }
  2051. else
  2052. {
  2053. sql_exam = $"SELECT c.examId, c.studentIds, c.sum FROM c where c.info.id = '{grouplistId}'";
  2054. }
  2055. if (ishaveSubjectId)
  2056. {
  2057. sql_exam += $" and c.subjectId = '{subjectId}'";
  2058. }
  2059. StringBuilder sb_examIds = new StringBuilder();
  2060. sb_examIds.Append("'',");
  2061. await foreach (var item in clientCommon.GetItemQueryIterator<ExamItem>(queryText: sql_exam))
  2062. {
  2063. examItem.Add(item);
  2064. }
  2065. for (int i = 0; i < examItem.Count; i++)
  2066. {
  2067. sb_examIds.Append($"'{examItem[i].examId}',");
  2068. }
  2069. // 取評量名稱
  2070. string sql_examName = $"SELECT c.id as examId, c.name, c.startTime FROM c where c.pk = 'Exam' and c.id in ({sb_examIds.ToString().Remove(sb_examIds.Length - 1, 1)})";
  2071. //string sql_examName = $"SELECT c.id as examId, c.name FROM c where c.pk = 'Exam' and c.id in ({sb_examIds.ToString().Remove(sb_examIds.Length - 1, 1)})";
  2072. await foreach (var item in clientCommon.GetItemQueryIterator<ExamItem>(queryText: sql_examName))
  2073. {
  2074. examItemNameStartTime.Add(item);
  2075. }
  2076. List<ExamItem> examItemCalcList = new List<ExamItem>();
  2077. // 重新比對資料以防 班級人數跟分數的數量對不上
  2078. //需要重新確認
  2079. for (int i = 0; i < examItem.Count; i++)
  2080. {
  2081. //因為有可能取出的資料 學生人數對不準,所以需要另外建一個ExamItem接正確的資料
  2082. ExamItem examItemCalc = new ExamItem();
  2083. examItemCalc.examId = examItem[i].examId;
  2084. examItemCalc.sum = new List<double>();
  2085. // 設定分數的預設值
  2086. for (int f = 0; f < members.Count; f++)
  2087. {
  2088. examItemCalc.sum.Add(0);
  2089. }
  2090. for (int j = 0; j < examItem[i].studentIds.Count; j++)
  2091. {
  2092. for (int k = 0; k < members.Count; k++)
  2093. {
  2094. //如果有比對中學生id再把分數設定過來
  2095. if (examItem[i].studentIds[j] == members[k].id)
  2096. {
  2097. examItemCalc.sum[k] = examItem[i].sum[j];
  2098. }
  2099. }
  2100. }
  2101. examItemCalcList.Add(examItemCalc);
  2102. }
  2103. // 檢查是否有評量資料有缺失的 有缺失的話就先移除該筆評量
  2104. for (int i = 0; i < examItemCalcList.Count; i++)
  2105. {
  2106. bool isDataOk = false;
  2107. for (int j = 0; j < examItemNameStartTime.Count; j++)
  2108. {
  2109. if (examItemCalcList[i].examId == examItemNameStartTime[j].examId)
  2110. {
  2111. isDataOk = true;
  2112. }
  2113. }
  2114. if (!isDataOk)
  2115. {
  2116. examItemCalcList.Remove(examItemCalcList[i]);
  2117. }
  2118. }
  2119. //如果評量ID的數量跟撈出來的名稱數量不一致
  2120. // 合併成完整資料
  2121. for (int i = 0; i < examItemCalcList.Count; i++)
  2122. {
  2123. ScoreCalcActivityItems scoreCalcActivityItems = new ScoreCalcActivityItems();
  2124. scoreCalcActivityItems.id = examItemCalcList[i].examId;
  2125. scoreCalcActivityItems.name = examItemNameStartTime[i].name;
  2126. scoreCalcActivityItems.createTime = examItemNameStartTime[i].startTime;
  2127. scoreCalcActivityItems.use = true;
  2128. scoreCalcActivity_eaxm.items.Add(scoreCalcActivityItems);
  2129. scoreCalcActivity_eaxm.stuActScores.Add(examItemCalcList[i].sum);
  2130. scoreCalcActivity_eaxm.stuActScoresOrg.Add(examItemCalcList[i].sum);
  2131. }
  2132. #endregion
  2133. #region ==== 4. 取系統作業活動成績====
  2134. //1. 取得此班級全部作業活動的id
  2135. string sql_homeworkIds = "";
  2136. // 由classId判斷是取甚麼班級
  2137. if (ishaveClassId)
  2138. {
  2139. sql_homeworkIds = $"SELECT c.id, c.name, c.startTime FROM c WHERE c.pk = 'Homework' AND ARRAY_CONTAINS(c.classes, \"{classId}\", true)";
  2140. }
  2141. else
  2142. {
  2143. sql_homeworkIds = $"SELECT c.id, c.name, c.startTime FROM c WHERE c.pk = \"Homework\" AND ARRAY_CONTAINS(c.stuLists, \"{grouplistId}\", true)";
  2144. }
  2145. await foreach (var item in clientCommon.GetItemQueryIterator<HomeworkItem>(queryText: sql_homeworkIds))
  2146. {
  2147. homeworkItems.Add(item);
  2148. }
  2149. //2. 用此班級全部作業活動的id去查詢此班級全部作業活動的分數
  2150. StringBuilder sb_homeworkItemIds = new StringBuilder();
  2151. sb_homeworkItemIds.Append("'',");
  2152. for (int i = 0; i < homeworkItems.Count; i++)
  2153. {
  2154. List<double> scores = new List<double>();
  2155. for (int j = 0; j < members.Count; j++)
  2156. {
  2157. scores.Add(0);
  2158. }
  2159. ScoreCalcActivityItems scoreCalcActivityItems = new ScoreCalcActivityItems();
  2160. scoreCalcActivityItems.id = homeworkItems[i].id;
  2161. scoreCalcActivityItems.name = homeworkItems[i].name;
  2162. scoreCalcActivityItems.createTime = homeworkItems[i].startTime;
  2163. scoreCalcActivityItems.use = true;
  2164. scoreCalcActivity_homework.items.Add(scoreCalcActivityItems);
  2165. scoreCalcActivity_homework.stuActScores.Add(scores);
  2166. scoreCalcActivity_homework.stuActScoresOrg.Add(scores);
  2167. // 組合id
  2168. sb_homeworkItemIds.Append($"'{homeworkItems[i].id}',");
  2169. }
  2170. // 取分數
  2171. string sql_homeworkData = $"SELECT c.pk, c.school, c.code, c.id, c.score FROM c WHERE c.pk = 'HomeworkRecord' and c.id in ({sb_homeworkItemIds.ToString().Remove(sb_homeworkItemIds.Length - 1, 1)}) order by c.code ";
  2172. await foreach (var item in clientStudent.GetItemQueryIterator<HomeworkItem>(queryText: sql_homeworkData))
  2173. {
  2174. homeworkItemsScore.Add(item);
  2175. }
  2176. // 先以子項目id群組化分數
  2177. Dictionary<string, List<HomeworkItem>> hidDataList = homeworkItemsScore.GroupBy(o => o.id).ToDictionary(o => o.Key, o => o.ToList());
  2178. // 整理出完整的學生作業分數資料
  2179. for (int i = 0; i < scoreCalcActivity_homework.items.Count; i++)
  2180. {
  2181. if (hidDataList.ContainsKey(scoreCalcActivity_homework.items[i].id))
  2182. {
  2183. List<HomeworkItem> listhi = hidDataList[scoreCalcActivity_homework.items[i].id];
  2184. for (int j = 0; j < listhi.Count; j++)
  2185. {
  2186. for (int k = 0; k < members.Count; k++)
  2187. {
  2188. if (listhi[j].code == $"{listhi[j].pk}-{listhi[j].school}-{members[k].id}")
  2189. {
  2190. scoreCalcActivity_homework.stuActScores[i][k] = listhi[j].score;
  2191. scoreCalcActivity_homework.stuActScoresOrg[i][k] = listhi[j].score;
  2192. }
  2193. }
  2194. }
  2195. }
  2196. }
  2197. #endregion
  2198. #endregion
  2199. return true;
  2200. }
  2201. /// <summary>
  2202. /// (十四)更新成績統計順序
  2203. /// </summary>
  2204. /// <param name="request"></param>
  2205. /// <returns></returns>
  2206. [ProducesDefaultResponseType]
  2207. [Authorize(Roles = "IES")]
  2208. [HttpPost("update-scorecalc-sort")]
  2209. public async Task<IActionResult> UpdateScoreCalcSort(JsonElement request)
  2210. {
  2211. try
  2212. {
  2213. if (!request.TryGetProperty("teammodelId", out JsonElement teammodelId)) return BadRequest();
  2214. var clientTeacher = _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher);
  2215. UpdateCalcSortRq updateCalcSortRq = JsonConvert.DeserializeObject<UpdateCalcSortRq>(request.ToString());
  2216. for (int i = 0; i < updateCalcSortRq.sortItems.Count; i++)
  2217. {
  2218. //取主表資料
  2219. ScoreCalcBase scoreCalcBase = await clientTeacher.ReadItemAsync<ScoreCalcBase>(updateCalcSortRq.sortItems[i].id.ToString(), new PartitionKey($"ScoreCalc-{teammodelId}"));
  2220. scoreCalcBase.sort = updateCalcSortRq.sortItems[i].sort;
  2221. //更新
  2222. await clientTeacher.ReplaceItemAsync(scoreCalcBase, $"{scoreCalcBase.id}", new PartitionKey(scoreCalcBase.code));
  2223. }
  2224. var result = new
  2225. {
  2226. RtCode = "0",
  2227. RtMsg = "OK"
  2228. };
  2229. return Ok(result);
  2230. }
  2231. catch (Exception e)
  2232. {
  2233. //await _dingDing.SendBotMsg($"OS,{_option.Location},open-api/upsert()\n{e.Message}\n{e.StackTrace}\n{e.StackTrace}", GroupNames.醍摩豆服務運維群組);
  2234. return BadRequest();
  2235. }
  2236. }
  2237. /// <summary>
  2238. /// (十五)更新活動項目順序
  2239. /// </summary>
  2240. /// <param name="request"></param>
  2241. /// <returns></returns>
  2242. [ProducesDefaultResponseType]
  2243. [Authorize(Roles = "IES")]
  2244. [HttpPost("update-scorecalcact-sort")]
  2245. public async Task<IActionResult> UpdateScoreCalcActSort(JsonElement request)
  2246. {
  2247. try
  2248. {
  2249. if (!request.TryGetProperty("teammodelId", out JsonElement teammodelId)) return BadRequest();
  2250. var clientTeacher = _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher);
  2251. UpdateActSortRq updateActSortRq = JsonConvert.DeserializeObject<UpdateActSortRq>(request.ToString());
  2252. for (int i = 0; i < updateActSortRq.sortItems.Count; i++)
  2253. {
  2254. // 取項目表資料
  2255. ScoreCalcActivityBase scoreCalcActivityBase = await clientTeacher.ReadItemAsync<ScoreCalcActivityBase>(updateActSortRq.sortItems[i].id.ToString(), new PartitionKey($"ScoreCalcAct-{teammodelId}"));
  2256. // 先判斷是否為課堂紀錄 根據項目的類別需要調整
  2257. if (scoreCalcActivityBase.type == "lessonrecord")
  2258. {
  2259. ScoreCalcLsRecord scoreCalcLsRecord = await clientTeacher.ReadItemAsync<ScoreCalcLsRecord>(updateActSortRq.sortItems[i].id.ToString(), new PartitionKey($"ScoreCalcAct-{teammodelId}"));
  2260. scoreCalcLsRecord.sort = updateActSortRq.sortItems[i].sort;
  2261. scoreCalcLsRecord = await clientTeacher.ReplaceItemAsync(scoreCalcLsRecord, $"{scoreCalcLsRecord.id}", new PartitionKey(scoreCalcLsRecord.code));
  2262. }
  2263. else
  2264. {
  2265. ScoreCalcActivity scoreCalcActivity = await clientTeacher.ReadItemAsync<ScoreCalcActivity>(updateActSortRq.sortItems[i].id.ToString(), new PartitionKey($"ScoreCalcAct-{teammodelId}"));
  2266. scoreCalcActivity.sort = updateActSortRq.sortItems[i].sort;
  2267. scoreCalcActivity = await clientTeacher.ReplaceItemAsync(scoreCalcActivity, $"{scoreCalcActivity.id}", new PartitionKey(scoreCalcActivity.code));
  2268. }
  2269. }
  2270. var result = new
  2271. {
  2272. RtCode = "0",
  2273. RtMsg = "OK"
  2274. };
  2275. return Ok(result);
  2276. }
  2277. catch (Exception e)
  2278. {
  2279. //await _dingDing.SendBotMsg($"OS,{_option.Location},open-api/upsert()\n{e.Message}\n{e.StackTrace}\n{e.StackTrace}", GroupNames.醍摩豆服務運維群組);
  2280. return BadRequest();
  2281. }
  2282. }
  2283. /// <summary>
  2284. /// (十六)更新活動子項目順序
  2285. /// </summary>
  2286. /// <param name="request"></param>
  2287. /// <returns></returns>
  2288. [ProducesDefaultResponseType]
  2289. [Authorize(Roles = "IES")]
  2290. [HttpPost("update-scorecalcactitem-sort")]
  2291. public async Task<IActionResult> UpdateScoreCalcActItemSort(JsonElement request)
  2292. {
  2293. try
  2294. {
  2295. if (!request.TryGetProperty("teammodelId", out JsonElement teammodelId)) return BadRequest();
  2296. if (!request.TryGetProperty("scoreCalcActId", out JsonElement scoreCalcActId)) return BadRequest();
  2297. var clientTeacher = _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher);
  2298. UpdateActItemSortRq updateActItemSortRq = JsonConvert.DeserializeObject<UpdateActItemSortRq>(request.ToString());
  2299. // 取項目表資料
  2300. ScoreCalcActivityBase scoreCalcActivityBase = await clientTeacher.ReadItemAsync<ScoreCalcActivityBase>(updateActItemSortRq.scoreCalcActId.ToString(), new PartitionKey($"ScoreCalcAct-{teammodelId}"));
  2301. // 先排序傳進來的參數 aesc
  2302. List<sortItem> sortItemsrq = (from e in updateActItemSortRq.sortItems
  2303. orderby e.sort
  2304. select e).ToList();
  2305. // 先判斷是否為課堂紀錄 根據項目的類別需要調整
  2306. if (scoreCalcActivityBase.type == "lessonrecord")
  2307. {
  2308. ScoreCalcLsRecord scoreCalcLsRecordDB = await clientTeacher.ReadItemAsync<ScoreCalcLsRecord>(updateActItemSortRq.scoreCalcActId.ToString(), new PartitionKey($"ScoreCalcAct-{teammodelId}"));
  2309. //存放排序後的參數
  2310. List<List<double>> up_stuActAttendOrgVals = new();
  2311. List<List<double>> up_stuActAttendScores = new();
  2312. List<List<double>> up_stuActPointOrgVals = new();
  2313. List<List<double>> up_stuActPointScores = new();
  2314. List<List<double>> up_stuActItactOrgVals = new();
  2315. List<List<double>> up_stuActItactScores = new();
  2316. List<double> up_itemRates = new();
  2317. //依照傳進來的id 順序修改 分數 比重 項目等順序
  2318. for (int i = 0; i < sortItemsrq.Count; i++)
  2319. {
  2320. for (int j = 0; j < scoreCalcLsRecordDB.items.Count; j++)
  2321. {
  2322. if (sortItemsrq[i].id == scoreCalcLsRecordDB.items[j].id)
  2323. {
  2324. up_stuActAttendOrgVals.Add(scoreCalcLsRecordDB.stuActAttendOrgVals[j]);
  2325. up_stuActAttendScores.Add(scoreCalcLsRecordDB.stuActAttendScores[j]);
  2326. up_stuActPointOrgVals.Add(scoreCalcLsRecordDB.stuActPointOrgVals[j]);
  2327. up_stuActPointScores.Add(scoreCalcLsRecordDB.stuActPointScores[j]);
  2328. up_stuActItactOrgVals.Add(scoreCalcLsRecordDB.stuActItactOrgVals[j]);
  2329. up_stuActItactScores.Add(scoreCalcLsRecordDB.stuActItactScores[j]);
  2330. up_itemRates.Add(scoreCalcLsRecordDB.itemRates[j]);
  2331. scoreCalcLsRecordDB.items[j].sort = sortItemsrq[i].sort;
  2332. }
  2333. }
  2334. }
  2335. scoreCalcLsRecordDB.stuActAttendOrgVals = up_stuActAttendOrgVals;
  2336. scoreCalcLsRecordDB.stuActAttendScores = up_stuActAttendScores;
  2337. scoreCalcLsRecordDB.stuActPointOrgVals = up_stuActPointOrgVals;
  2338. scoreCalcLsRecordDB.stuActPointScores = up_stuActPointScores;
  2339. scoreCalcLsRecordDB.stuActItactOrgVals = up_stuActItactOrgVals;
  2340. scoreCalcLsRecordDB.stuActItactScores = up_stuActItactScores;
  2341. scoreCalcLsRecordDB.itemRates = up_itemRates;
  2342. // 按照更新後的sort排序
  2343. scoreCalcLsRecordDB.items = (from e in scoreCalcLsRecordDB.items
  2344. orderby e.sort
  2345. select e).ToList();
  2346. scoreCalcLsRecordDB = await clientTeacher.ReplaceItemAsync(scoreCalcLsRecordDB, $"{scoreCalcLsRecordDB.id}", new PartitionKey(scoreCalcLsRecordDB.code));
  2347. }
  2348. else
  2349. {
  2350. ScoreCalcActivity scoreCalcActivityDB = await clientTeacher.ReadItemAsync<ScoreCalcActivity>(updateActItemSortRq.scoreCalcActId.ToString(), new PartitionKey($"ScoreCalcAct-{teammodelId}"));
  2351. //存放排序後的參數
  2352. List<List<double>> up_stuActScores = new();
  2353. List<List<double>> up_stuActScoresOrg = new();
  2354. List<double> up_itemRates = new();
  2355. //依照傳進來的id 順序修改 分數 比重 項目等順序
  2356. for (int i = 0; i < sortItemsrq.Count; i++)
  2357. {
  2358. for (int j = 0; j < scoreCalcActivityDB.items.Count; j++)
  2359. {
  2360. if (sortItemsrq[i].id == scoreCalcActivityDB.items[j].id)
  2361. {
  2362. up_stuActScores.Add(scoreCalcActivityDB.stuActScores[j]);
  2363. up_stuActScoresOrg.Add(scoreCalcActivityDB.stuActScoresOrg[j]);
  2364. up_itemRates.Add(scoreCalcActivityDB.itemRates[j]);
  2365. scoreCalcActivityDB.items[j].sort = sortItemsrq[i].sort;
  2366. }
  2367. }
  2368. }
  2369. scoreCalcActivityDB.stuActScores = up_stuActScores;
  2370. scoreCalcActivityDB.stuActScoresOrg = up_stuActScoresOrg;
  2371. scoreCalcActivityDB.itemRates = up_itemRates;
  2372. // 按照更新後的sort排序
  2373. scoreCalcActivityDB.items = (from e in scoreCalcActivityDB.items
  2374. orderby e.sort
  2375. select e).ToList();
  2376. scoreCalcActivityDB = await clientTeacher.ReplaceItemAsync(scoreCalcActivityDB, $"{scoreCalcActivityDB.id}", new PartitionKey(scoreCalcActivityDB.code));
  2377. }
  2378. var result = new
  2379. {
  2380. RtCode = "0",
  2381. RtMsg = "OK"
  2382. };
  2383. return Ok(result);
  2384. }
  2385. catch (Exception e)
  2386. {
  2387. //await _dingDing.SendBotMsg($"OS,{_option.Location},open-api/upsert()\n{e.Message}\n{e.StackTrace}\n{e.StackTrace}", GroupNames.醍摩豆服務運維群組);
  2388. return BadRequest();
  2389. }
  2390. }
  2391. /// <summary>
  2392. /// (十七)查詢項目屬性資料
  2393. /// </summary>
  2394. /// <param name="request"></param>
  2395. /// <returns></returns>
  2396. [ProducesDefaultResponseType]
  2397. [Authorize(Roles = "IES")]
  2398. [HttpPost("get-itemprops")]
  2399. public async Task<IActionResult> GetItemProps(JsonElement request)
  2400. {
  2401. try
  2402. {
  2403. if (!request.TryGetProperty("ids", out JsonElement ids)) return BadRequest();
  2404. if (!request.TryGetProperty("type", out JsonElement type)) return BadRequest();
  2405. request.TryGetProperty("scope", out JsonElement scope);
  2406. bool ishaveScope = !string.IsNullOrWhiteSpace(scope + "");
  2407. string[] idsarr = ids.ToString().Split(',');
  2408. StringBuilder idssb = new StringBuilder();
  2409. if (idsarr.Length > 0)
  2410. {
  2411. foreach (var id in idsarr)
  2412. {
  2413. idssb.Append("'");
  2414. idssb.Append(id);
  2415. idssb.Append("'");
  2416. idssb.Append(",");
  2417. }
  2418. if (idssb.Length > 0)
  2419. {
  2420. idssb.Remove(idssb.Length - 1, 1);
  2421. }
  2422. }
  2423. string sql = "";
  2424. List<ItemProps> ItemPropsList = new List<ItemProps>();
  2425. var clientCommon = _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common);
  2426. var clientSchool = _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School);
  2427. var clientTeacher = _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher);
  2428. switch (type.ToString())
  2429. {
  2430. case "lessonrecord":
  2431. // 如果是課堂紀錄需要多判斷是學校課程還是個人課程 來決定去哪邊撈資料
  2432. if (!ishaveScope) { return BadRequest(); }
  2433. sql = $"SELECT c.id, c.name, c.startTime FROM c where c.id in ({idssb}) and c.pk = 'LessonRecord'";
  2434. if (scope.ToString() == "school")
  2435. {
  2436. await foreach (var item in clientSchool.GetItemQueryIterator<ItemProps>(queryText: sql))
  2437. {
  2438. ItemPropsList.Add(item);
  2439. }
  2440. }
  2441. else
  2442. {
  2443. await foreach (var item in clientTeacher.GetItemQueryIterator<ItemProps>(queryText: sql))
  2444. {
  2445. ItemPropsList.Add(item);
  2446. }
  2447. }
  2448. break;
  2449. case "exam":
  2450. sql = $"SELECT c.id, c.name, c.startTime, c.source as type FROM c where c.id in ({idssb}) and c.pk = 'Exam'";
  2451. await foreach (var item in clientCommon.GetItemQueryIterator<ItemProps>(queryText: sql))
  2452. {
  2453. ItemPropsList.Add(item);
  2454. }
  2455. break;
  2456. case "homework":
  2457. sql = $"SELECT c.id, c.name, c.startTime FROM c where c.id in ({idssb}) and c.pk = 'Homework'";
  2458. await foreach (var item in clientCommon.GetItemQueryIterator<ItemProps>(queryText: sql))
  2459. {
  2460. ItemPropsList.Add(item);
  2461. }
  2462. break;
  2463. }
  2464. return Ok(ItemPropsList);
  2465. }
  2466. catch (Exception e)
  2467. {
  2468. //await _dingDing.SendBotMsg($"OS,{_option.Location},open-api/upsert()\n{e.Message}\n{e.StackTrace}\n{e.StackTrace}", GroupNames.醍摩豆服務運維群組);
  2469. return BadRequest();
  2470. }
  2471. }
  2472. /// <summary>
  2473. /// 查詢CourseTask用類別
  2474. /// </summary>
  2475. private class CourseTask_ta
  2476. {
  2477. /// <summary>
  2478. /// teacherId
  2479. /// </summary>
  2480. public string teacherId { get; set; }
  2481. /// <summary>
  2482. /// assistants
  2483. /// </summary>
  2484. public List<string> assistants { get; set; } = new List<string>();
  2485. }
  2486. }
  2487. }