1038 lines
35 KiB
C#
1038 lines
35 KiB
C#
|
||
//--------------------------------------------------------------------
|
||
// 此代码由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;
|
||
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>
|
||
/// 稽查记录 列表
|
||
/// </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.BeginTime != null, t => t.BeginTime >= inQuery.BeginTime)
|
||
.WhereIf(inQuery.EndTime != null, t => t.EndTime <= inQuery.EndTime)
|
||
.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_New(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.Where(n => n.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_New(SetIsAuthorizationInDto inDto)
|
||
{
|
||
//闭包表中找到 设置Id为祖先的所有 后代 包括自己
|
||
var matchIdQuery = _auditDocumentClosureRepository.Where(t => inDto.Ids.Contains(t.AncestorId)).Select(t => t.DescendantId);
|
||
|
||
await _auditDocumentRepository.BatchUpdateNoTrackingAsync(t => matchIdQuery.Contains(t.Id), u => new AuditDocument() { IsAuthorization = inDto.IsAuthorization });
|
||
|
||
return ResponseOutput.Ok();
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 复制文件或者文件夹
|
||
/// </summary>
|
||
/// <param name="inDto"></param>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<IResponseOutput> CopyFileOrFolder_New(MovieFileOrFolderInDto inDto)
|
||
{
|
||
|
||
foreach (var id in inDto.Ids)
|
||
{
|
||
|
||
//当前节点的后代(包括自己) 拷贝的节点以及子节点
|
||
var nodeList = await _auditDocumentClosureRepository.Where(t => t.AncestorId == id).Select(t => t.Descendant).ToListAsync();
|
||
|
||
|
||
foreach (var node in nodeList)
|
||
{
|
||
//设置新节点Id
|
||
node.Id = NewId.NextSequentialGuid();
|
||
|
||
//建立新的闭包关系
|
||
await AddClosureRelationsAsync(node.Id, inDto.ParentId);
|
||
}
|
||
|
||
}
|
||
|
||
return ResponseOutput.Ok();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 移动文件或者文件夹 到其他文件夹
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<IResponseOutput> MovieFileOrFolder_New(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]
|
||
public async Task<IResponseOutput> DeleteAuditDocument_New(DeleteAuditDocumentInDto inDto)
|
||
{
|
||
//闭包表中找到 设置Id为祖先的所有 后代 包括自己
|
||
var matchList = _auditDocumentClosureRepository.Where(t => inDto.Ids.Contains(t.AncestorId)).Select(t => new { t.DescendantId, t.Descendant.MainFileId });
|
||
|
||
//删除自己以及后代
|
||
var success = await _auditDocumentRepository.DeleteFromQueryAsync(t => matchList.Select(t => t.DescendantId).Distinct().Contains(t.Id), true);
|
||
|
||
//找到有版本的
|
||
var mainFileIdList = matchList.Where(t => t.MainFileId != null).ToList();
|
||
|
||
foreach (var item in mainFileIdList)
|
||
{
|
||
var historicalVersionList = await _auditDocumentRepository.Where(x => x.MainFileId == item.MainFileId).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();
|
||
|
||
}
|
||
|
||
|
||
|
||
#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;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 获取面包屑导航
|
||
/// </summary>
|
||
/// <param name="inDto"></param>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<List<AuditDocumentUpdateDto>> GetBreadcrumbData(GetBreadcrumbDataInDto inDto)
|
||
{
|
||
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
|
||
|
||
#region 闭包维护关系,只处理最底层调用 AddOrUpdateAuditDocument
|
||
|
||
|
||
/// <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);
|
||
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)
|
||
{
|
||
//维护新增闭包关系
|
||
await AddClosureRelationsAsync(entityData.Id, entityData.ParentId);
|
||
}
|
||
|
||
return entityData;
|
||
}
|
||
}
|
||
|
||
//同层级没找到同名的文件,那么走正常的新增 和更新
|
||
var entity = await _auditDocumentRepository.InsertOrUpdateAsync(inDto, true);
|
||
|
||
if (inDto.Id == null)
|
||
{
|
||
//维护新增闭包关系
|
||
await AddClosureRelationsAsync(entity.Id, entity.ParentId);
|
||
}
|
||
|
||
return entity;
|
||
}
|
||
|
||
#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
|
||
|
||
|
||
}
|
||
|
||
|
||
|