|
@@ -3,15 +3,23 @@ using Microsoft.AspNetCore.Authorization;
|
|
|
using Microsoft.AspNetCore.Http;
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
using Microsoft.Extensions.Options;
|
|
|
+using StackExchange.Redis;
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Linq;
|
|
|
+using System.Text;
|
|
|
using System.Text.Json;
|
|
|
using System.Threading.Tasks;
|
|
|
using TEAMModelOS.Filter;
|
|
|
using TEAMModelOS.Models;
|
|
|
+using TEAMModelOS.SDK.Context.Constant;
|
|
|
using TEAMModelOS.SDK.DI;
|
|
|
+using TEAMModelOS.SDK.Extension;
|
|
|
using TEAMModelOS.SDK.Models;
|
|
|
+using TEAMModelOS.SDK.Models.Cosmos.BI;
|
|
|
+using TEAMModelOS.SDK.Models.Cosmos.BI.BISchool;
|
|
|
+using TEAMModelOS.SDK.Models.Service.BI;
|
|
|
+using TEAMModelOS.SDK.Models.Service.BIStatsWay;
|
|
|
|
|
|
namespace TEAMModelOS.Controllers.Research
|
|
|
{
|
|
@@ -23,15 +31,17 @@ namespace TEAMModelOS.Controllers.Research
|
|
|
public class AreaController : ControllerBase
|
|
|
{
|
|
|
private readonly AzureCosmosFactory _azureCosmos;
|
|
|
+ private readonly AzureRedisFactory _azureRedis;
|
|
|
private readonly SnowflakeId _snowflakeId;
|
|
|
private readonly DingDing _dingDing;
|
|
|
private readonly Option _option;
|
|
|
- public AreaController(AzureCosmosFactory azureCosmos, SnowflakeId snowflakeId, DingDing dingDing, IOptionsSnapshot<Option> option)
|
|
|
+ public AreaController(AzureCosmosFactory azureCosmos, AzureRedisFactory azureRedis, SnowflakeId snowflakeId, DingDing dingDing, IOptionsSnapshot<Option> option)
|
|
|
{
|
|
|
_azureCosmos = azureCosmos;
|
|
|
+ _azureRedis = azureRedis;
|
|
|
_snowflakeId = snowflakeId;
|
|
|
_dingDing = dingDing;
|
|
|
- _option = option?.Value; ;
|
|
|
+ _option = option?.Value;
|
|
|
} /*
|
|
|
{"areaId":"册别id:0baf00db-0768-4b62-a8f7-280f6bcebf71","scope":"school","abilityCode":"册别分区键"}
|
|
|
*/
|
|
@@ -56,5 +66,314 @@ namespace TEAMModelOS.Controllers.Research
|
|
|
}
|
|
|
return Ok(new { areas });
|
|
|
}
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 区级统计接口
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="jsonElement"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ [ProducesDefaultResponseType]
|
|
|
+ [HttpPost("get-areastats")]
|
|
|
+#if !DEBUG
|
|
|
+ [Authorize(Roles = "IES")]
|
|
|
+#endif
|
|
|
+ [AuthToken(Roles = "area")]
|
|
|
+ public async Task<IActionResult> GetAreaStats(JsonElement jsonElement)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ if (!jsonElement.TryGetProperty("areaId", out JsonElement areaId)) return BadRequest();
|
|
|
+ var cosmosClient = _azureCosmos.GetCosmosClient();
|
|
|
+ var redisClinet = _azureRedis.GetRedisClient(8);
|
|
|
+ DateTimeOffset dateTime = DateTimeOffset.UtcNow;
|
|
|
+ Area area = null;
|
|
|
+ AreaStats areaScStats = new();
|
|
|
+ List<string> scIds = new();
|
|
|
+ List<BISchoolInfo> schoolInfos = new();
|
|
|
+ List<ScStats> scStatss = new();
|
|
|
+ List<StatsInfo> statsInfos = new();
|
|
|
+ long useSize = 0;
|
|
|
+ Dictionary<string, double?> typeStics = new(); //所有类型
|
|
|
+ var (weekS, weekE) = TimeHelper.GetStartOrEnd(dateTime, "week"); //计算本周开始/结束时间
|
|
|
+ var (mthS, mthE) = TimeHelper.GetStartOrEnd(dateTime, "month"); //本月开始/结束时间
|
|
|
+
|
|
|
+
|
|
|
+ await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<BISchoolInfo>(queryText: $"select c.id,c.name,c.picture,c.areaId,c.areaName,c.size,c.scale,c.assists,c.sales,c.createDate,c.serial,c.service,c.hard from c where c.areaId='{areaId}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("BIRel") }))
|
|
|
+ {
|
|
|
+ schoolInfos.Add(item);
|
|
|
+ }
|
|
|
+ if (schoolInfos.Count > 0)
|
|
|
+ scIds = schoolInfos.Select(s => s.id).ToList();
|
|
|
+ StringBuilder statsSql = new($"select value(c) from c where c.year={dateTime.Year}");
|
|
|
+ if (scIds.Count > 0)
|
|
|
+ statsSql.Append($" and {BICommonWay.ManyScSql("c.id", scIds, $"{dateTime.Year}-")}");
|
|
|
+
|
|
|
+ await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator<StatsInfo>(queryText: statsSql.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Statistics") }))
|
|
|
+ {
|
|
|
+ statsInfos.Add(item);
|
|
|
+ }
|
|
|
+
|
|
|
+ StringBuilder lastStsSql = new($"select c.lesson,c.activity from c where c.year={dateTime.Year - 1}");
|
|
|
+ if (scIds.Count > 0)
|
|
|
+ {
|
|
|
+ lastStsSql.Append($" and {BICommonWay.ManyScSql("c.id", scIds, $"{dateTime.Year - 1}-")}");
|
|
|
+ }
|
|
|
+
|
|
|
+ List<LastYearLessAndAct> lastYear = new();
|
|
|
+
|
|
|
+ await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator<LastYearLessAndAct>(queryText: lastStsSql.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Statistics") }))
|
|
|
+ {
|
|
|
+ lastYear.Add(item);
|
|
|
+ }
|
|
|
+
|
|
|
+ StatsInfo statsInfo = null;
|
|
|
+ statsInfo = SchoolStatsWay.GetAreaStats(cosmosClient, _option, statsInfos, scIds, area);
|
|
|
+ if (statsInfo != null)
|
|
|
+ {
|
|
|
+ areaScStats.id = statsInfo.id;
|
|
|
+ areaScStats.name = statsInfo.name;
|
|
|
+ areaScStats.weekSc = schoolInfos.Where(w => w.createDate >= weekS && w.createDate <= weekE).Count();
|
|
|
+ areaScStats.monthSc = schoolInfos.Where(w => w.createDate >= mthS && w.createDate <= mthE).Count();
|
|
|
+ areaScStats.tch = statsInfo.tch;
|
|
|
+ areaScStats.dayTch = statsInfo.dayTch;
|
|
|
+ areaScStats.weekTch = statsInfo.weekTch;
|
|
|
+ areaScStats.monthTch = statsInfo.monthTch;
|
|
|
+ areaScStats.stu = statsInfo.stu;
|
|
|
+ areaScStats.dayStu = statsInfo.dayStu;
|
|
|
+ areaScStats.weekStu = statsInfo.weekStu;
|
|
|
+ areaScStats.monthStu = statsInfo.monthStu;
|
|
|
+ areaScStats.room = statsInfo.room;
|
|
|
+ areaScStats.witRoom = statsInfo.witRoom;
|
|
|
+ areaScStats.resourceCnt = statsInfo.resourceCnt;
|
|
|
+ areaScStats.size = statsInfo.size;
|
|
|
+ //areaScStats.useSize = statsInfo.useSize;
|
|
|
+ areaScStats.lessStats.open = statsInfo.lesson.all;
|
|
|
+ areaScStats.lessStats.open = statsInfo.lesson.open;
|
|
|
+ areaScStats.lessStats.less = statsInfo.lesson.less;
|
|
|
+ areaScStats.lessStats.lastDay = statsInfo.lesson.lastDay;
|
|
|
+ areaScStats.lessStats.day = statsInfo.lesson.day;
|
|
|
+ areaScStats.lessStats.lastWeek = statsInfo.lesson.lastWeek;
|
|
|
+ areaScStats.lessStats.week = statsInfo.lesson.week;
|
|
|
+ areaScStats.lessStats.lastTerm = statsInfo.lesson.lastTerm;
|
|
|
+ areaScStats.lessStats.term = statsInfo.lesson.term;
|
|
|
+ areaScStats.lessStats.lastDayInter = statsInfo.lesson.lastDayInter;
|
|
|
+ areaScStats.lessStats.dayInter = statsInfo.lesson.dayInter;
|
|
|
+ areaScStats.lessStats.lastMonthInter = statsInfo.lesson.lastMonthInter;
|
|
|
+ areaScStats.lessStats.monthInter = statsInfo.lesson.monthInter;
|
|
|
+ areaScStats.lessStats.lastYearInter = statsInfo.lesson.lastYearInter;
|
|
|
+ areaScStats.lessStats.yearInter = statsInfo.lesson.yearInter;
|
|
|
+ areaScStats.lessStats.yearInters = TimeHelper.GetYearMonth(statsInfo.lesson.yearInters, dateTime.Year, dateTime.Month);
|
|
|
+ areaScStats.lessStats.lastYear = ((int)BICommonWay.ManyDoubleMerge(lastYear.Select(s => s.lesson.year).Where(w => w.Count > 0).ToList()).Sum());
|
|
|
+ areaScStats.lessStats.year = TimeHelper.GetYearMonth(statsInfo.lesson.year, dateTime.Year, dateTime.Month);
|
|
|
+ areaScStats.actStats.all = statsInfo.activity.all;
|
|
|
+ areaScStats.actStats.exam = statsInfo.activity.exam;
|
|
|
+ areaScStats.actStats.survey = statsInfo.activity.survey;
|
|
|
+ areaScStats.actStats.vote = statsInfo.activity.vote;
|
|
|
+ areaScStats.actStats.homework = statsInfo.activity.homework;
|
|
|
+ areaScStats.actStats.lastDay = statsInfo.activity.lastDay;
|
|
|
+ areaScStats.actStats.dayCnt = statsInfo.activity.dayCnt;
|
|
|
+ areaScStats.actStats.lastWeek = statsInfo.activity.lastWeek;
|
|
|
+ areaScStats.actStats.week = statsInfo.activity.week;
|
|
|
+ areaScStats.actStats.lastTerm = statsInfo.activity.lastTerm;
|
|
|
+ areaScStats.actStats.term = statsInfo.activity.term;
|
|
|
+ areaScStats.actStats.lastMonth = statsInfo.activity.lastMonth;
|
|
|
+ areaScStats.actStats.month = statsInfo.activity.month;
|
|
|
+ areaScStats.actStats.lastYear = ((int)BICommonWay.ManyDoubleMerge(lastYear.Select(s => s.activity.year).Where(w => w.Count > 0).ToList()).Sum());
|
|
|
+ areaScStats.actStats.year = TimeHelper.GetYearMonth(statsInfo.activity.year, dateTime.Year, dateTime.Month);
|
|
|
+ if (statsInfo.study != null)
|
|
|
+ {
|
|
|
+ areaScStats.srStats.learnTime = statsInfo.study.learnTime;
|
|
|
+ areaScStats.srStats.online = statsInfo.study.online;
|
|
|
+ areaScStats.srStats.offline = statsInfo.study.offline;
|
|
|
+ areaScStats.srStats.classRoom = statsInfo.study.classRoom;
|
|
|
+ areaScStats.srStats.submit = statsInfo.study.submit;
|
|
|
+ areaScStats.srStats.notStarted = statsInfo.study.notStarted;
|
|
|
+ areaScStats.srStats.ongoing = statsInfo.study.ongoing;
|
|
|
+ areaScStats.srStats.finish = statsInfo.study.finish;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ List<double> weekLess = BICommonWay.weekDoubleMerge(statsInfos.Select(s => s.lesson.year).Where(w => w.Count > 0).ToList(), dateTime);
|
|
|
+ schoolInfos.ForEach(fe =>
|
|
|
+ {
|
|
|
+ var tempSts = statsInfos.Find(f => f.schoolId.Equals(fe.id));
|
|
|
+ if (tempSts != null)
|
|
|
+ {
|
|
|
+ fe.less = tempSts.lesson.all;
|
|
|
+ fe.lastWeekLess = tempSts.lesson.lastWeek;
|
|
|
+ fe.monthLess = tempSts.lesson.month;
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ List<IdInfo> assits = new();
|
|
|
+ schoolInfos.ForEach(fe => assits.AddRange(fe.assists));
|
|
|
+ List<IdInfo> saless = new();
|
|
|
+ schoolInfos.ForEach(fe => saless.AddRange(fe.sales));
|
|
|
+ foreach (var itemId in scIds)
|
|
|
+ {
|
|
|
+ RedisValue value = redisClinet.HashGet($"Blob:Record", itemId);
|
|
|
+ if (value != default && !value.IsNullOrEmpty)
|
|
|
+ {
|
|
|
+ JsonElement record = value.ToString().ToObject<JsonElement>();
|
|
|
+ if (record.TryGetInt64(out long blobsize))
|
|
|
+ {
|
|
|
+ useSize += blobsize;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ SortedSetEntry[] Scores = redisClinet.SortedSetRangeByScoreWithScores($"Blob:Catalog:{itemId}");
|
|
|
+ if (Scores.Length > 0)
|
|
|
+ {
|
|
|
+ Dictionary<string, double?> schoolStics = new(); //学校空间
|
|
|
+ foreach (var score in Scores)
|
|
|
+ {
|
|
|
+ double val = score.Score;
|
|
|
+ string key = score.Element.ToString();
|
|
|
+ schoolStics.Add(key, val);
|
|
|
+ }
|
|
|
+ typeStics = typeStics.Concat(schoolStics).GroupBy(g => g.Key).ToDictionary(k => k.Key, k => k.Sum(kvp => kvp.Value)); //lamebda表达式
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return Ok(new { state = RespondCode.Ok, areaScStats, schoolInfos, weekLess, assists = assits.Where((w, i) => assits.FindIndex(s => s.id.Equals(w.id)) == i).ToList(), saless = saless.Where((w, i) => saless.FindIndex(f => f.id.Equals(w.id)) == i).ToList(), useSize, typeStics = typeStics.ToList() });
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ await _dingDing.SendBotMsg($"OS,{_option.Location},Area/GetAreaStats()\n{ex.Message}\n{ex.StackTrace}\n", GroupNames.醍摩豆服務運維群組);
|
|
|
+ return BadRequest(new { ex.Message, ex.StackTrace });
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 学校统计接口
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="jsonElement"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ [ProducesDefaultResponseType]
|
|
|
+ [HttpPost("get-schoolstats")]
|
|
|
+#if !DEBUG
|
|
|
+ [Authorize(Roles = "IES")]
|
|
|
+#endif
|
|
|
+ [AuthToken(Roles = "area")]
|
|
|
+ public async Task<IActionResult> GetSchoolStats(JsonElement jsonElement)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ if (!jsonElement.TryGetProperty("schoolId", out JsonElement scId)) return BadRequest();
|
|
|
+ var cosmosClient = _azureCosmos.GetCosmosClient();
|
|
|
+
|
|
|
+ School school = new();
|
|
|
+ ScStats scStats = new();
|
|
|
+
|
|
|
+ var respSc = await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").ReadItemStreamAsync($"{scId}", new PartitionKey($"Base"));
|
|
|
+ if (respSc.Status == 200)
|
|
|
+ {
|
|
|
+ using var fileJson = await JsonDocument.ParseAsync(respSc.ContentStream);
|
|
|
+ school = fileJson.ToObject<School>();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ return Ok(new { state = RespondCode.NotFound, msg = $"未找到id:{scId};相关的学校,请检查" });
|
|
|
+
|
|
|
+ bool isExist = true;
|
|
|
+ StatsInfo statsInfo = new();
|
|
|
+ var scDataStats = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Common").ReadItemStreamAsync($"{DateTimeOffset.UtcNow.Year}-{scId}", new PartitionKey("Statistics"));
|
|
|
+ if (scDataStats.Status == 200)
|
|
|
+ {
|
|
|
+ using var fileJson = await JsonDocument.ParseAsync(scDataStats.ContentStream);
|
|
|
+ statsInfo = fileJson.ToObject<StatsInfo>();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ scStats.id = school.id;
|
|
|
+ isExist = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ List<LastYearLessAndAct> lastYear = new();
|
|
|
+ await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator<LastYearLessAndAct>(queryText: $"select c.lesson,c.activity from c where c.id='{DateTimeOffset.UtcNow.Year - 1}-{scId}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Statistics") }))
|
|
|
+ {
|
|
|
+ lastYear.Add(item);
|
|
|
+ }
|
|
|
+
|
|
|
+ DateTimeOffset dateTime = DateTimeOffset.UtcNow;
|
|
|
+ long now = dateTime.ToUnixTimeMilliseconds();
|
|
|
+ if (!string.IsNullOrEmpty(statsInfo.id))
|
|
|
+ {
|
|
|
+ scStats.id = statsInfo.id;
|
|
|
+ scStats.schoolId = statsInfo.schoolId;
|
|
|
+ scStats.name = statsInfo.name;
|
|
|
+ scStats.picture = statsInfo.picture;
|
|
|
+ scStats.areaId = statsInfo.areaId;
|
|
|
+ scStats.tch = statsInfo.tch;
|
|
|
+ scStats.dayTch = statsInfo.dayTch;
|
|
|
+ scStats.weekTch = statsInfo.weekTch;
|
|
|
+ scStats.monthTch = statsInfo.monthTch;
|
|
|
+ scStats.stu = statsInfo.stu;
|
|
|
+ scStats.dayStu = statsInfo.dayStu;
|
|
|
+ scStats.weekStu = statsInfo.weekStu;
|
|
|
+ scStats.monthStu = statsInfo.monthStu;
|
|
|
+ scStats.room = statsInfo.room;
|
|
|
+ scStats.witRoom = statsInfo.witRoom;
|
|
|
+ scStats.resourceCnt = statsInfo.resourceCnt;
|
|
|
+ scStats.size = statsInfo.size;
|
|
|
+ scStats.scCreateTime = statsInfo.scCreateTime;
|
|
|
+ scStats.upTime = statsInfo.upTime;
|
|
|
+ scStats.lessStats.all = statsInfo.lesson.all;
|
|
|
+ scStats.lessStats.open = statsInfo.lesson.open;
|
|
|
+ scStats.lessStats.less = statsInfo.lesson.less;
|
|
|
+ scStats.lessStats.lastDay = statsInfo.lesson.lastDay;
|
|
|
+ scStats.lessStats.day = statsInfo.lesson.day;
|
|
|
+ scStats.lessStats.lastWeek = statsInfo.lesson.lastWeek;
|
|
|
+ scStats.lessStats.week = statsInfo.lesson.week;
|
|
|
+ scStats.lessStats.lastTerm = statsInfo.lesson.lastTerm;
|
|
|
+ scStats.lessStats.term = statsInfo.lesson.term;
|
|
|
+ scStats.lessStats.month = statsInfo.lesson.month;
|
|
|
+ scStats.lessStats.lastMonth = statsInfo.lesson.lastMonth;
|
|
|
+ scStats.lessStats.lastDayInter = statsInfo.lesson.lastDayInter;
|
|
|
+ scStats.lessStats.dayInter = statsInfo.lesson.dayInter;
|
|
|
+ scStats.lessStats.lastMonthInter = statsInfo.lesson.lastMonthInter;
|
|
|
+ scStats.lessStats.monthInter = statsInfo.lesson.monthInter;
|
|
|
+ scStats.lessStats.lastYear = ((int)BICommonWay.ManyDoubleMerge(lastYear.Select(s => s.lesson.year).Where(w => w.Count > 0).ToList()).Sum());
|
|
|
+ scStats.lessStats.lastYearInter = statsInfo.lesson.lastYearInter;
|
|
|
+ scStats.lessStats.yearInter = statsInfo.lesson.yearInter;
|
|
|
+ scStats.lessStats.yearInters = TimeHelper.GetYearMonth(statsInfo.lesson.yearInters, dateTime.Year, dateTime.Month);
|
|
|
+ scStats.lessStats.year = TimeHelper.GetYearMonth(statsInfo.lesson.year, dateTime.Year, dateTime.Month);
|
|
|
+ scStats.actStats.all = statsInfo.activity.all;
|
|
|
+ scStats.actStats.exam = statsInfo.activity.exam;
|
|
|
+ scStats.actStats.survey = statsInfo.activity.survey;
|
|
|
+ scStats.actStats.vote = statsInfo.activity.vote;
|
|
|
+ scStats.actStats.homework = statsInfo.activity.homework;
|
|
|
+ scStats.actStats.lastDay = statsInfo.activity.lastDay;
|
|
|
+ scStats.actStats.dayCnt = statsInfo.activity.dayCnt;
|
|
|
+ scStats.actStats.lastWeek = statsInfo.activity.lastWeek;
|
|
|
+ scStats.actStats.week = statsInfo.activity.week;
|
|
|
+ scStats.actStats.lastTerm = statsInfo.activity.lastTerm;
|
|
|
+ scStats.actStats.term = statsInfo.activity.term;
|
|
|
+ scStats.actStats.lastMonth = statsInfo.activity.lastMonth;
|
|
|
+ scStats.actStats.month = statsInfo.activity.month;
|
|
|
+ scStats.actStats.lastYear = ((int)BICommonWay.ManyDoubleMerge(lastYear.Select(s => s.activity.year).Where(w => w.Count > 0).ToList()).Sum());
|
|
|
+
|
|
|
+ scStats.actStats.year = TimeHelper.GetYearMonth(statsInfo.activity.year, dateTime.Year, dateTime.Month);
|
|
|
+ if (statsInfo.study != null)
|
|
|
+ {
|
|
|
+ scStats.srStats.learnTime = statsInfo.study.learnTime;
|
|
|
+ scStats.srStats.online = statsInfo.study.online;
|
|
|
+ scStats.srStats.offline = statsInfo.study.offline;
|
|
|
+ scStats.srStats.classRoom = statsInfo.study.classRoom;
|
|
|
+ scStats.srStats.submit = statsInfo.study.submit;
|
|
|
+ scStats.srStats.notStarted = statsInfo.study.notStarted;
|
|
|
+ scStats.srStats.ongoing = statsInfo.study.ongoing;
|
|
|
+ scStats.srStats.finish = statsInfo.study.finish;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return Ok(new { state = RespondCode.Ok, scStats, school.edition });
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ await _dingDing.SendBotMsg($"OS,{_option.Location},Area/GetSchoolStats()\n{ex.Message}\n{ex.StackTrace}\n", GroupNames.醍摩豆服務運維群組);
|
|
|
+ return BadRequest(new { ex.Message, ex.StackTrace });
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
}
|
|
|
}
|