FileImportController.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. using Microsoft.AspNetCore.Http;
  2. using Microsoft.AspNetCore.Mvc;
  3. using Microsoft.Extensions.Options;
  4. using Ropin.Core.Extensions.Redis;
  5. using Ropin.Core.Extensions;
  6. using Ropin.Inspection.Api.Common.Options;
  7. using Ropin.Inspection.Api.Common.Token;
  8. using Ropin.Inspection.Service.Interface;
  9. using Ropin.Inspection.Service.SYS.Interface;
  10. using Ropin.Inspection.Service;
  11. using System.Net.Http;
  12. using Ropin.Inspection.Common.Helper;
  13. using NPOI.HSSF.UserModel;
  14. using NPOI.SS.UserModel;
  15. using NPOI.XSSF.UserModel;
  16. using Ropin.Inspection.Api.Common;
  17. using System.ComponentModel.DataAnnotations;
  18. using System.Linq;
  19. using System.Threading.Tasks;
  20. using log4net;
  21. using System.Collections.Generic;
  22. using System.ComponentModel;
  23. using System;
  24. using Ropin.Inspection.Model.ViewModel.ISP;
  25. using NPOI.Util;
  26. using System.Reflection;
  27. using Ropin.Inspection.Model.ViewModel;
  28. using Ropin.Inspection.Model;
  29. using Ropin.Inspection.Model.SearchModel;
  30. using Ropin.Inspection.Model.Entities;
  31. using Ropin.Inspection.Common.Accessor.Interface;
  32. using System.Security.Claims;
  33. using NPOI.OpenXmlFormats.Dml.Diagram;
  34. using NPOI.SS.Formula.Functions;
  35. using NPOI.SS.Util;
  36. using Newtonsoft.Json;
  37. namespace Ropin.Inspection.Api.Controllers.Base
  38. {
  39. public class FileImportController : BaseController
  40. {
  41. private static readonly ILog log = LogManager.GetLogger(typeof(FileImportController));
  42. private readonly IClaimsAccessor _claims;
  43. private readonly ITsysOrganizeService _tsysOrganizeService;
  44. private readonly ITpntStoreService _TpntStoreService;
  45. private readonly ITispContentService _tispContentService;
  46. private readonly ITispContentGroupService _tispContentGroupService;
  47. private readonly ITispContentGroupItemService _tispContentGroupItemService;
  48. public FileImportController(IClaimsAccessor claims,ITsysOrganizeService tsysOrganizeService, ITpntStoreService TpntStoreService, ITispContentService tispContentService, ITispContentGroupService tispContentGroupService, ITispContentGroupItemService tispContentGroupItemService)
  49. {
  50. _claims= claims;
  51. _tsysOrganizeService = tsysOrganizeService;
  52. _TpntStoreService= TpntStoreService;
  53. _tispContentService = tispContentService;
  54. _tispContentGroupService= tispContentGroupService;
  55. _tispContentGroupItemService= tispContentGroupItemService;
  56. }
  57. /// <summary>
  58. /// 导入巡检内容
  59. /// </summary>
  60. /// <param name="orgCode"></param>
  61. /// <param name="storeCode"></param>
  62. /// <param name="file"></param>
  63. /// <returns></returns>
  64. [HttpPost("ImportIspContent")]
  65. public async Task<ApiResult> ImportIspContent(string orgCode, string storeCode,[Required] IFormFile file)
  66. {
  67. if (string.IsNullOrEmpty(orgCode) || string.IsNullOrEmpty(storeCode))
  68. {
  69. return new ApiResult(ReturnCode.ArgsError);
  70. }
  71. if (file == null)
  72. {
  73. return new ApiResult(ReturnCode.ArgsError,"请上传导入文件");
  74. }
  75. try
  76. {
  77. Guid OrgId = Guid.Parse(orgCode);
  78. Guid StoreId = Guid.Parse(storeCode);
  79. TsysOrganizeViewModel orgEntity = await _tsysOrganizeService.GetByIdAsync(OrgId);
  80. TpntStoreViewModel storeEntity = await _TpntStoreService.GetByIdAsync(StoreId);
  81. if (orgEntity == null || storeEntity == null)
  82. {
  83. return new ApiResult(ReturnCode.ArgsError, "业主和组织获取失败");
  84. }
  85. List<ISPFIleImport> researchExcels = new List<ISPFIleImport>();
  86. IWorkbook wk = null;
  87. var exName = file.FileName.Split('.').Last().ToLower();
  88. if (exName == "xlsx")
  89. {
  90. wk = new XSSFWorkbook(file.OpenReadStream());
  91. }
  92. else
  93. {
  94. wk = new HSSFWorkbook(file.OpenReadStream());
  95. }
  96. //获取第一个sheet
  97. ISheet sheet = wk.GetSheetAt(0);
  98. //获取第二行
  99. IRow headrow2 = sheet.GetRow(1);
  100. var nameCell2 = headrow2.Cells.Where(x => x.ToString() == "使用部门:").FirstOrDefault();
  101. var valCell2 = headrow2.Cells[2].ToString();
  102. //获取第三行
  103. IRow headrow3 = sheet.GetRow(2);
  104. var nameCell3 = headrow3.Cells.Where(x => x.ToString() == "服务公司:").FirstOrDefault();
  105. var valCell3 = headrow3.Cells[2].ToString();
  106. if (nameCell2 is null || nameCell3 is null)
  107. {
  108. return new ApiResult(ReturnCode.ArgsError, "导入格式有误,请使用模板进行导入");
  109. }
  110. if ((storeEntity.C_Name.Trim() != valCell2 && storeEntity.C_SName?.Trim() != valCell2) || (orgEntity.C_SName?.Trim() != valCell3 && orgEntity.C_Name.Trim() != valCell3))
  111. {
  112. return new ApiResult(ReturnCode.ArgsError, "业主和组织验证失败");
  113. }
  114. // 存储已处理的合并区域
  115. List<CellRangeAddress> processedMergedRegions = new List<CellRangeAddress>();
  116. //获取第四行-标题行
  117. IRow headrow4 = sheet.GetRow(3);
  118. var researchExcel = new ISPFIleImport();
  119. var units = new List<string>();
  120. //读取每行,从第五行起
  121. for (int r = 4; r <= sheet.LastRowNum; r++)
  122. {
  123. var copyExcel = researchExcel.Copy();
  124. //获取当前行
  125. IRow row = sheet.GetRow(r);
  126. // 判断当前行是否有内容
  127. bool hasContent = row != null && row.Cells.Any(cell =>
  128. {
  129. if (cell == null) return false;
  130. var cellValue = cell.ToString().Trim();
  131. return !string.IsNullOrEmpty(cellValue);
  132. });
  133. if (!hasContent)
  134. {
  135. // 如果当前行没有内容,跳过当前循环
  136. continue;
  137. }
  138. //读取每列
  139. for (int j = 0; j < row.Cells.Count; j++)
  140. {
  141. ICell cell = row.GetCell(j); //一个单元格
  142. var cellValue = cell.ToString();
  143. var properties = copyExcel.GetType().GetProperties().ToList();
  144. // 检查单元格是否在合并区域内
  145. bool isMerged = false; bool isNewMergedRegion = false;
  146. CellRangeAddress currentMergedRegion = null;
  147. for (int i = 0; i < sheet.NumMergedRegions; i++)
  148. {
  149. CellRangeAddress mergedRegion = sheet.GetMergedRegion(i);
  150. if (mergedRegion.FirstRow <= r && mergedRegion.LastRow >= r && mergedRegion.FirstColumn <= j && mergedRegion.LastColumn >= j)
  151. {
  152. isMerged = true;
  153. currentMergedRegion = mergedRegion;
  154. break;
  155. }
  156. }
  157. if (isMerged && r > 1)
  158. {
  159. // 判断是否为新的合并区域
  160. isNewMergedRegion = !processedMergedRegions.Contains(currentMergedRegion);
  161. if (isNewMergedRegion)
  162. {
  163. // 若为新的合并区域,添加到已处理列表
  164. processedMergedRegions.Add(currentMergedRegion);
  165. }
  166. }
  167. foreach (var x in properties)
  168. {
  169. if (x.IsDefined(typeof(DescriptionAttribute)))
  170. {
  171. //如果是合并行且不是第一列(第一列要拿数据的) cell.IsMergedCell
  172. if (isMerged && r > 1)
  173. {
  174. var value = x.GetValue(copyExcel)?.ToString();
  175. //新行不是空且与旧值不想等,则重新赋值.合并行后当前行数据是空.
  176. if ((!string.IsNullOrEmpty(cellValue) && cellValue != value) || isNewMergedRegion)
  177. {
  178. var attribute = x.GetCustomAttribute<DescriptionAttribute>();
  179. if (attribute.Description == headrow4.GetCell(j).ToString())
  180. {
  181. x.SetValue(copyExcel, cellValue);
  182. researchExcel = copyExcel;
  183. continue;
  184. }
  185. }
  186. }
  187. else
  188. {
  189. var attribute = x.GetCustomAttribute<DescriptionAttribute>();
  190. if (attribute.Description == headrow4.GetCell(j).ToString())
  191. {
  192. x.SetValue(copyExcel, cellValue);
  193. continue;
  194. }
  195. }
  196. }
  197. }
  198. }
  199. researchExcel = copyExcel;
  200. if (string.IsNullOrEmpty(copyExcel.Column4))
  201. {
  202. throw new Exception("巡检内容不能为空");
  203. }
  204. var copyExcel0 = copyExcel.Copy();
  205. // 检查 Column0 是否已存在
  206. var IsExist = researchExcels.Where(excel => excel.Column0.StartsWith(copyExcel.Column0)).ToList();
  207. if (IsExist != null && IsExist.Count > 0)
  208. {
  209. copyExcel0.Column0 += "-" + IsExist.Count;
  210. }
  211. researchExcels.Add(copyExcel0);
  212. }
  213. var content = researchExcels.Select(x => new { x.Column0, x.Column4, x.Column5 }).Distinct().ToList();
  214. var contentGroup = researchExcels.Select(x => new { x.Column1, x.Column2, x.Column3, x.Column6 }).Distinct().ToList();
  215. var contentList = await _tispContentService.GetAllAsync(storeCode);
  216. TispContentGroupsSearchModel searchModel = new TispContentGroupsSearchModel();
  217. searchModel.C_StoreCode = storeCode;
  218. var contentGroupList = await _tispContentGroupService.GetContentGroupsAsync(searchModel);
  219. List<TISP_Content> contentArray = new List<TISP_Content>();
  220. List<TISP_ContentGroup> contentGroupArray = new List<TISP_ContentGroup>();
  221. List<TISP_ContentGroupItem> groupItemArray = new List<TISP_ContentGroupItem>();
  222. foreach (var item in content)
  223. {
  224. int sort = 0;
  225. if (!string.IsNullOrEmpty(item.Column0))
  226. {
  227. sort = UtilConvert.GetIntByStr(item.Column0);
  228. }
  229. var contentModel = contentList.Where(c => c.C_Name == item.Column4).FirstOrDefault();
  230. if (contentModel == null)
  231. {
  232. TISP_Content contentAdd = new TISP_Content
  233. {
  234. C_ID = Guid.NewGuid(),
  235. C_StoreCode = storeCode,
  236. C_Name = item.Column4,
  237. C_AlarmLevel = "1",//1=轻;2 = 中;3 = 重
  238. C_Number = item.Column0,
  239. I_Sort = sort,
  240. C_Remark = item.Column5,
  241. C_CreateBy = _claims.ApiUserId,
  242. D_CreateOn = DateTime.Now,
  243. C_Status = "1",
  244. };
  245. contentArray.Add(contentAdd);
  246. }
  247. }
  248. foreach (var item in contentGroup)
  249. {
  250. int type = 1;
  251. //1=防火检查记录表(周);2 = 隐患整改验收单;3 = 消防设施每周检查记录;4 = 防火巡查记录表
  252. switch (item.Column1)
  253. {
  254. case "防火检查记录表(周)": type = 1; break;
  255. case "隐患整改验收单": type = 2; break;
  256. case "消防设施每周检查记录": type = 3; break;
  257. case "防火巡查记录表": type = 4; break;
  258. }
  259. int sort = 0;
  260. var GroupModel = contentGroupList.Where(g => g.C_Name == item.Column2 && g.I_Type == type && g.C_PatrolItem == item.Column3).FirstOrDefault();
  261. TISP_ContentGroup contentGroupAdd = null;
  262. if (GroupModel == null)
  263. {
  264. contentGroupAdd = new TISP_ContentGroup
  265. {
  266. G_ID = Guid.NewGuid(),
  267. C_StoreCode = storeCode,
  268. C_Name = item.Column2,
  269. I_Sort = sort,
  270. C_Remark = item.Column6,
  271. I_Type = type,
  272. C_PatrolItem = item.Column3,
  273. G_CreateBy = _claims.ApiUserId,
  274. D_CreateOn = DateTime.Now,
  275. C_Status = "1",
  276. };
  277. contentGroupArray.Add(contentGroupAdd);
  278. }
  279. }
  280. foreach (var item in researchExcels)
  281. {
  282. int type = 1;
  283. //1=防火检查记录表(周);2 = 隐患整改验收单;3 = 消防设施每周检查记录;4 = 防火巡查记录表
  284. switch (item.Column1)
  285. {
  286. case "防火检查记录表(周)": type = 1; break;
  287. case "隐患整改验收单": type = 2; break;
  288. case "消防设施每周检查记录": type = 3; break;
  289. case "防火巡查记录表": type = 4; break;
  290. }
  291. Guid contentGroupId = new Guid(), contentId = new Guid();
  292. if (contentArray.Count > 0)
  293. {
  294. var ccmodel = contentArray.Where(c => c.C_Name == item.Column4).FirstOrDefault();
  295. if (ccmodel != null) { contentId = ccmodel.C_ID; }
  296. }
  297. if (contentGroupArray.Count > 0)
  298. {
  299. var cgModel = contentGroupArray.Where(g => g.C_Name == item.Column2 && g.I_Type == type && g.C_PatrolItem == item.Column3).FirstOrDefault();
  300. if (cgModel!=null) { contentGroupId = cgModel.G_ID; }
  301. }
  302. if (Guid.Empty == contentId && contentList.Count() > 0)
  303. {
  304. var ccModel = contentList.Where(c => c.C_Name == item.Column4).FirstOrDefault();
  305. if (ccModel != null) { contentId = ccModel.C_ID; }
  306. }
  307. if (Guid.Empty == contentGroupId && contentGroupList.Count() > 0)
  308. {
  309. var cgModel= contentGroupList.Where(g => g.C_Name == item.Column2 && g.I_Type == type && g.C_PatrolItem == item.Column3).FirstOrDefault();
  310. if (cgModel != null) { contentGroupId = cgModel.G_ID; }
  311. }
  312. if (Guid.Empty != contentId && Guid.Empty != contentGroupId)
  313. {
  314. var ItemList = await _tispContentGroupItemService.GetContentGroupItemByIdAsync(contentGroupId, contentId);
  315. if (ItemList == null || ItemList.Count() == 0)
  316. {
  317. var groupItemAdd = new TISP_ContentGroupItem
  318. {
  319. G_ID = Guid.NewGuid(),
  320. G_ContentGroupCode = contentGroupId,
  321. G_ContentCode = contentId
  322. };
  323. groupItemArray.Add(groupItemAdd);
  324. }
  325. }
  326. }
  327. if (contentArray.Count == 0 && contentGroupArray.Count == 0 && groupItemArray.Count == 0)
  328. {
  329. return new ApiResult(ReturnCode.GeneralError, "要导入的数据已经存在!");
  330. }
  331. else
  332. {
  333. bool result = await _tispContentService.CreateIspContent(contentArray, contentGroupArray, groupItemArray);
  334. if (result)
  335. {
  336. return new ApiResult(ReturnCode.Success);
  337. }
  338. else
  339. {
  340. return new ApiResult(ReturnCode.GeneralError);
  341. }
  342. }
  343. }
  344. catch (Exception ex)
  345. {
  346. return new ApiResult(ReturnCode.GeneralError,ex.Message);
  347. }
  348. }
  349. }
  350. }