irc-netcore-api/IRaCIS.Core.Application/Service/Document/AuditDocumentService.cs

1216 lines
43 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

//--------------------------------------------------------------------
// 此代码由liquid模板自动生成 byzhouhang 20240909
// 生成时间 2025-03-27 06:13:33Z
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
using IRaCIS.Core.Domain.Models;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Infrastructure.Extention;
using System.Threading.Tasks;
using IRaCIS.Core.Infra.EFCore;
using AutoMapper.Execution;
using System.Linq;
using IRaCIS.Core.Infrastructure;
using DocumentFormat.OpenXml.Office2010.Excel;
using MassTransit;
using NPOI.POIFS.Properties;
using Org.BouncyCastle.Crypto;
using Microsoft.AspNetCore.Http;
using IRaCIS.Core.Application.Contracts;
using Microsoft.EntityFrameworkCore;
using static Microsoft.Extensions.Logging.EventSource.LoggingEventSource;
using NPOI.SS.Formula.Functions;
namespace IRaCIS.Core.Application.Service;
/// <summary>
/// 稽查文档
/// </summary>
/// <returns></returns>
[ApiExplorerSettings(GroupName = "FileRecord")]
public class AuditDocumentService(IRepository<AuditDocument> _auditDocumentRepository, IRepository<AuditRecord> _auditRecordRepository,
IRepository<AuditRecordPermission> _auditRecordPermissionRepository, IRepository<AuditRecordIdentityUser> _auditRecordIdentityUserRepository, IRepository<AuditDocumentClosure> _auditDocumentClosureRepository,
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService
{
#region 稽查新增需求
/// <summary>
/// 查看授权时间内的稽查 admin qa 看所有 EA只看到自己参与的
/// </summary>
/// <param name="inQuery"></param>
/// <returns></returns>
[HttpPost]
public async Task<List<AuditRecordView>> GetAuditRecordSelectList(AuditRecordQuery inQuery)
{
var dateTimeNow = DateTime.Now;
var isAdminOrQA = _userInfo.UserTypeEnumInt == (int)UserTypeEnum.Admin || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.SuperAdmin || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.QA;
var auditRecordQueryable = _auditRecordRepository
//过滤查看用户
.WhereIf(isAdminOrQA == false, t => t.AuditRecordIdentityUserList.Any(t => t.IdentityUserId == _userInfo.IdentityUserId) && t.BeginTime < dateTimeNow && t.EndTime > dateTimeNow)
.WhereIf(inQuery.BeginAuditTime != null, t => t.AuditTime >= inQuery.BeginAuditTime)
.WhereIf(inQuery.EndAuditTime != null, t => t.AuditTime <= inQuery.EndAuditTime)
.WhereIf(inQuery.AuditState != null, t => t.AuditState == inQuery.AuditState)
.WhereIf(inQuery.AuditType != null, t => t.AuditType == inQuery.AuditType)
.WhereIf(inQuery.BeginTime != null, t => t.BeginTime >= inQuery.BeginTime)
.WhereIf(inQuery.EndTime != null, t => t.EndTime <= inQuery.EndTime)
.WhereIf(inQuery.BeginCreateTime != null, t => t.CreateTime >= inQuery.BeginCreateTime)
.WhereIf(inQuery.EndCreateTime != null, t => t.CreateTime <= inQuery.EndCreateTime)
.WhereIf(inQuery.IdentityUserName.IsNotNullOrEmpty(), t => t.AuditRecordIdentityUserList.Any(c => c.IdentityUser.UserName.Contains(inQuery.IdentityUserName) || c.IdentityUser.FullName.Contains(inQuery.IdentityUserName)))
.WhereIf(inQuery.CompanyName.IsNotNullOrEmpty(), t => t.CompanyName.Contains(inQuery.CompanyName))
.WhereIf(inQuery.AuditContent.IsNotNullOrEmpty(), t => t.AuditContent.Contains(inQuery.AuditContent))
.ProjectTo<AuditRecordView>(_mapper.ConfigurationProvider);
var list = await auditRecordQueryable.OrderBy(t => t.AuditTime).ToListAsync();
return list;
}
/// <summary>
/// 稽查记录 列表
/// </summary>
/// <param name="inQuery"></param>
/// <returns></returns>
[HttpPost]
public async Task<PageOutput<AuditRecordView>> GetAuditRecordList(AuditRecordQuery inQuery)
{
var auditRecordQueryable = _auditRecordRepository
.WhereIf(inQuery.BeginAuditTime != null, t => t.AuditTime >= inQuery.BeginAuditTime)
.WhereIf(inQuery.EndAuditTime != null, t => t.AuditTime <= inQuery.EndAuditTime)
.WhereIf(inQuery.AuditState != null, t => t.AuditState == inQuery.AuditState)
.WhereIf(inQuery.AuditType != null, t => t.AuditType == inQuery.AuditType)
.WhereIf(inQuery.BeginTime != null, t => t.BeginTime >= inQuery.BeginTime)
.WhereIf(inQuery.EndTime != null, t => t.EndTime <= inQuery.EndTime)
.WhereIf(inQuery.BeginCreateTime != null, t => t.CreateTime >= inQuery.BeginCreateTime)
.WhereIf(inQuery.EndCreateTime != null, t => t.CreateTime <= inQuery.EndCreateTime)
.WhereIf(inQuery.IdentityUserName.IsNotNullOrEmpty(), t => t.AuditRecordIdentityUserList.Any(c => c.IdentityUser.UserName.Contains(inQuery.IdentityUserName) || c.IdentityUser.FullName.Contains(inQuery.IdentityUserName)))
.WhereIf(inQuery.CompanyName.IsNotNullOrEmpty(), t => t.CompanyName.Contains(inQuery.CompanyName))
.WhereIf(inQuery.AuditContent.IsNotNullOrEmpty(), t => t.AuditContent.Contains(inQuery.AuditContent))
.ProjectTo<AuditRecordView>(_mapper.ConfigurationProvider);
var pageList = await auditRecordQueryable.ToPagedListAsync(inQuery);
return pageList;
}
[HttpPost]
public async Task<IResponseOutput> AddOrUpdateAuditRecord(AuditRecordAddOrEdit addOrEditAuditRecord)
{
if (addOrEditAuditRecord.Id == null)
{
var entity = _mapper.Map<AuditRecord>(addOrEditAuditRecord);
if (await _auditRecordRepository.AnyAsync(t => t.CompanyName == addOrEditAuditRecord.CompanyName && t.AuditContent == addOrEditAuditRecord.AuditContent && t.AuditTime == addOrEditAuditRecord.AuditTime, true))
{
//---重复的稽查记录。
return ResponseOutput.NotOk(_localizer["AuditDocument_RepeatAuditRecord"]);
}
await _auditRecordRepository.AddAsync(entity, true);
return ResponseOutput.Ok(entity.Id.ToString());
}
else
{
if (await _auditRecordRepository.AnyAsync(t => t.CompanyName == addOrEditAuditRecord.CompanyName && t.AuditContent == addOrEditAuditRecord.AuditContent && t.AuditTime == addOrEditAuditRecord.AuditTime
&& t.Id != addOrEditAuditRecord.Id, true))
{
//---重复的稽查记录。
return ResponseOutput.NotOk(_localizer["AuditDocument_RepeatAuditRecord"]);
}
var find = _auditRecordRepository.Where(t => t.Id == addOrEditAuditRecord.Id, true).FirstOrDefault();
_mapper.Map(addOrEditAuditRecord, find);
find.UpdateTime = DateTime.Now;
var success = await _auditRecordRepository.SaveChangesAsync();
return ResponseOutput.Ok(find.Id.ToString());
}
}
/// <summary>
/// 删除稽查记录
/// </summary>
/// <param name="auditRecordId"></param>
/// <returns></returns>
[HttpDelete("{auditRecordId:guid}")]
public async Task<IResponseOutput> DeleteAuditRecord(Guid auditRecordId)
{
if (await _auditRecordRepository.Where(t => t.Id == auditRecordId).AnyAsync(u => u.AuditState != AuditState.NotStart))
{
//未开始的才允许删除
return ResponseOutput.NotOk(_localizer["AuditDocument_CannotDeleteStartRecod"]);
}
var success = await _auditRecordRepository.DeleteFromQueryAsync(t => t.Id == auditRecordId, true);
return ResponseOutput.Ok();
}
/// <summary>
/// 设置稽查记录某个文件 或者某个文件夹授权
/// </summary>
/// <param name="inCommand"></param>
/// <returns></returns>
public async Task<IResponseOutput> SetAuditRecordPermission(SetAuditRecordPermissionCommand inCommand)
{
var find = _auditRecordPermissionRepository.FirstOrDefaultAsync(t => t.AuditRecordId == inCommand.AuditRecordId && t.AuditDocumentId == inCommand.AuditDocumentId);
if (find == null && inCommand.IsAuthorization)
{
await _auditRecordPermissionRepository.AddAsync(new AuditRecordPermission() { AuditRecordId = inCommand.AuditRecordId, AuditDocumentId = inCommand.AuditDocumentId }, true);
}
else
{
await _auditRecordPermissionRepository.DeleteFromQueryAsync(t => t.AuditRecordId == inCommand.AuditRecordId && t.AuditDocumentId == inCommand.AuditDocumentId, true);
}
return ResponseOutput.Ok();
}
#endregion
#region 闭包修改
/// <summary>
/// 插入闭包表关系
/// </summary>
private async Task AddClosureRelationsAsync(Guid nodeId, Guid? parentId)
{
var closures = new List<AuditDocumentClosure>();
// 自身关系
closures.Add(new AuditDocumentClosure
{
AncestorId = nodeId,
DescendantId = nodeId,
Depth = 0
});
if (parentId.HasValue)
{
// 查出所有父级的祖先
var parentClosures = await _auditDocumentClosureRepository
.Where(c => c.DescendantId == parentId.Value).Select(t => new { t.AncestorId, t.Depth })
.ToListAsync();
// 生成父级的所有祖先到新节点的关系
foreach (var pc in parentClosures)
{
closures.Add(new AuditDocumentClosure
{
AncestorId = pc.AncestorId,
DescendantId = nodeId,
Depth = pc.Depth + 1
});
}
}
await _auditDocumentClosureRepository.AddRangeAsync(closures);
await _auditDocumentClosureRepository.SaveChangesAsync();
}
/// <summary>
/// 获取文件树形结构 (传Id 根节点就是自己)
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<PageOutput<AuditDocumentData>> GetAuditDocumentData(GetAuditDocumentDataInDto inDto)
{
var defalutSortArray = new string[] { nameof(AuditDocumentData.AuditDocumentTypeEnum), nameof(AuditDocumentData.Name) };
if (inDto.SortField.IsNotNullOrEmpty())
{
defalutSortArray = new string[] { nameof(AuditDocumentData.AuditDocumentTypeEnum), inDto.SortField + (inDto.Asc ? " asc" : " desc") };
inDto.SortField = string.Empty;
}
//匹配节点子查询
var matchedList = await _auditDocumentRepository.Where(x => x.AuditDocumentTypeEnum != AuditDocumentType.HistoricalVersion)
.WhereIf(inDto.IsAuthorization != null, x => x.IsAuthorization == inDto.IsAuthorization)
.WhereIf(inDto.AuditRecordId != null, x => x.IsAuthorization == inDto.IsAuthorization)
.WhereIf(inDto.Name.IsNotNullOrEmpty(), n => n.Name.Contains(inDto.Name))
.SelectMany(t => t.AncestorList).Select(t => t.Ancestor)//祖先包含自己
.Distinct() //可能包含相同的祖先
.ProjectTo<AuditDocumentData>(_mapper.ConfigurationProvider)
.SortToListAsync(defalutSortArray);
#region 针对某次稽查 授权展示
//某个稽查记录
if (inDto.AuditRecordId != null)
{
//找到该稽查记录 授权文件的所有父节点Id
var matchDocIdQuery = _auditRecordPermissionRepository.Where(t => t.AuditRecordId == inDto.AuditRecordId).Select(t => t.AuditDocumentId);
var parentIdList = _auditDocumentClosureRepository.Where(t => matchDocIdQuery.Contains(t.DescendantId)).Select(t => t.AncestorId).Distinct().ToList();
if (inDto.IsAuthorization == true)
{
//只查看授权的
matchedList = matchedList.Where(t => parentIdList.Contains((Guid)t.Id)).ToList();
}
foreach (var ancestorId in parentIdList)
{
var find = matchedList.FirstOrDefault(t => t.Id == ancestorId);
if (find != null)
{
//如果前端不想用新字段,那么就覆盖之前的授权字段
find.IsCurrentAuditRecordAuthorization = true;
}
}
}
#endregion
// 构建字典并拼装树
var dict = matchedList.ToDictionary(n => n.Id, t => t);
foreach (var node in dict.Values)
{
if (node.ParentId.HasValue && dict.TryGetValue(node.ParentId.Value, out var parent))
parent.Children.Add(node);
}
var query = dict.Values
.WhereIf(inDto.SelfId != null, x => inDto.SelfId == x.Id)
.WhereIf(inDto.Id != null, x => inDto.Id == x.ParentId)
.WhereIf(inDto.Id == null && inDto.SelfId == null, x => x.ParentId == null);
PageOutput<AuditDocumentData> result = new PageOutput<AuditDocumentData>()
{
PageIndex = inDto.PageIndex,
PageSize = inDto.PageSize,
TotalCount = query.Count(),
};
var root = query.Skip(inDto.PageSize * (inDto.PageIndex - 1)).Take(inDto.PageSize).ToList();
result.CurrentPageData = root;
return result;
}
/// <summary>
/// 设置是否授权
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> SetIsAuthorization(SetIsAuthorizationInDto inDto)
{
//闭包表中找到 设置Id为祖先的所有 后代 包括自己
var matchIdQuery = _auditDocumentClosureRepository.Where(t => inDto.Ids.Contains(t.AncestorId)).Select(t => t.DescendantId);
//闭包表中找到 设置Id为后代的所有 祖先 包括自己
var matchIdQuery2 = _auditDocumentClosureRepository.Where(t => inDto.Ids.Contains(t.DescendantId)).Select(t => t.AncestorId);
var unionQuery = matchIdQuery.Union(matchIdQuery2);
await _auditDocumentRepository.BatchUpdateNoTrackingAsync(t => unionQuery.Contains(t.Id), u => new AuditDocument() { IsAuthorization = inDto.IsAuthorization });
return ResponseOutput.Ok();
}
/// <summary>
/// 移动文件或者文件夹 到其他文件夹
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> MovieFileOrFolder(MovieFileOrFolderInDto inDto)
{
//闭包表中找到 设置Id为祖先的所有 后代 包括自己
var matchIdQuery = _auditDocumentClosureRepository.Where(t => inDto.Ids.Contains(t.AncestorId)).Select(t => t.DescendantId);
//无法将当前文件夹移动到当前目录以及子文件夹
if (matchIdQuery.Any(t => t == inDto.ParentId))
{
throw new BusinessValidationFailedException(_localizer["AuditDocument_CanNotMove"]);
}
foreach (var id in inDto.Ids)
{
//移动ParentId
var node = await _auditDocumentRepository.FirstOrDefaultAsync(t => t.Id == id);
node.ParentId = inDto.ParentId;
await _auditDocumentRepository.SaveChangesAsync();
// 删除原有闭包关系
await _auditDocumentClosureRepository.BatchDeleteNoTrackingAsync(t => t.DescendantId == id || t.AncestorId == id);
//建立新的闭包关系
await AddClosureRelationsAsync(node.Id, inDto.ParentId);
}
return ResponseOutput.Ok();
}
/// <summary>
/// 删除稽查文档
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
[UnitOfWork]
public async Task<IResponseOutput> DeleteAuditDocument(DeleteAuditDocumentInDto inDto)
{
var isNotOptHistoryFile = _auditDocumentRepository.Where(t => inDto.Ids.Contains(t.Id)).All(t => t.MainFileId == null);
// 删除文件 或者文件夹里所有内容 (能在闭包表中找到)
if (isNotOptHistoryFile)
{
//闭包表中找到 设置Id为祖先的所有 后代 包括自己
var matchList = _auditDocumentClosureRepository.Where(t => inDto.Ids.Contains(t.AncestorId)).Select(t => new { t.DescendantId, t.Descendant.MainFileId, IsExistOldVersion = t.Descendant.AuditDocumentOldVersionList.Any() });
var matchIdList = matchList.Select(t => t.DescendantId).Distinct();
//找到有版本的
var matchIdVersionList = matchList.Where(t => t.IsExistOldVersion).Select(t => t.DescendantId).Distinct();
//删除自己以及后代 (能在闭包表中找到的,肯定不是删除 当前历史版本的操作 和当前历史所有版本的操作,能在闭包包中找到,那么肯定是删除当前文件,和当前文件所有 版本文件)
var success = await _auditDocumentRepository.DeleteFromQueryAsync(t => matchIdList.Contains(t.Id) || matchIdVersionList.Any(c => c == t.MainFileId));
// 删除原有闭包关系
await _auditDocumentClosureRepository.BatchDeleteNoTrackingAsync(t => matchIdList.Contains(t.DescendantId) || matchIdList.Contains(t.AncestorId));
}
else
{
//删除历史版本操作 删除当前历史所有版本操作
var mainFileIdList = await _auditDocumentRepository.Where(t => inDto.Ids.Contains(t.Id)).Select(t => t.MainFileId).Distinct().ToListAsync();
//删除当前选择的历史版本
await _auditDocumentRepository.BatchDeleteNoTrackingAsync(t => inDto.Ids.Contains(t.Id));
foreach (var item in mainFileIdList)
{
var historicalVersionList = await _auditDocumentRepository.Where(x => x.MainFileId == item).OrderBy(x => x.Version).ToListAsync();
var num = 1;
foreach (var historical in historicalVersionList)
{
await _auditDocumentRepository.UpdatePartialFromQueryAsync(historical.Id, x => new AuditDocument()
{
Version = num,
});
num++;
}
}
}
await _auditDocumentRepository.SaveChangesAsync();
return ResponseOutput.Ok();
}
/// <summary>
/// 把历史版本设置为当前版本--修改 维护闭包表,之间的闭包关系指向新版本文件
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> SetCurrentVersion(SetCurrentVersionInDto inDto)
{
var file = await _auditDocumentRepository.Where(x => x.Id == inDto.Id).FirstNotNullAsync();
if (file.AuditDocumentTypeEnum != AuditDocumentType.HistoricalVersion)
{
throw new BusinessValidationFailedException(_localizer["AuditDocument_CanNotSetCurrentVersion"]);
}
var mainFile = await _auditDocumentRepository.Where(x => x.Id == file.MainFileId).FirstNotNullAsync();
var historicalVersionIds = await _auditDocumentRepository.Where(x => x.MainFileId == mainFile.Id && x.Id != inDto.Id).OrderBy(x => x.Version).Select(x => x.Id).ToListAsync();
historicalVersionIds.Add(mainFile.Id);
await _auditDocumentRepository.UpdatePartialFromQueryAsync(inDto.Id, x => new AuditDocument()
{
MainFileId = null,
ParentId = mainFile.ParentId,
AuditDocumentTypeEnum = AuditDocumentType.File,
});
int num = 1;
foreach (var item in historicalVersionIds)
{
await _auditDocumentRepository.UpdatePartialFromQueryAsync(item, x => new AuditDocument()
{
MainFileId = inDto.Id,
ParentId = null,
Version = num,
AuditDocumentTypeEnum = AuditDocumentType.HistoricalVersion
});
num++;
}
await _auditDocumentRepository.SaveChangesAsync();
#region 闭包修改
//版本设计这里当前版本才有parentId 不是当前版本就没有parentId->移动的时候还要维护历史版本的parentid
//增加闭包,所以这里要维护闭包表
await _auditDocumentClosureRepository.BatchUpdateNoTrackingAsync(t => t.AncestorId == mainFile.Id, t => new AuditDocumentClosure() { AncestorId = inDto.Id });
await _auditDocumentClosureRepository.BatchUpdateNoTrackingAsync(t => t.DescendantId == mainFile.Id, t => new AuditDocumentClosure() { DescendantId = inDto.Id });
#endregion
return ResponseOutput.Ok();
}
/// <summary>
/// 获取面包屑导航 (查询自己的祖先,不包括自己)
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<List<AuditDocumentUpdateDto>> GetBreadcrumbData(GetBreadcrumbDataInDto inDto)
{
//闭包表中找到 设置Id为后代的所有 祖先 Depth > 0 不包括自己
var list = await _auditDocumentClosureRepository.Where(t => inDto.Id == t.DescendantId /*&& t.Depth > 0*/)
.OrderByDescending(t => t.Depth).Select(t => t.Ancestor).ProjectTo<AuditDocumentUpdateDto>(_mapper.ConfigurationProvider).ToListAsync();
return list;
#region 无闭包表废弃
//List<AuditDocumentUpdateDto> result = new List<AuditDocumentUpdateDto>();
//await findParent(result, inDto.Id);
//async Task findParent(List<AuditDocumentUpdateDto> datas, Guid id)
//{
// var data = await _auditDocumentRepository.Where(x => x.Id == id).ProjectTo<AuditDocumentUpdateDto>(_mapper.ConfigurationProvider).FirstNotNullAsync();
// datas.Add(data);
// if (data.ParentId != null)
// {
// await findParent(datas, data.ParentId.Value);
// }
//}
//result.Reverse();
//return result;
#endregion
}
#endregion
#region 闭包维护关系,只处理最底层调用 AddOrUpdateAuditDocument
/// <summary>
/// 复制文件或者文件夹
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> CopyFileOrFolder(MovieFileOrFolderInDto inDto)
{
#region 不考虑版本的话处理方式
////1、当前节点的后代包括自己 拷贝的节点以及子节点
//var nodeList = await _auditDocumentClosureRepository.Where(t => t.AncestorId == id).Select(t => t.Descendant).ToListAsync();
//// 2. 创建映射表 OldId -> NewId
//var oldToNewId = new Dictionary<Guid, Guid>();
//// 3. 复制节点
//var newNodeList = nodeList.Clone();
//foreach (var node in newNodeList)
//{
// var newId = NewId.NextSequentialGuid();
// //存储旧Id 和新Id 关系
// oldToNewId[node.Id] = newId;
// //设置新节点Id
// node.Id = newId;
//}
//// 4. 调整 ParentId 指向新 Id
//foreach (var newNode in newNodeList)
//{
// if (newNode.ParentId.HasValue && oldToNewId.TryGetValue(newNode.ParentId.Value, out var newParentId))
// {
// newNode.ParentId = newParentId; // 指向新父节点
// }
// else
// {
// newNode.ParentId = inDto.ParentId; // 顶层节点指向目标父节点
// }
//}
//foreach (var node in newNodeList)
//{
// await _auditDocumentRepository.AddAsync(node);
// //建立新的闭包关系
// await AddClosureRelationsAsync(node.Id, inDto.ParentId);
//}
#endregion
foreach (var item in inDto.Ids)
{
var data = (await GetAuditDocumentData(new GetAuditDocumentDataInDto()
{
SelfId = item,
PageIndex = 1,
PageSize = 1000
})).CurrentPageData;
List<AuditDocumentAddOrEdit> auditDocumentAddOrEdits = _mapper.Map<List<AuditDocumentAddOrEdit>>(data);
auditDocumentAddOrEdits.ForEach(x =>
{
x.IsUpdate = false;
x.Id = null;
x.ParentId = inDto.ParentId;
});
await addData(auditDocumentAddOrEdits);
}
async Task addData(List<AuditDocumentAddOrEdit> data)
{
foreach (var item in data)
{
item.Id = null;
var result = await AddOrUpdateAuditDocument(item);
item.Children.ForEach(x =>
{
x.ParentId = result.Id;
x.IsUpdate = false;
x.Id = null;
});
if (item.Children.Count() > 0)
{
await addData(item.Children);
}
}
}
return ResponseOutput.Ok();
}
/// <summary>
/// 修改稽查文档
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> UpdateAuditDocument(AuditDocumentUpdateDto inDto)
{
AuditDocumentAddOrEdit addOrEdit = _mapper.Map<AuditDocumentAddOrEdit>(inDto);
addOrEdit.IsUpdate = true;
var result = await AddOrUpdateAuditDocument(addOrEdit);
return ResponseOutput.Ok(result.Id);
}
/// <summary>
/// 新增文件夹
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
/// <exception cref="BusinessValidationFailedException"></exception>
[HttpPost]
public async Task<IResponseOutput> AddFolder(AuditDocumentAddOrEdit inDto)
{
if (await _auditDocumentRepository.AnyAsync(x => x.Name == inDto.Name && x.AuditDocumentTypeEnum == inDto.AuditDocumentTypeEnum && x.ParentId == inDto.ParentId))
{
throw new BusinessValidationFailedException(_localizer["AuditDocument_CanNotAddFolder"]);
}
List<AuditDocumentAddOrEdit> auditDocumentAddOrEdits = new List<AuditDocumentAddOrEdit>();
auditDocumentAddOrEdits.Add(inDto);
var result = await AddAuditDocument(auditDocumentAddOrEdits);
return ResponseOutput.Ok(result);
}
/// <summary>
/// 新增稽查文档 (批量上传文件时才是数组,文件夹时单个对象)
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> AddAuditDocument(List<AuditDocumentAddOrEdit> inDto)
{
List<Guid> resultData = new List<Guid>();
inDto.ForEach(x => x.IsUpdate = false);
await addData(inDto);
//构建父子关系然后返回Id
async Task addData(List<AuditDocumentAddOrEdit> data)
{
foreach (var item in data)
{
var result = await AddOrUpdateAuditDocument(item);
resultData.Add(result.Id);
item.Children.ForEach(x =>
{
x.ParentId = result.Id;
x.IsUpdate = false;
});
if (item.Children.Count() > 0)
{
await addData(item.Children);
}
}
}
return ResponseOutput.Ok(resultData);
}
/// <summary>
/// 通用方法
/// </summary>
/// <param name="inDto"></param>
private async Task<AuditDocument> AddOrUpdateAuditDocument(AuditDocumentAddOrEdit inDto)
{
//同一层级不能加同名的文件
var alikeData = await _auditDocumentRepository.Where(x => x.Id != inDto.Id && x.ParentId == inDto.ParentId && x.Name == inDto.Name && x.AuditDocumentTypeEnum == inDto.AuditDocumentTypeEnum).FirstOrDefaultAsync();
//同层级找到了同名的
if (alikeData != null)
{
if (inDto.AuditDocumentTypeEnum == AuditDocumentType.Folder)
{
//更新
if (inDto.IsUpdate)
{
throw new BusinessValidationFailedException(_localizer["AuditDocument_CanNotAddFolder"]);
}
else
{
//添加相同目录,已存在,那么就不处理
return alikeData;
}
}
else
{
//同名文件,那么作为版本处理(首先插入)
var entityData = await _auditDocumentRepository.InsertOrUpdateAsync(inDto, true);
//找到该同名文件的历史版本
var historicalVersionIds = await _auditDocumentRepository.Where(x => x.MainFileId == alikeData.Id).OrderBy(x => x.Version).Select(x => x.Id).ToListAsync();
//加上当前的同名文件 一起重新设置版本号
historicalVersionIds.Add(alikeData.Id);
// 删除原有闭包关系 (重命的文件变成历史版本了)
await _auditDocumentClosureRepository.BatchDeleteNoTrackingAsync(t => t.AncestorId == alikeData.Id || t.DescendantId == alikeData.Id);
int num = 1;
foreach (var item in historicalVersionIds)
{
await _auditDocumentRepository.UpdatePartialFromQueryAsync(item, x => new AuditDocument()
{
MainFileId = entityData.Id,
ParentId = null,
Version = num,
AuditDocumentTypeEnum = AuditDocumentType.HistoricalVersion
});
num++;
await _auditDocumentRepository.SaveChangesAsync();
}
// 针对版本文件是不需要维护闭包表的
if (inDto.Id == null && entityData.MainFileId == null)
{
//维护新增闭包关系
await AddClosureRelationsAsync(entityData.Id, entityData.ParentId);
}
return entityData;
}
}
//同层级没找到同名的文件,那么走正常的新增 和更新
var entity = await _auditDocumentRepository.InsertOrUpdateAsync(inDto, true);
if (inDto.Id == null && entity.MainFileId == null)
{
//维护新增闭包关系
await AddClosureRelationsAsync(entity.Id, entity.ParentId);
}
return entity;
}
#endregion
#region 增加闭包设计 不用修改地方
/// <summary>
/// 获取稽查文档
/// </summary>
/// <param name="inQuery"></param>
/// <returns></returns>
///
[HttpPost]
public async Task<PageOutput<AuditDocumentView>> GetAuditDocumentList(AuditDocumentQuery inQuery)
{
var auditDocumentQueryable = _auditDocumentRepository
.ProjectTo<AuditDocumentView>(_mapper.ConfigurationProvider);
var pageList = await auditDocumentQueryable.ToPagedListAsync(inQuery);
return pageList;
}
/// <summary>
/// 获取历史版本
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<List<HistoricalVersionDto>> GetHistoricalVersion(GetHistoricalVersionInDto inDto)
{
List<HistoricalVersionDto> result = new List<HistoricalVersionDto>();
result = await _auditDocumentRepository.Where(x => x.MainFileId == inDto.Id).ProjectTo<HistoricalVersionDto>(_mapper.ConfigurationProvider).OrderByDescending(x => x.Version).ToListAsync();
var currentData = await _auditDocumentRepository.Where(x => x.Id == inDto.Id).ProjectTo<HistoricalVersionDto>(_mapper.ConfigurationProvider).FirstNotNullAsync();
currentData.IsCurrentVersion = true;
result.Insert(0, currentData);
return result;
}
#endregion
#region 闭包后续废弃方法
///// <summary>
///// 删除稽查文档
///// </summary>
///// <param name="inDto"></param>
///// <returns></returns>
//[HttpPost]
//public async Task<IResponseOutput> DeleteAuditDocument(DeleteAuditDocumentInDto inDto)
//{
// var data = await _auditDocumentRepository.Select(x => new DeleteAudit()
// {
// Id = x.Id,
// ParentId = x.ParentId,
// MainFileId = x.MainFileId
// }).ToListAsync();
// List<Guid> DeleteId = inDto.Ids;
// finId(inDto.Ids, data);
// void finId(List<Guid> deletids, List<DeleteAudit> deletes)
// {
// DeleteId.AddRange(deletids);
// var temp = deletes.Where(x => (x.ParentId != null && deletids.Contains(x.ParentId.Value)) || (x.MainFileId != null && deletids.Contains(x.MainFileId.Value))).Select(x => x.Id).ToList();
// if (temp.Count() > 0)
// {
// finId(temp, deletes);
// }
// }
// DeleteId = DeleteId.Distinct().ToList();
// var mainFileId = await _auditDocumentRepository.Where(x => DeleteId.Contains(x.Id) && x.MainFileId != null).Select(x => x.MainFileId).Distinct().ToListAsync();
// var success = await _auditDocumentRepository.DeleteFromQueryAsync(t => DeleteId.Distinct().Contains(t.Id), true);
// foreach (var item in mainFileId)
// {
// var historicalVersionList = await _auditDocumentRepository.Where(x => x.MainFileId == item).OrderBy(x => x.Version).ToListAsync();
// var num = 1;
// foreach (var historical in historicalVersionList)
// {
// await _auditDocumentRepository.UpdatePartialFromQueryAsync(historical.Id, x => new AuditDocument()
// {
// Version = num,
// }, true);
// num++;
// }
// }
// return ResponseOutput.Ok();
//}
///// <summary>
///// 获取文件树形结构 (传Id 根节点就是自己)
///// </summary>
///// <param name="inDto"></param>
///// <returns></returns>
//[HttpPost]
//public async Task<PageOutput<AuditDocumentData>> GetAuditDocumentData(GetAuditDocumentDataInDto inDto)
//{
// var defalutSortArray = new string[] { nameof(AuditDocumentData.AuditDocumentTypeEnum), nameof(AuditDocumentData.Name) };
// if (inDto.SortField.IsNotNullOrEmpty())
// {
// defalutSortArray = new string[] { nameof(AuditDocumentData.AuditDocumentTypeEnum), inDto.SortField + (inDto.Asc ? " asc" : " desc") };
// inDto.SortField = string.Empty;
// }
// // 新取出来排序 然后再找子项
// var data = (await _auditDocumentRepository
// .Where(x => x.AuditDocumentTypeEnum != AuditDocumentType.HistoricalVersion)
// .WhereIf(inDto.IsAuthorization != null, x => x.IsAuthorization == inDto.IsAuthorization)
// .ProjectTo<AuditDocumentData>(_mapper.ConfigurationProvider).ToPagedListAsync(new PageInput()
// {
// PageIndex = 1,
// PageSize = 999999,
// }, defalutSortArray)).CurrentPageData.ToList();
// if (inDto.Name.IsNotNullOrEmpty())
// {
// List<Guid> findIds = new List<Guid>();
// var findData = data.Where(x => x.Name.Contains(inDto.Name)).Select(x => x.Id.Value).ToList();
// GetParentId(findIds, findData, data);
// findIds.AddRange(findData);
// data = data.Where(x => findIds.Distinct().Contains(x.Id.Value)).ToList();
// }
// var query = data
// .WhereIf(inDto.SelfId != null, x => inDto.SelfId == x.Id)
// .WhereIf(inDto.Id != null, x => inDto.Id == x.ParentId)
// .WhereIf(inDto.Id == null && inDto.SelfId == null, x => x.ParentId == null);
// PageOutput<AuditDocumentData> result = new PageOutput<AuditDocumentData>()
// {
// PageIndex = inDto.PageIndex,
// PageSize = inDto.PageSize,
// TotalCount = query.Count(),
// };
// var root = query
// .Skip(inDto.PageSize * (inDto.PageIndex - 1)).Take(inDto.PageSize).ToList();
// var historicalVersionList = await _auditDocumentRepository
// .Where(x => x.AuditDocumentTypeEnum == AuditDocumentType.HistoricalVersion).ProjectTo<AuditDocumentData>(_mapper.ConfigurationProvider).ToListAsync();
// foreach (var item in root)
// {
// GetChildren(item, data, historicalVersionList);
// }
// result.CurrentPageData = root;
// return result;
//}
//private void GetParentId(List<Guid> parentIds, List<Guid> ids, List<AuditDocumentData> dataList)
//{
// var parentid = dataList.Where(x => ids.Contains(x.Id.Value) && x.ParentId != null).Select(x => x.ParentId.Value).ToList();
// if (parentid.Count() > 0)
// {
// parentIds.AddRange(parentid);
// GetParentId(parentIds, parentid, dataList);
// }
//}
//private void GetChildren(AuditDocumentData item, List<AuditDocumentData> dataList, List<AuditDocumentData> historyList)
//{
// item.Children = dataList.Where(x => x.ParentId == item.Id).ToList();
// item.HistoricalVersionsCount = historyList.Where(x => x.MainFileId == item.Id).Count();
// foreach (var x in item.Children)
// {
// GetChildren(x, dataList, historyList);
// }
//}
///// <summary>
///// 移动文件或者文件夹 到其他文件夹
///// </summary>
///// <returns></returns>
//[HttpPost]
//public async Task<IResponseOutput> MovieFileOrFolder(MovieFileOrFolderInDto inDto)
//{
// var data = await _auditDocumentRepository.Select(x => new DeleteAudit()
// {
// Id = x.Id,
// ParentId = x.ParentId,
// AuditDocumentTypeEnum = x.AuditDocumentTypeEnum,
// MainFileId = x.MainFileId
// }).ToListAsync();
// foreach (var id in inDto.Ids)
// {
// var file = data.Where(x => x.Id == id).FirstOrDefault();
// if (file.AuditDocumentTypeEnum == AuditDocumentType.Folder)
// {
// if (finChild(new List<Guid> { id }, inDto.ParentId, data))
// {
// throw new BusinessValidationFailedException(_localizer["AuditDocument_CanNotMove"]);
// }
// }
// }
// bool finChild(List<Guid> ids, Guid ChildId, List<DeleteAudit> data)
// {
// var child = data.Where(x => x.ParentId != null && ids.Contains(x.ParentId.Value)).ToList();
// if (child.Count() == 0)
// {
// return false;
// }
// else if (child.Any(x => x.Id == ChildId))
// {
// return true;
// }
// else
// {
// var newids = child.Select(x => x.Id).ToList();
// return finChild(newids, ChildId, data);
// }
// }
// foreach (var id in inDto.Ids)
// {
// await _auditDocumentRepository.UpdatePartialFromQueryAsync(id, x => new AuditDocument()
// {
// ParentId = inDto.ParentId
// });
// await _auditDocumentRepository.SaveChangesAsync();
// }
// return ResponseOutput.Ok();
//}
///// <summary>
///// 复制文件或者文件夹
///// </summary>
///// <param name="inDto"></param>
///// <returns></returns>
//[HttpPost]
//public async Task<IResponseOutput> CopyFileOrFolder(MovieFileOrFolderInDto inDto)
//{
// foreach (var item in inDto.Ids)
// {
// var data = (await GetAuditDocumentData(new GetAuditDocumentDataInDto()
// {
// SelfId = item,
// PageIndex = 1,
// PageSize = 1000
// })).CurrentPageData;
// List<AuditDocumentAddOrEdit> auditDocumentAddOrEdits = _mapper.Map<List<AuditDocumentAddOrEdit>>(data);
// auditDocumentAddOrEdits.ForEach(x =>
// {
// x.IsUpdate = false;
// x.Id = null;
// x.ParentId = inDto.ParentId;
// });
// await addData(auditDocumentAddOrEdits);
// }
// async Task addData(List<AuditDocumentAddOrEdit> data)
// {
// foreach (var item in data)
// {
// item.Id = null;
// var result = await AddOrUpdateAuditDocument(item);
// item.Children.ForEach(x =>
// {
// x.ParentId = result.Id;
// x.IsUpdate = false;
// x.Id = null;
// });
// if (item.Children.Count() > 0)
// {
// await addData(item.Children);
// }
// }
// }
// return ResponseOutput.Ok();
//}
///// <summary>
///// 设置是否授权
///// </summary>
///// <param name="inDto"></param>
///// <returns></returns>
//[HttpPost]
//public async Task<IResponseOutput> SetIsAuthorization(SetIsAuthorizationInDto inDto)
//{
// var data = await _auditDocumentRepository.Select(x => new DeleteAudit()
// {
// Id = x.Id,
// ParentId = x.ParentId,
// MainFileId = x.MainFileId
// }).ToListAsync();
// List<Guid> allid = new List<Guid>();
// findChild(allid, inDto.Ids, data);
// if (inDto.IsAuthorization)
// {
// findParent(allid, inDto.Ids, data);
// }
// allid = allid.Distinct().ToList();
// await _auditDocumentRepository.UpdatePartialFromQueryAsync(t => allid.Contains(t.Id), x => new AuditDocument()
// {
// IsAuthorization = inDto.IsAuthorization
// });
// await _auditDocumentRepository.SaveChangesAsync();
// return ResponseOutput.Ok();
// void findParent(List<Guid> allId, List<Guid> current, List<DeleteAudit> data)
// {
// allId.AddRange(current);
// var parent = data.Where(x => current.Contains(x.Id)).Select(x => x.ParentId).Where(x => x != null).Select(x => (Guid)x).ToList();
// if (parent.Count() > 0)
// {
// findParent(allId, parent, data);
// }
// }
// void findChild(List<Guid> allId, List<Guid> current, List<DeleteAudit> data)
// {
// allId.AddRange(current);
// var child = data.Where(x => (x.ParentId != null && current.Contains(x.ParentId.Value)) || (x.MainFileId != null && current.Contains(x.MainFileId.Value))).Select(x => x.Id).ToList();
// if (child.Count() > 0)
// {
// findChild(allId, child, data);
// }
// }
//}
#endregion
}