1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990 |
- using Azure.Cosmos;
- using Azure.Storage.Blobs.Models;
- using Azure.Storage.Sas;
- using Microsoft.AspNetCore.Authorization;
- using Microsoft.AspNetCore.Http;
- using Microsoft.AspNetCore.Mvc;
- using Microsoft.Extensions.Options;
- using System;
- using System.Collections.Generic;
- using System.IdentityModel.Tokens.Jwt;
- using System.IO;
- using System.Linq;
- using System.Text;
- using System.Text.Json;
- using System.Threading.Tasks;
- using TEAMModelOS.Models;
- using TEAMModelOS.Filter;
- using TEAMModelOS.SDK.DI;
- using TEAMModelOS.SDK.Extension;
- using Microsoft.Azure.Cosmos.Table;
- using TEAMModelOS.SDK.Models;
- using System.Dynamic;
- using HTEXLib.COMM.Helpers;
- using StackExchange.Redis;
- using TEAMModelOS.SDK.Models.Cosmos.Common;
- using TEAMModelOS.SDK;
- using Microsoft.Extensions.Configuration;
- using Azure.Messaging.ServiceBus;
- using TEAMModelOS.SDK.Services;
- using TEAMModelOS.SDK.Models.Service;
- using TEAMModelOS.Models.Request;
- using Azure;
- namespace TEAMModelOS.Controllers.Client
- {
- [ProducesResponseType(StatusCodes.Status200OK)]
- [ProducesResponseType(StatusCodes.Status400BadRequest)]
- //[Authorize(Roles = "HiTeach")]
- [Route("hiteach")]
- [ApiController]
- public class HiTeachController : ControllerBase
- {
- private readonly AzureStorageFactory _azureStorage;
- private readonly AzureRedisFactory _azureRedis;
- private readonly AzureCosmosFactory _azureCosmos;
- private readonly DingDing _dingDing;
- private readonly Option _option;
- private readonly SnowflakeId _snowflakeId;
- private readonly AzureServiceBusFactory _serviceBus;
- private readonly IConfiguration _configuration;
- private readonly CoreAPIHttpService _coreAPIHttpService;
- private readonly IPSearcher _searcher;
- private readonly HttpTrigger _httpTrigger;
- public HiTeachController(
- AzureStorageFactory azureStorage,
- AzureRedisFactory azureRedis,
- AzureCosmosFactory azureCosmos,
- DingDing dingDing,
- SnowflakeId snowflakeId,
- IOptionsSnapshot<Option> option,
- AzureServiceBusFactory serviceBus,
- IConfiguration configuration,
- CoreAPIHttpService coreAPIHttpService, IPSearcher searcher, HttpTrigger httpTrigger)
- {
- _azureStorage = azureStorage;
- _azureRedis = azureRedis;
- _azureCosmos = azureCosmos;
- _dingDing = dingDing;
- _snowflakeId = snowflakeId;
- _option = option?.Value;
- _serviceBus = serviceBus;
- _configuration = configuration;
- _coreAPIHttpService = coreAPIHttpService;
- _searcher = searcher;
- _httpTrigger = httpTrigger;
- }
- /// <summary>
- /// 更新课堂记录
- /// </summary>
- /// <param name="request"></param>
- /// <returns></returns>
- //[Authorize(Roles = "HiTeach")]
- [ProducesDefaultResponseType]
- [HttpPost("update-lesson-record")]
- public async Task<IActionResult> UpdateLessonRecord(JsonElement request)
- {
- var client = _azureCosmos.GetCosmosClient();
- if (!request.TryGetProperty("lesson_id", out JsonElement _lessonId)) return BadRequest();
- if (!request.TryGetProperty("tmdid", out JsonElement _tmdid)) return BadRequest();
- request.TryGetProperty("name", out JsonElement name);
- request.TryGetProperty("school", out JsonElement _school);
- if (!request.TryGetProperty("scope", out JsonElement _scope)) return BadRequest();
- request.TryGetProperty("grant_types", out JsonElement _grant_types);
- string tbname;
- string code;
- if (_scope.GetString().Equals("school") && !string.IsNullOrWhiteSpace(_school.GetString()))
- {
- code = $"LessonRecord-{_school}";
- tbname = "School";
- }
- else if ($"{_scope}".Equals("private"))
- {
- code = $"LessonRecord";
- tbname = "Teacher";
- }
- else
- {
- return BadRequest();
- }
- try
- {
- LessonRecord lessonRecord = await client.GetContainer(Constant.TEAMModelOS, tbname).ReadItemAsync<LessonRecord>($"{_lessonId}", new PartitionKey(code));
- List<LessonUpdate> updates = new List<LessonUpdate>() { new LessonUpdate { grant_type = "up-base" } };
- if (_grant_types.ValueKind.Equals(JsonValueKind.Array))
- {
- updates = _grant_types.ToObject<List<LessonUpdate>>();
- if (!updates.Select(x => x.grant_type).Contains("up-base"))
- {
- updates.Add(new LessonUpdate { grant_type = "up-base" });
- }
- }
- if (!string.IsNullOrWhiteSpace($"{name}"))
- {
- lessonRecord.name = $"{name}";
- await client.GetContainer(Constant.TEAMModelOS, tbname).ReplaceItemAsync<LessonRecord>(lessonRecord, $"{_lessonId}", new PartitionKey(code));
- }
- var ActiveTask = _configuration.GetValue<string>("Azure:ServiceBus:ActiveTask");
- string msg = null;
- msg = new { lesson_id = $"{_lessonId}", tmdid = $"{_tmdid}", grant_types = updates, school = $"{_school}", scope = $"{_scope}" }.ToJsonString();
- var messageChange = new ServiceBusMessage(msg);
- messageChange.ApplicationProperties.Add("name", "LessonRecordEvent");
- //await _dingDing.SendBotMsg($"{_option.Location},课堂id:{_lessonId} 更新事件,{msg}", GroupNames.醍摩豆服務運維群組);
- await _serviceBus.GetServiceBusClient().SendMessageAsync(ActiveTask, messageChange);
- return Ok(new { status = 200 });
- }
- catch (CosmosException ex) when (ex.Status == 404)
- {
- await _dingDing.SendBotMsg($"更新课堂记录出错\n{ex.StackTrace}{ex.Message}", GroupNames.成都开发測試群組);
- return BadRequest("课堂记录不存在");
- }
- catch (Exception ex)
- {
- await _dingDing.SendBotMsg($"更新课堂记录出错\n{ex.StackTrace}{ex.Message}", GroupNames.成都开发測試群組);
- return BadRequest();
- }
- }
- /// <summary>
- /// 创建课堂开课记录(新版)
- /// </summary>
- /// <param name="request"></param>
- /// <returns></returns>
- [Authorize(Roles = "HiTeach")]
- [ProducesDefaultResponseType]
- [HttpPost("create-lesson")]
- public async Task<IActionResult> CreateLesson(CreateLessondRequest request)
- {
- try
- {
- string id_token = HttpContext.GetXAuth("IdToken");
- //判斷ID Token
- if (string.IsNullOrWhiteSpace(id_token)) return BadRequest();
- var jwt = new JwtSecurityToken(id_token);
- if (!jwt.Payload.Iss.Equals("account.teammodel", StringComparison.OrdinalIgnoreCase)) return BadRequest();
- var tid = jwt.Payload.Sub;
- //初始化
- var r8 = _azureRedis.GetRedisClient(8);
- var db = _azureCosmos.GetCosmosClient();
- var sbm = new List<ServiceBusMessage>();
- var sp = request.sp.Equals("school", StringComparison.OrdinalIgnoreCase);
- int size = 0; //學校或個人總空間
- int tsize = 0; //學校分配給老師的總空間
- double usize = 0; //學校或個人已使用空間
- string timezone = string.Empty;
- if (sp)
- {
- //取得學校資訊
- if (string.IsNullOrWhiteSpace(request.school)) return BadRequest();
- await foreach (Response item in db.GetContainer(Constant.TEAMModelOS, Constant.School).GetItemQueryStreamIterator(
- queryText: $"SELECT TOP 1 c.id, c.size, c.tsize, c.timeZone FROM c WHERE c.id = '{request.school}'",
- requestOptions: new() { PartitionKey = new("Base") }))
- {
- using var json = await JsonDocument.ParseAsync(item.ContentStream);
- if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
- {
- var school = json.RootElement.GetProperty("Documents").EnumerateArray().First();
- timezone = school.GetProperty("timeZone").GetProperty("value").GetString();
- size = school.GetProperty("size").GetInt32();
- tsize = school.TryGetProperty("tsize", out var tsvalue) ? tsvalue.GetInt32() : 0;
- }
- else return BadRequest();
- }
- }
- else
- {
- Teacher teacher = await db.GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemAsync<Teacher>(tid, new PartitionKey("Base"));
- size = teacher.size;
- foreach (var school in teacher.schools)
- {
- SchoolTeacher st = await db.GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemAsync<SchoolTeacher>(tid, new PartitionKey($"Teacher-{school.schoolId}"));
- size += st.size;
- }
- }
- //計算學校或個人的使用空間
- RedisValue redisValue = r8.HashGet($"Blob:Record", $"{(sp ? request.school : tid)}");
- if (redisValue.HasValue && long.TryParse(redisValue.ToString(), out var bsize))
- {
- usize = Math.Round(bsize / 1073741824.0 - (sp ? tsize : 0), 2, MidpointRounding.AwayFromZero); //1073741824 1G
- }
- else //如果檢測不到緩存,觸發刷新計算空間
- {
- await BlobService.RefreshBlobRoot(new BlobRefreshMessage { progress = "update", root = "records", name = $"{(sp ? request.school : tid)}" }, _serviceBus, _configuration, _azureRedis);
- }
- //取得學校或個人名單
- (List<RMember> students, _) = await GroupListService.GetMemberByListids(_coreAPIHttpService, db, _dingDing, new List<string>() { request.sid }, request.school);
- //觸發IMEI更新消息
- var stus = students.Select(x => x.id).ToList();
- var imeimsg = new ServiceBusMessage(new { request.channel, userid = request.did, request.school, stus }.ToJsonString());
- imeimsg.ApplicationProperties.Add("name", "Imei");
- sbm.Add(imeimsg);
- //開課記錄保存
- LessonRecord lr = new()
- {
- school = request.sp.Equals("school") ? request?.school : null,
- code = request.sp.Equals("school") ? $"LessonRecord-{request.school}" : $"LessonRecord",
- id = _snowflakeId.NextId().ToString(), //取得授課ID
- courseId = request.cid,
- groupIds = new() { request.sid },
- tmdid = tid,
- scope = request.sp,
- pk = "LessonRecord",
- name = request.cname,
- startTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
- };
- await db.GetContainer(Constant.TEAMModelOS, request.sp.Equals("school") ? "School" : "Teacher").CreateItemAsync(lr, new PartitionKey(lr.code));
- //觸發開課統計
- var messageChange = new ServiceBusMessage(lr.ToJsonString());
- messageChange.ApplicationProperties.Add("name", "LessonRecordEvent");
- sbm.Add(messageChange);
- //批量發送消息
- await _serviceBus.GetServiceBusClient().SendBatchMessageAsync(_configuration.GetValue<string>("Azure:ServiceBus:ActiveTask"), sbm);
-
- if (sp && usize>size)
- {
- ////处理学校开课,空间不足时。检查是否有 当前教师tid,强制保存save<>1,没有标记未删除status<>404,没有被收藏favorite<=0 ,时间最旧的一条记录startTime
- LessonRecord lessonRecord = null;
- string sql = $"SELECT top 1 value(c) FROM c where ( c.expire<=0 or IS_DEFINED(c.expire) = false ) and c.tmdid='{tid}' and c.save<>1 and c.status<>404 and c.favorite<=0 order by c.startTime ";
- await foreach (var item in db.GetContainer(Constant.TEAMModelOS, Constant.School).GetItemQueryIterator<LessonRecord>(
- queryText: sql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"LessonRecord-{request.school}") }))
- {
- lessonRecord = item;
- break;
- }
- if (lessonRecord != null)
- {
- lessonRecord.status = 404;
- await db.GetContainer(Constant.TEAMModelOS, Constant.School).ReplaceItemAsync(lessonRecord, lessonRecord.id, new PartitionKey(lessonRecord.code));
- var ActiveTask = _configuration.GetValue<string>("Azure:ServiceBus:ActiveTask");
- var messageChangeEvent = new ServiceBusMessage(request.ToJsonString());
- messageChangeEvent.ApplicationProperties.Add("name", "LessonRecordEvent");
- await _serviceBus.GetServiceBusClient().SendMessageAsync(ActiveTask, messageChangeEvent);
- //保证客户端可以正常开课。
- usize -= 1;
- }
- else
- { //没有找到匹配当前 教师tid,save<>1,status<>404,没有被收藏,时间最旧的一条记录。无法手动再继续 usize -= 1;,则不能继续开课。
-
- }
- }
-
- return Ok(new { status = 200, lr.id, students, size, usize });
- }
- catch (Exception ex)
- {
- await _dingDing.SendBotMsg($"IES5,{_option.Location}, hiteach/create-lesson:()\n{ex.Message}\n{ex.StackTrace}{request.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
- return BadRequest();
- }
- }
- /// <summary>
- /// 创建课堂开课记录(舊版,已被CreateLesson取代)
- /// </summary>
- /// <param name="request"></param>
- /// <returns></returns>
- [Authorize(Roles = "HiTeach")]
- [ProducesDefaultResponseType]
- [HttpPost("create-lesson-record")]
- public async Task<IActionResult> CreateLessonRecord(JsonElement request)
- {
- if (!request.TryGetProperty("lesson", out JsonElement _lesson)) return BadRequest();
- var client = _azureCosmos.GetCosmosClient();
- LessonRecord lessonRecord = _lesson.ToObject<LessonRecord>();
- int blobTotal = 0;
- long teach = 0;
- string blobName = "";
- if (!string.IsNullOrEmpty(lessonRecord.scope) && !string.IsNullOrEmpty(lessonRecord.tmdid) && !string.IsNullOrEmpty(lessonRecord.id))
- {
- string tbname = null;
- if (lessonRecord.scope.Equals("school") && !string.IsNullOrEmpty(lessonRecord.school))
- {
- School school = await client.GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemAsync<School>(lessonRecord.school, new PartitionKey("Base"));
- lessonRecord.code = $"LessonRecord-{lessonRecord.school}";
- tbname = "School";
- blobTotal = school.size;
- //计算分配给学校教师的空间
- await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryStreamIterator(queryText: $"SELECT sum(c.size) as size FROM c ",
- requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Teacher-{lessonRecord.school}") }))
- {
- var json = await JsonDocument.ParseAsync(item.ContentStream);
- foreach (var elmt in json.RootElement.GetProperty("Documents").EnumerateArray())
- {
- if (elmt.TryGetProperty("size", out JsonElement _size) && _size.ValueKind.Equals(JsonValueKind.Number))
- {
- teach = _size.GetInt32();
- break;
- }
- }
- }
- blobName = lessonRecord.school;
- }
- if (lessonRecord.scope.Equals("private"))
- {
- lessonRecord.code = $"LessonRecord";
- tbname = "Teacher";
- Teacher teacher = await client.GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemAsync<Teacher>(lessonRecord.tmdid, new PartitionKey("Base"));
- blobTotal = teacher.size;
- foreach (var school in teacher.schools)
- {
- SchoolTeacher st = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<SchoolTeacher>(lessonRecord.tmdid, new PartitionKey($"Teacher-{school.schoolId}"));
- blobTotal += st.size;
- }
- blobName = lessonRecord.tmdid;
- }
- RedisValue redisValue = _azureRedis.GetRedisClient(8).HashGet($"Blob:Record", $"{blobName}");
- long blobsize = 0;
- if (redisValue != default && !redisValue.IsNullOrEmpty)
- {
- JsonElement record = redisValue.ToString().ToObject<JsonElement>();
- if (record.TryGetInt64(out blobsize))
- {
- }
- }
- else
- {
- await BlobService.RefreshBlobRoot(new BlobRefreshMessage { progress = "update", root = "records", name = $"{blobName}" }, _serviceBus, _configuration, _azureRedis);
- }
- double blobUsed = blobsize / 1073741824.0 + teach; //1073741824 1G
- if (tbname == null)
- {
- return BadRequest("参数异常:scope应为school或private,scope=school ,school字段不能为空");
- }
- if (lessonRecord.startTime == 0)
- {
- lessonRecord.startTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
- }
- lessonRecord.pk = "LessonRecord";
- try
- {
- await client.GetContainer(Constant.TEAMModelOS, tbname).CreateItemAsync(lessonRecord, new PartitionKey(lessonRecord.code));
- var ActiveTask = _configuration.GetValue<string>("Azure:ServiceBus:ActiveTask");
- var messageChange = new ServiceBusMessage(lessonRecord.ToJsonString());
- messageChange.ApplicationProperties.Add("name", "LessonRecordEvent");
- await _serviceBus.GetServiceBusClient().SendMessageAsync(ActiveTask, messageChange);
- return Ok(new { status = 200, blobTotal, blobUsed });
- }
- catch (Exception ex)
- {
- await _dingDing.SendBotMsg($"IES5,{_option.Location}, hiteach/create-lesson-record:()\n{ex.Message}\n{ex.StackTrace}{request.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
- return BadRequest();
- }
- }
- else
- {
- return BadRequest();
- }
- }
- [Authorize(Roles = "HiTeach")]
- [ProducesDefaultResponseType]
- [HttpPost("get-teacher-info")]
- public async Task<IActionResult> GetTeacherInfo()
- {
- //Debug
- //string json = System.Text.Json.JsonSerializer.Serialize(id_token);
- try
- {
- string id_token = HttpContext.GetXAuth("IdToken");
- (string ip, string region) = await LoginService.LoginIp(HttpContext, _searcher);
- if (string.IsNullOrEmpty(id_token)) return BadRequest();
- var jwt = new JwtSecurityToken(id_token);
- if (!jwt.Payload.Iss.Equals("account.teammodel", StringComparison.OrdinalIgnoreCase)) return BadRequest();
- var id = jwt.Payload.Sub;
- jwt.Payload.TryGetValue("name", out object name);
- jwt.Payload.TryGetValue("picture", out object picture);
- List<object> schools = new List<object>();
- string defaultschool = null;
- //TODK 取得Teacher 個人相關數據(課程清單、虛擬教室清單、歷史紀錄清單等),學校數據另外API處理,多校切換時不同
- var client = _azureCosmos.GetCosmosClient();
- var response = await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReadItemStreamAsync(id, new PartitionKey("Base"));
- if (response.Status == 200)
- {
- var jsonsc = await JsonDocument.ParseAsync(response.ContentStream);
- if (jsonsc.RootElement.TryGetProperty("schools", out JsonElement value))
- {
- GetTeacherInfoApiSchool schoolExtobj;
- foreach (var obj in value.EnumerateArray())
- {
- string statusNow = obj.GetProperty("status").ToString();
- if (statusNow.Equals("join")) //成為老師的才放入
- {
- var schoolJson = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemStreamAsync($"{obj.GetProperty("schoolId")}", new PartitionKey("Base"));
- var school = await JsonDocument.ParseAsync(schoolJson.ContentStream);
- schoolExtobj = new GetTeacherInfoApiSchool();
- schoolExtobj.schoolId = Convert.ToString(obj.GetProperty("schoolId"));
- schoolExtobj.name = Convert.ToString(school.RootElement.GetProperty("name"));
- schoolExtobj.status = Convert.ToString(obj.GetProperty("status"));
- schoolExtobj.picture = Convert.ToString(school.RootElement.GetProperty("picture"));
- schools.Add(schoolExtobj);
- var sctch = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemStreamAsync(id, new PartitionKey($"Teacher-{obj.GetProperty("schoolId")}"));
- if (sctch.Status == 200 && sctch != null && sctch.ContentStream != null)
- {
- var jsonDoc = await JsonDocument.ParseAsync(sctch.ContentStream);
- SchoolTeacher schoolTeacher = jsonDoc.RootElement.ToObject<SchoolTeacher>();
- }
- }
- }
- }
- //預設學校ID
- if (jsonsc.RootElement.TryGetProperty("defaultSchool", out JsonElement valueD) && !string.IsNullOrEmpty(valueD.ToString()))
- {
- defaultschool = valueD.ToString();
- }
- }
- else
- {
- //如果沒有,則初始化Teacher基本資料到Cosmos
- Teacher teacher = new Teacher
- {
- createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
- id = id,
- pk = "Base",
- code = "Base",
- name = name?.ToString(),
- picture = picture?.ToString(),
- //创建账号并第一次登录IES5则默认赠送1G
- size = 1,
- defaultSchool = null,
- schools = new List<Teacher.TeacherSchool>(),
- };
- teacher = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").CreateItemAsync<Teacher>(teacher, new PartitionKey("Base"));
- }
- //老師個人課程清單
- List<GetTeacherInfoApiCourse> courses = new List<GetTeacherInfoApiCourse>();
- await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryStreamIterator(queryText: $"SELECT c.id, c.name, c.schedule, c.scope FROM c ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Course-{id}") }))
- {
- var jsontcs = await JsonDocument.ParseAsync(item.ContentStream);
- if (jsontcs.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
- {
- GetTeacherInfoApiCourse courseExtobj;
- List<GetTeacherInfoApiCourseClass> classes;
- foreach (var obj in jsontcs.RootElement.GetProperty("Documents").EnumerateArray())
- {
- courseExtobj = new GetTeacherInfoApiCourse();
- courseExtobj.id = Convert.ToString(obj.GetProperty("id"));
- courseExtobj.name = Convert.ToString(obj.GetProperty("name"));
- courseExtobj.scope = Convert.ToString(obj.GetProperty("scope"));
- classes = new List<GetTeacherInfoApiCourseClass>();
- if (obj.TryGetProperty("schedule", out JsonElement schedule))
- {
- GetTeacherInfoApiCourseClass classExtobj;
- foreach (var scheduleobj in schedule.EnumerateArray())
- {
- classExtobj = new GetTeacherInfoApiCourseClass();
- classExtobj.id = null;
- classExtobj.code = null;
- classExtobj.teacher = null;
- if (scheduleobj.TryGetProperty("teacherId", out JsonElement teacherId) && !string.IsNullOrWhiteSpace(Convert.ToString(teacherId)))
- {
- await foreach (var teaitem in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryStreamIterator(queryText: $"SELECT c.id, c.name FROM c WHERE c.id = '{teacherId}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Base") }))
- {
- var jsontea = await JsonDocument.ParseAsync(teaitem.ContentStream);
- foreach (var teaobj in jsontea.RootElement.GetProperty("Documents").EnumerateArray())
- {
- classExtobj.teacher = new GetTeacherInfoApiSimlpeBase();
- classExtobj.teacher = teaobj.ToObject<GetTeacherInfoApiSimlpeBase>();
- }
- }
- }
- classExtobj.scope = "private";
- int stuCount = 0;
- string stuListId = Convert.ToString(scheduleobj.GetProperty("stulist"));
- classExtobj.stuListId = stuListId;
- await foreach (var stuitem in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryStreamIterator(queryText: $"SELECT c.id, c.name, c.tcount, c.scount FROM c WHERE c.id = '{stuListId}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("GroupList") }))
- {
- //取得學生總數
- var jsonstu = await JsonDocument.ParseAsync(stuitem.ContentStream);
- foreach (var stuobj in jsonstu.RootElement.GetProperty("Documents").EnumerateArray())
- {
- classExtobj.name = Convert.ToString(stuobj.GetProperty("name"));
- stuCount += stuobj.GetProperty("scount").GetInt32();
- stuCount += stuobj.GetProperty("tcount").GetInt32();
- }
- }
- classExtobj.stuCnt = stuCount;
- classExtobj.grpCnt = 0;
- classExtobj.gradeId = null;
- classExtobj.year = 0;
- classes.Add(classExtobj);
- }
- }
- courseExtobj.classes = classes;
- courses.Add(courseExtobj);
- }
- }
- }
- //取得老師個人評測
- List<object> exams = new List<object>();
- //取得評測ID List (HiTeach只取source='1'(課中评量) && progress = 'going'(進行中))
- List<string> examIdList = new List<string>();
- await foreach (var exam in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryStreamIterator(queryText: $"SELECT c.id FROM c where (c.status<>404 or IS_DEFINED(c.status) = false ) and c.source = '1' AND c.progress = 'going'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Exam-{id}") }))
- {
- using var json = await JsonDocument.ParseAsync(exam.ContentStream);
- if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
- {
- foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
- {
- examIdList.Add(obj.GetProperty("id").GetString());
- }
- }
- }
- //取得有作答的評測班級
- Dictionary<string, List<string>> examClassFinDic = new Dictionary<string, List<string>>();
- await foreach (var exam in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryStreamIterator(queryText: $"SELECT c.examId, c.info.id as classId FROM c where (c.status<>404 or IS_DEFINED(c.status) = false ) and ARRAY_CONTAINS({JsonSerializer.Serialize(examIdList)}, c.examId) AND c.progress=true", requestOptions: new QueryRequestOptions() { }))
- {
- var jsonecr = await JsonDocument.ParseAsync(exam.ContentStream);
- if (jsonecr.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
- {
- foreach (var obj in jsonecr.RootElement.GetProperty("Documents").EnumerateArray())
- {
- string examId = obj.GetProperty("examId").ToString();
- string classId = obj.GetProperty("classId").ToString();
- if (examClassFinDic.ContainsKey(examId) && !examClassFinDic[examId].Contains(classId))
- {
- examClassFinDic[examId].Add(classId);
- }
- else
- {
- List<string> classIdList = new List<string>();
- classIdList.Add(classId);
- examClassFinDic.Add(examId, classIdList);
- }
- }
- }
- }
- //取得評測資料
- await foreach (var exam in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryStreamIterator(queryText: $"SELECT c.code, c.id, c.name, c.createTime, c.startTime, c.endTime ,c.year, c.source, c.type, c.progress, c.stuCount, c.scope, c.owner, c.period, c.grades, c.subjects, c.classes, c.stuLists, ARRAY(SELECT p.id, p.code, p.name, p.blob, p.scope FROM p IN c.papers) AS papers FROM c WHERE ARRAY_CONTAINS({JsonSerializer.Serialize(examIdList)}, c.id)", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Exam-{id}") }))
- {
- var jsonex = await JsonDocument.ParseAsync(exam.ContentStream);
- if (jsonex.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
- {
- dynamic examExtobj;
- foreach (var obj in jsonex.RootElement.GetProperty("Documents").EnumerateArray())
- {
- examExtobj = new ExpandoObject();
- string examId = obj.GetProperty("id").GetString();
- examExtobj.code = obj.GetProperty("code");
- examExtobj.id = examId;
- examExtobj.name = obj.GetProperty("name");
- examExtobj.createTime = obj.GetProperty("createTime");
- examExtobj.startTime = obj.GetProperty("startTime");
- examExtobj.endTime = obj.GetProperty("endTime");
- examExtobj.year = obj.GetProperty("year");
- examExtobj.source = obj.GetProperty("source");
- examExtobj.type = obj.GetProperty("type");
- examExtobj.progress = obj.GetProperty("progress");
- examExtobj.stuCount = obj.GetProperty("stuCount");
- examExtobj.scope = obj.GetProperty("scope");
- examExtobj.owner = obj.GetProperty("owner");
- examExtobj.period = obj.GetProperty("period");
- examExtobj.grades = obj.GetProperty("grades");
- examExtobj.subjects = obj.GetProperty("subjects");
- examExtobj.classes = (obj.TryGetProperty("classes", out JsonElement classes)) ? classes.ToObject<List<string>>() : new List<string>();
- examExtobj.stuLists = (obj.TryGetProperty("stuLists", out JsonElement stuLists)) ? stuLists.ToObject<List<string>>() : new List<string>();
- examExtobj.finishClasses = (examClassFinDic.ContainsKey(examId)) ? examClassFinDic[examId] : new List<string>();
- examExtobj.papers = obj.GetProperty("papers");
- //examExtobj = obj.ToObject<object>();
- exams.Add(examExtobj);
- }
- }
- }
- //用户在线记录
- try
- {
- _ = _httpTrigger.RequestHttpTrigger(new { school = defaultschool, scope = $"{Constant.ScopeTeacher}", id = $"{id}", ip = $"{ip}", expire = 1 }, _option.Location, "online-record");
- }
- catch { }
- //取得Teacher Blob 容器位置及SAS
- var container = _azureStorage.GetBlobContainerClient(id);
- await container.CreateIfNotExistsAsync(PublicAccessType.None); //嘗試創建Teacher私有容器,如存在則不做任何事,保障容器一定存在
- var (blob_uri, blob_sas) = _azureStorage.GetBlobContainerSAS(id, BlobContainerSasPermissions.Write | BlobContainerSasPermissions.Read | BlobContainerSasPermissions.List | BlobContainerSasPermissions.Delete);
- var (blob_uri_read, blob_sas_read) = _azureStorage.GetBlobContainerSAS(id, BlobContainerSasPermissions.Read);
- var (blob_uri_write, blob_sas_write) = _azureStorage.GetBlobContainerSAS(id, BlobContainerSasPermissions.Write);
- return Ok(new { blob_uri, blob_sas, blob_sas_read, blob_sas_write, schools, defaultschool, courses, exams });
- }
- catch (Exception ex)
- {
- await _dingDing.SendBotMsg($"IES5,{_option.Location},hiteach/GetTeacherInfo()\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
- return BadRequest();
- }
- }
- [Authorize(Roles = "HiTeach")]
- [ProducesDefaultResponseType]
- [HttpPost("get-school-info")]
- public async Task<IActionResult> GetSchoolInfo(JsonElement request)
- {
- try
- {
- string id_token = HttpContext.GetXAuth("IdToken");
- (string ip, string region) = await LoginService.LoginIp(HttpContext, _searcher);
- if (string.IsNullOrEmpty(id_token)) return BadRequest();
- if (!request.TryGetProperty("school_code", out JsonElement school_code)) return BadRequest();
- var jwt = new JwtSecurityToken(id_token);
- if (!jwt.Payload.Iss.Equals("account.teammodel", StringComparison.Ordinal)) return BadRequest();
- var id = jwt.Payload.Sub;
- var client = _azureCosmos.GetCosmosClient();
- //取得學校學段、年級、科目、考試類型
- List<object> periods = new List<object>();
- List<object> grades = new List<object>();
- List<object> subjects = new List<object>();
- List<object> examTypes = new List<object>();
- School school_base = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<School>($"{school_code}", new PartitionKey("Base"));
- if (!string.IsNullOrWhiteSpace(school_base.id))
- {
- foreach(Period periodinfo in school_base.period)
- {
- periods.Add(new { id= periodinfo.id, name= periodinfo.name });
- int gradeIndex = 0;
- foreach (string gradeName in periodinfo.grades)
- {
- grades.Add(new { id = gradeIndex.ToString(), name = gradeName, periodId = periodinfo.id });
- gradeIndex++;
- }
- foreach (Subject subjectinfo in periodinfo.subjects)
- {
- subjects.Add(new { id = subjectinfo.id, name = subjectinfo.name, periodId = periodinfo.id });
- }
- foreach (var examType in periodinfo.analysis.type)
- {
- examTypes.Add(examType);
- }
- }
- }
- else //無此學校資料
- {
- return BadRequest();
- }
- //該老師排定的學校課程
- List<object> courses = new List<object>();
- List<string> classIds = new List<string>(); //班級ID列表 篩選校園評測用
- List<string> groupIds = new List<string>(); //團體ID列表 篩選校園評測用
- //取得所有班级
- (List<Class> school_classes, _) = await SchoolService.DoGraduateClasses(_httpTrigger, _azureCosmos, null, school_base, _option, _dingDing);
- //取得學校安排老師課程
- var query = $"SELECT DISTINCT c.id, c.name, c.scope, c.subject, c.period.id AS periodId, schedule.classId AS scheduleClassId, schedule.teacher AS scheduleTeacher, schedule.stulist AS scheduleStulist, schedule.notice AS scheduleNotice FROM c JOIN schedule IN c.schedule WHERE schedule.teacherId = '{id}'";
- //var query = $"SELECT c.id, c.name, c.teacher, cc.course, c.scope FROM c JOIN cc IN c.courses JOIN cct IN cc.teachers WHERE cct.id = '{id}'";
- await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Course-{school_code}") }))
- {
- var jsoncs = await JsonDocument.ParseAsync(item.ContentStream);
- if (jsoncs.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
- {
- foreach (var obj in jsoncs.RootElement.GetProperty("Documents").EnumerateArray())
- {
- dynamic classExtobj = new ExpandoObject();
- classExtobj.id = null;
- classExtobj.code = null;
- classExtobj.name = null;
- classExtobj.scope = null;
- classExtobj.gradeId = null;
- classExtobj.gradeName = null;
- classExtobj.year = 0;
- classExtobj.teacher = null;
- classExtobj.stuListId = null;
- classExtobj.stuCnt = 0;
- classExtobj.grpCnt = 0;
- //編制班
- string classIdNow = string.Empty;
- if (obj.TryGetProperty("scheduleClassId", out JsonElement scheduleClassId))
- {
- classIdNow = Convert.ToString(scheduleClassId);
- }
- if (!string.IsNullOrWhiteSpace(classIdNow))
- {
- Class classInfo = school_classes.Where((Class x) => x.id == classIdNow).FirstOrDefault();
- if(classInfo != null && !string.IsNullOrWhiteSpace(classInfo.id))
- {
- classIds.Add(classInfo.id);
- classExtobj.id = classInfo.id;
- classExtobj.code = classInfo.code;
- classExtobj.name = classInfo.name;
- classExtobj.year = classInfo.year;
- classExtobj.teacher = classInfo.teacher;
- //取得學生數
- var queryclstc = $"SELECT Count(1) AS stuCnt FROM c WHERE c.classId = '{classIdNow}'";
- await foreach (var itemclstc in client.GetContainer(Constant.TEAMModelOS, "Student").GetItemQueryStreamIterator(queryText: queryclstc, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base-{school_code}") }))
- {
- var jsonclstc = await JsonDocument.ParseAsync(itemclstc.ContentStream);
- foreach (var objstc in jsonclstc.RootElement.GetProperty("Documents").EnumerateArray())
- {
- classExtobj.stuCnt = objstc.GetProperty("stuCnt").GetInt32();
- }
- }
- //取得分組數
- var queryclgp = $"SELECT c.groupId FROM c WHERE c.classId = '{classIdNow}' AND IS_NULL(c.groupId)=false GROUP BY c.groupId";
- await foreach (var itemgp in client.GetContainer(Constant.TEAMModelOS, "Student").GetItemQueryStreamIterator(queryText: queryclgp, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base-{school_code}") }))
- {
- var jsongp = await JsonDocument.ParseAsync(itemgp.ContentStream);
- if (jsongp.RootElement.TryGetProperty("_count", out JsonElement gpcount) && gpcount.GetInt32() > 0)
- {
- classExtobj.grpCnt = gpcount.GetInt32();
- }
- }
- //取得年級
- if (obj.TryGetProperty("periodId", out JsonElement curPeriodIdJson))
- {
- string curPeriodId = curPeriodIdJson.GetString();
- Period curPeriod = school_base.period.Where((Period x) => x.id == curPeriodId).FirstOrDefault();
- if(curPeriodId != null)
- {
- var gradeInfo = getGradeInfoByYear(classInfo.year, curPeriod);
- if(!string.IsNullOrWhiteSpace(gradeInfo.id))
- {
- classExtobj.gradeId = gradeInfo.id;
- classExtobj.gradeName = gradeInfo.name;
- }
- }
- }
-
- }
- }
- //選課班 (過期者不選)
- long nowtime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
- var stuListId = obj.GetProperty("scheduleStulist");
- if (!stuListId.ValueKind.Equals(JsonValueKind.Null) && !string.IsNullOrWhiteSpace(stuListId.GetString()))
- {
- classExtobj.stuListId = Convert.ToString(stuListId);
- await foreach (var stuitem in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryStreamIterator(queryText: $"SELECT c.code, c.id, c.name, c.year, c.tcount, c.scount FROM c WHERE c.id = '{stuListId}' AND (NOT IS_DEFINED(c.expire) OR {nowtime} <= c.expire )", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"GroupList-{school_code}") }))
- {
- var jsonstu = await JsonDocument.ParseAsync(stuitem.ContentStream);
- foreach (var stuobj in jsonstu.RootElement.GetProperty("Documents").EnumerateArray())
- {
- groupIds.Add(Convert.ToString(stuobj.GetProperty("id")));
- classExtobj.id = Convert.ToString(stuobj.GetProperty("id"));
- classExtobj.code = Convert.ToString(stuobj.GetProperty("code"));
- classExtobj.name = Convert.ToString(stuobj.GetProperty("name"));
- classExtobj.gradeId = null;
- classExtobj.year = (stuobj.TryGetProperty("year", out JsonElement yearJson)) ? yearJson.GetInt32() : 0;
- classExtobj.teacher = null;
- classExtobj.stuCnt += stuobj.GetProperty("tcount").GetInt32();
- classExtobj.stuCnt += stuobj.GetProperty("scount").GetInt32();
- }
- }
- }
- //課程
- string courseIdNow = obj.GetProperty("id").ToString();
- var courseExist = courses.Where((dynamic x) => x.id == courseIdNow).FirstOrDefault();
- if (courseExist == null)
- {
- dynamic courseExtobj = new ExpandoObject();
- courseExtobj.id = courseIdNow;
- courseExtobj.name = obj.GetProperty("name").ToString();
- courseExtobj.scope = obj.GetProperty("scope").ToString();
- courseExtobj.classes = new List<object>();
- courseExtobj.subject = obj.GetProperty("subject");
- //classExtobj.teacher = scheduleTeacherInfo;
- if (!string.IsNullOrWhiteSpace(classExtobj.id))
- {
- courseExtobj.classes.Add(classExtobj);
- }
- courses.Add(courseExtobj);
- }
- else
- {
- //classExtobj.teacher = scheduleTeacherInfo;
- if (!string.IsNullOrWhiteSpace(classExtobj.id))
- {
- courseExist.classes.Add(classExtobj);
- }
- }
- }
- }
- }
- //取得校園評測 (HiTeach只取source='1'(課中评量) && progress = 'going'(進行中)) && 排定的學校課程班級
- List<object> exams = new List<object>();
- string classSqlString = "";
- if (classIds.Count > 0 || groupIds.Count > 0)
- {
- if (classIds.Count > 0)
- {
- foreach (string classId in classIds)
- {
- if (!string.IsNullOrWhiteSpace(classSqlString))
- {
- classSqlString += " OR ";
- }
- classSqlString += $"ARRAY_CONTAINS(c.classes, '{classId}')";
- }
- }
- if (groupIds.Count > 0)
- {
- foreach (string groupId in groupIds)
- {
- if (!string.IsNullOrWhiteSpace(classSqlString))
- {
- classSqlString += " OR ";
- }
- classSqlString += $"ARRAY_CONTAINS(c.classes, '{groupId}')";
- }
- }
- }
- else //無分配任何課程教室,校園評測不取
- {
- classSqlString += "c.id = '0'";
- }
- classSqlString = $"AND ({classSqlString})";
- //取得評測ID List
- List<string> examIdList = new List<string>();
- await foreach (var exam in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryStreamIterator(queryText: $"SELECT c.id FROM c WHERE c.source = '1' AND c.progress = 'going' {classSqlString}", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Exam-{school_code}") }))
- {
- using var json = await JsonDocument.ParseAsync(exam.ContentStream);
- if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
- {
- foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
- {
- examIdList.Add(obj.GetProperty("id").GetString());
- }
- }
- }
- //取得有作答的評測班級
- Dictionary<string, List<string>> examClassFinDic = new Dictionary<string, List<string>>();
- await foreach (var exam in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryStreamIterator(queryText: $"SELECT c.examId, c.info.id as classId FROM c WHERE ARRAY_CONTAINS({JsonSerializer.Serialize(examIdList)}, c.examId) AND c.progress=true", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ExamClassResult-{school_code}") }))
- {
- var jsonecr = await JsonDocument.ParseAsync(exam.ContentStream);
- if (jsonecr.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
- {
- foreach (var obj in jsonecr.RootElement.GetProperty("Documents").EnumerateArray())
- {
- string examId = obj.GetProperty("examId").ToString();
- string classId = obj.GetProperty("classId").ToString();
- if (examClassFinDic.ContainsKey(examId) && !examClassFinDic[examId].Contains(classId))
- {
- examClassFinDic[examId].Add(classId);
- }
- else
- {
- List<string> classIdList = new List<string>();
- classIdList.Add(classId);
- examClassFinDic.Add(examId, classIdList);
- }
- }
- }
- }
- //取得評測資料
- await foreach (var exam in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryStreamIterator(queryText: $"SELECT c.code, c.id, c.name, c.createTime, c.startTime, c.endTime ,c.year, c.source, c.type, c.progress, c.stuCount, c.scope, c.owner, c.period, c.grades, c.subjects, c.classes, c.stuLists, ARRAY(SELECT p.id, p.code, p.name, p.blob, p.scope FROM p IN c.papers) AS papers FROM c WHERE ARRAY_CONTAINS({JsonSerializer.Serialize(examIdList)}, c.id)", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Exam-{school_code}") }))
- {
- var jsonex = await JsonDocument.ParseAsync(exam.ContentStream);
- if (jsonex.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
- {
- foreach (var obj in jsonex.RootElement.GetProperty("Documents").EnumerateArray())
- {
- dynamic examExtobj = new ExpandoObject();
- string examId = obj.GetProperty("id").GetString();
- examExtobj.code = obj.GetProperty("code");
- examExtobj.id = examId;
- examExtobj.name = obj.GetProperty("name");
- examExtobj.createTime = obj.GetProperty("createTime");
- examExtobj.startTime = obj.GetProperty("startTime");
- examExtobj.endTime = obj.GetProperty("endTime");
- examExtobj.year = obj.GetProperty("year");
- examExtobj.source = obj.GetProperty("source");
- examExtobj.type = obj.GetProperty("type");
- examExtobj.progress = obj.GetProperty("progress");
- examExtobj.stuCount = obj.GetProperty("stuCount");
- examExtobj.scope = obj.GetProperty("scope");
- examExtobj.owner = obj.GetProperty("owner");
- examExtobj.period = obj.GetProperty("period");
- examExtobj.grades = obj.GetProperty("grades");
- examExtobj.subjects = obj.GetProperty("subjects");
- examExtobj.classes = (obj.TryGetProperty("classes", out JsonElement classes)) ? classes.ToObject<List<string>>() : new List<string>();
- examExtobj.stuLists = (obj.TryGetProperty("stuLists", out JsonElement stuLists)) ? stuLists.ToObject<List<string>>() : new List<string>();
- examExtobj.finishClasses = (examClassFinDic.ContainsKey(examId)) ? examClassFinDic[examId] : new List<string>();
- examExtobj.papers = obj.GetProperty("papers");
- //examExtobj = obj.ToObject<object>();
- exams.Add(examExtobj);
- }
- }
- }
- //用户在线记录
- try
- {
- _ = _httpTrigger.RequestHttpTrigger(new { school = school_code.GetString(), scope = $"{Constant.ScopeTeacher}", id = $"{id}", ip = $"{ip}", expire = 1 }, _option.Location, "online-record");
- }
- catch { }
- //取得School Blob 容器位置及SAS
- string school_code_blob = school_code.GetString().ToLower();
- var (blob_uri, blob_sas) = _azureStorage.GetBlobContainerSAS(school_code_blob, BlobContainerSasPermissions.Read | BlobContainerSasPermissions.List | BlobContainerSasPermissions.Write); //讀列
- var (blob_uri_read, blob_sas_read) = _azureStorage.GetBlobContainerSAS(school_code_blob, BlobContainerSasPermissions.Read); //讀
- var (blob_uri_write, blob_sas_write) = _azureStorage.GetBlobContainerSAS(school_code_blob, BlobContainerSasPermissions.Write); //寫
- return Ok(new { blob_uri, blob_sas, blob_sas_read, blob_sas_write, periods, grades, subjects, courses, examTypes, exams });
- }
- catch (Exception ex)
- {
- await _dingDing.SendBotMsg($"IES5,{_option.Location},hiteach/GetSchoolInfo()\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
- return BadRequest();
- }
- }
- //取得試卷
- [Authorize(Roles = "HiTeach")]
- [ProducesDefaultResponseType]
- [HttpPost("get-paper")]
- public async Task<IActionResult> GetPaperList(JsonElement request)
- {
- try
- {
- //Header驗證
- string id_token = HttpContext.GetXAuth("IdToken");
- if (string.IsNullOrEmpty(id_token)) return BadRequest();
- var jwt = new JwtSecurityToken(id_token);
- if (!jwt.Payload.Iss.Equals("account.teammodel", StringComparison.Ordinal)) return BadRequest();
- var id = jwt.Payload.Sub;
- var client = _azureCosmos.GetCosmosClient();
- //參數
- if (!request.TryGetProperty("grant_type", out JsonElement grant_type)) return BadRequest();
- string partitionid = string.Empty;
- string container = string.Empty;
- if (grant_type.ToString().Equals("school"))
- {
- if (!request.TryGetProperty("school_code", out JsonElement school_code_json))
- {
- return BadRequest();
- }
- else
- {
- partitionid = school_code_json.ToString();
- container = "School";
- }
- }
- else
- {
- partitionid = id.ToString();
- container = "Teacher";
- }
- //SQL文
- List<object> papers = new List<object>();
- string queryWhere = " WHERE 1=1 ";
- string queryOption = string.Empty;
- //學段
- if (request.TryGetProperty("periodId", out JsonElement periodId) && container.Equals("School"))
- {
- queryWhere += $" AND c.periodId = '{periodId}'";
- }
- //年級
- if (request.TryGetProperty("gradeId", out JsonElement gradeIds) && gradeIds.GetArrayLength() > 0 && container.Equals("School"))
- {
- string queryOptionForGrade = string.Empty;
- for (int i = 0; i < gradeIds.GetArrayLength(); i++)
- {
- if (!string.IsNullOrWhiteSpace(queryOptionForGrade))
- {
- queryOptionForGrade += " OR ";
- }
- queryOptionForGrade += $" ARRAY_CONTAINS(c.gradeIds, '{gradeIds[i]}', true)";
- }
- queryWhere += $" AND ( {queryOptionForGrade} )";
- }
- //科目ID
- if (request.TryGetProperty("subjectId", out JsonElement subjectId) && container.Equals("School"))
- {
- queryWhere += $" AND c.subjectId = '{subjectId}'";
- }
- //科目名稱
- if (request.TryGetProperty("subjectName", out JsonElement subjectName))
- {
- queryWhere += $" AND c.subjectName = '{subjectName}'";
- }
- //試卷ID
- if (request.TryGetProperty("id", out JsonElement paperId))
- {
- queryWhere += $" AND c.id = '{paperId}'";
- }
- int perpage = 0; //每頁幾條
- if (request.TryGetProperty("perpage", out JsonElement perpage_json)) perpage = perpage_json.GetInt32();
- int page = 0; //目前第幾頁
- if (request.TryGetProperty("page", out JsonElement page_json))
- {
- if (page_json.GetInt32() > 0)
- {
- page = page_json.GetInt32() - 1;
- }
- }
- string order = "createTime"; //排序項目
- if (request.TryGetProperty("order", out JsonElement order_json))
- {
- if (order_json.ToString().Equals("useCount"))
- {
- order = order_json.ToString();
- }
- }
- queryOption += $" Order By c." + order + " DESC ";
- if (perpage > 0)
- {
- queryOption += $" OFFSET {perpage * page} LIMIT {perpage}";
- }
- //資料取得
- await foreach (var item in client.GetContainer(Constant.TEAMModelOS, container).GetItemQueryStreamIterator(queryText: $"SELECT c.code, c.id, c.periodId, c.gradeIds, c.subjectId, c.subjectName, c.name, REPLACE(c.blob, 'index.json', '') AS blob, c.score, c.useCount, ARRAY_LENGTH(c.scoring) AS itemCount, c.createTime, c.scope From c {queryWhere + queryOption}", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Paper-{partitionid}") }))
- {
- using var json = await JsonDocument.ParseAsync(item.ContentStream);
- if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
- {
- foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
- {
- papers.Add(obj.ToObject<object>());
- }
- }
- }
- //總件數
- int totalCount = 0;
- await foreach (var item in client.GetContainer(Constant.TEAMModelOS, container).GetItemQueryStreamIterator(queryText: $"SELECT VALUE COUNT(1) From c {queryWhere}", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Paper-{partitionid}") }))
- {
- using var json = await JsonDocument.ParseAsync(item.ContentStream);
- if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
- {
- foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
- {
- totalCount = obj.GetInt32();
- }
- }
- }
- return Ok(new { papers, totalCount });
- }
- catch (Exception ex)
- {
- return BadRequest();
- }
- }
- //取得試題
- [Authorize(Roles = "HiTeach")]
- [ProducesDefaultResponseType]
- [HttpPost("get-item")]
- public async Task<IActionResult> GetItemList(JsonElement request)
- {
- try
- {
- //Header驗證
- string id_token = HttpContext.GetXAuth("IdToken");
- if (string.IsNullOrEmpty(id_token)) return BadRequest();
- var jwt = new JwtSecurityToken(id_token);
- if (!jwt.Payload.Iss.Equals("account.teammodel", StringComparison.Ordinal)) return BadRequest();
- var id = jwt.Payload.Sub;
- var client = _azureCosmos.GetCosmosClient();
- //參數
- if (!request.TryGetProperty("grant_type", out JsonElement grant_type)) return BadRequest();
- string partitionid = string.Empty;
- string container = string.Empty;
- if (grant_type.ToString().Equals("school"))
- {
- if (!request.TryGetProperty("school_code", out JsonElement school_code_json))
- {
- return BadRequest();
- }
- else
- {
- partitionid = school_code_json.ToString();
- container = "School";
- }
- }
- else
- {
- partitionid = id.ToString();
- container = "Teacher";
- }
- //SQL文
- List<object> items = new List<object>();
- string queryWhere = " WHERE 1=1 ";
- string queryOption = string.Empty;
- //學段
- if (request.TryGetProperty("periodId", out JsonElement periodId) && container.Equals("School"))
- {
- queryWhere += $" AND c.periodId = '{periodId}'";
- }
- //年級
- if (request.TryGetProperty("gradeId", out JsonElement gradeIds) && gradeIds.GetArrayLength() > 0 && container.Equals("School"))
- {
- string queryOptionForGrade = string.Empty;
- for (int i = 0; i < gradeIds.GetArrayLength(); i++)
- {
- if (!string.IsNullOrWhiteSpace(queryOptionForGrade))
- {
- queryOptionForGrade += " OR ";
- }
- queryOptionForGrade += $" ARRAY_CONTAINS(c.gradeIds, '{gradeIds[i]}', true)";
- }
- queryWhere += $" AND ( {queryOptionForGrade} )";
- }
- //科目ID
- if (request.TryGetProperty("subjectId", out JsonElement subjectId) && container.Equals("school"))
- {
- queryWhere += $" AND c.subjectId = '{subjectId}'";
- }
- //科目名稱
- if (request.TryGetProperty("subjectName", out JsonElement subjectName))
- {
- queryWhere += $" AND c.subjectName = '{subjectName}'";
- }
- //題型
- int dummy = 0;
- if (request.TryGetProperty("type", out JsonElement type))
- {
- queryWhere += $" AND c.type = '{type}'";
- }
- //難度
- dummy = 0;
- if (request.TryGetProperty("level", out JsonElement level) && int.TryParse(level.ToString(), out dummy))
- {
- queryWhere += $" AND c.level = {level}";
- }
- //層次
- if (request.TryGetProperty("field", out JsonElement field) && int.TryParse(field.ToString(), out dummy))
- {
- queryWhere += $" AND c.field = {field}";
- }
- int perpage = 0; //每頁幾條
- if (request.TryGetProperty("perpage", out JsonElement perpage_json)) perpage = perpage_json.GetInt32();
- int page = 0; //目前第幾頁
- if (request.TryGetProperty("page", out JsonElement page_json))
- {
- if (page_json.GetInt32() > 0)
- {
- page = page_json.GetInt32() - 1;
- }
- }
- string order = "createTime"; //排序項目
- if (request.TryGetProperty("order", out JsonElement order_json))
- {
- if (order_json.ToString().Equals("useCount"))
- {
- order = order_json.ToString();
- }
- }
- queryOption += $" Order By c." + order + " DESC ";
- if (perpage > 0)
- {
- queryOption += $" OFFSET {perpage * page} LIMIT {perpage}";
- }
- //資料取得
- await foreach (var item in client.GetContainer(Constant.TEAMModelOS, container).GetItemQueryStreamIterator(queryText: $"SELECT c.id, c.periodId, c.gradeIds, c.subjectId, c.subjectName, c.blob, c.field, c.level, c.type, c.useCount, c.createTime From c {queryWhere + queryOption}", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Item-{partitionid}") }))
- {
- using var json = await JsonDocument.ParseAsync(item.ContentStream);
- if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
- {
- foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
- {
- items.Add(obj.ToObject<object>());
- }
- }
- }
- //總件數
- int totalCount = 0;
- await foreach (var item in client.GetContainer(Constant.TEAMModelOS, container).GetItemQueryStreamIterator(queryText: $"SELECT VALUE COUNT(1) From c {queryWhere}", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Item-{partitionid}") }))
- {
- using var json = await JsonDocument.ParseAsync(item.ContentStream);
- if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
- {
- foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
- {
- totalCount = obj.GetInt32();
- }
- }
- }
- return Ok(new { items, totalCount });
- }
- catch (Exception ex)
- {
- return BadRequest();
- }
- }
- //取得知識點
- [Authorize(Roles = "HiTeach")]
- [ProducesDefaultResponseType]
- [HttpPost("get-knowledge")]
- public async Task<IActionResult> GetKnowledgePointList(JsonElement request)
- {
- var client = _azureCosmos.GetCosmosClient();
- if (!request.TryGetProperty("school_code", out JsonElement school_code)) return BadRequest();
- //知識點
- List<object> points = new List<object>();
- await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryStreamIterator(queryText: $"SELECT c.id, c.name, c.subjectId FROM c WHERE c.type = 'point'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Knowledge-{school_code}") }))
- {
- using var json = await JsonDocument.ParseAsync(item.ContentStream);
- if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
- {
- foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
- {
- points.Add(obj.ToObject<object>());
- }
- }
- }
- return Ok(points);
- }
- //取得課綱
- [Authorize(Roles = "HiTeach")]
- [ProducesDefaultResponseType]
- [HttpPost("get-syllabus")]
- public async Task<IActionResult> GetSyllabusList(JsonElement request)
- {
- //Header驗證
- string id_token = HttpContext.GetXAuth("IdToken");
- if (string.IsNullOrEmpty(id_token)) return BadRequest();
- var jwt = new JwtSecurityToken(id_token);
- if (!jwt.Payload.Iss.Equals("account.teammodel", StringComparison.OrdinalIgnoreCase)) return BadRequest();
- var id = jwt.Payload.Sub;
- //參數驗證
- if (!request.TryGetProperty("grant_type", out JsonElement grant_type)) return BadRequest();
- string grantType = (grant_type.GetString().Equals("school")) ? "school" : "private";
- JsonElement school_code = new();
- if (grantType == "school" && !request.TryGetProperty("school_code", out school_code)) return BadRequest();
- string dataId = (grantType.Equals("school")) ? school_code.GetString() : id;
- string container = (grantType.Equals("school")) ? "School" : "Teacher";
- string periodId = (request.TryGetProperty("periodId", out JsonElement periodIdJobj)) ? periodIdJobj.GetString() : String.Empty;
- string subjectId = (request.TryGetProperty("subjectId", out JsonElement subjectIdJobj)) ? subjectIdJobj.GetString() : String.Empty;
- string volumeId = (request.TryGetProperty("volumeId", out JsonElement volumeIdJobj)) ? volumeIdJobj.GetString() : String.Empty;
- string syllabusId = (request.TryGetProperty("syllabusId", out JsonElement syllabusIdJobj)) ? syllabusIdJobj.GetString() : String.Empty;
- int display = (request.TryGetProperty("display", out JsonElement displayJobj)) ? displayJobj.GetInt32() : 0;
- var client = _azureCosmos.GetCosmosClient();
- //取得卷前置作業:有給syllabusId,取得該課綱的卷ID
- string volumeIdFromSyllabusId = String.Empty;
- if (!string.IsNullOrWhiteSpace(syllabusId))
- {
- await foreach (string volid in client.GetContainer(Constant.TEAMModelOS, container).GetItemQueryIterator<string>(queryText: $"SELECT value(c.volumeId) FROM c WHERE c.id = '{syllabusId}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Syllabus-{dataId}") }))
- {
- volumeIdFromSyllabusId = volid;
- }
- }
- //取得卷
- List<object> volumes = new();
- List<Volume> volumeList = new();
- List<string> volumeIdList = new();
- string queryTextVol = string.Empty;
- List<string> WhereVol = new();
- if (!string.IsNullOrWhiteSpace(periodId)) WhereVol.Add($" c.periodId = '{periodId}' ");
- if (!string.IsNullOrWhiteSpace(subjectId)) WhereVol.Add($" c.subjectId = '{subjectId}' ");
- if (!string.IsNullOrWhiteSpace(volumeId)) WhereVol.Add($" c.id = '{volumeId}' ");
- if (!string.IsNullOrWhiteSpace(volumeIdFromSyllabusId)) WhereVol.Add($" c.id = '{volumeIdFromSyllabusId}' ");
- foreach (string Where in WhereVol)
- {
- queryTextVol += (String.IsNullOrWhiteSpace(queryTextVol)) ? $" WHERE {Where} " : $" AND {Where} ";
- }
- queryTextVol = "SELECT * FROM c " + queryTextVol;
- await foreach (var itemv in client.GetContainer(Constant.TEAMModelOS, container).GetItemQueryStreamIterator(queryText: queryTextVol, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Volume-{dataId}") }))
- {
- var jsons = await JsonDocument.ParseAsync(itemv.ContentStream);
- if (jsons.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
- {
- foreach (var obj in jsons.RootElement.GetProperty("Documents").EnumerateArray())
- {
- Volume volExtobj = obj.ToObject<Volume>();
- volumeList.Add(volExtobj);
- volumeIdList.Add(volExtobj.id);
- }
- }
- }
- //取得課綱 ※display=1時不取任何課綱
- List<SyllabusTreeNode> treeNodes = new();
- if (!display.Equals(1))
- {
- string queryTextSyl = $"SELECT value(c) FROM c WHERE ARRAY_CONTAINS({JsonSerializer.Serialize(volumeIdList)}, c.volumeId, true)";
- if (!string.IsNullOrWhiteSpace(syllabusId)) queryTextSyl += $" AND c.id = '{syllabusId}'";
- await foreach (Syllabus items in client.GetContainer(Constant.TEAMModelOS, container).GetItemQueryIterator<Syllabus>(queryText: queryTextSyl, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Syllabus-{dataId}") }))
- {
- List<SyllabusTree> trees = SyllabusService.ListToTree(items.children);
- SyllabusTreeNode tree = new() { id = items.id, scope = items.scope, trees = trees, volumeId = items.volumeId, auth = items.auth, codeval = $"{id}" };
- treeNodes.Add(tree);
- }
- }
- //輸出結果
- foreach (Volume vr in volumeList)
- {
- volumes.Add(new
- {
- vr.periodId,
- vr.subjectId,
- vr.id,
- vr.gradeId,
- vr.semesterId,
- vr.name,
- vr.creatorId,
- vr.creatorName,
- vr.school,
- vr.scope,
- vr.syllabusIds,
- vr.auth,
- vr.order,
- syllabus = treeNodes.Where(t => t.volumeId == vr.id).ToList()
- });
- }
- return Ok(volumes);
- }
- //取得被分享的課綱
- [ProducesDefaultResponseType]
- [Authorize(Roles = "HiTeach")]
- [HttpPost("get-share-syllabus")]
- public async Task<IActionResult> GetShareSyllabusList(JsonElement request)
- {
- //Header驗證
- string id_token = HttpContext.GetXAuth("IdToken");
- if (string.IsNullOrEmpty(id_token)) return BadRequest();
- var jwt = new JwtSecurityToken(id_token);
- if (!jwt.Payload.Iss.Equals("account.teammodel", StringComparison.OrdinalIgnoreCase)) return BadRequest();
- var id = jwt.Payload.Sub;
- //參數驗證
- string volumeId = (request.TryGetProperty("volumeId", out JsonElement volumeIdJobj)) ? volumeIdJobj.GetString() : String.Empty;
- string syllabusId = (request.TryGetProperty("syllabusId", out JsonElement syllabusIdJobj)) ? syllabusIdJobj.GetString() : String.Empty;
- int display = (request.TryGetProperty("display", out JsonElement displayJobj)) ? displayJobj.GetInt32() : 0;
- var client = _azureCosmos.GetCosmosClient();
- //取得分享內容
- Dictionary<string, string> tmidDic = new Dictionary<string, string>();
- List<Volume> volumeList = new List<Volume>();
- StringBuilder queryText = new StringBuilder("SELECT value(c) FROM c WHERE c.type='share' ");
- if (!string.IsNullOrWhiteSpace(volumeId))
- {
- queryText.Append($"AND c.volumeId='{volumeId}'");
- }
- await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<Share>(queryText: queryText.ToString(),
- requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Share-share-{id}") }))
- {
-
- if(!string.IsNullOrWhiteSpace(syllabusId))
- {
- if(item.id.Equals(syllabusId))
- {
- Volume volumeExist = volumeList.Where((Volume v) => v.id == item.volumeId).FirstOrDefault();
- if(volumeExist == null)
- {
- Volume volume = new Volume();
- volume.id = item.volumeId;
- volume.name = item.volumeName;
- volume.creatorId = item.issuer;
- volume.creatorName = item.issuerName;
- volume.syllabusIds.Add(item.id);
- volumeList.Add(volume);
- var (blob_uri, blob_sas) = _azureStorage.GetBlobContainerSAS(item.issuer, BlobContainerSasPermissions.Read | BlobContainerSasPermissions.List);
- if (!tmidDic.ContainsKey(item.issuer)) tmidDic.Add(item.issuer, blob_sas);
- }
- else
- {
- volumeExist.syllabusIds.Add(item.id);
- }
- }
- }
- else
- {
- Volume volumeExist = volumeList.Where((Volume v) => v.id == item.volumeId).FirstOrDefault();
- if (volumeExist == null)
- {
- Volume volume = new Volume();
- volume.id = item.volumeId;
- volume.name = item.volumeName;
- volume.creatorId = item.issuer;
- volume.creatorName = item.issuerName;
- volume.syllabusIds.Add(item.id);
- volumeList.Add(volume);
- var (blob_uri, blob_sas) = _azureStorage.GetBlobContainerSAS(item.issuer, BlobContainerSasPermissions.Read | BlobContainerSasPermissions.List);
- if(!tmidDic.ContainsKey(item.issuer)) tmidDic.Add(item.issuer, blob_sas);
- }
- else
- {
- volumeExist.syllabusIds.Add(item.id);
- }
- }
- }
- //取得課綱並輸出回傳值
- List<object> result = new List<object>();
- foreach(Volume volTmp in volumeList)
- {
- List<SyllabusTreeNode> treeNodes = new();
- if (!display.Equals(1))
- {
- string queryTextSyl = $"SELECT value(c) FROM c WHERE ARRAY_CONTAINS({JsonSerializer.Serialize(volTmp.syllabusIds)}, c.id, true)";
- await foreach (Syllabus items in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<Syllabus>(queryText: queryTextSyl, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Syllabus-{volTmp.creatorId}") }))
- {
- List<SyllabusTree> trees = SyllabusService.ListToTree(items.children);
- SyllabusTreeNode tree = new() { id = items.id, scope = items.scope, trees = trees, volumeId = items.volumeId, auth = items.auth, codeval = $"{volTmp.creatorId}" };
- treeNodes.Add(tree);
- }
- }
- result.Add(new
- {
- id = volTmp.id,
- name = volTmp.name,
- creatorId = volTmp.creatorId,
- creatorName = volTmp.creatorName,
- creatorSas = (tmidDic.ContainsKey(volTmp.creatorId)) ? tmidDic[volTmp.creatorId] : null,
- syllabusIds = volTmp.syllabusIds,
- syllabus = treeNodes.ToList(),
- });
- }
- return Ok(result);
- }
- //取得某班級的學生成員
- [Authorize(Roles = "HiTeach")]
- [ProducesDefaultResponseType]
- [HttpPost("get-students-list")]
- public async Task<IActionResult> GetStudentsList(JsonElement request)
- {
- string id_token = HttpContext.GetXAuth("IdToken");
- if (string.IsNullOrWhiteSpace(id_token)) return BadRequest();
- var jwt = new JwtSecurityToken(id_token);
- if (!jwt.Payload.Iss.Equals("account.teammodel", StringComparison.Ordinal)) return BadRequest();
- var id = jwt.Payload.Sub;
- if (!request.TryGetProperty("grant_type", out JsonElement grant_type)) return BadRequest();
- request.TryGetProperty("class_code", out JsonElement class_code);
- request.TryGetProperty("stulist_id", out JsonElement stulist_id);
- string classId = Convert.ToString(class_code);
- string stulist = Convert.ToString(stulist_id);
- if (string.IsNullOrWhiteSpace(classId) && string.IsNullOrWhiteSpace(stulist)) return BadRequest();
- request.TryGetProperty("school_code", out JsonElement school_code);
- if (grant_type.GetString().Equals("school") && string.IsNullOrWhiteSpace(Convert.ToString(school_code))) return BadRequest();
- var client = _azureCosmos.GetCosmosClient();
- Dictionary<string, string> irsDic = new Dictionary<string, string>(); //key:學生ID或TMID value:irs號碼
- string container = (grant_type.GetString().Equals("school")) ? "School" : "Teacher";
- List<string> listids = new List<string>();
- if (!string.IsNullOrWhiteSpace(stulist))
- {
- listids.Add(stulist);
- }
- else if (!string.IsNullOrWhiteSpace(classId))
- {
- listids.Add(classId);
- }
- (List<RMember> students, List<RGroupList> groupList) = await GroupListService.GetMemberByListids(_coreAPIHttpService, client, _dingDing, listids, $"{school_code}");
- return Ok(new { students });
- }
- /// <summary>
- /// 開始課堂(舊版,已被CreateLesson取代)
- /// </summary>
- /// <param name="request"></param>
- /// <returns></returns>
- [Authorize(Roles = "HiTeach")]
- [ProducesDefaultResponseType]
- [HttpPost("start-lesson")]
- public async Task<IActionResult> StartLesson(JsonElement request)
- {
- //醍摩豆ID驗證
- string teacherId = string.Empty;
- string id_token = HttpContext.GetXAuth("IdToken");
- if (!string.IsNullOrWhiteSpace(id_token))
- {
- var jwt = new JwtSecurityToken(id_token);
- if (!jwt.Payload.Iss.Equals("account.teammodel", StringComparison.OrdinalIgnoreCase)) return BadRequest();
- teacherId = jwt.Payload.Sub;
- }
- if (string.IsNullOrWhiteSpace(teacherId)) return BadRequest(); //無醍摩豆ID,BadRequest
- //取得授課ID
- string lesson_code = _snowflakeId.NextId().ToString();
- //bool get_lesson_id = (string.IsNullOrWhiteSpace(Convert.ToString(lesson_id)) || Convert.ToString(lesson_id) != lesson_code) ? false : true;
- //string tableName = "TeacherLesson";
- return Ok(new { lesson_code });
- }
- //上傳評測結果
- //錯誤代碼:error = 1001 message = "Paper blob copy failure."
- // error = 1002 message = "Student answers blob upload failure."
- [Authorize(Roles = "HiTeach")]
- [ProducesDefaultResponseType]
- [HttpPost("upd-exam-result")]
- public async Task<IActionResult> UploadExamResult(JsonElement request)
- {
- try
- {
- string message = "";
- int error = 0;
- string id_token = HttpContext.GetXAuth("IdToken");
- if (string.IsNullOrWhiteSpace(id_token)) return BadRequest();
- var jwt = new JwtSecurityToken(id_token);
- if (!jwt.Payload.Iss.Equals("account.teammodel", StringComparison.Ordinal)) return BadRequest();
- var id = jwt.Payload.Sub;
- if (!request.TryGetProperty("exam", out JsonElement exam)) return BadRequest();
- if (!request.TryGetProperty("examClassResult", out JsonElement examClassResult)) return BadRequest();
- bool blobUploaded = (request.TryGetProperty("blobUploaded", out JsonElement blobUploadedJson)) ? blobUploadedJson.GetBoolean() : false;
- bool recordSwitch = (request.TryGetProperty("recordSwitch", out JsonElement recordSwitchJson)) ? recordSwitchJson.GetBoolean() : false;
- //ExamInfo ExamInfoFromReq = exam.ToObject<ExamInfo>();
- string strExam = JsonSerializer.Serialize(exam);
- if (strExam.Contains("\"publish\":\"0\""))
- {
- strExam = strExam.Replace("\"publish\":\"0\"", "\"publish\":0");
- }
- ExamInfo ExamInfoFromReq = JsonSerializer.Deserialize<ExamInfo>(strExam);
- string examId = ExamInfoFromReq.id;
- string excode = ExamInfoFromReq.code;
- //ExamInfo dbExamInfo = exam.ToObject<ExamInfo>();
- ExamInfo dbExamInfo = JsonSerializer.Deserialize<ExamInfo>(strExam);
- var queryex = $"SELECT * FROM c WHERE c.id = '{examId}'";
- await foreach (var itemex in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryStreamIterator(queryText: queryex, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"{excode}") }))
- {
- var jsonex = await JsonDocument.ParseAsync(itemex.ContentStream);
- if (jsonex.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
- {
- foreach (var obj in jsonex.RootElement.GetProperty("Documents").EnumerateArray())
- {
- string strExamDb = JsonSerializer.Serialize(obj);
- if (strExamDb.Contains("\"publish\":\"0\""))
- {
- strExamDb = strExamDb.Replace("\"publish\":\"0\"", "\"publish\":0");
- }
- dbExamInfo = JsonSerializer.Deserialize<ExamInfo>(strExamDb);
- //dbExamInfo = obj.ToObject<ExamInfo>();
- }
- }
- }
- if (string.IsNullOrWhiteSpace(dbExamInfo.id))
- {
- dbExamInfo = ExamInfoFromReq;
- }
- //Boolean isTestFlg = (_option.Location.Contains("Test") || _option.Location.Contains("Dep")) ? true : false;
- //ExamInfo內容取得、調整 [2021-7-13 廢除,給予HiTeach學校Blob寫入權限,API不再對Blob做搬運]
- //※規則 owner:"school" => 校園評測 "teacher" => 個人評測
- //※規則 scope:"school" => 校本班級 "private" => 個人班級
- //※規則 BLOB容器: scope:"school" => {學校ID}下 scope:"private" => {個人ID}下
- string blobContainer = (!string.IsNullOrWhiteSpace(dbExamInfo.school) && dbExamInfo.scope.Equals("school")) ? dbExamInfo.school : id; //blob容器
- //dbExamInfo.source = "1"; //評測來源固定為 1:課中評量(不應由API擅自變更)
- //試卷List
- List<Dictionary<string, string>> recordPaperInfo = new List<Dictionary<string, string>>();
- int paperIndex = 0;
- foreach (PaperSimple paperInfo in ExamInfoFromReq.papers)
- {
- string paperBlobPath = (!paperInfo.blob.EndsWith("/")) ? paperInfo.blob + "/" : paperInfo.blob;
- paperBlobPath = (paperInfo.blob.StartsWith("/")) ? paperBlobPath.Remove(0, 1) : paperBlobPath;
- string subjectId = dbExamInfo.subjects[paperIndex].id;
- recordPaperInfo.Add(new Dictionary<string, string>() { { "id", paperInfo.id }, { "blob", paperBlobPath }, { "subjectId", subjectId }, { "itemcount", paperInfo.point.Count.ToString() } });
- paperIndex++;
- }
- //取得課堂紀錄下的試卷資料(blob)、複製到評測紀錄下
- bool paperDataCopyErrFlg = false; //試卷資料拷貝錯誤Flag true:拷貝錯誤 [2021-7-13 (測試站)不再對Blob做搬運 永為false]
- //Blob搬運 (待HiTeach完善後刪除)
- if (!blobUploaded)
- {
- foreach (Dictionary<string, string> recordPaperInfoDic in recordPaperInfo)
- {
- string targetScope = dbExamInfo.scope; //評測對象 school:校本班級 private:私人課程
- var blobPrivateContainer = _azureStorage.GetBlobContainerClient(id);
- string sourceBlobPath = recordPaperInfoDic["blob"];
- string destBlobPath = $"exam/{dbExamInfo.id}/paper/{recordPaperInfoDic["subjectId"]}/"; //拷貝對象路徑 path:exam/{評測ID}/paper/{subjectID}/ ※2022-1-6 式樣變更[原]/paper/{試卷ID}/ [新]/paper/{subjectID}/
- if (targetScope.Equals("school")) //校本
- {
- string schoolId = dbExamInfo.school;
- var blobSchoolContainer = _azureStorage.GetBlobContainerClient(schoolId);
- var sourceBlobContainer = (recordSwitch) ? blobSchoolContainer : blobPrivateContainer;
- Azure.Pageable<BlobItem> sourceBlobs = sourceBlobContainer.GetBlobs(prefix: sourceBlobPath);
- if (sourceBlobs.Count() > 0)
- {
- foreach (var blob in sourceBlobs)
- {
- var sourceFileBlob = sourceBlobContainer.GetBlobClient(blob.Name);
- if (sourceFileBlob.Exists())
- {
- var sourceFileUri = sourceBlobContainer.GetBlobClient(blob.Name).Uri;
- string fileName = blob.Name.Replace(sourceBlobPath, "");
- string destBlobFilePath = $"{destBlobPath}{fileName}";
- await blobSchoolContainer.GetBlobClient(destBlobFilePath).StartCopyFromUriAsync(sourceFileUri);
- }
- else
- {
- paperDataCopyErrFlg = true;
- }
- }
- }
- }
- else //私人
- {
- var sourceBlobContainer = blobPrivateContainer;
- Azure.Pageable<BlobItem> sourceBlobs = sourceBlobContainer.GetBlobs(prefix: sourceBlobPath);
- if (sourceBlobs.Count() > 0)
- {
- foreach (var blob in sourceBlobs)
- {
- var sourceFileBlob = sourceBlobContainer.GetBlobClient(blob.Name);
- if (sourceFileBlob.Exists())
- {
- var sourceFileUri = sourceBlobContainer.GetBlobClient(blob.Name).Uri;
- string fileName = blob.Name.Replace(sourceBlobPath, "");
- string destBlobFilePath = $"{destBlobPath}{fileName}";
- await blobPrivateContainer.GetBlobClient(destBlobFilePath).StartCopyFromUriAsync(sourceFileUri);
- }
- else
- {
- paperDataCopyErrFlg = true;
- }
- }
- }
- }
- //替換 Exam.papers.blob
- PaperSimple paperInfoNow = dbExamInfo.papers.Where((PaperSimple p) => p.id == recordPaperInfoDic["id"]).FirstOrDefault();
- string destBlobPathForDocument = (destBlobPath.EndsWith("/")) ? destBlobPath.Remove(destBlobPath.Length - 1, 1) : destBlobPath;
- destBlobPathForDocument = (!destBlobPathForDocument.StartsWith("/")) ? "/" + destBlobPathForDocument : destBlobPathForDocument;
- paperInfoNow.blob = destBlobPathForDocument;
- }
- }
- //ExamClassResult內容調整
- bool studentAnswerCopyErrFlg = false; //學生作答資料拷貝錯誤Flag true:拷貝錯誤 [2021-7-13 不再對Blob做搬運 永為false]
- //Blob搬運 (待HiTeach完善後刪除)
- if (!blobUploaded)
- {
- List<ExamClassResultStudentAnswerArrayOld> dbExamClassResultList = examClassResult.ToObject<List<ExamClassResultStudentAnswerArrayOld>>();
- foreach (ExamClassResultStudentAnswerArrayOld examClassResultRow in dbExamClassResultList)
- {
- //以subjectId及classId(info.id)取得DB中的ExamClassResult
- ExamClassResult examClassResultUpd = new ExamClassResult();
- string exclcode = examClassResultRow.code;
- string classId = examClassResultRow.info.id;
- string subjectId = examClassResultRow.subjectId;
- var querycr = $"SELECT * FROM c WHERE c.examId = '{examId}' AND c.info.id = '{classId}' AND c.subjectId = '{subjectId}'";
- await foreach (var itemcr in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryStreamIterator(queryText: querycr, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"{exclcode}") }))
- {
- var jsontcr = await JsonDocument.ParseAsync(itemcr.ContentStream);
- if (jsontcr.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
- {
- foreach (var obj in jsontcr.RootElement.GetProperty("Documents").EnumerateArray())
- {
- examClassResultUpd = obj.ToObject<ExamClassResult>();
- examClassResultUpd.progress = examClassResultRow.progress;
- examClassResultUpd.studentIds = examClassResultRow.studentIds;
- examClassResultUpd.studentAnswers = new List<List<string>>();
- examClassResultUpd.studentScores = examClassResultRow.studentScores;
- examClassResultUpd.status = examClassResultRow.status;
- examClassResultUpd.sum = examClassResultRow.sum;
- }
- }
- }
- //無法取得既有ExamClassResult,新建
- if (string.IsNullOrWhiteSpace(examClassResultUpd.id))
- {
- examClassResultUpd.pk = examClassResultRow.pk;
- examClassResultUpd.code = examClassResultRow.code;
- examClassResultUpd.id = examClassResultRow.id;
- examClassResultUpd.school = examClassResultRow.school;
- examClassResultUpd.examId = examClassResultRow.examId;
- examClassResultUpd.subjectId = examClassResultRow.subjectId;
- examClassResultUpd.gradeId = examClassResultRow.gradeId;
- examClassResultUpd.year = examClassResultRow.year;
- examClassResultUpd.info = examClassResultRow.info;
- examClassResultUpd.progress = examClassResultRow.progress;
- examClassResultUpd.studentIds = examClassResultRow.studentIds;
- examClassResultUpd.studentAnswers = new List<List<string>>(); //學生作答Blob位置
- examClassResultUpd.studentScores = examClassResultRow.studentScores;
- examClassResultUpd.status = examClassResultRow.status;
- examClassResultUpd.scope = examClassResultRow.scope;
- examClassResultUpd.sum = examClassResultRow.sum;
- }
- //examClassResult.studentAnswers (1)將學生答案上傳blob後轉換內容為blob路徑 //[2021-7-13 不再對Blob做搬運] (2)將學生答案放入examClassResult.ans
- if (examClassResultRow.studentIds != null && examClassResultRow.studentIds.Count > 0 && examClassResultRow.studentAnswersArray != null && examClassResultRow.studentAnswersArray.Count > 0)
- {
- for (int i = 0; i < examClassResultRow.studentAnswersArray.Count; i++)
- {
- string studentId = examClassResultRow.studentIds[i];
- string fileName = examId + "/" + subjectId + "/" + studentId;
- string blob = fileName + "/" + "ans.json";
- var uploadFileResult = await _azureStorage.GetBlobContainerClient(blobContainer).UploadFileByContainer(examClassResultRow.studentAnswersArray[i].ToJsonString(), "exam", blob, false);
- if (string.IsNullOrWhiteSpace(uploadFileResult))
- {
- studentAnswerCopyErrFlg = true;
- }
- //studentAnswers
- List<string> studenrAnswerRow = new List<string>();
- studenrAnswerRow.Add(blob);
- examClassResultUpd.studentAnswers.Add(studenrAnswerRow);
- }
- //examClassResult.ans 將學生答案放入
- examClassResultUpd.ans = examClassResultRow.studentAnswersArray;
- }
- //批註欄位處理
- Dictionary<string, string> paperStatusNow = recordPaperInfo.Where((Dictionary<string, string> p) => p.TryGetValue("subjectId", out string paperStatusSubjectId) && paperStatusSubjectId.Equals(subjectId)).FirstOrDefault();
- int itemCount = Convert.ToInt32(paperStatusNow["itemcount"]);
- if (examClassResultUpd.mark.Count != examClassResultUpd.studentIds.Count || (examClassResultUpd.mark.ElementAtOrDefault(0) != null && examClassResultUpd.mark[0].Count != itemCount)) //第一層:學生數不符 OR 第二層:第一位學生批註數!=試卷題數 => 批註格式不符
- {
- examClassResultUpd.mark = this.createEmptyMark(examClassResultUpd.studentIds.Count, itemCount);
- }
- //UPDATE ExamClassResult
- var examClassResultResponse = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Common").UpsertItemAsync(examClassResultUpd, new PartitionKey(examClassResultUpd.code));
- }
- }
- else
- {
- List<ExamClassResultStudentAnswerArray> dbExamClassResultList = examClassResult.ToObject<List<ExamClassResultStudentAnswerArray>>();
- foreach (ExamClassResultStudentAnswerArray examClassResultRow in dbExamClassResultList)
- {
- //以subjectId及classId(info.id)取得DB中的ExamClassResult
- ExamClassResult examClassResultUpd = new ExamClassResult();
- string exclcode = examClassResultRow.code;
- string classId = examClassResultRow.info.id;
- string subjectId = examClassResultRow.subjectId;
- var querycr = $"SELECT * FROM c WHERE c.examId = '{examId}' AND c.info.id = '{classId}' AND c.subjectId = '{subjectId}'";
- await foreach (var itemcr in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryStreamIterator(queryText: querycr, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"{exclcode}") }))
- {
- var jsontcr = await JsonDocument.ParseAsync(itemcr.ContentStream);
- if (jsontcr.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
- {
- foreach (var obj in jsontcr.RootElement.GetProperty("Documents").EnumerateArray())
- {
- examClassResultUpd = obj.ToObject<ExamClassResult>();
- examClassResultUpd.progress = examClassResultRow.progress;
- examClassResultUpd.studentIds = examClassResultRow.studentIds;
- examClassResultUpd.studentAnswers = new List<List<string>>();
- examClassResultUpd.studentScores = examClassResultRow.studentScores;
- examClassResultUpd.status = examClassResultRow.status;
- examClassResultUpd.sum = examClassResultRow.sum;
- }
- }
- }
- //無法取得既有ExamClassResult,新建
- if (string.IsNullOrWhiteSpace(examClassResultUpd.id))
- {
- examClassResultUpd.pk = examClassResultRow.pk;
- examClassResultUpd.code = examClassResultRow.code;
- examClassResultUpd.id = examClassResultRow.id;
- examClassResultUpd.school = examClassResultRow.school;
- examClassResultUpd.examId = examClassResultRow.examId;
- examClassResultUpd.subjectId = examClassResultRow.subjectId;
- examClassResultUpd.gradeId = examClassResultRow.gradeId;
- examClassResultUpd.year = examClassResultRow.year;
- examClassResultUpd.info = examClassResultRow.info;
- examClassResultUpd.progress = examClassResultRow.progress;
- examClassResultUpd.studentIds = examClassResultRow.studentIds;
- examClassResultUpd.studentAnswers = new List<List<string>>();
- examClassResultUpd.studentScores = examClassResultRow.studentScores;
- examClassResultUpd.status = examClassResultRow.status;
- examClassResultUpd.scope = examClassResultRow.scope;
- examClassResultUpd.sum = examClassResultRow.sum;
- }
- //學生作答Blob位置[2021-7-13 不再對Blob做搬運 學生答案直接寫入DB]
- examClassResultUpd.studentAnswers = examClassResultRow.studentAnswersArray;
- //學生作答答案 (從blob取得學生答案、放入ans欄位)
- string targetScope = dbExamInfo.scope; //評測對象 school:校本班級 private:私人課程
- var targetBlobContainer = _azureStorage.GetBlobContainerClient(id);
- string blobCntr = id;
- if (targetScope.Equals("school")) //校本
- {
- string schoolId = dbExamInfo.school;
- blobCntr = schoolId;
- }
- targetBlobContainer = _azureStorage.GetBlobContainerClient(blobCntr);
- if (examClassResultRow.studentAnswersArray.Count > 0)
- {
- foreach (List<string> studentAnswerBlobPath in examClassResultRow.studentAnswersArray)
- {
- string stuAnswerBlobPath = studentAnswerBlobPath.FirstOrDefault();
- if (stuAnswerBlobPath != null)
- {
- StringBuilder builder = new StringBuilder();
- builder.Append("exam").Append("/").Append(stuAnswerBlobPath);
- var Download = await targetBlobContainer.GetBlobClient(builder.ToString()).DownloadAsync();
- var json = await JsonDocument.ParseAsync(Download.Value.Content);
- var Record = json.RootElement.ToObject<List<List<string>>>();
- examClassResultUpd.ans.Add(Record);
- }
- }
- }
- //批註欄位處理
- Dictionary<string, string> paperStatusNow = recordPaperInfo.Where((Dictionary<string, string> p) => p.TryGetValue("subjectId", out string subjectId) && subjectId.Equals(examClassResultUpd.subjectId)).FirstOrDefault();
- int itemCount = Convert.ToInt32(paperStatusNow["itemcount"]);
- if (examClassResultUpd.mark.Count != examClassResultUpd.studentIds.Count || (examClassResultUpd.mark.ElementAtOrDefault(0) != null && examClassResultUpd.mark[0].Count != itemCount)) //第一層:學生數不符 OR 第二層:第一位學生批註數!=試卷題數 => 批註格式不符
- {
- examClassResultUpd.mark = this.createEmptyMark(examClassResultUpd.studentIds.Count, itemCount);
- }
- //UPDATE ExamClassResult
- var examClassResultResponse = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Common").UpsertItemAsync(examClassResultUpd, new PartitionKey(examClassResultUpd.code));
- }
- }
- //UPDATE Exam
- await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Common").UpsertItemAsync(dbExamInfo, new PartitionKey(dbExamInfo.code));
- //錯誤處理
- if (paperDataCopyErrFlg) //試卷Blob拷貝失敗
- {
- error = 1001;
- message = "Paper blob copy failure.";
- }
- else if (studentAnswerCopyErrFlg) //學生作答資料上傳blob失敗
- {
- error = 1002;
- message = "Student answers blob upload failure.";
- }
- return Ok(new { error, message });
- }
- catch (CosmosException cex)
- {
- return BadRequest(cex.Message);
- }
- catch (StorageException bex)
- {
- return BadRequest(bex.Message);
- }
- catch (Exception ex)
- {
- return BadRequest(ex.Message);
- }
- }
- /**
- * 根据学年获取年级信息
- * @param year 学年
- * @param Period 学段資料
- */
- private ExamSimple getGradeInfoByYear(int year, Period curPeriod)
- {
- ExamSimple result = new ExamSimple();
- if (year > 0)
- {
- DateTime date = DateTime.UtcNow;
- int curYear = date.Year;
- int month = date.Month;
- Semester semesterStart = curPeriod.semesters.Where((Semester x) => x.start.Equals(1)).FirstOrDefault();
- if (semesterStart != null)
- {
- if (month < semesterStart.month)
- {
- curYear--;
- }
- int gradeIndex = curYear - year;
- if (gradeIndex >= curPeriod.grades.Count)
- {
- result.id = gradeIndex.ToString();
- result.name = "graduated";
- }
- else
- {
- result.id = gradeIndex.ToString();
- result.name = curPeriod.grades[gradeIndex];
- }
- }
- }
- return result;
- }
- private List<List<List<Details>>> createEmptyMark(int studentNum, int itemNum)
- {
- List<List<List<Details>>> mark = new List<List<List<Details>>>();
- for (int i = 0; i < studentNum; i++)
- {
- List<List<Details>> markRow = new List<List<Details>>();
- for (int j = 0; j < itemNum; j++)
- {
- markRow.Add(new List<Details>());
- }
- mark.Add(markRow);
- }
- return mark;
- }
- public class ClassStudents
- {
- public string id { get; set; }
- public string name { get; set; }
- public string no { get; set; }
- public string schoolId { get; set; }
- public string groupId { get; set; }
- public string groupName { get; set; }
- public string irs { get; set; }
- public int type { get; set; } //类型 1 tmdid,2 student
- public string nickname { get; set; }
- }
- public class ClassGroups
- {
- public ClassGroups()
- {
- studentIds = new List<string>();
- }
- public string id { get; set; }
- public string name { get; set; }
- public List<string> studentIds { get; set; }
- }
- //ExamClassResult 學生作答紀錄(舊式 正式站暫時用這個)
- public class ExamClassResultStudentAnswerArrayOld : ExamClassResult
- {
- public List<List<List<string>>> studentAnswersArray { get; set; }
- }
- //ExamClassResult 學生作答紀錄
- public class ExamClassResultStudentAnswerArray : ExamClassResult
- {
- public List<List<string>> studentAnswersArray { get; set; }
- }
- //get-teacher-info API輸出 schools
- private class GetTeacherInfoApiSchool
- {
- public string schoolId { get; set; }
- public string name { get; set; }
- public string status { get; set; }
- public string picture { get; set; }
- }
- //get-teacher-info輸出 courses
- private class GetTeacherInfoApiCourse : GetTeacherInfoApiSimlpeBase
- {
- public string scope { get; set; }
- public List<GetTeacherInfoApiCourseClass> classes { get; set; }
- }
- //get-teacher-info輸出 courses.classes
- private class GetTeacherInfoApiCourseClass : GetTeacherInfoApiSimlpeBase
- {
- public string code { get; set; }
- public GetTeacherInfoApiSimlpeBase teacher { get; set; }
- public string scope { get; set; }
- public string stuListId { get; set; }
- public int stuCnt { get; set; }
- public int grpCnt { get; set; }
- public string gradeId { get; set; }
- public int year { get; set; }
- }
- //get-teacher-info輸出 基本class(各class繼承用)
- internal class GetTeacherInfoApiSimlpeBase
- {
- public string id { get; set; }
- public string name { get; set; }
- }
- }
- }
|