Files
Docker/CloudBuilder/CloudBuilder.Master.Service/DmsFileService.auto.cs
T
2026-10-22 07:59:53 +08:00

2060 lines
97 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using CliWrap;
using CloudBuilder.Core.DatabaseAccessor;
using CloudBuilder.Core.DatabaseAccessor.Entity;
using CloudBuilder.Core.Extensions;
using CloudBuilder.Core.Service;
using CloudBuilder.Master.Data;
using CloudBuilder.Master.Entity;
using CloudBuilder.Master.Policy;
using CloudBuilder.Master.SearchCriteria;
using CloudBuilder.Security.Entity;
using CloudBuilder.Security.Policy;
using CloudBuilder.Security.Service;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using System;
using System.Globalization;
using System.Linq;
using static System.Net.Mime.MediaTypeNames;
using Image = SixLabors.ImageSharp.Image;
namespace CloudBuilder.Master.Service
{
public class DmsFileService : IDmsFileService
{
private readonly IApplicationService service;
private readonly IHttpContextAccessor httpContextAccessor;
private IRepository<DmsFileEntity> repository;
public DmsFileService(IApplicationService service, IHttpContextAccessor httpContextAccessor)
{
this.service = service;
this.httpContextAccessor = httpContextAccessor;
repository = service.GetRepository<IRepository<DmsFileEntity>>();
}
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Find)]
public DmsFileEntity FindByKey(long key)
{
return repository.DetachedEntities.Where(x => x.FileId == key).FirstOrDefault()!;
}
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Find)]
public DmsFileResultData FindBySearchCriteria(DmsFileSearchCriteria criteria)
{
DmsFileResultData data = new DmsFileResultData();
DmsFileUploadViewEntity[] list = null;
Int64 count = 0;
string sqlWhere = null;
if (criteria.Filter != null && criteria.Filter.Length > 0)
{
sqlWhere = SearchFilter.ComposeWhereClause(criteria.Filter);
}
sqlWhere = sqlWhere + string.Format(" and {0} ='{1}' ", DmsFileUploadViewEntity.DB_CREATED_BY, service.UserId);
DmsFileUploadViewEntity entity = DmsFileUploadViewEntity.GetInstance(repository.GetDbContext().Database.ProviderName);
string sql = entity.GetSelectTopFrom(criteria.limit, criteria.page, criteria.orderby.StringToDbField(), criteria.orderbytag, sqlWhere);
IRepository<DmsFileUploadViewEntity> repositoryView = repository.GetRepository<IRepository<DmsFileUploadViewEntity>>();
string err = null;
try
{
list = repositoryView.FromSql(sql).ToArray();
}
catch (System.Exception ex)
{
err = ex.Message;
}
if (list != null && list.Length > 0)
{
//list = list.OrderByDescending(x => x.IsDirectoryIndc).ThenByDescending(x => x.CreatedDatetime).ToArray();
sql = entity.GetSelectCountFrom(sqlWhere);
count = Convert.ToInt64(repository.ExecuteScalar(sql));
var webRootPath = service.Configuration[ServiceSettingsPolicy.RequestPath];
var phy = service.Configuration[ServiceSettingsPolicy.PhysicalFileDirectory];
var scale = ServiceSettingsPolicy.GetDmsFileScaleDirectory(service).Replace(phy, "");
List<string> prvs = new List<string>();
//bool isAttached = Debugger.IsAttached;
foreach (var item in list)
{
item.Url = FileTypePolicy.PackUrl(service, item.CreatedBy, item.OrderKey);
}
data.Datas = list.Select(x => new DmsFileUploadViewDisplayData(x)
{
FormattedPic = FileTypePolicy.PackPicUrl(service, x.CreatedBy, x.OrderKey),
FormattedM3u8 = FileTypePolicy.PackM3u8Url(service, x.CreatedBy, x.OrderKey)
}).ToArray();
}
data.Limit = criteria.limit;
data.Page = criteria.page;
data.Total = count;
//data.Sql = sql;
data.ErrorMessage = err;
return data;
}
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Find)]
public DmsFileResultData FindDatasBySearchCriteria(DmsFileSearchCriteria criteria)
{
DmsFileResultData data = new DmsFileResultData();
DmsFileUploadViewEntity[] list = null;
Int64 count = 0;
string sqlWhere = null;
if (criteria.Filter != null && criteria.Filter.Length > 0)
{
sqlWhere = SearchFilter.ComposeWhereClause(criteria.Filter);
}
sqlWhere = sqlWhere + string.Format(" and {0} ='{1}' and {2} ='{3}' ",
DmsFileUploadViewEntity.DB_CREATED_BY, service.UserId,
DmsFileUploadViewEntity.DB_IS_DIRECTORY_INDC, YesNoPolicy.NO
);
DmsFileUploadViewEntity entity = DmsFileUploadViewEntity.GetInstance(repository.GetDbContext().Database.ProviderName);
string sql = entity.GetSelectTopFrom(criteria.limit, criteria.page, criteria.orderby.StringToDbField(), criteria.orderbytag, sqlWhere);
IRepository<DmsFileUploadViewEntity> repositoryView = repository.GetRepository<IRepository<DmsFileUploadViewEntity>>();
string err = null;
try
{
list = repositoryView.FromSql(sql).ToArray();
}
catch (System.Exception ex)
{
err = ex.Message;
}
if (list != null && list.Length > 0)
{
//list = list.OrderByDescending(x => x.IsDirectoryIndc).ThenByDescending(x => x.CreatedDatetime).ToArray();
sql = entity.GetSelectCountFrom(sqlWhere);
count = Convert.ToInt64(repository.ExecuteScalar(sql));
var webRootPath = service.Configuration[ServiceSettingsPolicy.RequestPath];
var phy = service.Configuration[ServiceSettingsPolicy.PhysicalFileDirectory];
var scale = ServiceSettingsPolicy.GetDmsFileScaleDirectory(service).Replace(phy, "");
List<string> prvs = new List<string>();
//bool isAttached = Debugger.IsAttached;
foreach (var item in list)
{
item.Url = FileTypePolicy.PackUrl(service, item.CreatedBy, item.OrderKey);
}
data.Datas = list.Select(x => new DmsFileUploadViewDisplayData(x)
{
FormattedPic = FileTypePolicy.PackPicUrl(service, x.CreatedBy, x.OrderKey),
FormattedM3u8 = FileTypePolicy.PackM3u8Url(service, x.CreatedBy, x.OrderKey)
}).ToArray();
}
data.Limit = criteria.limit;
data.Page = criteria.page;
data.Total = count;
//data.Sql = sql;
data.ErrorMessage = err;
return data;
}
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Find)]
public DmsFileResultData FindDeleteLogBySearchCriteria(DmsFileSearchCriteria criteria)
{
DmsFileResultData data = new DmsFileResultData();
DmsFileUploadDeleteLogViewEntity[] list = null;
Int64 count = 0;
string sqlWhere = null;
if (criteria.Filter != null && criteria.Filter.Length > 0)
{
sqlWhere = SearchFilter.ComposeWhereClause(criteria.Filter);
}
sqlWhere = sqlWhere + string.Format(" and {0} ='{1}' ", DmsFileUploadViewEntity.DB_CREATED_BY, service.UserId);
DmsFileUploadDeleteLogViewEntity entity = DmsFileUploadDeleteLogViewEntity.GetInstance(repository.GetDbContext().Database.ProviderName);
string sql = entity.GetSelectTopFrom(criteria.limit, criteria.page, criteria.orderby.StringToDbField(), criteria.orderbytag, sqlWhere);
IRepository<DmsFileUploadDeleteLogViewEntity> repositoryView = repository.GetRepository<IRepository<DmsFileUploadDeleteLogViewEntity>>();
string err = null;
try
{
list = repositoryView.FromSql(sql).ToArray();
}
catch (System.Exception ex)
{
err = ex.Message;
}
if (list != null && list.Length > 0)
{
//list = list.OrderByDescending(x => x.IsDirectoryIndc).ThenByDescending(x => x.CreatedDatetime).ToArray();
sql = entity.GetSelectCountFrom(sqlWhere);
count = Convert.ToInt64(repository.ExecuteScalar(sql));
var webRootPath = service.Configuration[ServiceSettingsPolicy.RequestPath];
var phy = service.Configuration[ServiceSettingsPolicy.PhysicalFileDirectory];
var scale = ServiceSettingsPolicy.GetDmsFileScaleDirectory(service).Replace(phy, "");
foreach (var item in list)
{
item.Url = FileTypePolicy.PackUrl(service, item.CreatedBy, item.OrderKey);
}
data.Logs = list.Select(x => new DmsFileUploadDeleteLogViewDisplayData(x)
{
FormattedPic = FileTypePolicy.PackPicUrl(service, x.CreatedBy, x.OrderKey),
FormattedM3u8 = FileTypePolicy.PackM3u8Url(service, x.CreatedBy, x.OrderKey)
}).ToArray();
}
data.Limit = criteria.limit;
data.Page = criteria.page;
data.Total = count;
//data.Sql = sql;
data.ErrorMessage = err;
return data;
}
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Find)]
public DmsFileResultData FindFamilyBySearchCriteria(DmsFileSearchCriteria criteria)
{
DmsFileResultData data = new DmsFileResultData();
FamilyDmsFileViewEntity[] list = null;
Int64 count = 0;
string sqlWhere = null;
if (criteria.Filter != null && criteria.Filter.Length > 0)
{
sqlWhere = SearchFilter.ComposeWhereClause(criteria.Filter);
}
if (criteria.UserIdIndc == true || criteria.Filter.Where(x => x.Column == FamilyDmsFileViewEntity.DB_FAMILY_NAME).Count() == 0)
{
sqlWhere = sqlWhere + string.Format(" and {0} ='{1}' ", FamilyDmsFileViewEntity.DB_CREATED_BY, service.UserId);
}
//取了顶级目录
if (string.IsNullOrEmpty(sqlWhere)) sqlWhere = string.Format(" and {0} ={1} ", FamilyDmsFileViewEntity.DB_FAMILY_NAME, FamilyDmsFileViewEntity.DB_FILE_PATH);
FamilyDmsFileViewEntity entity = FamilyDmsFileViewEntity.GetInstance(repository.GetDbContext().Database.ProviderName);
string sql = entity.GetSelectTopFrom(criteria.limit, criteria.page, criteria.orderby.StringToDbField(), criteria.orderbytag, sqlWhere);
IRepository<FamilyDmsFileViewEntity> repositoryView = repository.GetRepository<IRepository<FamilyDmsFileViewEntity>>();
IRepository<FamilyGroupPermissionEntity> repositoryFamilyGroupPermission = repository.GetRepository<IRepository<FamilyGroupPermissionEntity>>();
IRepository<FamilyFolderFavoriteEntity> repositoryFamilyFolderFavorite = repository.GetRepository<IRepository<FamilyFolderFavoriteEntity>>();
FamilyGroupPermissionEntity[] permissionEntities = repositoryFamilyGroupPermission.DetachedEntities.Where(x => x.UserName == service.UserId).ToArray();
FamilyFolderFavoriteEntity[] favorites = repositoryFamilyFolderFavorite.DetachedEntities.Where(x => x.UserName == service.UserId).ToArray();
// 管理员权限的唯一出口:本人任管理员的群,所有目录一律有权限(与 FamilyGroupService.FindByKey 管理员视角 IsSharePermission 全 Y 同口径)。
// 权限表只记普通成员的授权记录,管理员不逐目录补录——否则别的管理员建的新目录会漏锁(本接口是共享大厅/文件页/共享目标选择器共用的PermissionIndc判定点)
IRepository<FamilyGroupManagerEntity> repositoryFamilyGroupManager = repository.GetRepository<IRepository<FamilyGroupManagerEntity>>();
string[] managerFamilyNames = repositoryFamilyGroupManager.DetachedEntities
.Where(x => x.UserName == service.UserId && x.ManagerIndc == YesNoPolicy.YES && x.ValidIndc == YesNoPolicy.YES)
.Select(x => x.FamilyName).Distinct().ToArray();
// 群组开启「公开成员目录权限」(open_dir_indc=Y):群内所有目录对所有成员开放,与管理员放行同一出口
string[] memberFamilyNames = repositoryFamilyGroupManager.DetachedEntities
.Where(x => x.UserName == service.UserId && x.ValidIndc == YesNoPolicy.YES)
.Select(x => x.FamilyName).Distinct().ToArray();
IRepository<FamilyGroupEntity> repositoryFamilyGroup = repository.GetRepository<IRepository<FamilyGroupEntity>>();
string[] openDirFamilyNames = memberFamilyNames.Length > 0
? repositoryFamilyGroup.DetachedEntities
.Where(x => x.OpenDirIndc == YesNoPolicy.YES && memberFamilyNames.AsQueryable().Contains(x.FamilyName))
.Select(x => x.FamilyName).ToArray()
: new string[0];
string err = null;
try
{
list = repositoryView.FromSql(sql).ToArray();
}
catch (System.Exception ex)
{
err = ex.Message;
}
if (list != null && list.Length > 0)
{
sql = entity.GetSelectCountFrom(sqlWhere);
count = Convert.ToInt64(repository.ExecuteScalar(sql));
foreach (var item in list)
{
if (managerFamilyNames.Contains(item.FamilyName) || openDirFamilyNames.Contains(item.FamilyName))
{
// 管理员 / 群开放全部目录:全目录放行
item.PermissionIndc = YesNoPolicy.YES;
}
else if (permissionEntities != null && permissionEntities.Length > 0)
{
foreach (var p in permissionEntities)
{
if (item.TopFolderName == p.FolderName)
{
item.PermissionIndc = YesNoPolicy.YES;
break;
}
}
}
if (favorites != null && favorites.Length > 0)
{
foreach (var f in favorites)
{
if (item.FolderName == f.FolderName)
{
item.FavoriteIndc = YesNoPolicy.YES;
break;
}
}
}
}
var webRootPath = service.Configuration[ServiceSettingsPolicy.RequestPath];
var phy = service.Configuration[ServiceSettingsPolicy.PhysicalFileDirectory];
var scale = ServiceSettingsPolicy.GetDmsFileScaleDirectory(service).Replace(phy, "");
foreach (var item in list)
{
item.Url = FileTypePolicy.PackUrl(service, item.CreatedBy, item.OrderKey);
}
data.Families = list.Select(x => new FamilyDmsFileViewDisplayData(x)
{
FileType = FileTypePolicy.GetType(x.OrderKey),
FormattedPic = FileTypePolicy.PackPicUrl(service, x.CreatedBy, x.OrderKey),
FormattedM3u8 = FileTypePolicy.PackM3u8Url(service, x.CreatedBy, x.OrderKey)
}).ToArray();
}
data.Limit = criteria.limit;
data.Page = criteria.page;
data.Total = count;
//data.Sql = sql;
data.ErrorMessage = err;
return data;
}
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Find)]
public DmsFileDeleteLogEntity FindDmsFileDeleteLogByKey(long key)
{
IRepository<DmsFileDeleteLogEntity> repositoryDmsFileDeleteLog = repository.GetRepository<IRepository<DmsFileDeleteLogEntity>>();
return repositoryDmsFileDeleteLog.DetachedEntities.Where(x => x.FileId == key).FirstOrDefault()!;
}
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Print)]
public dynamic PrintBySearchCriteria(DmsFileSearchCriteria criteria)
{
throw new NotImplementedException();
}
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Insert)]
[UnitOfWork]
public DmsFileEntity Insert(DmsFileEntity data)
{
throw new NotImplementedException();
}
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Update)]
[UnitOfWork]
public DmsFileEntity Update(DmsFileEntity data)
{
throw new NotImplementedException();
}
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Delete)]
[UnitOfWork]
public void Delete(long key)
{
Delete(key, false);
}
private void Delete(long key, bool hasCreateDmsFileDeleteLog)
{
DmsFileEntity dmsFile = repository.DetachedEntities.Where(x => x.FileId == key).FirstOrDefault()!;
if (dmsFile == null) return;
if (!hasCreateDmsFileDeleteLog) CreateDmsFileDeleteLog(dmsFile, null);
IRepository<DmsFileUploadEntity> repositoryUpload = repository.GetRepository<IRepository<DmsFileUploadEntity>>();
IRepository<DmsFolderMapEntity> repositoryFolderMap = repository.GetRepository<IRepository<DmsFolderMapEntity>>();
IRepository<DmsFolderEntity> repositoryFolder = repository.GetRepository<IRepository<DmsFolderEntity>>();
repository.DeleteNow(dmsFile);
DmsFileUploadEntity DmsFileUpload = repositoryUpload.DetachedEntities.Where(x => x.FileId == key).FirstOrDefault()!;
if (DmsFileUpload != null)
{
repositoryUpload.DeleteNow(DmsFileUpload);
}
if (dmsFile.IsDirectoryIndc == YesNoPolicy.YES)
{
DmsFolderEntity folder = repositoryFolder.DetachedEntities.Where(x => x.FolderName == dmsFile.FileName).FirstOrDefault()!;
if (folder == null) return;
if (folder != null)
{
repositoryFolder.DeleteNow(folder);
}
DmsFolderMapEntity[] folderMaps = repositoryFolderMap.DetachedEntities.Where(x => x.FolderNameSon == dmsFile.FileName || x.FolderNameParent == dmsFile.FileName).ToArray();
if (folderMaps != null && folderMaps.Length > 0)
{
foreach (var map in folderMaps)
{
repositoryFolderMap.DeleteNow(map);
if (map.FolderNameSon == folder.FolderName) continue;
//刪除dmsfoler下的所有內容
DeleteFolder(map.FolderNameSon);
}
}
}
else
{
//删除文件与文件夹的映射关系
DmsFolderMapEntity folderMap = repositoryFolderMap.DetachedEntities.Where(x => x.FolderNameSon == dmsFile.FileName).FirstOrDefault();
if (folderMap != null)
repositoryFolderMap.DeleteNow(folderMap);
}
}
private void CreateDmsFileDeleteLogByDirectory(DmsFileEntity dmsFile, DmsFolderDeleteLogEntity folder)
{
IRepository<DmsFolderDeleteLogEntity> repositoryFolder = repository.GetRepository<IRepository<DmsFolderDeleteLogEntity>>();
ISecurityGeneratorNumberService securityGeneratorNumberService = service.ServiceProvider.GetService<ISecurityGeneratorNumberService>()!;
string folderNameParent = folder.FolderName;
//创建当前目录
folder = new DmsFolderDeleteLogEntity();
folder.FolderName = securityGeneratorNumberService.GetNo(MasterPrefixPolicy.DMS_FOLDER_DELETE_LOG, MasterPrefixPolicy.DMS_FOLDER_DELETE_LOG_FOLDER_NAME, "DR", YesNoPolicy.NO, "00000000");
folder.FolderLocalName = dmsFile.OrgFileName;//如果是目录,这个就是目录名称
repositoryFolder.InsertNow(folder);
//创建目录关系表
DmsFolderMapDeleteLogEntity map = new DmsFolderMapDeleteLogEntity();
IRepository<DmsFolderMapDeleteLogEntity> repositoryFolderMap = repository.GetRepository<IRepository<DmsFolderMapDeleteLogEntity>>();
map.FolderNameParent = folderNameParent;
map.FolderNameSon = folder.FolderName;
repositoryFolderMap.InsertNow(map);
//创建Dms目录
IRepository<DmsFileDeleteLogEntity> repositoryDmsFileDeleteLog = repository.GetRepository<IRepository<DmsFileDeleteLogEntity>>();
DmsFileDeleteLogEntity entity = new DmsFileDeleteLogEntity();
ObjectCopyHelper.Copy(dmsFile, entity);
entity.OrderKey = entity.FileName = folder.FolderName;
entity.FileId = 0;
entity.FilePath = folderNameParent;
repositoryDmsFileDeleteLog.InsertNow(entity);
DmsFileUploadDeleteLogEntity upload = new DmsFileUploadDeleteLogEntity();
upload.FileId = entity.FileId;
upload.FileCategory = "MASTER";
upload.UploadName = securityGeneratorNumberService.GetNo(MasterPrefixPolicy.UPLOAD_DMS_FILE_DELETE_LOG, MasterPrefixPolicy.UPLOAD_DMS_FILE_DELETE_LOG_UPLOAD_NAME, "DR", YesNoPolicy.NO, MasterPrefixPolicy.UPLOAD_DMS_FILE_DELETE_LOG_FORMAT);
upload.OrgFileName = entity.OrgFileName;
IRepository<DmsFileUploadDeleteLogEntity> repositoryUpload = repository.GetRepository<IRepository<DmsFileUploadDeleteLogEntity>>();
repositoryUpload.InsertNow(upload);
//创建所有目录下的内容
DmsFileEntity[] dmsFiles = repository.DetachedEntities.Where(x => x.FilePath == dmsFile.FileName).ToArray();
if (dmsFiles == null || dmsFiles.Length == 0) return;
foreach (var dms in dmsFiles)
{
CreateDmsFileDeleteLog(dms, folder);
}
}
private void CreateDmsFileDeleteLog(DmsFileEntity dmsFile, DmsFolderDeleteLogEntity folderLog)
{
IRepository<DmsFileDeleteLogEntity> repositoryDmsFileDeleteLog = repository.GetRepository<IRepository<DmsFileDeleteLogEntity>>();
IRepository<DmsFileUploadDeleteLogEntity> repositoryDmsFileUploadDeleteLog = repository.GetRepository<IRepository<DmsFileUploadDeleteLogEntity>>();
IRepository<DmsFolderDeleteLogEntity> repositoryDmsFolderDeleteLog = repository.GetRepository<IRepository<DmsFolderDeleteLogEntity>>();
IRepository<DmsFolderMapDeleteLogEntity> repositoryDmsFolderMapDeleteLog = repository.GetRepository<IRepository<DmsFolderMapDeleteLogEntity>>();
ISecurityGeneratorNumberService securityGeneratorNumberService = service.ServiceProvider.GetService<ISecurityGeneratorNumberService>()!;
//如果顶级目录不存在,创建顶级目录
if (folderLog == null)
folderLog = repositoryDmsFolderDeleteLog.DetachedEntities.Where(x => x.FolderLocalName == service.UserId).FirstOrDefault()!;
if (folderLog == null)
{
folderLog = new DmsFolderDeleteLogEntity();
folderLog.FolderName = securityGeneratorNumberService.GetNo(MasterPrefixPolicy.DMS_FOLDER_DELETE_LOG, MasterPrefixPolicy.DMS_FOLDER_DELETE_LOG_FOLDER_NAME, null, YesNoPolicy.NO, "00000000");
folderLog.FolderLocalName = service.UserId;
repositoryDmsFolderDeleteLog.InsertNow(folderLog);
}
string folderNameParent = folderLog.FolderName;
if (dmsFile.IsDirectoryIndc == YesNoPolicy.YES)
{
CreateDmsFileDeleteLogByDirectory(dmsFile, folderLog);
return;
}
IRepository<DmsFileUploadEntity> repositoryDmsFileUpload = repository.GetRepository<IRepository<DmsFileUploadEntity>>();
DmsFileUploadEntity upload = repositoryDmsFileUpload.DetachedEntities.Where(x => x.FileId == dmsFile.FileId).FirstOrDefault()!;
DmsFileUploadDeleteLogEntity uploadLog = new DmsFileUploadDeleteLogEntity();
uploadLog.FileCategory = "MASTER";
uploadLog.UploadName = securityGeneratorNumberService.GetNo(MasterPrefixPolicy.UPLOAD_DMS_FILE_DELETE_LOG, MasterPrefixPolicy.UPLOAD_DMS_FILE_DELETE_LOG_UPLOAD_NAME, "FL", YesNoPolicy.NO, MasterPrefixPolicy.UPLOAD_DMS_FILE_DELETE_LOG_FORMAT);
uploadLog.OrgFileName = upload.OrgFileName;
//创建Dms文件,需更新父目录
DmsFileDeleteLogEntity entityLog = new DmsFileDeleteLogEntity();
ObjectCopyHelper.Copy(dmsFile, entityLog);
entityLog.FilePath = folderNameParent;
entityLog.FileId = 0;
repositoryDmsFileDeleteLog.InsertNow(entityLog);
uploadLog.FileId = entityLog.FileId;
repositoryDmsFileUploadDeleteLog.InsertNow(uploadLog);
//创建目录关系表
DmsFolderMapDeleteLogEntity mapLog = new DmsFolderMapDeleteLogEntity();
mapLog.FolderNameParent = folderNameParent;
mapLog.FolderNameSon = entityLog.FileName;
repositoryDmsFolderMapDeleteLog.InsertNow(mapLog);
}
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Insert)]
[UnitOfWork]
public void RestoreDmsFile(long key)
{
DeleteLog(key, true);
}
private void RestoreDmsFileByDirectory(DmsFileDeleteLogEntity dmsFile, DmsFolderEntity folder)
{
IRepository<DmsFolderEntity> repositoryFolder = repository.GetRepository<IRepository<DmsFolderEntity>>();
ISecurityGeneratorNumberService securityGeneratorNumberService = service.ServiceProvider.GetService<ISecurityGeneratorNumberService>()!;
string folderNameParent = folder.FolderName;
//创建当前目录
folder = new DmsFolderEntity();
folder.FolderName = securityGeneratorNumberService.GetNo(MasterPrefixPolicy.DMS_FOLDER_DELETE_LOG, MasterPrefixPolicy.DMS_FOLDER_DELETE_LOG_FOLDER_NAME, "DR", YesNoPolicy.NO, "00000000");
folder.FolderLocalName = dmsFile.OrgFileName;//如果是目录,这个就是目录名称
repositoryFolder.InsertNow(folder);
//创建目录关系表
DmsFolderMapEntity map = new DmsFolderMapEntity();
IRepository<DmsFolderMapEntity> repositoryFolderMap = repository.GetRepository<IRepository<DmsFolderMapEntity>>();
map.FolderNameParent = folderNameParent;
map.FolderNameSon = folder.FolderName;
repositoryFolderMap.InsertNow(map);
//创建Dms目录,要更新目录名
IRepository<DmsFileEntity> repositoryDmsFile = repository.GetRepository<IRepository<DmsFileEntity>>();
DmsFileEntity entity = new DmsFileEntity();
ObjectCopyHelper.Copy(dmsFile, entity);
entity.OrderKey = entity.FileName = folder.FolderName;
entity.FileId = 0;
entity.FilePath = folderNameParent;
repositoryDmsFile.InsertNow(entity);
DmsFileUploadEntity upload = new DmsFileUploadEntity();
upload.FileId = entity.FileId;
upload.FileCategory = "MASTER";
upload.UploadName = securityGeneratorNumberService.GetNo(MasterPrefixPolicy.UPLOAD_DMS_FILE_DELETE_LOG, MasterPrefixPolicy.UPLOAD_DMS_FILE_DELETE_LOG_UPLOAD_NAME, "DR", YesNoPolicy.NO, MasterPrefixPolicy.UPLOAD_DMS_FILE_DELETE_LOG_FORMAT);
upload.OrgFileName = entity.OrgFileName;
IRepository<DmsFileUploadEntity> repositoryUpload = repository.GetRepository<IRepository<DmsFileUploadEntity>>();
repositoryUpload.InsertNow(upload);
IRepository<DmsFileDeleteLogEntity> repositoryDmsFileDeleteLog = repository.GetRepository<IRepository<DmsFileDeleteLogEntity>>();
//创建所有目录下的内容
DmsFileDeleteLogEntity[] dmsFiles = repositoryDmsFileDeleteLog.DetachedEntities.Where(x => x.FilePath == dmsFile.FileName).ToArray();
if (dmsFiles == null || dmsFiles.Length == 0) return;
foreach (var dms in dmsFiles)
{
RestoreDmsFile(dms, folder);
}
}
private void RestoreDmsFile(DmsFileDeleteLogEntity dmsFile, DmsFolderEntity folder)
{
IRepository<DmsFileEntity> repositoryDmsFile = repository.GetRepository<IRepository<DmsFileEntity>>();
IRepository<DmsFileUploadEntity> repositoryDmsFileUpload = repository.GetRepository<IRepository<DmsFileUploadEntity>>();
IRepository<DmsFolderEntity> repositoryDmsFolder = repository.GetRepository<IRepository<DmsFolderEntity>>();
IRepository<DmsFolderMapEntity> repositoryDmsFolderMap = repository.GetRepository<IRepository<DmsFolderMapEntity>>();
ISecurityGeneratorNumberService securityGeneratorNumberService = service.ServiceProvider.GetService<ISecurityGeneratorNumberService>()!;
//如果顶级目录不存在,创建顶级目录
if (folder == null)
folder = repositoryDmsFolder.DetachedEntities.Where(x => x.FolderLocalName == service.UserId).FirstOrDefault()!;
if (folder == null)
{
folder = new DmsFolderEntity();
folder.FolderName = securityGeneratorNumberService.GetNo(MasterPrefixPolicy.DMS_FOLDER_DELETE_LOG, MasterPrefixPolicy.DMS_FOLDER_DELETE_LOG_FOLDER_NAME, null, YesNoPolicy.NO, "00000000");
folder.FolderLocalName = service.UserId;
repositoryDmsFolder.InsertNow(folder);
}
string folderNameParent = folder.FolderName;
if (dmsFile.IsDirectoryIndc == YesNoPolicy.YES)
{
RestoreDmsFileByDirectory(dmsFile, folder);
return;
}
DmsFileUploadEntity uploadLog = new DmsFileUploadEntity();
IRepository<DmsFileUploadDeleteLogEntity> repositoryDmsFileUploadDeleteLog = repository.GetRepository<IRepository<DmsFileUploadDeleteLogEntity>>();
DmsFileUploadDeleteLogEntity dmsFileUploadDeleteLog = repositoryDmsFileUploadDeleteLog.DetachedEntities.Where(x => x.FileId == dmsFile.FileId).FirstOrDefault()!;
uploadLog.FileCategory = "MASTER";
uploadLog.UploadName = securityGeneratorNumberService.GetNo(MasterPrefixPolicy.UPLOAD_DMS_FILE_DELETE_LOG, MasterPrefixPolicy.UPLOAD_DMS_FILE_DELETE_LOG_UPLOAD_NAME, "FL", YesNoPolicy.NO, MasterPrefixPolicy.UPLOAD_DMS_FILE_DELETE_LOG_FORMAT);
uploadLog.OrgFileName = dmsFileUploadDeleteLog.OrgFileName;
//创建Dms文件,需更新父目录
DmsFileEntity entityLog = new DmsFileEntity();
ObjectCopyHelper.Copy(dmsFile, entityLog);
entityLog.FilePath = folderNameParent;
entityLog.FileId = 0;
repositoryDmsFile.InsertNow(entityLog);
uploadLog.FileId = entityLog.FileId;
repositoryDmsFileUpload.InsertNow(uploadLog);
//创建目录关系表
DmsFolderMapEntity mapLog = new DmsFolderMapEntity();
mapLog.FolderNameParent = folderNameParent;
mapLog.FolderNameSon = entityLog.FileName;
repositoryDmsFolderMap.InsertNow(mapLog);
}
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Delete)]
[UnitOfWork]
public void DeleteLog(long key)
{
DeleteLog(key, false);
}
private void DeleteLog(long key, bool isRestore)
{
IRepository<DmsFileDeleteLogEntity> repositoryDmsFileDeleteLog = repository.GetRepository<IRepository<DmsFileDeleteLogEntity>>();
DmsFileDeleteLogEntity dmsFile = repositoryDmsFileDeleteLog.DetachedEntities.Where(x => x.FileId == key).FirstOrDefault()!;
if (dmsFile == null) return;
if (isRestore) RestoreDmsFile(dmsFile, null);
repositoryDmsFileDeleteLog.DeleteNow(dmsFile);
IRepository<DmsFileUploadDeleteLogEntity> repositoryDmsFileUploadDeleteLog = repository.GetRepository<IRepository<DmsFileUploadDeleteLogEntity>>();
DmsFileUploadDeleteLogEntity DmsFileUpload = repositoryDmsFileUploadDeleteLog.DetachedEntities.Where(x => x.FileId == key).FirstOrDefault()!;
IRepository<DmsFolderMapDeleteLogEntity> repositoryDmsFolderMapDeleteLog = repository.GetRepository<IRepository<DmsFolderMapDeleteLogEntity>>();
if (DmsFileUpload != null)
{
repositoryDmsFileUploadDeleteLog.DeleteNow(DmsFileUpload);
}
if (dmsFile.IsDirectoryIndc == YesNoPolicy.YES)
{
IRepository<DmsFolderDeleteLogEntity> repositoryDmsFolderDeleteLog = repository.GetRepository<IRepository<DmsFolderDeleteLogEntity>>();
DmsFolderDeleteLogEntity folder = repositoryDmsFolderDeleteLog.DetachedEntities.Where(x => x.FolderName == dmsFile.FileName).FirstOrDefault()!;
if (folder == null) return;
if (folder != null)
{
repositoryDmsFolderDeleteLog.DeleteNow(folder);
}
DmsFolderMapDeleteLogEntity[] folderMaps = repositoryDmsFolderMapDeleteLog.DetachedEntities.Where(x => x.FolderNameSon == dmsFile.FileName || x.FolderNameParent == dmsFile.FileName).ToArray();
if (folderMaps != null && folderMaps.Length > 0)
{
foreach (var map in folderMaps)
{
repositoryDmsFolderMapDeleteLog.DeleteNow(map);
if (map.FolderNameSon == folder.FolderName) continue;
//刪除dmsfoler下的所有內容
DeleteFolderDeleteLog(map.FolderNameSon);
}
}
}
else
{
//删除文件与文件夹的映射关系
DmsFolderMapDeleteLogEntity folderMap = repositoryDmsFolderMapDeleteLog.DetachedEntities.Where(x => x.FolderNameSon == dmsFile.FileName).FirstOrDefault();
if (folderMap != null)
repositoryDmsFolderMapDeleteLog.DeleteNow(folderMap);
}
}
private void DeleteFolderDeleteLog(string folderName)
{
IRepository<DmsFileDeleteLogEntity> repositoryDmsFileDeleteLog = repository.GetRepository<IRepository<DmsFileDeleteLogEntity>>();
DmsFileDeleteLogEntity[] dmsFiles = repositoryDmsFileDeleteLog.DetachedEntities.Where(x => x.FileName == folderName).ToArray();
if (dmsFiles == null || dmsFiles.Length == 0) return;
foreach (var dmsFile in dmsFiles)
{
DeleteLog(dmsFile.FileId, false);
}
}
public void DeleteFolder(string folderName)
{
DmsFileEntity[] dmsFiles = repository.DetachedEntities.Where(x => x.FileName == folderName).ToArray();
if (dmsFiles == null || dmsFiles.Length == 0) return;
foreach (var dmsFile in dmsFiles)
{
Delete(dmsFile.FileId, true);
}
}
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Insert)]
[UnitOfWork]
public string CreateDmsFolder(DmsFileEntity dmsFile)
{
IRepository<DmsFolderEntity> repositoryFolder = repository.GetRepository<IRepository<DmsFolderEntity>>();
ISecurityGeneratorNumberService securityGeneratorNumberService = service.ServiceProvider.GetService<ISecurityGeneratorNumberService>()!;
DmsFolderEntity folder = null;
string folderNameParent = dmsFile.FilePath;
//父目录是空,创建顶级目录
folder = repositoryFolder.DetachedEntities.Where(x => x.FolderLocalName == service.UserId).FirstOrDefault()!;
if (folder == null)
{
folder = new DmsFolderEntity();
folder.FolderName = securityGeneratorNumberService.GetNo(MasterPrefixPolicy.DMS_FOLDER, MasterPrefixPolicy.DMS_FOLDER_FOLDER_NAME, "DR", YesNoPolicy.NO, "00000000");
folder.FolderLocalName = service.UserId;
repositoryFolder.InsertNow(folder);
}
if (string.IsNullOrEmpty(dmsFile.FilePath))
{
folderNameParent = folder.FolderName;
}
//创建当前目录
folder = new DmsFolderEntity();
folder.FolderName = securityGeneratorNumberService.GetNo(MasterPrefixPolicy.DMS_FOLDER, MasterPrefixPolicy.DMS_FOLDER_FOLDER_NAME, "DR", YesNoPolicy.NO, "00000000");
folder.FolderLocalName = dmsFile.FileName;
repositoryFolder.InsertNow(folder);
//创建目录关系表
DmsFolderMapEntity map = new DmsFolderMapEntity();
IRepository<DmsFolderMapEntity> repositoryFolderMap = repository.GetRepository<IRepository<DmsFolderMapEntity>>();
map.FolderNameParent = folderNameParent;
map.FolderNameSon = folder.FolderName;
repositoryFolderMap.InsertNow(map);
//创建Dms目录
DmsFileEntity entity = new DmsFileEntity();
entity.OrderKey = entity.FileName = folder.FolderName;
entity.OrgFileName = dmsFile.FileName;
entity.AllowDeleteIndc = entity.AllowRenameIndc = entity.IsDirectoryIndc = YesNoPolicy.YES;
entity.FilePath = folderNameParent;
entity.OwerId = service.UserId;
entity.IsLinkIndc = YesNoPolicy.NO;
repository.InsertNow(entity);
DmsFileUploadEntity upload = new DmsFileUploadEntity();
upload.FileId = entity.FileId;
upload.FileCategory = "MASTER";
upload.UploadName = securityGeneratorNumberService.GetNo(MasterPrefixPolicy.UPLOAD_DMS_FILE, MasterPrefixPolicy.UPLOAD_DMS_FILE_UPLOAD_NAME, "DR", YesNoPolicy.NO, MasterPrefixPolicy.UPLOAD_DMS_FILE_FORMAT);
upload.OrgFileName = entity.OrgFileName;
IRepository<DmsFileUploadEntity> repositoryUpload = repository.GetRepository<IRepository<DmsFileUploadEntity>>();
repositoryUpload.InsertNow(upload);
return folder.FolderName;
}
public void CreateFamilyDmsFolder(FamilyGroupEntity familyGroup, FamilyGroupFolderEntity[] familyGroupFolders)
{
ISecurityGeneratorNumberService securityGeneratorNumberService = service.ServiceProvider.GetService<ISecurityGeneratorNumberService>()!;
IRepository<DmsFolderEntity> repositoryFolder = repository.GetRepository<IRepository<DmsFolderEntity>>();
DmsFolderEntity folder = repositoryFolder.DetachedEntities.Where(x => x.FolderLocalName == familyGroup.FamilyName).FirstOrDefault()!;
if (folder == null)
{
folder = new DmsFolderEntity();
folder.FolderName = familyGroup.FamilyName;
folder.FolderLocalName = familyGroup.FamilyName;
repositoryFolder.InsertNow(folder);
}
if (familyGroupFolders != null && familyGroupFolders.Length > 0)
CreateFamilyGroupFolderDetail(folder, familyGroupFolders);
}
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Insert)]
[UnitOfWork]
public void DeleteFamilyDmsFolder(FamilyDmsFileViewEntity familyDmsFile)
{
ISecurityGeneratorNumberService securityGeneratorNumberService = service.ServiceProvider.GetService<ISecurityGeneratorNumberService>()!;
IRepository<FamilyGroupFolderEntity> repositoryFamilyGroupFolder = repository.GetRepository<IRepository<FamilyGroupFolderEntity>>();
IRepository<DmsFolderEntity> repositoryFolder = repository.GetRepository<IRepository<DmsFolderEntity>>();
IRepository<DmsFolderMapEntity> repositoryFolderMap = repository.GetRepository<IRepository<DmsFolderMapEntity>>();
DmsFolderEntity folder;
DmsFolderMapEntity map;
DmsFileEntity entity;
FamilyGroupFolderEntity familyGroupFolder = repositoryFamilyGroupFolder.DetachedEntities.Where(x => x.FolderName == familyDmsFile.FolderName).FirstOrDefault()!;
repositoryFamilyGroupFolder.DeleteNow(familyGroupFolder);
//如果只是文件分享,则返回
if (familyDmsFile.IsDirectoryIndc == YesNoPolicy.NO) return;
folder = repositoryFolder.DetachedEntities.Where(x => x.FolderName == familyDmsFile.FolderName).FirstOrDefault()!;
repositoryFolder.DeleteNow(folder);
map = repositoryFolderMap.DetachedEntities.Where(x => x.FolderNameSon == folder.FolderName).FirstOrDefault()!;
repositoryFolderMap.DeleteNow(map);
entity = repository.DetachedEntities.Where(x => x.FileName == folder.FolderName).FirstOrDefault()!;
repository.DeleteNow(entity);
IRepository<FamilyFolderFavoriteEntity> repositoryFamilyFolderFavorite = repository.GetRepository<IRepository<FamilyFolderFavoriteEntity>>();
FamilyFolderFavoriteEntity[] folderFavorite = repositoryFamilyFolderFavorite.DetachedEntities.Where(x => x.FolderName == folder.FolderName).ToArray();
repositoryFamilyFolderFavorite.DeleteNow(folderFavorite);
}
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Insert)]
[UnitOfWork]
public void CreateFamilyDmsFolder(FamilyDmsFileViewEntity familyDmsFile)
{
ISecurityGeneratorNumberService securityGeneratorNumberService = service.ServiceProvider.GetService<ISecurityGeneratorNumberService>()!;
IRepository<FamilyGroupFolderEntity> repositoryFolder = repository.GetRepository<IRepository<FamilyGroupFolderEntity>>();
//上级目录
FamilyGroupFolderEntity folder = repositoryFolder.DetachedEntities.Where(x => x.FolderName == familyDmsFile.FilePath).FirstOrDefault()!;
if (folder == null) return;
if (string.IsNullOrEmpty(familyDmsFile.FolderLocalName)) return;
CreateFamilyGroupFolder(folder, familyDmsFile);
}
private void CreateFamilyGroupFolder(FamilyGroupFolderEntity dmsFolder, FamilyDmsFileViewEntity familyDmsFile)
{
ISecurityGeneratorNumberService securityGeneratorNumberService = service.ServiceProvider.GetService<ISecurityGeneratorNumberService>()!;
IRepository<DmsFolderEntity> repositoryFolder = repository.GetRepository<IRepository<DmsFolderEntity>>();
IRepository<DmsFolderMapEntity> repositoryFolderMap = repository.GetRepository<IRepository<DmsFolderMapEntity>>();
DmsFolderEntity folder;
DmsFolderMapEntity map;
DmsFileEntity entity;
FamilyGroupFolderEntity familyGroupFolder = new FamilyGroupFolderEntity();
familyGroupFolder.FamilyName = familyDmsFile.FamilyName;
familyGroupFolder.FolderName = securityGeneratorNumberService.GetNo(MasterPrefixPolicy.DMS_FOLDER, MasterPrefixPolicy.DMS_FOLDER_FOLDER_NAME, "FG", YesNoPolicy.NO, "00000000");
familyGroupFolder.FolderLocalName = familyDmsFile.FolderLocalName;
familyGroupFolder.Notice = familyDmsFile.Notice;
//设置顶级目录
familyGroupFolder.TopFolderName = dmsFolder.TopFolderName;
IRepository<FamilyGroupFolderEntity> repositoryFamilyGroupFolder = repository.GetRepository<IRepository<FamilyGroupFolderEntity>>();
repositoryFamilyGroupFolder.InsertNow(familyGroupFolder);
folder = new DmsFolderEntity();
folder.FolderName = familyGroupFolder.FolderName;
folder.FolderLocalName = familyGroupFolder.FolderLocalName;
repositoryFolder.InsertNow(folder);
map = new DmsFolderMapEntity();
map.FolderNameParent = dmsFolder.FolderName;
map.FolderNameSon = folder.FolderName;
repositoryFolderMap.InsertNow(map);
//创建Dms目录
entity = new DmsFileEntity();
entity.OrderKey = entity.FileName = familyGroupFolder.FolderName;
entity.OrgFileName = folder.FolderLocalName;
entity.AllowDeleteIndc = entity.AllowRenameIndc = entity.IsDirectoryIndc = YesNoPolicy.YES;
entity.FilePath = map.FolderNameParent;
entity.OwerId = folder.FolderName;
entity.IsLinkIndc = YesNoPolicy.NO;
repository.InsertNow(entity);
}
private void CreateFamilyGroupFolderDetail(DmsFolderEntity dmsFolder, FamilyGroupFolderEntity[] familyGroupFolders)
{
ISecurityGeneratorNumberService securityGeneratorNumberService = service.ServiceProvider.GetService<ISecurityGeneratorNumberService>()!;
IRepository<DmsFolderEntity> repositoryFolder = repository.GetRepository<IRepository<DmsFolderEntity>>();
IRepository<DmsFolderMapEntity> repositoryFolderMap = repository.GetRepository<IRepository<DmsFolderMapEntity>>();
DmsFolderEntity folder;
DmsFolderMapEntity map;
DmsFileEntity entity;
foreach (var item in familyGroupFolders)
{
//如果是已创建,则跳过
if (!string.IsNullOrEmpty(item.CreatedBy)) continue;
folder = new DmsFolderEntity();
folder.FolderName = item.FolderName;
folder.FolderLocalName = item.FolderLocalName;
repositoryFolder.InsertNow(folder);
map = new DmsFolderMapEntity();
map.FolderNameParent = dmsFolder.FolderName;
map.FolderNameSon = folder.FolderName;
repositoryFolderMap.InsertNow(map);
//创建Dms目录
entity = new DmsFileEntity();
entity.OrderKey = entity.FileName = item.FolderName;
entity.OrgFileName = folder.FolderLocalName;
entity.AllowDeleteIndc = entity.AllowRenameIndc = entity.IsDirectoryIndc = YesNoPolicy.YES;
entity.FilePath = map.FolderNameParent;
entity.OwerId = folder.FolderName;
entity.IsLinkIndc = YesNoPolicy.NO;
repository.InsertNow(entity);
}
}
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Update)]
[UnitOfWork]
public void UpdateDmsFolder(DmsFileEntity dmsFile)
{
IRepository<DmsFileUploadEntity> repositoryUpload = repository.GetRepository<IRepository<DmsFileUploadEntity>>();
DmsFileUploadEntity upload = repositoryUpload.DetachedEntities.Where(x => x.FileId == dmsFile.FileId).FirstOrDefault()!;
if (upload == null)
{
throw new ValidatedException("记录不存在.");
}
upload.OrgFileName = dmsFile.FileName;
repositoryUpload.UpdateNow(upload);
DmsFileEntity file = repository.DetachedEntities.Where(x => x.FileId == dmsFile.FileId).FirstOrDefault()!;
// 主表 OrgFileName 是列表显示/下载名的权威来源,重命名必须同步(历史上只改 upload 表,前端列表名字改不动);
// 注意只同步 OrgFileName,主表 FileName 是 FL 编号不能拿新名覆盖
file.OrgFileName = dmsFile.FileName;
repository.UpdateNow(file);
//修改目录档对应的名称
IRepository<DmsFolderEntity> repositoryFolder = repository.GetRepository<IRepository<DmsFolderEntity>>();
DmsFolderEntity dmsFolder = repositoryFolder.DetachedEntities.Where(x => x.FolderName == file.FileName).FirstOrDefault()!;
if (dmsFolder == null) return;
dmsFolder.FolderLocalName = upload.OrgFileName;
repositoryFolder.UpdateNow(dmsFolder);
}
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Find)]
public SelectOption[] FindDmsFolders()
{
IRepository<DmsFolderEntity> repositoryFolder = repository.GetRepository<IRepository<DmsFolderEntity>>();
//排除FamilyGroup创建的目录
DmsFolderEntity[] ents = repositoryFolder.DetachedEntities.Where(x => x.FolderName.StartsWith("DR") && x.CreatedBy == service.UserId && x.FolderLocalName != service.UserId).ToArray();
List<SelectOption> l = new List<SelectOption>();
SelectOption selectOption;
DmsFolderEntity my = repositoryFolder.DetachedEntities.Where(x => x.CreatedBy == service.UserId && x.FolderLocalName == service.UserId).FirstOrDefault()!;
selectOption = new SelectOption();
selectOption.BindValue = string.Empty;
if (my == null)
{
selectOption.DisplayName = "我的网盘";
}
else
{
selectOption.DisplayName = "所有文件(夹)";
}
l.Add(selectOption);
if (my != null)
{
selectOption = new SelectOption();
selectOption.BindValue = my.FolderName;
selectOption.DisplayName = "我的网盘";
l.Add(selectOption);
}
if (ents == null || ents.Length == 0) return l.ToArray();
foreach (DmsFolderEntity ent in ents)
{
selectOption = new SelectOption();
selectOption.BindValue = ent.FolderName;
selectOption.DisplayName = ent.FolderLocalName;
l.Add(selectOption);
}
return l.ToArray();
}
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Find)]
public SelectOption[] FindDmsFolderDeleteLogs()
{
IRepository<DmsFolderDeleteLogEntity> repositoryFolder = repository.GetRepository<IRepository<DmsFolderDeleteLogEntity>>();
//排除FamilyGroup创建的目录
DmsFolderDeleteLogEntity[] ents = repositoryFolder.DetachedEntities.Where(x => x.FolderName.StartsWith("DR") && x.CreatedBy == service.UserId && x.FolderLocalName != service.UserId).ToArray();
List<SelectOption> l = new List<SelectOption>();
SelectOption selectOption;
DmsFolderDeleteLogEntity my = repositoryFolder.DetachedEntities.Where(x => x.CreatedBy == service.UserId && x.FolderLocalName == service.UserId).FirstOrDefault()!;
selectOption = new SelectOption();
selectOption.BindValue = string.Empty;
if (my == null)
{
selectOption.DisplayName = "我的网盘";
}
else
{
selectOption.DisplayName = "所有文件(夹)";
}
l.Add(selectOption);
if (my != null)
{
selectOption = new SelectOption();
selectOption.BindValue = my.FolderName;
selectOption.DisplayName = "我的网盘";
l.Add(selectOption);
}
if (ents == null || ents.Length == 0) return l.ToArray();
foreach (DmsFolderDeleteLogEntity ent in ents)
{
selectOption = new SelectOption();
selectOption.BindValue = ent.FolderName;
selectOption.DisplayName = ent.FolderLocalName;
l.Add(selectOption);
}
return l.ToArray();
}
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Find)]
public DmsFolderData FindDmsFolderData()
{
DmsFolderData data = new DmsFolderData();
IRepository<DmsFolderEntity> repositoryFolder = repository.GetRepository<IRepository<DmsFolderEntity>>();
DmsFolderEntity[] dmsFolders = repositoryFolder.DetachedEntities.Where(x => x.CreatedBy == service.UserId).ToArray();
data.DmsFolders = dmsFolders;
IRepository<DmsFolderMapEntity> repositoryFolderMap = repository.GetRepository<IRepository<DmsFolderMapEntity>>();
DmsFolderMapEntity[] dmsFolderMaps = repositoryFolderMap.DetachedEntities.Where(x => x.CreatedBy == service.UserId).ToArray();
data.DmsFoldersMaps = dmsFolderMaps;
return data;
}
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Update)]
[UnitOfWork]
public void MoveDmsFolder(DmsFileEntity dmsFile)
{
DmsFileEntity file = repository.DetachedEntities.Where(x => x.FileId == dmsFile.FileId).FirstOrDefault()!;
if (file == null) return;
if (file.FilePath == dmsFile.FilePath) return;
file.FilePath = dmsFile.FilePath;
repository.UpdateNow(file);
IRepository<DmsFolderMapEntity> repositoryFolderMap = repository.GetRepository<IRepository<DmsFolderMapEntity>>();
DmsFolderMapEntity map = repositoryFolderMap.Entities.Where(x => x.FolderNameSon == file.FileName).FirstOrDefault()!;
if (map == null) return;
repositoryFolderMap.DeleteNow(map);
map = new DmsFolderMapEntity();
map.FolderNameSon = file.FileName;
map.FolderNameParent = dmsFile.FilePath;
repositoryFolderMap.InsertNow(map);
}
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Insert)]
[UnitOfWork]
public FamilyPersonDisplayData UploadIdCardFile()
{
FamilyPersonDisplayData data = new FamilyPersonDisplayData();
//1) 先走原有分片上传落盘(FilePath 头指定 idcard 目录)
UploadFile();
//2) 取本次上传文件,server-to-server 调 OCR 识别服务(无浏览器跨域)
var file = httpContextAccessor.HttpContext?.Request?.Form?.Files?.FirstOrDefault();
if (file == null || file.Length <= 0) return data;
//文件名(xxxx-1-1.ext 分片名)与识别面:side 以普通表单字段传入,缺省取配置
data.IdCardFilename = file.FileName;
string side = ServiceSettingsPolicy.GetIdCardOcrSide(service);
if (httpContextAccessor.HttpContext.Request.Form.ContainsKey("side"))
{
var formSide = httpContextAccessor.HttpContext.Request.Form["side"].ToString();
if (!string.IsNullOrWhiteSpace(formSide)) side = formSide;
}
string apiUrl = ServiceSettingsPolicy.GetIdCardOcrApiUrl(service);
if (string.IsNullOrWhiteSpace(apiUrl)) return data;
try
{
using var recognizeStream = file.OpenReadStream();
using var form = new System.Net.Http.MultipartFormDataContent();
var fileContent = new System.Net.Http.StreamContent(recognizeStream);
fileContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(
string.IsNullOrWhiteSpace(file.ContentType) ? "image/jpeg" : file.ContentType);
form.Add(fileContent, "file", file.FileName);
form.Add(new System.Net.Http.StringContent(side), "side");
using var client = new System.Net.Http.HttpClient();
client.Timeout = TimeSpan.FromSeconds(ServiceSettingsPolicy.GetIdCardOcrTimeoutSeconds(service));
//识别服务已启用 Bearer Token 鉴权(appsettings 配置 API_TOKENS 中 win-service 的 Token)
var apiKey = ServiceSettingsPolicy.GetIdCardOcrApiKey(service);
if (!string.IsNullOrWhiteSpace(apiKey))
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", apiKey);
using var response = client.PostAsync(apiUrl, form).GetAwaiter().GetResult();
string json = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
if (!response.IsSuccessStatusCode)
{
Console.WriteLine($"[UploadIdCardFile] OCR service returned HTTP {(int)response.StatusCode}: {json}");
return data;
}
if (string.IsNullOrWhiteSpace(json)) return data;
using var doc = System.Text.Json.JsonDocument.Parse(json);
var root = doc.RootElement;
//识别服务返回 { code:0, data:{... } },code!=0 视为未识别到,仅返回文件名
int code = -1;
if (root.TryGetProperty("code", out var codeEl) && codeEl.ValueKind == System.Text.Json.JsonValueKind.Number)
code = codeEl.GetInt32();
if (code != 0) return data;
if (!root.TryGetProperty("data", out var info) || info.ValueKind != System.Text.Json.JsonValueKind.Object)
return data;
string GetStr(string key)
{
if (info.TryGetProperty(key, out var el))
{
if (el.ValueKind == System.Text.Json.JsonValueKind.String) return el.GetString();
if (el.ValueKind != System.Text.Json.JsonValueKind.Null && el.ValueKind != System.Text.Json.JsonValueKind.Undefined)
return el.ToString();
}
return null;
}
//常用名/民族/住址/身份证号/签发机关/有效期限(姓名映射到 CommonName 已在需求确认)
data.CommonName = GetStr("name");
data.Nation = GetStr("nation");
data.Address = GetStr("address");
data.IdNumber = GetStr("id_number");
data.Issuer = GetStr("issuer");
data.Validity = GetStr("validity");
//性别回传原始文本(如“男”),由前端按 GenderPolicy 匹配为策略编码,避免后端依赖运行时语言包
data.Gender = GetStr("gender");
//出生日期:OCR 返回多为 yyyyMMdd,解析为 DateTime(Kind=Unspecified,避免时区偏移)
var birth = GetStr("birth");
if (!string.IsNullOrWhiteSpace(birth))
{
var digits = new string(birth.Where(char.IsDigit).ToArray());
if (digits.Length >= 8
&& DateTime.TryParseExact(digits.Substring(0, 8), "yyyyMMdd",
System.Globalization.CultureInfo.InvariantCulture,
DateTimeStyles.None, out var birthDate))
{
data.BirthDate = birthDate;
}
}
}
catch (Exception ex)
{
//OCR 调用失败不影响图片已上传:记录日志,返回仅含文件名的 data,前端据此提示“未识别到信息”
Console.WriteLine($"[UploadIdCardFile] OCR recognize failed: {ex.Message}");
}
return data;
}
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Insert)]
[UnitOfWork]
public void UploadFile()
{
//采用分片上传文件(以及后面分片下载)
DmsFileEntity dmsFile = null;
var files = httpContextAccessor.HttpContext.Request.Form.Files;
var currentDate = DateTime.Now;
if (files.Any())
{
foreach (var file in files)
{
string filePath = null;
if (httpContextAccessor.HttpContext.Request.Headers.ContainsKey("FilePath"))
filePath = httpContextAccessor.HttpContext.Request.Headers["FilePath"].ToString();
PackUploadFile(file, filePath);
break;
}
}
}
public void PackUploadFile(IFormFile file, string folderName)
{
var uploadFileRootPath = ServiceSettingsPolicy.GetUploadFileDirectory(service);
//文件后缀
var fileExtension = Path.GetExtension(file.Name.Replace(" ", "")).ToLower();//获取文件格式,拓展名
if (string.IsNullOrEmpty(fileExtension)) fileExtension = "ext";
var filePath = Path.Combine(folderName, fileExtension.Replace(".", ""), "");
//创建存储文件夹
if (!Directory.Exists(Path.Combine(uploadFileRootPath, filePath)))
{
Directory.CreateDirectory(Path.Combine(uploadFileRootPath, filePath));
}
//判断文件大小
var fileSize = file.Length;
if (fileSize > 1024 * 1024 * 100) //100M TODO:(1mb=1024X1024b)
{
return;
}
//保存的文件名称
string fullName = Path.Combine(uploadFileRootPath, filePath, file.FileName);
if (File.Exists(fullName)) File.Delete(fullName);
//文件保存
using (var fs = System.IO.File.Create(fullName))
{
file.CopyTo(fs);
fs.Flush();
}
//FileName上传Uid:xxxx-1-1.xxx
string[] fns = file.FileName.Split('-');
//如果上传的不是最后一个分片
if (fns[fns.Length - 2] != fns[fns.Length - 1].Split('.')[0])
{
return;
}
else
{
string backupRootPath = ServiceSettingsPolicy.GetBackupFileDirectory(service);
string backupFileName = Path.Combine(backupRootPath, filePath, file.FileName);
if (!Directory.Exists(Path.Combine(backupRootPath, filePath)))
{
Directory.CreateDirectory(Path.Combine(backupRootPath, filePath));
}
if (fns[fns.Length - 1].Split('.')[0] == "1")
{
if (File.Exists(backupFileName)) File.Delete(backupFileName);
File.Copy(fullName, backupFileName, true);
}
else//合并文件
{
List<byte[]> all = new List<byte[]>();
List<string> fileNames = new List<string>();
//文件分片从1开始
for (int i = 1; i <= Convert.ToInt32(fns[fns.Length - 1].Split('.')[0]); i++)
{
fns[fns.Length - 2] = i.ToString();
fileNames.Add(Path.Combine(uploadFileRootPath, filePath, fns.ToDelimiteredList('-')));
}
if (File.Exists(backupFileName)) File.Delete(backupFileName);
using (FileStream outputFile = File.Create(backupFileName)) // 创建输出文件流
{
foreach (string fileName in fileNames)
{
byte[] buffer = File.ReadAllBytes(fileName); // 读取每个文件内容到字节数组
outputFile.Write(buffer, 0, buffer.Length); // 将字节数组写入输出文件流
}
}
}
}
}
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Insert)]
[UnitOfWork]
public void UploadDmsFile()
{
//采用分片上传文件(以及后面分片下载)
DmsFileEntity dmsFile = null;
var files = httpContextAccessor.HttpContext.Request.Form.Files;
var currentDate = DateTime.Now;
if (files.Any())
{
foreach (var file in files)
{
string filePath = null;
if (httpContextAccessor.HttpContext.Request.Headers.ContainsKey("FilePath"))
filePath = httpContextAccessor.HttpContext.Request.Headers["FilePath"].ToString();
dmsFile = PackUploadDmsFile(file, filePath);
break;
}
}
if (dmsFile != null)
{
CreateDmsFile(dmsFile);
}
}
public DmsFileEntity PackUploadDmsFile(IFormFile file, string folderName)
{
var webRootPath = ServiceSettingsPolicy.GetDmsFileUploadDirectory(service);
DmsFileEntity dmsFile = new DmsFileEntity();
dmsFile.OrgFileName = file.Name.Replace(" ", "");
dmsFile.FilePath = folderName;
//文件后缀
var fileExtension = Path.GetExtension(file.Name.Replace(" ", "")).ToLower();//获取文件格式,拓展名
if (string.IsNullOrEmpty(fileExtension)) fileExtension = "ext";
var filePath = Path.Combine(service.UserId, fileExtension.Replace(".", ""), "");
//创建存储文件夹
if (!Directory.Exists(Path.Combine(webRootPath, filePath)))
{
Directory.CreateDirectory(Path.Combine(webRootPath, filePath));
}
//判断文件大小
var fileSize = file.Length;
if (fileSize > 1024 * 1024 * 100) //100M TODO:(1mb=1024X1024b)
{
return null;
}
//保存的文件名称
string fullName = Path.Combine(webRootPath, filePath, file.FileName);
if (File.Exists(fullName)) File.Delete(fullName);
//文件保存
using (var fs = System.IO.File.Create(fullName))
{
file.CopyTo(fs);
fs.Flush();
}
//FileName上传Uid:xxxx-1-1.xxx
string[] fns = file.FileName.Split('-');
//如果上传的不是最后一个分片,不写入表
if (fns[fns.Length - 2] != fns[fns.Length - 1].Split('.')[0])
{
dmsFile = null;
return null;
}
else
{
dmsFile.OrderKey = file.FileName;
if (fns[fns.Length - 1].Split('.')[0] == "1")
{
dmsFile.OrderKey = file.FileName;
dmsFile.FileName = file.FileName;
dmsFile.FileSize = Convert.ToInt32(fileSize / 1024);
var backupRootPath = ServiceSettingsPolicy.GetDmsFileBackupDirectory(service);
string backupName = Path.Combine(backupRootPath, filePath, dmsFile.FileName);
if (!Directory.Exists(Path.Combine(backupRootPath, filePath)))
{
Directory.CreateDirectory(Path.Combine(backupRootPath, filePath));
}
if (File.Exists(backupName)) File.Delete(backupName);
File.Copy(fullName, backupName, true);
//生成缩略图
if (FileTypePolicy.GetType(fileExtension.ToLower()) == FileTypePolicy.PHOTO)
{
ImageToScare(fullName, dmsFile);
}
else if (FileTypePolicy.GetType(fileExtension.ToLower()) == FileTypePolicy.VIDEO)
{
// 单片上传(小文件、App 端整文件不分片)也要出视频封面:走与多片合并分支同一条链,
// 截图落在备份目录里的同名 .jpg(前端宫格/详情封面读的就是这个文件),
// 否则只有被切成多片的视频有封面,小视频上传后永远是黑块
dmsFile.TranscodeIndc = YesNoPolicy.YES;
TsToM3u8(dmsFile.OrderKey, backupName, backupName.Replace(fileExtension, FileTypePolicy.JPG));
}
}
else//合并文件
{
List<byte[]> all = new List<byte[]>();
List<string> fileNames = new List<string>();
//文件分片从1开始
for (int i = 1; i <= Convert.ToInt32(fns[fns.Length - 1].Split('.')[0]); i++)
{
fns[fns.Length - 2] = i.ToString();
fileNames.Add(Path.Combine(webRootPath, filePath, fns.ToDelimiteredList('-')));
}
dmsFile.FileName = Path.GetFileName(fullName);
var backupRootPath = ServiceSettingsPolicy.GetDmsFileBackupDirectory(service);
fullName = Path.Combine(backupRootPath, filePath, dmsFile.FileName);
if (!Directory.Exists(Path.Combine(backupRootPath, filePath)))
{
Directory.CreateDirectory(Path.Combine(backupRootPath, filePath));
}
if (File.Exists(fullName)) File.Delete(fullName);
using (FileStream outputFile = File.Create(fullName)) // 创建输出文件流
{
foreach (string fileName in fileNames)
{
byte[] buffer = File.ReadAllBytes(fileName); // 读取每个文件内容到字节数组
outputFile.Write(buffer, 0, buffer.Length); // 将字节数组写入输出文件流
dmsFile.FileSize += buffer.Length;
}
dmsFile.FileSize = Convert.ToInt32(dmsFile.FileSize / 1024);//kb
}
//task:ImageSharpTask uid:SYSTEM file_size:5351 file_name:vc-upload-1709274146458-2-11-11_DSC_6141.JPG order_key:vc-upload-1709257162571-2-6-6.JPG
//生成缩略图
if (FileTypePolicy.GetType(fullName.ToLower()) == FileTypePolicy.PHOTO)
{
ImageToScare(fullName, dmsFile);
}
else if (FileTypePolicy.GetType(fullName.ToLower()) == FileTypePolicy.VIDEO)
{
foreach (string fileName in fileNames)
{
if (File.Exists(fileName)) File.Delete(fileName);
}
string m3u8FilePath = fullName.Replace(fileExtension, FileTypePolicy.JPG);
//生成m3u8(生成10秒视频,只生成截图)
dmsFile.TranscodeIndc = YesNoPolicy.YES;
TsToM3u8(dmsFile.OrderKey, fullName, m3u8FilePath);
}
}
}
return dmsFile;
}
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Find)]
public string FindM3u8Path(long fileId)
{
DmsFileEntity entity = repository.DetachedEntities.Where(x => x.FileId == fileId && x.CreatedBy == service.UserId).FirstOrDefault()!;
return FileTypePolicy.PackSourceVideoUrl(service, entity.CreatedBy, entity.OrderKey, entity.TranscodeIndc);
}
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Find)]
public string FindSourceVideoPath(long fileId)
{
DmsFileEntity entity = repository.DetachedEntities.Where(x => x.FileId == fileId && x.CreatedBy == service.UserId).FirstOrDefault()!;
return FileTypePolicy.PackSourceVideoUrl(service, entity.CreatedBy, entity.OrderKey, entity.TranscodeIndc);
}
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Find)]
public string FindDeleteLogM3u8Path(long fileId)
{
IRepository<DmsFileDeleteLogEntity> repositoryDmsFileDeleteLog = repository.GetRepository<IRepository<DmsFileDeleteLogEntity>>();
DmsFileDeleteLogEntity entity = repositoryDmsFileDeleteLog.DetachedEntities.Where(x => x.FileId == fileId && x.CreatedBy == service.UserId).FirstOrDefault()!;
return FileTypePolicy.PackSourceVideoUrl(service, entity.CreatedBy, entity.OrderKey, entity.TranscodeIndc);
}
private string PackParameters(DmsFileEntity dmsFile)
{
List<string> para = new List<string>();
para.Add("task:" + "ImageSharpTask");
para.Add("uid:" + service.UserId);
para.Add("file_size:" + dmsFile.FileSize);
para.Add("file_name:" + dmsFile.FileName);
para.Add("order_key:" + dmsFile.OrderKey);
return para.ToArray().ToDelimiteredList(' ');
}
public void TsToM3u8(string documentId, string mp4Url, string m3u8Url)
{
string para = string.Format(service.Configuration[ServiceSettingsPolicy.FfmpegPictrue], mp4Url, m3u8Url);
try
{
RunMyProcess(service.Configuration[ServiceSettingsPolicy.FfmpegPath], para);
}
catch (Exception ex)
{
new FileLog(service.Configuration).WriteToFile(ex.Message);
}
var backupRootPath = ServiceSettingsPolicy.GetDmsFileBackupDirectory(service);
var fileExtension = "m3u8";
var filePath = Path.Combine(service.UserId, fileExtension.Replace(".", ""), "");
var orgFileExtension = Path.GetExtension(documentId);
var fullName = Path.Combine(backupRootPath, filePath, documentId.Replace(orgFileExtension, ".m3u8"));
string targetDir = Path.GetDirectoryName(fullName);
if (!Directory.Exists(targetDir))
{
Directory.CreateDirectory(targetDir);
}
para = string.Format(service.Configuration[ServiceSettingsPolicy.FfmpegArguments], mp4Url, "", fullName);
IRepository<SecurityScheduleTaskQueueEntity> logRepository = repository.GetRepository<IRepository<SecurityScheduleTaskQueueEntity>>();
SecurityScheduleTaskQueueEntity task = new SecurityScheduleTaskQueueEntity();
task.DocumentId = documentId;
task.TaskId = service.Configuration[ServiceSettingsPolicy.FfmpegPath];
task.TaskParam = para;
logRepository.InsertNow(task);
para = string.Format(service.Configuration[ServiceSettingsPolicy.FfmpegArguments], mp4Url, " -t 10", fullName);
//直接转码视频文件10秒,影响服务器性能,改为在闭时自动生成全部
RunMyProcess(task.TaskId, para);
}
public void ImageToScare(string fullName, DmsFileEntity dmsFile)
{
var fileExtension = Path.GetExtension(fullName).ToLower();//获取文件格式,拓展名
if (string.IsNullOrEmpty(fileExtension)) fileExtension = "ext";
// 仅修改这一行,替换硬编码反斜杠字符串拼接
var filePath = Path.Combine(service.UserId, fileExtension.Replace(".", ""), "");
// 这里同步改成Path.Combine,不要直接+字符串拼接
string saveName = Path.Combine(ServiceSettingsPolicy.GetDmsFileScaleDirectory(service), filePath, dmsFile.OrderKey);
if (!Directory.Exists(Path.GetDirectoryName(saveName)))
{
Directory.CreateDirectory(Path.GetDirectoryName(saveName));
}
using (Image image = Image.Load(fullName))
{
decimal scale = 1;
if (image.Width > 932 && image.Width > image.Height)
{
if (dmsFile != null)
{
dmsFile.LandscapeIndc = YesNoPolicy.YES;
}
scale = image.Width / 932m;
int newWidth = Convert.ToInt32(image.Width / scale);
int newHeight = Convert.ToInt32(image.Height / scale);
image.Mutate(x => x.Resize(newWidth, newHeight, KnownResamplers.Lanczos3));
if (newWidth > 932)
image.Mutate(a => a.Crop(new Rectangle((newWidth - 932) / 2, 0, 932, 430)));
}
else if (image.Height > 932 && image.Height > image.Width)
{
if (dmsFile != null)
{
dmsFile.LandscapeIndc = YesNoPolicy.NO;
}
scale = image.Height / 932m;
int newWidth = Convert.ToInt32(image.Width / scale);
int newHeight = Convert.ToInt32(image.Height / scale);
image.Mutate(x => x.Resize(newWidth, newHeight, KnownResamplers.Lanczos3));
if (newWidth > 430)
image.Mutate(a => a.Crop(new Rectangle((newWidth - 430) / 2, 0, 430, 932)));
}
image.Save(saveName);
}
}
/// <summary>
/// 执行cmd指令(异步不等待,await要求等待返回,转码太耗时)
/// </summary>
/// <param name="Parameters"></param>
public void RunMyProcess(string exePath, string Parameters)
{
FileLog log = new FileLog(service.Configuration);
try
{
log.WriteToFile(exePath + Parameters);
if (string.IsNullOrEmpty(exePath)) return;
// 必须等 ffmpeg 真正退出:视频封面(jpg)要在接口返回前落盘,
// 否则前端刷新列表时文件还没生成,<img> 请求 404 且不会自动重试,
// 表现为"上传完看不到封面,手动刷新才有"。
// 最多等 25 秒,超时就交给前端的封面重试机制兜底,不再死等拖住上传请求。
// CliWrap 的 ExecuteAsync 返回 CommandTask<CommandResult>,取它的 Task 才能等待
var task = Cli.Wrap(exePath)
.WithArguments(Parameters)
.ExecuteAsync()
.Task;
if (!task.Wait(TimeSpan.FromSeconds(25)))
{
log.WriteToFile("ffmpeg 执行超时(25s):" + Parameters);
return;
}
log.WriteToFile("ffmpeg 执行完成,ExitCode:" + task.Result.ExitCode);
}
catch (Exception ex)
{
// 截图失败不影响上传本身,这里只记日志,封面由前端重试兜底
log.WriteToFile(ex.Message);
}
}
public DmsFileEntity CreateDmsFile(DmsFileEntity dmsFile)
{
IRepository<DmsFolderEntity> repositoryFolder = repository.GetRepository<IRepository<DmsFolderEntity>>();
ISecurityGeneratorNumberService securityGeneratorNumberService = service.ServiceProvider.GetService<ISecurityGeneratorNumberService>()!;
DmsFolderEntity folder = null;
string folderNameParent = dmsFile.FilePath;
//父目录是空,创建顶级目录
if (string.IsNullOrEmpty(dmsFile.FilePath))
{
folder = repositoryFolder.DetachedEntities.Where(x => x.FolderLocalName == service.UserId).FirstOrDefault()!;
if (folder == null)
{
folder = new DmsFolderEntity();
folder.FolderName = securityGeneratorNumberService.GetNo(MasterPrefixPolicy.DMS_FOLDER, MasterPrefixPolicy.DMS_FOLDER_FOLDER_NAME, null, YesNoPolicy.NO, "00000000");
folder.FolderLocalName = service.UserId;
repositoryFolder.InsertNow(folder);
}
folderNameParent = folder.FolderName;
}
DmsFileUploadEntity upload = new DmsFileUploadEntity();
upload.FileCategory = "MASTER";
upload.UploadName = securityGeneratorNumberService.GetNo(MasterPrefixPolicy.UPLOAD_DMS_FILE, MasterPrefixPolicy.UPLOAD_DMS_FILE_UPLOAD_NAME, "FL", YesNoPolicy.NO, MasterPrefixPolicy.UPLOAD_DMS_FILE_FORMAT);
upload.OrgFileName = dmsFile.OrgFileName;
//创建Dms文件
DmsFileEntity entity = new DmsFileEntity();
entity.OrderKey = dmsFile.OrderKey;
entity.FileName = upload.UploadName;
entity.FileType = FileTypePolicy.GetType(entity.OrderKey);
// 主表必须存原始文件名(前端 multipart 字段名),不能存 dmsFile.FileName 物理分片名,否则下载时拿到的就是系统保存名
entity.OrgFileName = dmsFile.OrgFileName;
entity.FileSize = dmsFile.FileSize;
entity.AllowDeleteIndc = entity.AllowRenameIndc = YesNoPolicy.YES;
entity.IsDirectoryIndc = YesNoPolicy.NO;
entity.FilePath = folderNameParent;
entity.TranscodeIndc = dmsFile.TranscodeIndc;
entity.OwerId = service.UserId;
entity.IsLinkIndc = YesNoPolicy.NO;
// 网盘额度闸门:按当前用户类型限额,已用(KB)+本次(KB) 超限直接拒。
// 放任何 InsertNow 之前,抛异常时主表/上传表/目录关系均未落库,DB 保持一致(仅物理文件可能成为孤儿,属上传前置阶段)。
EnsureQuotaAllowed(dmsFile.FileSize);
repository.InsertNow(entity);
IRepository<DmsFileUploadEntity> repositoryUpload = repository.GetRepository<IRepository<DmsFileUploadEntity>>();
upload.FileId = entity.FileId;
repositoryUpload.InsertNow(upload);
//创建目录关系表
DmsFolderMapEntity map = new DmsFolderMapEntity();
IRepository<DmsFolderMapEntity> repositoryFolderMap = repository.GetRepository<IRepository<DmsFolderMapEntity>>();
map.FolderNameParent = folderNameParent;
map.FolderNameSon = entity.FileName;
repositoryFolderMap.InsertNow(map);
return entity;
}
/// <summary>
/// 当前登录用户的网盘用量汇总:类型/头像取自 security_user,已用取自 dms_file_usage_view(ower_id=本人 且非目录),
/// 额度按 user_type 从 appsettings:NetDiskQuota 解析。供 dashboard 两张卡片一次拉取。
/// </summary>
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Find)]
public StorageUsageData GetMyStorageUsage()
{
IRepository<SecurityUserEntity> repositoryUser = repository.GetRepository<IRepository<SecurityUserEntity>>();
SecurityUserEntity user = repositoryUser.DetachedEntities.Where(x => x.UserName == service.UserId).FirstOrDefault();
string userType = user?.UserType;
if (string.IsNullOrWhiteSpace(userType)) userType = SecurityUserTypePolicy.UNAUTHENTICATED_USERS;
long usedKB = GetUsedKB(service.UserId);
long quotaKB = ServiceSettingsPolicy.GetNetDiskQuotaKB(service, userType);
int percent = quotaKB > 0 ? (int)(usedKB * 100 / quotaKB) : 0;
return new StorageUsageData
{
UserType = userType,
AvatarUrl = FileTypePolicy.PackAvatarUrl(service, UploadFolderPolicy.USER_AVATAR, user?.UserIconImgPath) ?? "",
UsedKB = usedKB,
QuotaKB = quotaKB,
Percent = percent
};
}
/// <summary>
/// 上传并保存当前登录用户头像:复用与成员头像同一套 PackUploadFile 落盘(目录名统一走 UploadFolderPolicy.USER_AVATAR),
/// 末片物理名回写 security_user.user_icon_img_path(与 family_person.avatar_filename 同口径存物理名),返回可访问 URL。
/// </summary>
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Insert)]
[UnitOfWork]
public string UploadUserAvatar()
{
var files = httpContextAccessor.HttpContext.Request.Form.Files;
if (files == null || files.Count == 0) return "";
IFormFile file = files[0];
if (file == null || file.Length <= 0) return "";
// 落盘:单片三段式名(uni-时间戳-1-1.ext)会在 PackUploadFile 内合并到备份目录
PackUploadFile(file, UploadFolderPolicy.USER_AVATAR);
string filename = file.FileName;
IRepository<SecurityUserEntity> repositoryUser = repository.GetRepository<IRepository<SecurityUserEntity>>();
SecurityUserEntity user = repositoryUser.DetachedEntities.Where(x => x.UserName == service.UserId).FirstOrDefault();
if (user != null)
{
user.UserIconImgPath = filename;
repositoryUser.UpdateNow(user);
}
return FileTypePolicy.PackAvatarUrl(service, UploadFolderPolicy.USER_AVATAR, filename) ?? "";
}
/// <summary>查本人已用容量(KB)。按 dms_file_usage_view 视图实体标准 LINQ 链路取数,
/// 无行(从未上传)记 0;ower_id 源自 JWT 登录态非外部入参。</summary>
private long GetUsedKB(string owerId)
{
IRepository<DmsFileUsageViewEntity> repositoryView = repository.GetRepository<IRepository<DmsFileUsageViewEntity>>();
return repositoryView.DetachedEntities.Where(x => x.OwerId == owerId).Select(x => x.UsedKb).FirstOrDefault();
}
/// <summary>上传额度校验:额度未配(≤0)视为不限;已用+本次超额度则抛业务异常拒上传。</summary>
private void EnsureQuotaAllowed(int incomingKB)
{
IRepository<SecurityUserEntity> repositoryUser = repository.GetRepository<IRepository<SecurityUserEntity>>();
string userType = repositoryUser.DetachedEntities.Where(x => x.UserName == service.UserId).FirstOrDefault()?.UserType;
long quotaKB = ServiceSettingsPolicy.GetNetDiskQuotaKB(service, userType);
if (quotaKB <= 0) return;
long usedKB = GetUsedKB(service.UserId);
if (usedKB + incomingKB > quotaKB)
{
long limitGB = quotaKB / (1024 * 1024);
long usedGB = usedKB / (1024 * 1024);
throw new ValidatedException($"网盘容量不足(上限约 {limitGB} GB,已用约 {usedGB} GB),请清理或升级会员后再上传。");
}
}
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Find)]
public dynamic DownloadFile(long fileId)
{
DmsFileEntity entity = repository.DetachedEntities.Where(x => x.FileId == fileId && x.CreatedBy == service.UserId).FirstOrDefault()!;
if (entity == null) throw new ValidatedException("文件不存在.");
var fileExtension = Path.GetExtension(entity.OrderKey);//获取文件格式,拓展名
string path = FileTypePolicy.PackFilePath(service, entity.CreatedBy, entity.OrderKey);
IRepository<DmsFileUploadEntity> repositoryUpload = repository.GetRepository<IRepository<DmsFileUploadEntity>>();
DmsFileUploadEntity DmsFileUpload = repositoryUpload.DetachedEntities.Where(x => x.FileId == fileId).FirstOrDefault()!;
if (DmsFileUpload == null || !File.Exists(path)) throw new ValidatedException("文件不存在.");
var stream = System.IO.File.OpenRead(path);
string contentType = "application/octet-stream";
switch (fileExtension.Replace(".", "").ToLower())
{
case "xls":
case "xlt":
case "xla":
contentType = "application/vnd.ms-excel";
break;
case "xlsx":
case "xltx":
contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
break;
case "doc":
contentType = "application/msword";
break;
case "docx":
contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
break;
case "txt":
contentType = "text/plain";
break;
case "png":
case "jpg":
case "jpeg":
case "gif":
contentType = "image/*";
break;
case "mp4":
case "mpg":
case "mpeg":
case "avi":
contentType = "video/*";
break;
case "pdf":
contentType = "application/pdf";
break;
default:
break;
}
return new FileStreamResult(stream, contentType) { FileDownloadName = DmsFileUpload.OrgFileName };
}
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Find)]
public dynamic DownloadFilePreview(DmsFileEntity dmsFile)
{
var webRootPath = ServiceSettingsPolicy.GetDmsFileScaleDirectory(service);
var fileExtension = Path.GetExtension(dmsFile.OrderKey);
var filePath = Path.Combine(dmsFile.CreatedBy, fileExtension.Replace(".", ""), "");
string path = Path.Combine(webRootPath, filePath, dmsFile.OrderKey);
if (!File.Exists(path)) throw new ValidatedException("文件不存在.");
var stream = System.IO.File.OpenRead(path);
//string contentType = "image/*";
string contentType = "application/octet-stream";
return new FileStreamResult(stream, contentType) { FileDownloadName = dmsFile.OrderKey };
}
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Find)]
public dynamic DownloadFileCombine(string fileName)
{
var webRootPath = ServiceSettingsPolicy.GetDmsFileUploadDirectory(service);
var fileExtension = Path.GetExtension(fileName);
var filePath = Path.Combine(service.UserId, fileExtension.Replace(".", ""), "");
string path = Path.Combine(webRootPath, filePath, fileName);
if (!File.Exists(path)) throw new ValidatedException("文件不存在.");
var stream = System.IO.File.OpenRead(path);
//string contentType = "image/*";
string contentType = "application/octet-stream";
return new FileStreamResult(stream, contentType) { FileDownloadName = fileName };
}
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Find)]
public SelectOption[] FindFamilyDmsFolders()
{
IRepository<FamilyGroupManagerUserViewEntity> repositoryFamilyGroupManager = repository.GetRepository<IRepository<FamilyGroupManagerUserViewEntity>>();
FamilyGroupManagerUserViewEntity[] ents = repositoryFamilyGroupManager.DetachedEntities.Where(x => x.UserName == service.UserId && x.ValidIndc == "Y").ToArray();
List<SelectOption> l = new List<SelectOption>();
SelectOption selectOption;
if (ents == null || ents.Length == 0) return l.ToArray();
foreach (FamilyGroupManagerUserViewEntity ent in ents)
{
selectOption = new SelectOption();
selectOption.BindValue = ent.FamilyName;
selectOption.DisplayName = ent.FamilyLocalName;
l.Add(selectOption);
}
return l.ToArray();
}
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Find)]
public SelectOption[] FindFamilyDmsFoldersByFamilyName(string familyName)
{
List<SelectOption> l = new List<SelectOption>();
SelectOption selectOption;
if (string.IsNullOrEmpty(familyName)) return l.ToArray();
IRepository<FamilyGroupEntity> repositoryFamilyGroup = repository.GetRepository<IRepository<FamilyGroupEntity>>();
FamilyGroupEntity group = repositoryFamilyGroup.DetachedEntities.Where(x => x.FamilyName == familyName && x.ValidIndc == YesNoPolicy.YES).FirstOrDefault()!;
if (group == null) return l.ToArray();
selectOption = new SelectOption();
selectOption.BindValue = group.FamilyName;
selectOption.DisplayName = group.FamilyLocalName;
l.Add(selectOption);
IRepository<FamilyGroupFolderEntity> repositoryFamilyGroupFolder = repository.GetRepository<IRepository<FamilyGroupFolderEntity>>();
FamilyGroupFolderEntity[] ents = repositoryFamilyGroupFolder.DetachedEntities.Where(x => x.FamilyName == familyName && string.IsNullOrEmpty(x.FilePath)).ToArray();
if (ents == null || ents.Length == 0) return l.ToArray();
foreach (FamilyGroupFolderEntity ent in ents)
{
selectOption = new SelectOption();
selectOption.BindValue = ent.FolderName;
selectOption.DisplayName = ent.FolderLocalName;
l.Add(selectOption);
}
return l.ToArray();
}
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Find)]
public int FindDmsFolderMapByFolderName(string folderName)
{
IRepository<DmsFolderMapEntity> repositoryFolderMap = repository.GetRepository<IRepository<DmsFolderMapEntity>>();
return repositoryFolderMap.DetachedEntities.Where(x => x.FolderNameParent == folderName).Count();
}
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Find)]
public string FindFolderNameParentByFolderName(string folderName)
{
IRepository<DmsFolderMapEntity> repositoryFolderMap = repository.GetRepository<IRepository<DmsFolderMapEntity>>();
if (repositoryFolderMap.DetachedEntities.Where(x => x.FolderNameSon == folderName).Count() == 0) return string.Empty;
return repositoryFolderMap.DetachedEntities.Where(x => x.FolderNameSon == folderName).FirstOrDefault()!.FolderNameParent;
}
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Insert)]
public void CreateFamilyGroupFolder(FamilyGroupFolderEntity[] familyGroupFolder)
{
FamilyGroupFolderEntity folder;
IRepository<FamilyGroupFolderEntity> repositoryFamilyGroupFolder = repository.GetRepository<IRepository<FamilyGroupFolderEntity>>();
foreach (var item in familyGroupFolder)
{
folder = repositoryFamilyGroupFolder.DetachedEntities.Where(x => x.FolderName == item.FolderName
&& x.FamilyName == item.FamilyName && x.FilePath == item.FilePath).FirstOrDefault()!;
if (folder != null) continue;
folder = new FamilyGroupFolderEntity();
folder.FolderName = item.FolderName;
folder.FamilyName = item.FamilyName;
folder.TopFolderName = item.TopFolderName;
folder.FolderLocalName = item.FolderLocalName;
folder.FilePath = item.FilePath;
repositoryFamilyGroupFolder.InsertNow(folder);
}
}
[PermissionOperate(name: MasterPermissionPolicy.DmsFile, operate: Operate.Delete)]
public void DeleteFamilyGroupFolder(FamilyGroupFolderEntity[] familyGroupFolder)
{
FamilyGroupFolderEntity folder;
IRepository<FamilyGroupFolderEntity> repositoryFamilyGroupFolder = repository.GetRepository<IRepository<FamilyGroupFolderEntity>>();
IRepository<FamilyGroupPermissionEntity> repositoryFamilyGroupPermission = repository.GetRepository<IRepository<FamilyGroupPermissionEntity>>();
FamilyGroupPermissionEntity fgp;
foreach (var item in familyGroupFolder)
{
folder = repositoryFamilyGroupFolder.DetachedEntities.Where(x => x.FolderName == item.FolderName
&& x.FamilyName == item.FamilyName && x.FilePath == (string.IsNullOrEmpty(item.FilePath) ? null : item.FilePath)).FirstOrDefault()!;
if (folder == null) continue;
//再分析是否有权限
fgp = repositoryFamilyGroupPermission.DetachedEntities.Where(x => x.FamilyName == folder.FamilyName
&& x.FolderName == folder.TopFolderName && x.UserName == service.UserId).FirstOrDefault()!;
if (fgp == null) throw new ValidatedException("你没有权限删除.");
repositoryFamilyGroupFolder.DeleteNow(folder);
}
}
}
}