BizOverallEducationController.cs 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622
  1. using Microsoft.AspNetCore.Http;
  2. using Microsoft.AspNetCore.Mvc;
  3. using Microsoft.Extensions.Configuration;
  4. using TEAMModelOS.SDK.DI;
  5. using TEAMModelOS.SDK;
  6. using TEAMModelOS.Models;
  7. using Microsoft.Extensions.Options;
  8. using System.Threading.Tasks;
  9. using TEAMModelOS.SDK.Models.Dtos;
  10. using TEAMModelOS.SDK.Context.Constant;
  11. using System.Collections.Generic;
  12. using System.Text.Json;
  13. using TEAMModelOS.SDK.Extension;
  14. using TEAMModelOS.Filter;
  15. using TEAMModelOS.SDK.Models;
  16. using Microsoft.Azure.Cosmos;
  17. using TEAMModelOS.SDK.Models.Cosmos.OpenEntity;
  18. using System;
  19. using System.Text;
  20. namespace TEAMModelOS.Controllers
  21. {
  22. /// <summary>
  23. /// 五育并举接口
  24. /// </summary>
  25. [Route("business")]
  26. [ApiController]
  27. public class BizOverallEducationController : ControllerBase
  28. {
  29. public AzureCosmosFactory _azureCosmos;
  30. private readonly AzureStorageFactory _azureStorage;
  31. private readonly AzureRedisFactory _azureRedis;
  32. private readonly DingDing _dingDing;
  33. private readonly Option _option;
  34. private readonly IConfiguration _configuration;
  35. private readonly CoreAPIHttpService _coreAPIHttpService;
  36. private readonly AzureServiceBusFactory _serviceBus;
  37. private readonly SnowflakeId _snowflakeId;
  38. public BizOverallEducationController(AzureCosmosFactory azureCosmos, AzureStorageFactory azureStorage, AzureRedisFactory azureRedis, AzureServiceBusFactory serviceBus, DingDing dingDing, CoreAPIHttpService coreAPIHttpService, IOptionsSnapshot<Option> option, IConfiguration configuration, SnowflakeId snowflakeId)
  39. {
  40. _azureCosmos = azureCosmos;
  41. _azureStorage = azureStorage;
  42. _azureRedis = azureRedis;
  43. _dingDing = dingDing;
  44. _option = option?.Value;
  45. _configuration = configuration;
  46. _coreAPIHttpService = coreAPIHttpService;
  47. _serviceBus = serviceBus;
  48. _snowflakeId = snowflakeId;
  49. }
  50. /// <summary>
  51. /// 设置学生画像
  52. /// </summary>
  53. /// <param name="portrait"></param>
  54. /// <returns></returns>
  55. [ProducesDefaultResponseType]
  56. [HttpPost("upsert-student-portrait")]
  57. [ApiToken(Auth = "1901", Name = "设置学生全面教育画像", TName = "設置學生全面教育畫像", EName = "Set up students overall education portrait", RWN = "W", Limit = false)]
  58. public async Task<IActionResult> UpsertStudentPortrait(JsonElement jsonElement)
  59. {
  60. var (id, school) = HttpContext.GetApiTokenInfo();
  61. var responseData = await OpenApiService.UpsertStudentPortrait(_azureCosmos, _dingDing, _azureRedis, jsonElement,school);
  62. return Ok(new { responseData });
  63. }
  64. #region 杉达公司
  65. /// <summary>
  66. /// 开课或者上传课例信息 是因支持VR/AR的公司(杉达)
  67. /// </summary>
  68. /// <param name="jsonElement"></param>
  69. /// <returns></returns>
  70. //[ProducesDefaultResponseType]
  71. //[HttpPost("set-lesson-relord")]
  72. //[ApiToken(Auth = "1903", Name = "开课/上传课例信息", TName = "開課/上傳課例信息", EName = "Start class/upload class information", RWN = "W", Limit = false)]
  73. public async Task<IActionResult> UpLessonRec(JsonElement jsonElement)
  74. {
  75. var (id, school) = HttpContext.GetApiTokenInfo();
  76. try
  77. {
  78. jsonElement.TryGetProperty("baseJson", out JsonElement baseJson); //课例基础文件信息json
  79. jsonElement.TryGetProperty("timLineJson", out JsonElement timLineJson); //时间json
  80. jsonElement.TryGetProperty("lessonId", out JsonElement lessonId); //课例id
  81. if (!jsonElement.TryGetProperty("tmdId", out JsonElement tmdId)) return Ok(new { responseDate = new ResponseData<dynamic>() { code = RespondCode.ParamsError, msg = "tmdId参数错误", data = null } }); //上课人ID
  82. jsonElement.TryGetProperty("tmdName", out JsonElement tmdName); //上课人昵称
  83. jsonElement.TryGetProperty("tmdPicture", out JsonElement tmdpicture); //上课人头像
  84. if (!jsonElement.TryGetProperty("startTime", out JsonElement startTime)) return Ok(new { responseDate = new ResponseData<dynamic>() { code = RespondCode.ParamsError, msg = "startTime参数错误", data = null } }); //开始时间
  85. if (!jsonElement.TryGetProperty("duration", out JsonElement duration)) return Ok(new { responseDate = new ResponseData<dynamic>() { code = RespondCode.ParamsError, msg = "startTime参数错误", data = null } }); //上课时长
  86. jsonElement.TryGetProperty("periodId", out JsonElement periodId); //学段id
  87. jsonElement.TryGetProperty("periodName", out JsonElement periodName); //学段名称
  88. jsonElement.TryGetProperty("groupIds", out JsonElement _groupIds); //名单id
  89. jsonElement.TryGetProperty("groupNames", out JsonElement _groupNames); //名单名称
  90. jsonElement.TryGetProperty("gradeIds", out JsonElement _gradeIds); //年级id
  91. jsonElement.TryGetProperty("gradeNames", out JsonElement _gradeNames); //年级名称
  92. jsonElement.TryGetProperty("subjectId", out JsonElement subjectId); //科目id
  93. jsonElement.TryGetProperty("subjecName", out JsonElement subjecName); //科目名称
  94. jsonElement.TryGetProperty("courseId", out JsonElement courseId); //课程id
  95. jsonElement.TryGetProperty("courseName", out JsonElement courseName); //课程名称
  96. LessonRecord lessonRecord = new();
  97. LessonBase lessonBase = null;
  98. TimeLine timeLine = null;
  99. if (!string.IsNullOrEmpty($"{baseJson}"))
  100. {
  101. lessonBase = baseJson.ToObject<LessonBase>();
  102. lessonRecord.upload = 1;
  103. }
  104. else
  105. lessonRecord.upload = 0;
  106. if (!string.IsNullOrEmpty($"{timLineJson}"))
  107. {
  108. timeLine = timLineJson.ToObject<TimeLine>();
  109. lessonRecord.upload = 1;
  110. }
  111. else
  112. lessonRecord.upload = 0;
  113. List<string> groupIds = new();
  114. List<string> groupNames = new();
  115. List<string> gradeIds = new();
  116. List<string> gradeNames = new();
  117. if (!string.IsNullOrEmpty($"{_groupIds}"))
  118. groupIds = _groupIds.ToObject<List<string>>();
  119. if (!string.IsNullOrEmpty($"{_groupNames}"))
  120. groupNames = _groupNames.ToObject<List<string>>();
  121. if (!string.IsNullOrEmpty($"{_gradeIds}"))
  122. gradeIds = _gradeIds.ToObject<List<string>>();
  123. if (!string.IsNullOrEmpty($"{_gradeNames}"))
  124. gradeNames = _gradeNames.ToObject<List<string>>();
  125. var cosmosClient = _azureCosmos.GetCosmosClient();
  126. string code = $"LessonRecord-{school}";
  127. var resLess = await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").ReadItemStreamAsync($"{lessonId}", new PartitionKey($"{code}"));
  128. if (resLess.StatusCode==System.Net.HttpStatusCode.OK)
  129. {
  130. JsonDocument jsonD = JsonDocument.Parse(resLess.Content);
  131. lessonRecord = jsonD.RootElement.ToObject<LessonRecord>();
  132. }
  133. else
  134. {
  135. lessonRecord.id = _snowflakeId.NextId().ToString();
  136. lessonRecord.code = code;
  137. }
  138. lessonRecord.tmdid = $"{tmdId}";
  139. lessonRecord.tmdname = $"{tmdName}";
  140. lessonRecord.tmdpicture = $"{tmdpicture}";
  141. lessonRecord.school = school;
  142. lessonRecord.scope = "school";
  143. lessonRecord.startTime = long.Parse($"{startTime}");
  144. lessonRecord.duration = double.Parse($"{duration}");
  145. lessonRecord.periodId = $"{periodId}";
  146. lessonRecord.periodName = $"{periodName}";
  147. lessonRecord.subjectId = $"{subjectId}";
  148. lessonRecord.subjecName = $"{subjecName}";
  149. lessonRecord.courseId = $"{courseId}";
  150. lessonRecord.courseName = $"{courseName}";
  151. lessonRecord.groupIds = groupIds;
  152. lessonRecord.groupNames = groupNames;
  153. lessonRecord.grade = gradeIds;
  154. lessonRecord.gradeName = gradeNames;
  155. if (!string.IsNullOrEmpty($"{baseJson}"))
  156. {
  157. lessonRecord.name = lessonBase.summary.activityName;
  158. lessonRecord.attendCount = lessonBase.summary.attendCount;
  159. lessonRecord.clientCount = lessonBase.summary.clientCount;
  160. lessonRecord.attendRate = lessonBase.summary.attendRate;
  161. lessonRecord.groupCount = lessonBase.summary.groupCount;
  162. lessonRecord.collateTaskCount = lessonBase.summary.collateTaskCount;
  163. lessonRecord.collateCount = lessonBase.summary.collateCount;
  164. lessonRecord.pushCount = lessonBase.summary.pushCount;
  165. lessonRecord.totalPoint = lessonBase.summary.totalPoint;
  166. lessonRecord.examQuizCount = lessonBase.summary.examQuizCount;
  167. lessonRecord.interactionCount = lessonBase.summary.interactionCount;
  168. lessonRecord.examPointRate = lessonBase.summary.examPointRate;
  169. lessonRecord.clientInteractionCount = lessonBase.summary.clientInteractionCount;
  170. lessonRecord.clientInteractionAverge = lessonBase.summary.clientInteractionAverge;
  171. lessonRecord.examCount = lessonBase.summary.examCount;
  172. lessonRecord.totalInteractPoint = lessonBase.summary.totalInteractPoint;
  173. lessonRecord.learningCategory = lessonBase.summary.learningCategory;
  174. lessonRecord.source = 1;
  175. //计算TP灯
  176. {
  177. int T = -1;
  178. int P = -1;
  179. if (lessonRecord.clientInteractionAverge <= 0)
  180. {
  181. T = 0;
  182. }
  183. else if (lessonRecord.clientInteractionAverge >= 1 && lessonRecord.clientInteractionAverge <= 2)
  184. {
  185. T = 1;
  186. }
  187. else
  188. {
  189. T = 2;
  190. }
  191. //if (lessonRecord.examCount > 0)
  192. //{
  193. // //有评测次数大于0则P是直接绿灯
  194. // P = 2;
  195. //}
  196. //else {
  197. //}
  198. int a = lessonRecord.hitaClientCmpCount;
  199. int b = lessonRecord.pushCount;
  200. int c = lessonRecord.examCount;
  201. switch (true)
  202. {
  203. case bool when T == 0:
  204. P = 0;
  205. break;
  206. case bool when T == 1 || T == 2:
  207. if (a == 0 && b == 0 && c == 0)
  208. {
  209. P = 0;
  210. }
  211. else if ((a > 0 && b > 0) || (a > 0 && c > 0) || (b > 0 && c > 0))
  212. {
  213. P = 2;
  214. }
  215. else
  216. {
  217. P = 1;
  218. }
  219. break;
  220. }
  221. lessonRecord.tLevel = T;
  222. lessonRecord.pLevel = P;
  223. }
  224. }
  225. if (resLess.StatusCode==System.Net.HttpStatusCode.OK)
  226. lessonRecord = await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync<LessonRecord>(lessonRecord, lessonRecord.id, new PartitionKey($"{code}"));
  227. else
  228. lessonRecord = await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").CreateItemAsync<LessonRecord>(lessonRecord, new PartitionKey($"{code}"));
  229. var blobClient = _azureStorage.GetBlobContainerClient(containerName: $"{school}");
  230. if (!string.IsNullOrEmpty($"{baseJson}"))
  231. //保存Basejson文件
  232. await AzureStorageBlobExtensions.UploadFileByContainer(blobClient, lessonBase.ToJsonString(), $"records/{lessonRecord.id}/IES", $"Base.json");
  233. if (!string.IsNullOrEmpty($"{timLineJson}"))
  234. //保存TimeLinejson文件
  235. await AzureStorageBlobExtensions.UploadFileByContainer(blobClient, timeLine.ToJsonString(), $"records/{lessonRecord.id}/IES", $"TimeLine.json");
  236. return Ok(new
  237. {
  238. responseData = new ResponseData<dynamic>()
  239. {
  240. code = RespondCode.Ok,
  241. msg = "成功",
  242. data = new
  243. {
  244. lessonRecord,
  245. analysis = new
  246. {
  247. lessonRecord.id,
  248. lessonRecord.name,
  249. lessonRecord.subjectId,
  250. lessonRecord.courseId,
  251. intIndex = lessonRecord.tLevel,
  252. learning = lessonRecord.pLevel,
  253. atendCnt = lessonRecord.attendCount,
  254. grCnt = lessonRecord.groupCount,
  255. taskCnt = lessonRecord.collateTaskCount,
  256. worksCnt = lessonRecord.collateCount,
  257. pushCnt = lessonRecord.pushCount,
  258. scoreCnt = lessonRecord.totalPoint,
  259. emCnt = lessonRecord.examCount,
  260. intTopicCnt = lessonRecord.interactionCount,
  261. emPct = $"{lessonRecord.examPointRate} %",
  262. stuIntCnt = lessonRecord.clientInteractionCount,
  263. study = new
  264. {
  265. coopCnt = lessonRecord.learningCategory.cooperation,
  266. testCnt = lessonRecord.learningCategory.exam,
  267. intCnt = lessonRecord.learningCategory.interaction,
  268. dCnt = lessonRecord.learningCategory.diffential,
  269. taskCnt = lessonRecord.learningCategory.task,
  270. }
  271. }
  272. }
  273. }
  274. });
  275. }
  276. catch (Exception ex)
  277. {
  278. await _dingDing.SendBotMsg($"OpenApi,{Environment.GetEnvironmentVariable("Option:Location")} BizOverallEducation/UpLessonRec() 参数:bizId:{id},school:{school},json:{jsonElement.ToJsonString()} \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  279. return Ok(new { responseData = new ResponseData<dynamic>() { code = RespondCode.Error, msg = "服务端异常" } });
  280. }
  281. }
  282. /// <summary>
  283. /// 获取学校课例 是因支持VR/AR的公司(杉达)
  284. /// </summary>
  285. /// <param name="jsonElement"></param>
  286. /// <returns></returns>
  287. //[ProducesDefaultResponseType]
  288. //[HttpPost("get-lesson-relords")]
  289. //[ApiToken(Auth = "1904", Name = "获取学校课例", TName = "獲取學校課例", EName = "Get school lessons", RWN = "R", Limit = false)]
  290. public async Task<IActionResult> GetLessonRec(JsonElement jsonElement)
  291. {
  292. var (id, school) = HttpContext.GetApiTokenInfo();
  293. jsonElement.TryGetProperty("lessonId", out JsonElement lessId);
  294. var cosmosClient = _azureCosmos.GetCosmosClient();
  295. StringBuilder sql = new("select value(c) from c where c.source=1");
  296. if (!string.IsNullOrEmpty($"{lessId}"))
  297. sql.Append($" and c.id='{lessId}'");
  298. List<OLessonRecord> lessonRecords = new();
  299. await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIteratorSql<OLessonRecord>(queryText: sql.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"LessonRecord-{school}") }))
  300. {
  301. lessonRecords.Add(item);
  302. }
  303. return Ok(new { responseData = new ResponseData<dynamic>() { code = RespondCode.Ok, msg = "成功", data = lessonRecords } });
  304. }
  305. /// <summary>
  306. /// 获取学校课例分析结果 是因支持VR/AR的公司(杉达)
  307. /// </summary>
  308. /// <param name="jsonElement"></param>
  309. /// <returns></returns>
  310. [ProducesDefaultResponseType]
  311. [HttpPost("get-lesson-analysis")]
  312. [ApiToken(Auth = "1906", Name = "获取学校课例", TName = "獲取學校課例", EName = "Get school lessons", RWN = "R", Limit = false)]
  313. public async Task<IActionResult> GetLessonStats(JsonElement jsonElement)
  314. {
  315. var (id, school) = HttpContext.GetApiTokenInfo();
  316. if(!jsonElement.TryGetProperty("lessonId", out JsonElement lessonId)) return Ok(new { responseDate = new ResponseData<dynamic>() { code = RespondCode.ParamsError, msg = "lessId参数错误", data = null } }); //上课人ID ;
  317. var cosmosClient = _azureCosmos.GetCosmosClient();
  318. dynamic analysis = null;
  319. await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryStreamIteratorSql(queryText: $"select c.id,c.name,c.subjectId,c.courseId,c.tLevel,c.pLevel,c.attendCount,c.groupCount,c.collateTaskCount,c.collateCount,c.pushCount,c.totalPoint,c.examCount,c.interactionCount,c.examPointRate,c.clientInteractionCount,c.learningCategory from c where c.id='{lessonId}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"LessonRecord-{school}") }))
  320. {
  321. using var json = await JsonDocument.ParseAsync(item.Content);
  322. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  323. {
  324. var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
  325. while (accounts.MoveNext())
  326. {
  327. JsonElement account = accounts.Current;
  328. LearningCategory learningCategory = account.GetProperty("learningCategory").ToObject<LearningCategory>();
  329. analysis = new
  330. {
  331. id = account.GetProperty("id").GetString(),
  332. name = account.GetProperty("name").GetString(),
  333. subjectId = account.GetProperty("subjectId").GetString(),
  334. courseId = account.GetProperty("courseId").GetString(),
  335. intIndex = account.GetProperty("tLevel").GetInt64(),
  336. learning = account.GetProperty("pLevel").GetInt64(),
  337. atendCnt = account.GetProperty("attendCount").GetInt64(),
  338. grCnt = account.GetProperty("groupCount").GetInt64(),
  339. taskCnt = account.GetProperty("collateTaskCount").GetInt64(),
  340. worksCnt = account.GetProperty("collateCount").GetInt64(),
  341. pushCnt = account.GetProperty("pushCount").GetInt64(),
  342. scoreCnt = account.GetProperty("totalPoint").GetInt64(),
  343. emCnt = account.GetProperty("examCount").GetInt64(),
  344. intTopicCnt = account.GetProperty("interactionCount").GetInt64(),
  345. emPct = $"{account.GetProperty("examPointRate").GetDouble()} %",
  346. stuIntCnt = account.GetProperty("clientInteractionCount").GetInt64(),
  347. study = new
  348. {
  349. coopCnt = learningCategory.cooperation,
  350. testCnt = learningCategory.exam,
  351. intCnt = learningCategory.interaction,
  352. dCnt = learningCategory.diffential,
  353. taskCnt = learningCategory.task,
  354. }
  355. };
  356. //var ids = account.GetProperty("id").GetString();
  357. //var name = account.GetProperty("name").GetString();
  358. //var intIndex = account.GetProperty("tLevel").GetInt64();
  359. //var learning = account.GetProperty("pLevel").GetInt64();
  360. //var atendCnt = account.GetProperty("attendCount").GetInt64();
  361. //var grCnt = account.GetProperty("groupCount").GetInt64();
  362. //var taskCnt = account.GetProperty("collateTaskCount").GetInt64();
  363. //var worksCnt = account.GetProperty("collateCount").GetInt64();
  364. //var pushCnt = account.GetProperty("pushCount").GetInt64();
  365. //var scoreCnt = account.GetProperty("totalPoint").GetInt64();
  366. //var emCnt = account.GetProperty("examCount").GetInt64();
  367. //var intTopicCnt = account.GetProperty("interactionCount").GetInt64();
  368. //var emPct = $"{account.GetProperty("examPointRate").GetDouble()} %";
  369. //var stuIntCnt = account.GetProperty("clientInteractionCount").GetInt64();
  370. //var study = new
  371. //{
  372. // coopCnt = learningCategory.cooperation,
  373. // testCnt = learningCategory.exam,
  374. // intCnt = learningCategory.interaction,
  375. // dCnt = learningCategory.diffential
  376. //};
  377. }
  378. }
  379. }
  380. return Ok(new { responseData = new ResponseData<dynamic>() { code = RespondCode.Ok, msg = "成功", data = analysis } });
  381. }
  382. #endregion
  383. ///数据结构说明
  384. /**
  385. *
  386. url[post]https: //www.teammodel.cn/business/upsert-student-portrait
  387. header:
  388. X-Auth-School:hbcn 授权访问的学校
  389. X-Auth-ApiToken:授权token eyJhbGciOiJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGRzaWctbW9yZSNobWFjLXNoYTI1NiIsInR5cCI6IkpXVCJ9
  390. Content-Type: application/json
  391. params [body json]:
  392. {
  393. "schoolCode": "hbcn",
  394. "periodId": "463db08d-cbe7-48a0-a81a-fc39b3c1fep1",
  395. "subjectId": "subject_sport",
  396. "students": [
  397. {
  398. "studentId": "202001001",
  399. "name": "卢三诗",
  400. "classId": "2ffbd7f9-2445-4139-90a7-59e27c0d097e",
  401. "semesterData": [
  402. {
  403. "examName": "评测名称",
  404. "examId": "评测id2",
  405. "examDate": 1629947402486,
  406. "examType": "期末",
  407. "year": 2020,
  408. "semester": 1,
  409. "semesterId": "17f85c96-253d-4f84-84ad-c819f0b605s21",
  410. "totalScore": 100,
  411. "sumScore": 80,
  412. "excellenceRate": 61.73,
  413. "passRate": 91.88,
  414. "itemScore": [
  415. {
  416. "name": "立定跳远",
  417. "score": 99.95
  418. }
  419. ]
  420. }
  421. ]
  422. }
  423. ]
  424. }
  425. //正确返回
  426. {
  427. "responseData": {
  428. "code": 200,
  429. "msg": "成功",
  430. "data": {
  431. "unmatchStuInfo": [],//如果数组长度大于0则,学生信息或班级信息不匹配
  432. "unmatchSemester":[],//如果数组长度大于0则,包含的学期信息不匹配
  433. "upsertDatas":[],//如果数组长度大于0则,表示更新或保存成功的数据
  434. }
  435. }
  436. }
  437. //错误返回
  438. {
  439. "responseData": {
  440. "code": 500,
  441. "msg": "返回信息"
  442. }
  443. }
  444. code:
  445. 500 服务端异常
  446. 404 学校编码不存在
  447. 404 periodId不存在
  448. 400 当前subjectId未开放画像业务
  449. 400 students为空或格式错误
  450. 400 subjectId为空
  451. 400 periodId为空
  452. 400 schoolCode为空
  453. //接口规范
  454. {
  455. "schoolCode": "hbcn", //学校简码
  456. "periodId": "52076c94-7581-fbae-4487-4b162a61fea3", //学段id
  457. "subjectId": "subject_sport", //体育科目id
  458. "students": [
  459. {
  460. "studentId": "20220901", //学生编号
  461. "name": "海献仪", //学生姓名
  462. "classId": "c406eee2-1ce9-caf4-5fc0-57351604b615", //行政班id
  463. "semesterData": [ //学期数据
  464. {
  465. "examName": "评测名称", //评测名称
  466. "examId": "评测id", //用于数据新增或更新
  467. "examDate": 1629947402486, //评测时间,13位时间戳
  468. "examType": "期末", //期末,期中,季考,月考,周考,测验,练习,作业,日常,课中
  469. "year": 2021, //所属学年,学年跨年,按上一年。
  470. "semester": 2, //学期,与semesterId选填其一
  471. "semesterId": "17f85c96-253d-4f84-84ad-c819f0b605s2", //学期id
  472. "totalScore": 100, //配分,总分
  473. "sumScore": 74.29, //总成绩
  474. "excellenceRate": 61.73, //优秀率
  475. "passRate": 91.88, //及格率
  476. "itemScore": [ //考核项目数据
  477. {
  478. "name": "立定跳远", //项目名称
  479. "score": 99.95 //项目分数
  480. }
  481. ]
  482. }
  483. ]
  484. }
  485. ]
  486. }
  487. //五育数据看板结构
  488. {
  489. "id": "年份2021-学期id",
  490. "semesterName": "上学期",
  491. "year": 2021,
  492. "semesterId": "17f85c96-253d-4f84-84ad-c819f0b605s2",
  493. "code": "hbcn-20220901",
  494. "schoolCode": "hbcn",
  495. "studentId": "20220901",
  496. "name": "海献仪",
  497. "classId": [
  498. "c406eee2-1ce9-caf4-5fc0-57351604b615"
  499. ],
  500. "periodId": "52076c94-7581-fbae-4487-4b162a61fea3",
  501. "grade": 1,
  502. "virtue": //德
  503. [
  504. {
  505. "id": "17f85c96-253d-4f84-84ad-c819f0b605s2",
  506. "name": "评测名称",
  507. "type": "日常", //期末,期中,季考,月考,周考,测验,练习,作业,日常,课中
  508. "subjectId": "52076c94-7581-fbae-4487-4b162a61fea3",
  509. "examDate": 1629947402486,
  510. "sumScore": 74.29,
  511. "excellenceRate": 61.73,
  512. "passRate": 91.88,
  513. "itemScore": [ //考核项目数据
  514. {
  515. "name": "迟到", //
  516. "score": -1, //计分
  517. "time": 1629947402486,
  518. }
  519. ]
  520. }
  521. ],
  522. "intelligence": //智
  523. [
  524. {
  525. "id": "17f85c96-253d-4f84-84ad-c819f0b605s2",
  526. "name": "评测名称",
  527. "type": "期末", //期末,期中,季考,月考,周考,测验,练习,作业,日常,课中
  528. "subjectId": "52076c94-7581-fbae-4487-4b162a61fea3",
  529. "examDate": 1629947402486,
  530. "level": 1
  531. }
  532. ],
  533. "sports": //体
  534. [
  535. {
  536. "id": "17f85c96-253d-4f84-84ad-c819f0b605s2",
  537. "name": "评测名称",
  538. "type": "期末", //期末,期中,季考,月考,周考,测验,练习,作业,日常,课中
  539. "subjectId": "52076c94-7581-fbae-4487-4b162a61fea3",
  540. "examDate": 1629947402486,
  541. "sumScore": 74.29,
  542. "excellenceRate": 61.73,
  543. "passRate": 91.88,
  544. "itemScore": [ //考核项目数据
  545. {
  546. "name": "立定跳远", //项目名称
  547. "score": 99.95 //项目分数
  548. }
  549. ]
  550. }
  551. ],
  552. "art": //美
  553. [
  554. {
  555. "id": "17f85c96-253d-4f84-84ad-c819f0b605s2",
  556. "name": "评测名称",
  557. "type": "期末", //期末,期中,季考,月考,周考,测验,练习,作业,日常,课中
  558. "subjectId": "52076c94-7581-fbae-4487-4b162a61fea3",
  559. "examDate": 1629947402486,
  560. "level": 1,
  561. }
  562. ],
  563. "labour": //劳
  564. [
  565. {
  566. "id": "17f85c96-253d-4f84-84ad-c819f0b605s2",
  567. "name": "任务名称",
  568. "type": "日常", //期末,期中,季考,月考,周考,测验,练习,作业,日常,课中
  569. "subjectId": "52076c94-7581-fbae-4487-4b162a61fea3",
  570. "examDate": 1629947402486,
  571. "itemScore": [ //考核项目数据
  572. {
  573. "name": "洗碗", //洗碗,倒垃圾,打扫卫生等...
  574. "score": 1, //项目计分
  575. "time": 1629947402486,
  576. }
  577. ]
  578. }
  579. ]
  580. }
  581. * **/
  582. }
  583. }