DocumentService.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Security.Principal;
  6. using System.Threading.Tasks;
  7. using BO.AppServer.Business.Exceptions;
  8. using BO.AppServer.Business.Mapper;
  9. using BO.AppServer.Business.Services.Base;
  10. using BO.AppServer.Data.Entity;
  11. using BO.AppServer.Data.Repository;
  12. using BO.AppServer.Metadata.Dto;
  13. using BO.AppServer.Metadata.Enums;
  14. using Microsoft.AspNetCore.Identity;
  15. using Microsoft.Extensions.Logging;
  16. using Microsoft.Extensions.Options;
  17. using Quadarax.Foundation.Core.Data;
  18. using Quadarax.Foundation.Core.Data.Interface;
  19. using Quadarax.Foundation.Core.Data.Interface.Entity.Dto;
  20. namespace BO.AppServer.Business.Services
  21. {
  22. public class DocumentService : UserContextService
  23. {
  24. #region *** Private fields ***
  25. private WorkspaceRepo _repoWorkspace;
  26. private MetadocumentRepo _repoDocument;
  27. private MimeTypeRepo _repoMType;
  28. private ArtifactRepo _repoArtifact;
  29. private StorageService _srvStorage;
  30. #endregion
  31. #region *** Constructors ***
  32. public DocumentService(
  33. WorkspaceRepo repoWorkspace,
  34. MetadocumentRepo repoDocument,
  35. MimeTypeRepo repoMType,
  36. ArtifactRepo repoArtifact,
  37. IOptions<Configuration.Configuration> config,
  38. UserRepo repoUser,
  39. UserManager<IdentityUser> userManager,
  40. IPrincipal currentPrincipal,
  41. ILoggerFactory logger) : base(config, repoUser, userManager, currentPrincipal, logger)
  42. {
  43. _repoWorkspace = repoWorkspace ?? throw new ArgumentNullException(nameof(repoWorkspace));
  44. _repoDocument = repoDocument ?? throw new ArgumentNullException(nameof(repoDocument));
  45. _repoMType = repoMType ?? throw new ArgumentNullException(nameof(repoMType));
  46. _repoArtifact = repoArtifact ?? throw new ArgumentNullException(nameof(repoArtifact));
  47. }
  48. #endregion
  49. #region *** Public Operations ***
  50. public async Task<ResultValueDto<DocumentRDto>> GetDocumentAsync(long workspaceId, long documentId)
  51. {
  52. var document = CheckAndGetDocument(workspaceId, documentId);
  53. return new ResultValueDto<DocumentRDto>(document.Map<Metadocument, DocumentRDto>());
  54. }
  55. public async Task<ResultsValueDto<DocumentRDto>> GetAllDocumentsAsync(long workspaceId, DocumentsScopeEnums scope, PagingDto paging)
  56. {
  57. CheckAndGetWorkspace(workspaceId);
  58. IList<Metadocument> documents = new List<Metadocument>();
  59. switch (scope)
  60. {
  61. case DocumentsScopeEnums.All:
  62. documents = _repoDocument.Query(paging).Where(x => x.Structure.WorkspaceId == workspaceId).OrderBy(x => x.Name).ToList();
  63. break;
  64. case DocumentsScopeEnums.Pending:
  65. documents = _repoDocument.Query(paging).Where(x => x.Structure.WorkspaceId == workspaceId && x.Status == (int)DocumentStatusEnum.Pending).OrderBy(x => x.Name).ToList();
  66. break;
  67. case DocumentsScopeEnums.Done:
  68. documents = _repoDocument.Query(paging).Where(x => x.Structure.WorkspaceId == workspaceId && x.Status == (int)DocumentStatusEnum.DoneOk).OrderBy(x => x.Name).ToList();
  69. break;
  70. case DocumentsScopeEnums.Working:
  71. documents = _repoDocument.Query(paging).Where(x => x.Structure.WorkspaceId == workspaceId && x.Status == (int)DocumentStatusEnum.Processing).OrderBy(x => x.Name).ToList();
  72. break;
  73. case DocumentsScopeEnums.Failed:
  74. documents = _repoDocument.Query(paging).Where(x => x.Structure.WorkspaceId == workspaceId && x.Status == (int)DocumentStatusEnum.DoneFail).OrderBy(x => x.Name).ToList();
  75. break;
  76. }
  77. return new ResultsValueDto<DocumentRDto>(documents.MapList<Metadocument, DocumentRDto>());
  78. }
  79. public async Task<ResultsValueDto<DocumentRDto>> GetAllDocumentsAsync(DocumentsScopeEnums scope, PagingDto paging)
  80. {
  81. IList<Metadocument> documents = new List<Metadocument>();
  82. switch (scope)
  83. {
  84. case DocumentsScopeEnums.All:
  85. documents = _repoDocument.Query(paging).OrderBy(x => x.Name).ToList();
  86. break;
  87. case DocumentsScopeEnums.Pending:
  88. documents = _repoDocument.Query(paging).Where(x => x.Status == (int)DocumentStatusEnum.Pending).OrderBy(x => x.Name).ToList();
  89. break;
  90. case DocumentsScopeEnums.Done:
  91. documents = _repoDocument.Query(paging).Where(x => x.Status == (int)DocumentStatusEnum.DoneOk).OrderBy(x => x.Name).ToList();
  92. break;
  93. case DocumentsScopeEnums.Working:
  94. documents = _repoDocument.Query(paging).Where(x => x.Status == (int)DocumentStatusEnum.Processing).OrderBy(x => x.Name).ToList();
  95. break;
  96. case DocumentsScopeEnums.Failed:
  97. documents = _repoDocument.Query(paging).Where(x => x.Status == (int)DocumentStatusEnum.DoneFail).OrderBy(x => x.Name).ToList();
  98. break;
  99. }
  100. return new ResultsValueDto<DocumentRDto>(documents.MapList<Metadocument, DocumentRDto>());
  101. }
  102. public async Task<ResultValueDto<DocumentRDto>> CreateDocumentAsync(long workspaceId, DocumentCDto document)
  103. {
  104. var workspace = CheckAndGetWorkspace(workspaceId);
  105. var exists = _repoDocument.Query(new Paging())
  106. .Any(x => x.Structure.WorkspaceId == workspaceId && x.Name == document.Name);
  107. if (exists)
  108. {
  109. var exc = new EntityAlreadyExistsException(typeof(Metadocument), document.Name);
  110. Log.LogWarning(exc.Message);
  111. throw exc;
  112. }
  113. var newDocument = _repoDocument.New();
  114. document.CopyToDto(newDocument);
  115. newDocument.Created = DateTime.Now;
  116. newDocument.CreatedByUser = GetCurrentUser();
  117. newDocument.Status = (int)DocumentStatusEnum.New;
  118. newDocument.StructureId = workspace.Structures.First().Id;
  119. _repoDocument.Set(newDocument);
  120. _repoDocument.Commit();
  121. return new ResultValueDto<DocumentRDto>(newDocument.Map<Metadocument, DocumentRDto>());
  122. }
  123. public async Task<ResultValueDto<ArtifactRDto>> AppendArtifactAsync(long workspaceId, long documentId,
  124. ArtifactCDto artifact, ArtifactTypeEnum type, Stream content)
  125. {
  126. //TODO: Rewrite better way - mainly rollback scenario
  127. var document = CheckAndGetDocument(workspaceId, documentId);
  128. var exists = document.Artifacts.Any(x =>
  129. x.Name.ToLower() == artifact.Name.ToLower() && x.Extension.ToLower() == artifact.Extension.ToLower());
  130. if (exists)
  131. {
  132. var exc = new EntityAlreadyExistsException(typeof(Artifact), artifact.Name + "." + artifact.Extension);
  133. Log.LogWarning(exc.Message);
  134. throw exc;
  135. }
  136. var mtype = _repoMType.GetByMimeType(artifact.MimeType);
  137. if (mtype == null)
  138. {
  139. var exc = new EntityNotExistsException(typeof(MimeType), artifact.MimeType, 0);
  140. Log.LogWarning(exc.Message);
  141. throw exc;
  142. }
  143. var newArtifact = _repoArtifact.New();
  144. newArtifact.Name = artifact.Name;
  145. newArtifact.Extension = artifact.Extension;
  146. newArtifact.Length = content.Length;
  147. newArtifact.Metadocument = document;
  148. newArtifact.MimeType = mtype;
  149. newArtifact.Created = DateTime.Now;
  150. newArtifact.CreatedByUser = GetCurrentUser();
  151. newArtifact.Type = (int)type;
  152. _repoArtifact.Set(newArtifact);
  153. document = _repoDocument.Get(documentId);
  154. document.Modified = DateTime.Now;
  155. document.ModifiedByUser = GetCurrentUser();
  156. _repoDocument.Set(document);
  157. _repoArtifact.Commit();
  158. _repoDocument.Commit();
  159. await _srvStorage.PushContentAsync(newArtifact.Id, content);
  160. return new ResultValueDto<ArtifactRDto>(newArtifact.Map<Artifact, ArtifactRDto>());
  161. }
  162. public async Task<Tuple<Stream, string>> GetArtifactAsync(long workspaceId, long documentId, long artifactId)
  163. {
  164. var artifact = CheckAndGetArtifact(workspaceId, documentId, artifactId);
  165. var result = await _srvStorage.PopContentAsync(artifact.Id);
  166. return new Tuple<Stream, string>(result.Item1, artifact.MimeType.Mimetype1);
  167. }
  168. #endregion
  169. #region *** Private Operations ***
  170. private Workspace CheckAndGetWorkspace(long workspaceId)
  171. {
  172. var workspace = _repoWorkspace.Get(workspaceId);
  173. if (workspace == null)
  174. {
  175. var exc = new EntityNotExistsException(typeof(Workspace), nameof(Workspace.Id), workspaceId);
  176. Log.LogWarning(exc.Message);
  177. throw exc;
  178. }
  179. return workspace;
  180. }
  181. private Metadocument CheckAndGetDocument(long workspaceId, long documentId)
  182. {
  183. CheckAndGetWorkspace(workspaceId);
  184. var document = _repoDocument.Get(workspaceId ,documentId);
  185. if (document == null)
  186. {
  187. var exc = new EntityNotExistsException(typeof(Metadocument), nameof(Metadocument.Id), documentId);
  188. Log.LogWarning(exc.Message);
  189. throw exc;
  190. }
  191. return document;
  192. }
  193. private Artifact CheckAndGetArtifact(long workspaceId, long documentId, long artifactId)
  194. {
  195. CheckAndGetWorkspace(workspaceId);
  196. CheckAndGetDocument(workspaceId, documentId);
  197. var artifact = _repoDocument.GetArtifact(documentId, artifactId);
  198. if (artifact == null)
  199. {
  200. var exc = new EntityNotExistsException(typeof(Artifact), nameof(Artifact.Id), artifactId);
  201. Log.LogWarning(exc.Message);
  202. throw exc;
  203. }
  204. return artifact;
  205. }
  206. #endregion
  207. }
  208. }