소스 검색

优化文件处理和代码结构

- 移除 `PersonnelModuleController.cs` 中的调试属性。
- 在 `ResourceController.cs` 中添加新的命名空间引用。
- 新增 `MediaSupplierExcelImport` 方法以支持 Excel 文件导入。
- 修改 `GoodsRepository.cs` 中的字符串格式化以提高可读性。
- 在 `CommonFun.cs` 中移除冗余引用并添加文件签名验证功能。
- 定义多种文件类型的签名以增强文件上传的安全性。
LEIYI 3 일 전
부모
커밋
a8a4c12f56

+ 0 - 2
OASystem/OASystem.Api/Controllers/PersonnelModuleController.cs

@@ -2104,9 +2104,7 @@ WHERE
         /// </summary>
         /// <returns></returns>
         [HttpPost]
-        #if !DEBUG
         [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
-        #endif
         public async Task<IActionResult> GoodsReceiveAuditList(GoodsReceiveAuditListDTO dto)
         {
             //token验证

+ 147 - 0
OASystem/OASystem.Api/Controllers/ResourceController.cs

@@ -8,8 +8,10 @@ using OASystem.Domain.Dtos.Groups;
 using OASystem.Domain.Entities.Groups;
 using OASystem.Domain.ViewModels.Groups;
 using OASystem.Infrastructure.Repositories.Groups;
+using System.Collections.Generic;
 using System.Data;
 using System.Diagnostics;
+using System.Linq;
 using static OASystem.API.OAMethodLib.JWTHelper;
 
 namespace OASystem.API.Controllers
@@ -4659,6 +4661,151 @@ WHERE
             return Ok(await _mediaSupplierRep.SoftDel(dto));
         }
 
+        /// <summary>
+        /// 策划部供应商资料
+        /// excel导入
+        /// </summary>
+        /// <param name="file"></param>
+        /// <param name="currUserId">录入人userId</param>
+        /// <returns></returns>
+        [HttpPost]
+        [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
+        public async Task<IActionResult> MediaSupplierExcelImport(IFormFile file, [FromQuery] int currUserId = 258)
+        {
+            // 检查文件是否为空
+            if (file == null || file.Length == 0)
+            {
+                return Ok(JsonView(false,"请选择文件!"));
+            }
+
+            // 文件签名验证
+            var perExtensions = new[] { ".xls", ".xlsx" };
+            Dictionary<string, List<byte[]>> fileSignature = CommonFun.FileSignature;
+            fileSignature = fileSignature.Where(pair => perExtensions.Contains(pair.Key)).ToDictionary(pair => pair.Key, pair => pair.Value);
+
+            // 文件扩展名验证
+            var ext = Path.GetExtension(file.FileName).ToLowerInvariant();
+            if (string.IsNullOrEmpty(ext) || !fileSignature.ContainsKey(ext))
+            {
+                return Ok(JsonView(false, "不支持的文件类型!"));
+            }
+
+            using (var memoryStream = new MemoryStream())
+            {
+                await file.CopyToAsync(memoryStream);
+
+                // 检查文件签名
+                var fileData = memoryStream.ToArray();
+                var signatures = fileSignature[ext];
+                bool signatureValid = signatures.Any(signature =>
+                    fileData.Take(signature.Length).SequenceEqual(signature));
+
+                if (!signatureValid)
+                {
+                    return Ok(JsonView(false, "文件内容与类型不匹配!"));
+                }
+            }
+
+            // 保存文件到服务器
+            var uploadsFolder = @$"D:\FTP\File\OA2023\Office\Excel\MediaSupplierExcelImportFile";
+            if (!Directory.Exists(uploadsFolder))
+            {
+                Directory.CreateDirectory(uploadsFolder);
+            }
+
+            var fileName = CommonFun.ValidFileName(file.Name);
+
+            var filePath = Path.Combine(uploadsFolder, fileName);
+            using (var stream = new FileStream(filePath, FileMode.Create))
+            {
+                await file.CopyToAsync(stream);
+            }
+
+            Workbook workbook = new Workbook(filePath);
+
+            // 获取第一个工作表
+            Worksheet worksheet = workbook.Worksheets[0];
+
+            // 获取表头(第一行作为列名)
+            int headerRowIndex = 0; 
+            Row headerRow = worksheet.Cells.Rows[headerRowIndex];
+            int colCount = worksheet.Cells.MaxDataColumn + 1;
+
+            // 动态存储列名
+            var datas = new List<Res_MediaSuppliers>();
+
+            var typeDatas = await _sqlSugar.Queryable<Sys_SetData>()
+               .Where(x => x.IsDel == 0 && x.STid == 21)
+               .Select(x => new { x.Id, Text = x.Name })
+               .ToListAsync();
+
+            // 遍历数据行(从第二行开始)
+            int rowCount = worksheet.Cells.MaxDataRow + 1;
+            var msgs = new StringBuilder();
+            for (int row = headerRowIndex + 2; row < rowCount; row++)
+            {
+                var cellVal1 = worksheet.Cells[row, 0].Value;    //序号
+                var cellVal2 = worksheet.Cells[row, 1].Value;    //供应商类型
+                var cellVal3 = worksheet.Cells[row, 2].Value;    //地区
+                var cellVal4 = worksheet.Cells[row, 3].Value;    //城市
+                var cellVal5 = worksheet.Cells[row, 4].Value;    //单位名称
+                var cellVal6 = worksheet.Cells[row, 5].Value;    //单位联系人
+                var cellVal7 = worksheet.Cells[row, 6].Value;    //性别
+                var cellVal8 = worksheet.Cells[row, 7].Value;    //联系电话
+                var cellVal9 = worksheet.Cells[row, 8].Value;    //电子邮件
+                var cellVal10 = worksheet.Cells[row, 9].Value;   //单位缩写
+                var cellVal11 = worksheet.Cells[row, 10].Value;  //职位
+                var cellVal12 = worksheet.Cells[row, 11].Value;  //传真号码
+                var cellVal13 = worksheet.Cells[row, 12].Value;  //微信
+                var cellVal14 = worksheet.Cells[row, 13].Value;  //单位地址
+                var cellVal15 = worksheet.Cells[row, 14].Value;  //备注
+
+                int typeId = typeDatas.FirstOrDefault(x => x.Text == cellVal2?.ToString())?.Id ?? 0;
+                if (typeId < 1)
+                {
+                    var name = cellVal5?.ToString() ?? $"序号:{cellVal1?.ToString() ?? "-"}";
+                    msgs.AppendLine($"[{name}]未设置供应商类型!请手动录入!!!");
+                    continue;
+                }
+
+                var rowData = new Res_MediaSuppliers()
+                {
+                    TypeId = typeId,
+                    Privince = cellVal3?.ToString() ?? "",
+                    City = cellVal4?.ToString() ?? "",
+                    UnitName = cellVal5?.ToString() ?? "",
+                    Contact = cellVal6?.ToString() ?? "",
+                    Sex = string.IsNullOrEmpty(cellVal7?.ToString() ?? "") ? -1 : cellVal7.ToString().Equals("男") ? 0 : 1,
+                    Tel = cellVal8?.ToString() ?? "",
+                    Email = cellVal9?.ToString() ?? "",
+                    UnitAbbreviation = cellVal10?.ToString() ?? "",
+                    Post = cellVal11?.ToString() ?? "",
+                    Fax = cellVal12?.ToString() ?? "",
+                    WeChat = cellVal13?.ToString() ?? "",
+                    UnitAddress = cellVal14?.ToString() ?? "",
+                    Remark = cellVal15?.ToString() ?? "",
+                    CreateUserId = currUserId
+
+                };
+
+                datas.Add(rowData); // 将当前行数据添加到集合中
+            }
+
+            if (datas.Any())
+            {
+                var insert = await _sqlSugar.Insertable(datas).ExecuteCommandAsync();
+                if (insert > 0)
+                {
+                    return Ok(JsonView(true, $"导入成功!count:{insert} warningMsg:{msgs.ToString()}"));
+                }
+
+            }
+            return Ok(JsonView(false,"excel导入失败!"));
+        }
+
+
+
+
         #endregion
 
         #region 保险国家基础费用

+ 1 - 1
OASystem/OASystem.Infrastructure/Repositories/PersonnelModule/GoodsRepository.cs

@@ -3104,7 +3104,7 @@ FROM
                         details = text.ToString();
                     }
                 }
-                else details = $"归属团组:{item.GroupName} <br/><br/>物品名称:{item.GoodsName}   物品类型:{item.GoodsType}   领用数量:{item.Quantity}   备注:{item.Remark}<br/>";
+                else details = $"归属团组/类型:{item.GroupName} <br/><br/>物品名称:{item.GoodsName}   物品类型:{item.GoodsType}   领用数量:{item.Quantity}   备注:{item.Remark}<br/>";
 
                 item.GoodsDetails = details;
 

+ 37 - 1
OASystem/OASystem.Infrastructure/Tools/CommonFun.cs

@@ -1,4 +1,5 @@
-using Newtonsoft.Json;
+using MathNet.Numerics.Statistics;
+using Newtonsoft.Json;
 using Newtonsoft.Json.Linq;
 using OASystem.Domain.ViewModels.Groups;
 using System.Collections;
@@ -145,6 +146,41 @@ public static class CommonFun
 
         return new string(fileName.Where(c => !invalidChars.Contains(c)).ToArray());
     }
+
+    /// <summary>
+    /// 文件后缀名签名
+    /// </summary>
+    public static Dictionary<string, List<byte[]>> FileSignature => new Dictionary<string, List<byte[]>>
+        {
+            { ".jpeg", new List<byte[]>
+                {
+                    new byte[] { 0xFF, 0xD8, 0xFF, 0xE0 },
+                    new byte[] { 0xFF, 0xD8, 0xFF, 0xE2 },
+                    new byte[] { 0xFF, 0xD8, 0xFF, 0xE3 },
+                }
+            },
+            { ".png", new List<byte[]>
+                {
+                    new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }
+                }
+            },
+            { ".pdf", new List<byte[]>
+                {
+                    new byte[] { 0x25, 0x50, 0x44, 0x46 }
+                }
+            },
+            { ".xls", new List<byte[]>
+                { 
+                    new byte[] { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 } 
+                } 
+            },
+            { ".xlsx", new List<byte[]> 
+                { 
+                    new byte[] { 0x50, 0x4B, 0x03, 0x04 } 
+                } 
+            }
+        };
+
     #endregion
 
     #region IP