using Hh.Mes.Common.log; using Hh.Mes.Common.Request; using Hh.Mes.POJO.Entity; using Hh.Mes.POJO.Response; using Hh.Mes.Service.Repository; using SqlSugar; using System; using System.Linq; using System.Linq.Expressions; using System.Data; using System.IO; using Hh.Mes.Pojo.System; using System.Collections.Generic; using Microsoft.AspNetCore.Http; using Hh.Mes.Service.SystemAuth; namespace Hh.Mes.Service.Base { public class SysFileService : RepositorySqlSugar<sys_File> { public SysFileService(IAuth auth) : base(auth) { } /// <summary> /// 文件存储路径 new JoinQueryInfos(JoinType.Left, file.targetId == y.code) /// </summary> private readonly string FileNamePath = "\\wwwroot\\Document"; #region 列表、树结构数据 public dynamic Load(PageReq pageReq, sys_File entity) { return ExceptionsHelp.Instance.ExecuteT(() => { var result = new Response(); var expression = LinqWhere(entity); //先组合查询表达式 var query = Context.Queryable<sys_File, base_equipment>((x, y) => new JoinQueryInfos(JoinType.Inner, x.targetId == y.equipmentCode)) .Where(expression) .Select((x, y) => new { x.fileName, x.id, x.targetId, x.host, x.url, x.size, x.suffix, x.remark, x.createBy, x.createTime }); if (!entity.isSelectEquipment) { var expressions=LinqAnotherWhere(entity); query = Context.Queryable<sys_File>() .Where(expressions) .Select(x => new { x.fileName, x.id, x.targetId, x.host, x.url, x.size, x.suffix, x.remark, x.createBy, x.createTime }); } //Exel为ture就不分页,因为导出的话是全部导出 if (pageReq != null) { int total = 0; var list = query.ToOffsetPage(pageReq.page, pageReq.limit, ref total).Distinct(); result.Result = list; result.Count = total; } else { result.Result = query.ToList().Distinct(); result.Count = result.Result.Count; } return result; }, catchRetrunValue: "list"); } public Expression<Func<sys_File, base_equipment, bool>> LinqWhere(sys_File model) { try { var exp = Expressionable.Create<sys_File, base_equipment>(); //数据过滤条件 //根节点 if (!string.IsNullOrWhiteSpace(model.targetTableName) && model.targetTableName != "root") { exp.And((x, y) => x.targetTableName.Contains(model.targetTableName)); } if (!string.IsNullOrWhiteSpace(model.fileCode)) { exp.And((x, y) => x.fileCode.Contains(model.fileCode)); } if (!string.IsNullOrWhiteSpace(model.host)) { exp.And((x, y) => x.host.Contains(model.host)); } //根节点 if (!string.IsNullOrEmpty(model.targetId) && model.targetId != "r-1") { exp.And((x, y) => x.targetId.Equals(model.targetId)); } if (!string.IsNullOrWhiteSpace(model.fileName)) { exp.And((x, y) => x.fileName.Contains(model.fileName)); } //读取当前用户下面所有的设备 string currentUser = sysWebUser.Account; if (currentUser != SystemVariable.DefaultCreated) { var projectRoleKeys = GetProjectRoleKeys(currentUser); exp.And((x, y) => SqlFunc.Subqueryable<sys_role_projects_rel>().Where(c => projectRoleKeys.Contains(c.project_roles_key) && c.project_key == y.projectKeys).Any()); } return exp.ToExpression();//拼接表达式 } catch (Exception ex) { throw new Exception($"{ex.Message}"); } } public Expression<Func<sys_File, bool>> LinqAnotherWhere(sys_File model) { try { var exp = Expressionable.Create<sys_File>(); //数据过滤条件 //根节点 if (!string.IsNullOrWhiteSpace(model.targetTableName) && model.targetTableName != "root") { exp.And(x => x.targetTableName.Contains(model.targetTableName)); } //根节点 if (!string.IsNullOrEmpty(model.targetId) && model.targetId != "r-1") { exp.And(x => x.targetId.Equals(model.targetId)); } return exp.ToExpression();//拼接表达式 } catch (Exception ex) { throw new Exception($"{ex.Message}"); } } /// <summary> /// /左侧列表 设备类型+设备 /// </summary> public dynamic GetTreeList() { return ExceptionsHelp.Instance.ExecuteT(() => { string user = sysWebUser.Account; var equipmentNodes = Context.Queryable<base_equipment>().Where(GetTreeListExpression(user)).Select(x => new { id = "eq-" + x.id.ToString(), name = x.equipmentName + " " + x.equipmentCode, keys = x.equipmentCode, parentId = x.equipmentTypeCode, isok = true, code = "eq", projectKeys = x.projectKeys }).Distinct().ToList(); var equipmentTypeCodes = equipmentNodes.Select(x => x.parentId).Distinct().ToList(); var rootNode = new { id = Guid.NewGuid(), name = "根节点", keys = "r-1", parentId = "0", isok = false, code = "root", projectKeys = Guid.Empty }; var equipmentTypeNodes = Context.Queryable<base_equipment_type>() .Where(x => equipmentTypeCodes.Contains(x.code)) .Select(x => new { id = "eqType-" + x.id.ToString(), name = x.name, keys = x.code, parentId = rootNode.keys, isok = true, code = "eqType", projectKeys = Guid.Empty }).ToList(); var nodes = new List<dynamic> { rootNode }; nodes.AddRange(equipmentTypeNodes); nodes.AddRange(equipmentNodes); return nodes; }); } public Expression<Func<base_equipment, bool>> GetTreeListExpression(string userAccount) { var exp = Expressionable.Create<base_equipment>(); var ignoreEquipmentTypeCodes = SystemVariable.IotNotContainDevice.Split(','); exp.And(x => !ignoreEquipmentTypeCodes.Contains(x.equipmentTypeCode)); if (userAccount != SystemVariable.DefaultCreated) { var projectRoleKeys = GetProjectRoleKeys(userAccount); exp.And(x => SqlFunc.Subqueryable<sys_role_projects_rel>().Where(c => projectRoleKeys.Contains(c.project_roles_key) && c.project_key == x.projectKeys).Any()); } return exp.ToExpression(); } #endregion public dynamic DelByIds(int[] ids) { return ExceptionsHelp.Instance.ExecuteT(() => { var response = new Response(); var docs = Context.Queryable<sys_File>().Where(x => ids.Contains(x.id)).ToList(); docs.ForEach((item) => { DeleteDocument(item.url); }); Context.Deleteable<sys_File>(t => ids.Contains(t.id)).ExecuteCommand(); return response; }); } /// <summary> /// 删除服务器内文件 /// </summary> /// <param name="fileName"></param> public void DeleteDocument(string fileName) { string path = $"{Directory.GetCurrentDirectory()}{FileNamePath}\\{fileName}"; if (File.Exists(path)) { File.Delete(path); } } #region 文件上传新增 /// <summary> /// 文件上传新增 需要在外面指定targetTableName /// </summary> public dynamic AddOrUpdate(sys_File entity) { return ExceptionsHelp.Instance.ExecuteT<dynamic>(() => { var response = new Response(); string fileEmptyErrorMessage = "上传文件数据时,文件不能为空!"; if (!ValidateInitialConditions(entity, response, fileEmptyErrorMessage)) return response; // 获取目标表名并检查有效性 entity.targetTableName = GetTargetTableName(entity.targetTableName); var uploadPath = EnsureUploadDirectory(); foreach (var file in entity.excelfile) { if (!ValidateFile(file, response, fileEmptyErrorMessage)) { return response; } var (newFileName, size) = SaveFile(file, uploadPath); UpdateEntity(entity, newFileName, size); Context.Insertable(entity).AddQueue(); } var result = Context.SaveQueuesAsync().Result > 0; if (!result) return response.ResponseError("文件上传保存失败,请刷新后重试,反复出现请联系管理员!"); return response; }); } // 验证初始条件,确保文件列表和targetId有效 private bool ValidateInitialConditions(sys_File entity, Response response, string errorMessage) { if (entity.excelfile == null || entity.excelfile.Count == 0) { response.ResponseError(errorMessage); return false; } if (string.IsNullOrEmpty(entity.targetId)) { response.ResponseError("上传文件,目标targetId不能为空!"); return false; } return true; } private bool ValidateFile(IFormFile file, Response response, string errorMessage) { if (file == null || file.Length == 0) { response.ResponseError(errorMessage); return false; } var fileTypes = new List<string> { ".exe", ".bat" }; foreach (var item in fileTypes) { if (file.FileName.EndsWith(item, StringComparison.OrdinalIgnoreCase)) { response.ResponseError($"禁止上传“{item}”文件"); return false; } } return true; } // 获取目标表名, private string GetTargetTableName(string targetTableName) { return targetTableName switch { "eqType" => "base_equipment_type", "eq" => "base_equipment", _ => targetTableName }; } // 确保上传目录存在 private string EnsureUploadDirectory() { var uploadPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "Document"); if (!Directory.Exists(uploadPath)) { Directory.CreateDirectory(uploadPath); } return uploadPath; } // 保存文件并返回新文件名和文件大小 private (string newFileName, long size) SaveFile(IFormFile file, string uploadPath) { var suffix = Path.GetExtension(file.FileName); var fileName = Path.GetFileNameWithoutExtension(file.FileName); var newFileName = $"{fileName}_{DateTime.Now:yyyy-MM-dd-HH-mm-ss}{suffix}"; long size; using (var fs = File.Create(Path.Combine(uploadPath, newFileName))) { file.CopyTo(fs); size = fs.Length / 1024; // 以 KB 为单位 } return (newFileName, size); } // 更新实体的文件信息 private void UpdateEntity(sys_File entity, string newFileName, long size) { entity.size = size > 1024 ? $"{size / 1024:N1}M" : $"{size:N1}Kb"; entity.suffix = Path.GetExtension(newFileName); entity.fileName = Path.GetFileNameWithoutExtension(newFileName); entity.url = newFileName; entity.createBy = sysWebUser.Account; entity.createTime = DateTime.Now; } #endregion } }