using Model; using Model.Entity.Asset; using ORM; using Service.Interface; using SqlSugar; using System; using System.Collections.Generic; using System.IO; using System.Threading.Tasks; namespace Service.Implement { /// /// 设备附件服务实现(资产附件管理) /// public class EquipmentAttachmentService : IEquipmentAttachmentService { private readonly SqlSugarRepository _repository; public EquipmentAttachmentService(SqlSugarRepository repository) { _repository = repository; } /// /// 查询指定设备的附件列表(按上传时间倒序) /// public async Task>> GetByEquipmentAsync(long equipmentId) { try { var list = await _repository.Entities .Where(x => x.EquipmentId == equipmentId && x.IsDel == 0) .OrderBy(x => x.CreateTime, OrderByType.Desc) .ToListAsync(); return Result>.Success(list); } catch (Exception ex) { return Result>.Error("查询附件列表失败", ex); } } /// /// 上传附件(保存文件到 uploads 目录并写入附件记录) /// public async Task> UploadAsync(long equipmentId, Stream stream, string originalFileName, long fileSize, AttachmentTypeEnum fileType, string? uploader, string? remark, string webRootPath) { if (equipmentId <= 0) { return Result.Error("设备 Id 无效"); } if (stream == null || fileSize <= 0) { return Result.Error("上传文件为空"); } try { // 按设备分目录存储:uploads/equipment/{equipmentId}/ string relativeDir = Path.Combine("uploads", "equipment", equipmentId.ToString()); string physicalDir = Path.Combine(webRootPath, relativeDir); if (!Directory.Exists(physicalDir)) { Directory.CreateDirectory(physicalDir); } // 存储文件名:时间戳 + 原扩展名,避免重名与中文路径问题 string ext = Path.GetExtension(originalFileName); string storedName = $"{DateTime.Now:yyyyMMddHHmmssfff}{ext}"; string physicalPath = Path.Combine(physicalDir, storedName); using (var fileStream = new FileStream(physicalPath, FileMode.Create)) { await stream.CopyToAsync(fileStream); } var entity = new EquipmentAttachmentEntity { EquipmentId = equipmentId, FileName = originalFileName, FileType = fileType, FileExt = ext, FileUrl = $"/{relativeDir.Replace('\\', '/')}/{storedName}", FileSize = fileSize, Uploader = uploader, Remark = remark, CreateTime = DateTime.Now }; await _repository.Context.Insertable(entity).ExecuteCommandAsync(); return Result.Success(entity); } catch (Exception ex) { return Result.Error("上传附件失败", ex); } } /// /// 删除附件(软删除记录并删除物理文件) /// public async Task> DeleteAsync(long id) { if (id <= 0) { return Result.Error("附件 Id 无效"); } try { var attachment = await _repository.Entities .Where(x => x.Id == id && x.IsDel == 0) .FirstAsync(); if (attachment == null) { return Result.Error("附件不存在或已被删除"); } var result = await _repository.Context.Updateable() .SetColumns(x => x.IsDel == 1) .Where(x => x.Id == id) .ExecuteCommandAsync(); // 删除物理文件(失败不影响记录删除结果) try { string webRoot = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "wwwroot"); string physicalPath = Path.Combine(webRoot, (attachment.FileUrl ?? string.Empty).TrimStart('/').Replace('/', Path.DirectorySeparatorChar)); if (File.Exists(physicalPath)) { File.Delete(physicalPath); } } catch { // 物理文件删除失败忽略 } return Result.Success(result > 0); } catch (Exception ex) { return Result.Error("删除附件失败", ex); } } } }