VolumeController.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. using Azure;
  2. using Azure.Cosmos;
  3. using Microsoft.AspNetCore.Http;
  4. using Microsoft.AspNetCore.Mvc;
  5. using Microsoft.Extensions.Options;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using System.Text;
  10. using System.Text.Json;
  11. using System.Threading.Tasks;
  12. using TEAMModelOS.Models;
  13. using TEAMModelOS.SDK.DI;
  14. using TEAMModelOS.SDK.Extension;
  15. using TEAMModelOS.SDK;
  16. using TEAMModelOS.SDK.Models;
  17. using TEAMModelOS.SDK.Models.Cosmos;
  18. using TEAMModelOS.SDK.Models.Cosmos.Common;
  19. using HTEXLib.COMM.Helpers;
  20. using Microsoft.AspNetCore.Authorization;
  21. using TEAMModelOS.Filter;
  22. namespace TEAMModelOS.Controllers
  23. {
  24. [ProducesResponseType(StatusCodes.Status200OK)]
  25. [ProducesResponseType(StatusCodes.Status400BadRequest)]
  26. //
  27. [Route("common/volume")]
  28. [ApiController]
  29. public class VolumeController : ControllerBase
  30. {
  31. private readonly AzureCosmosFactory _azureCosmos;
  32. private readonly SnowflakeId _snowflakeId;
  33. private readonly DingDing _dingDing;
  34. private readonly Option _option;
  35. public VolumeController(AzureCosmosFactory azureCosmos, SnowflakeId snowflakeId, DingDing dingDing, IOptionsSnapshot<Option> option)
  36. {
  37. _azureCosmos = azureCosmos;
  38. _snowflakeId = snowflakeId;
  39. _dingDing = dingDing;
  40. _option = option?.Value; ;
  41. }
  42. /*
  43. {
  44. "id": "册别id",
  45. "code": "学校编码/教师编码",
  46. "scope": "school/private"
  47. }
  48. */
  49. /// <summary>
  50. /// 删除册别
  51. /// </summary>
  52. /// <param name="request"></param>
  53. /// <returns></returns>
  54. [ProducesDefaultResponseType]
  55. //[AuthToken(Roles = "teacher")]
  56. [HttpPost("delete")]
  57. [Authorize(Roles = "IES")]
  58. [AuthToken(Roles = "teacher,admin")]
  59. public async Task<IActionResult> Delete(JsonElement request)
  60. {
  61. try
  62. {
  63. if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
  64. if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
  65. if (!request.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
  66. var client = _azureCosmos.GetCosmosClient();
  67. string sql = $"select value(c) from c where c.volumeId='{id}'";
  68. List<Syllabus> syllabus = new List<Syllabus>();
  69. if (scope.ToString().Equals("school"))
  70. {
  71. var response = await client.GetContainer(Constant.TEAMModelOS, "School").DeleteItemStreamAsync(id.ToString(), new PartitionKey($"Volume-{code}"));
  72. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<Syllabus>(queryText: sql, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Syllabus-{code}") })) {
  73. syllabus.Add(item);
  74. }
  75. if (syllabus.IsNotEmpty())
  76. {
  77. foreach (var s in syllabus) {
  78. if (s.auth.IsNotEmpty()) {
  79. foreach (var a in s.auth) {
  80. try {
  81. Share share = await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReadItemAsync<Share>(s.id, new PartitionKey($"Share-{a.type}-{a.tmdid}"));
  82. share.agree = -1;
  83. await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync<Share>(share, s.id, new PartitionKey($"Share-{a.type}-{a.tmdid}"));
  84. } catch (Exception ex) {
  85. ///仅用于处理查不到该数据的问题
  86. }
  87. }
  88. }
  89. }
  90. var sresponse = await client.GetContainer(Constant.TEAMModelOS, "School").DeleteItemsStreamAsync(syllabus.Select(x => x.id).ToList(), $"Syllabus-{code}");
  91. }
  92. return Ok(new { code = response.Status });
  93. }
  94. else
  95. {
  96. var response = await client.GetContainer(Constant.TEAMModelOS, "Teacher").DeleteItemStreamAsync(id.ToString(), new PartitionKey($"Volume-{code}"));
  97. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<Syllabus>(queryText: sql, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Syllabus-{code}") }))
  98. {
  99. syllabus.Add(item);
  100. }
  101. if (syllabus.IsNotEmpty())
  102. {
  103. foreach (var s in syllabus)
  104. {
  105. if (s.auth.IsNotEmpty())
  106. {
  107. foreach (var a in s.auth)
  108. {
  109. try
  110. {
  111. Share share = await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReadItemAsync<Share>(s.id, new PartitionKey($"Share-{a.type}-{a.tmdid}"));
  112. share.agree = -1;
  113. await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync<Share>(share, s.id, new PartitionKey($"Share-{a.type}-{a.tmdid}"));
  114. }
  115. catch (Exception ex)
  116. {
  117. ///仅用于处理查不到该数据的问题
  118. }
  119. }
  120. }
  121. }
  122. var sresponse = await client.GetContainer(Constant.TEAMModelOS, "Teacher").DeleteItemsStreamAsync(syllabus.Select(x => x.id).ToList(), $"Syllabus-{code}");
  123. }
  124. return Ok(new { code = response.Status });
  125. }
  126. }
  127. catch (Exception ex)
  128. {
  129. await _dingDing.SendBotMsg($"OS,{_option.Location},VolumeController:Delete\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
  130. return BadRequest();
  131. }
  132. }
  133. /*
  134. {
  135. "periodId": "学段id",
  136. "subjectId": "科目id",//
  137. "status": 1,//状态
  138. "code": "学校编码或者tmdid",
  139. "scope": "school/private" 如果是私人课纲 则学段科目id可以为空
  140. }
  141. */
  142. /// <summary>
  143. /// 查找册别
  144. /// </summary>
  145. /// <param name="request"></param>
  146. /// <returns></returns>
  147. [ProducesDefaultResponseType]
  148. //[AuthToken(Roles = "teacher")]
  149. [HttpPost("find")]
  150. [Authorize(Roles = "IES")]
  151. [AuthToken(Roles = "teacher,admin,student")]
  152. public async Task<IActionResult> Find(JsonElement request) {
  153. try {
  154. List<Volume> volumes = new List<Volume>();
  155. request.TryGetProperty("periodId", out JsonElement periodCode);
  156. request.TryGetProperty("subjectId", out JsonElement subjectCode);
  157. request.TryGetProperty("status", out JsonElement status);
  158. if (request.TryGetProperty("code", out JsonElement code))
  159. {
  160. request.TryGetProperty("scope", out JsonElement scope);
  161. //私有课纲
  162. if (scope.GetString().Equals("private"))
  163. {
  164. await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<Volume>(queryText: $"select value(c) from c where c.status = {status}", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Volume-{code}") }))
  165. {
  166. volumes.Add(item);
  167. }
  168. }
  169. else if (scope.GetString().Equals("school"))
  170. {
  171. await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<Volume>(queryText: $"select value(c) from c where c.status = {status} and c.periodId = '{periodCode}' and c.subjectId = '{subjectCode}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Volume-{code}") }))
  172. {
  173. volumes.Add(item);
  174. }
  175. }
  176. }
  177. else { return BadRequest(); };
  178. volumes= volumes.OrderBy(x => x.order).ToList();
  179. return Ok(new { volumes });
  180. } catch (Exception ex) {
  181. await _dingDing.SendBotMsg($"OS,{_option.Location},VolumeController:find\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
  182. return BadRequest();
  183. }
  184. }
  185. //{"code":"hbcn/1528783259","scope":"school/private","update":"order","data":[{"key":"1","value":1}]}
  186. /// <summary>
  187. /// 批量更新相同的属性。
  188. /// </summary>
  189. /// <param name="request"></param>
  190. /// <returns></returns>
  191. [ProducesDefaultResponseType]
  192. //[AuthToken(Roles = "teacher")]
  193. [HttpPost("update-same-property")]
  194. [Authorize(Roles = "IES")]
  195. [AuthToken(Roles = "teacher,admin")]
  196. public async Task<IActionResult> UpsertSameProperty(JsonElement request) {
  197. var client = _azureCosmos.GetCosmosClient();
  198. request.TryGetProperty("code", out JsonElement _code);
  199. request.TryGetProperty("scope", out JsonElement _scope);
  200. request.TryGetProperty("update", out JsonElement _update);
  201. request.TryGetProperty("data", out JsonElement _data);
  202. string tbname = $"{_scope}".Equals("school") ? "School" : "Teacher";
  203. List<Dictionary<string, object>> dicts = _data.ToObject<List<Dictionary<string, object>>>();
  204. foreach (var dict in dicts)
  205. {
  206. try
  207. {
  208. Volume volume = await client.GetContainer(Constant.TEAMModelOS, tbname).ReadItemAsync<Volume>($"{dict["key"]}", new PartitionKey($"Volume-{_code}"));
  209. bool modify = false;
  210. switch (true)
  211. {
  212. //修改排序
  213. case bool when $"{_update}".Equals("order", StringComparison.OrdinalIgnoreCase):
  214. if (int.TryParse($"{dict["value"]}", out int order))
  215. {
  216. volume.order = order;
  217. modify= true;
  218. }
  219. break;
  220. }
  221. if (modify) {
  222. await client.GetContainer(Constant.TEAMModelOS, tbname).ReplaceItemAsync<Volume>(volume, volume.id, new PartitionKey($"Volume-{_code}"));
  223. }
  224. }
  225. catch (Exception ex)
  226. {
  227. continue;
  228. }
  229. }
  230. return Ok(new { status=200});
  231. }
  232. /*
  233. {
  234. "id": "册别id",
  235. "code": "学校编码或教师id",
  236. "periodId": "学段id",
  237. "subjectId": "学科id",
  238. "gradeId": "年级id",
  239. "semesterId": "学期id",
  240. "status": 1,
  241. "name": "册别名",
  242. "creatorId": "创建者id",
  243. "school": "学校编码",
  244. "scope": "school|private"
  245. }
  246. */
  247. /// <summary>
  248. /// 新增册别
  249. /// </summary>
  250. /// <param name="request"></param>
  251. /// <returns></returns>
  252. [ProducesDefaultResponseType]
  253. //[AuthToken(Roles = "teacher")]
  254. [HttpPost("upsert")]
  255. [Authorize(Roles = "IES")]
  256. [AuthToken(Roles = "teacher,admin")]
  257. public async Task<IActionResult> Upsert(Volume request) {
  258. //var client = _azureCosmos.GetCosmosClient();
  259. //if (request.editors != null && request.editors.Count > 5)
  260. //{
  261. // return BadRequest("共编人数大于5人!");
  262. // // throw new BizException("共编人数大于5人!");
  263. //}
  264. request.pk = "Volume";
  265. request.ttl = -1;
  266. request.code = "Volume-" + request.code;
  267. // 检查册别条件相同的是否存在
  268. string code = "Volume-";
  269. if (request.scope.Equals("private"))
  270. {
  271. code = $"Volume-{request.creatorId}";
  272. }
  273. else if (request.scope.Equals("school"))
  274. {
  275. code = $"Volume-{request.school}";
  276. }
  277. request.createTime= DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  278. request.code = code;
  279. ///表示更新
  280. if (!string.IsNullOrEmpty(request.id))
  281. {
  282. try {
  283. if (request.scope.Equals("school"))
  284. {
  285. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync<Volume>(request, request.id, new Azure.Cosmos.PartitionKey(request.code));
  286. }
  287. else if (request.scope.Equals("private")) {
  288. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync<Volume>(request, request.id, new Azure.Cosmos.PartitionKey(request.code));
  289. }
  290. }
  291. catch (Exception ex) {
  292. return BadRequest(new { error = ResponseCode.FAILED });
  293. }
  294. }
  295. //表示新增,则需要检查是否重复
  296. else {
  297. try
  298. {
  299. StringBuilder sql = new StringBuilder("select value(c) from c where c.status = 1 ");
  300. //私人课纲 只检查是否重名
  301. if (request.scope.Equals("private"))
  302. {
  303. sql.Append($" and c.name = '{request.name}' ");
  304. List<Volume> volumes = new List<Volume>();
  305. await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher")
  306. .GetItemQueryIterator<Volume>(queryText: sql.ToString(), requestOptions: new Azure.Cosmos.QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey(request.code) }))
  307. {
  308. volumes.Add(item);
  309. }
  310. if (volumes.Count > 0)
  311. {
  312. return Ok(new { error = ResponseCode.DATA_EXIST });
  313. }
  314. }
  315. //学校课纲检查 学段 科目 年级 学期
  316. else if (request.scope.Equals("school")
  317. && !string.IsNullOrEmpty(request.periodId)
  318. && !string.IsNullOrEmpty(request.subjectId)
  319. && request.gradeId>=0
  320. && !string.IsNullOrEmpty(request.semesterId))
  321. {
  322. sql.Append($" and c.periodId = '{request.periodId}' and c.subjectId = '{request.subjectId}'" +
  323. $" and c.gradeId = {request.gradeId} and c.semesterId = '{request.semesterId}' and c.name = '{request.name}' ");
  324. List<Volume> volumes = new List<Volume>();
  325. await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School")
  326. .GetItemQueryIterator<Volume>(queryText: sql.ToString(), requestOptions: new Azure.Cosmos.QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey(request.code) })) {
  327. volumes.Add(item);
  328. }
  329. if (volumes.Count>0)
  330. {
  331. return Ok(new { error = ResponseCode.DATA_EXIST });
  332. }
  333. }
  334. else {
  335. return BadRequest(new { error = ResponseCode.PARAMS_ERROR });
  336. }
  337. request.id = System.Guid.NewGuid().ToString();
  338. if (request.scope.Equals("private"))
  339. {
  340. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").CreateItemAsync(request, new PartitionKey(request.code));
  341. }
  342. else {
  343. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").CreateItemAsync(request, new PartitionKey(request.code));
  344. }
  345. }
  346. catch (Exception ex)
  347. {
  348. await _dingDing.SendBotMsg($"OS,{_option.Location},VolumeController:Upsert\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
  349. }
  350. }
  351. ///处理更新 分享及共编的数据
  352. //if (request.auth.IsNotEmpty()) {
  353. // long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  354. // foreach (var au in request.auth) {
  355. // var share= new Share
  356. // {
  357. // id = request.id,
  358. // code = $"Share-{au.tmdid}",
  359. // pk = "Share",
  360. // ttl = -1,
  361. // scode=request.code,
  362. // issuer=request.creatorId,
  363. // createTime= now,
  364. // school=request.school,
  365. // scope=request.scope
  366. // };
  367. // await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync(share, new PartitionKey($"{share.code}"));
  368. // }
  369. //}
  370. return Ok(request);
  371. }
  372. }
  373. }