This commit is contained in:
owenchen committed 2026-10-20 15:44:56 +08:00
1 parent 9b01c4a57a
commit 6417562c4f
37 files changed
+2767 -202

No files matched your search

@@ -1698,6 +1698,10 @@ namespace CloudBuilder.Master.Service
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>>();
@@ -1715,6 +1719,86 @@ namespace CloudBuilder.Master.Service
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)
{