944 lines
50 KiB
C#
944 lines
50 KiB
C#
using Backend.Models;
|
||
using Microsoft.AspNetCore.Http;
|
||
using Microsoft.AspNetCore.Mvc;
|
||
using Microsoft.Extensions.Logging;
|
||
using NPOI.HSSF.UserModel;
|
||
using NPOI.SS.UserModel;
|
||
using NPOI.XSSF.UserModel;
|
||
using Repository.BackendRepository.Interface;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using System.Text.Json;
|
||
using System.Threading.Tasks;
|
||
|
||
namespace Backend.Controllers
|
||
{
|
||
public class DeviceImportController : MybaseController<DeviceImportController>
|
||
{
|
||
private readonly IBackendRepository backendRepository;
|
||
private readonly IDeviceImportRepository deviceImportRepository;
|
||
|
||
public DeviceImportController(IBackendRepository backendRepository, IDeviceImportRepository deviceImportRepository)
|
||
{
|
||
this.backendRepository = backendRepository;
|
||
this.deviceImportRepository = deviceImportRepository;
|
||
}
|
||
|
||
|
||
public IActionResult Index()
|
||
{
|
||
return View();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 設備匯入列表
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<ApiResult<List<DeviceImport>>> RawDataList()
|
||
{
|
||
ApiResult<List<DeviceImport>> apiResult = new ApiResult<List<DeviceImport>>();
|
||
List<DeviceImport> deviceImports = new List<DeviceImport>();
|
||
|
||
try
|
||
{
|
||
deviceImports = await backendRepository.GetAllAsync<DeviceImport>("device_import_temp", null, null, "device_result DESC,created_at DESC");
|
||
|
||
apiResult.Code = "0000";
|
||
apiResult.Data = deviceImports;
|
||
}
|
||
catch (Exception exception)
|
||
{
|
||
apiResult.Code = "9999";
|
||
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
|
||
}
|
||
|
||
return apiResult;
|
||
}
|
||
|
||
|
||
[HttpPost]
|
||
public async Task<ApiResult<string>> ImportRawDataFile(IFormFile[] import_files)
|
||
{
|
||
ApiResult<string> apiResult = new ApiResult<string>();
|
||
|
||
try
|
||
{
|
||
Dictionary<string, IWorkbook> workbooks = new Dictionary<string, IWorkbook>();
|
||
|
||
//List<IWorkbook> workbooks = new List<IWorkbook>();
|
||
|
||
#region 檢驗各檔案是否正確
|
||
foreach (var import_file in import_files)
|
||
{
|
||
IWorkbook workbook;
|
||
|
||
var filename_ext = Path.GetExtension(import_file.FileName).ToLower();
|
||
|
||
if (filename_ext == ".xls")
|
||
{
|
||
workbook = new HSSFWorkbook(import_file.OpenReadStream());
|
||
workbooks.Add($"{import_file.FileName}", workbook);
|
||
}
|
||
else if (filename_ext == ".xlsx")
|
||
{
|
||
workbook = new XSSFWorkbook(import_file.OpenReadStream());
|
||
workbooks.Add($"{import_file.FileName}", workbook);
|
||
}
|
||
else
|
||
{
|
||
workbook = null;
|
||
}
|
||
|
||
if (workbook == null)
|
||
{
|
||
apiResult.Code = "9998";
|
||
apiResult.Msg = $"{import_file.FileName}該檔案失效,請重新操作。";
|
||
|
||
return apiResult;
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
List<Dictionary<string, object>> deviceImports = new List<Dictionary<string, object>>();
|
||
|
||
//抓取系統類別(以供驗證判斷)
|
||
var sWhere = @$"deleted = 0 AND system_type = @system_type";
|
||
var system_category_param = new { system_type = "device_system_category_layer3" };
|
||
var system_categories_layer3 = await backendRepository.GetAllAsync<Variable>("variable", sWhere, system_category_param);
|
||
|
||
var disaster_param = new { system_type = "disaster" };
|
||
var disasters = await backendRepository.GetAllAsync<Variable>("variable", sWhere, disaster_param);
|
||
var temp_building = ""; //預設的棟別(檢查用,整份excel需相同),目前只針對單一檔案情況,如後續有需再改成多檔情況。
|
||
|
||
#region 抓取每個檔案的資料
|
||
foreach (var keyValuePair in workbooks)
|
||
{
|
||
IWorkbook workbook = keyValuePair.Value;
|
||
|
||
var total_sheet = workbook.NumberOfSheets;
|
||
for (var sheet_num = 2; sheet_num < total_sheet - 1; sheet_num++)
|
||
{
|
||
var tags_name_index = -1;
|
||
var system_category_index = -1; //系統類別
|
||
var disaster_index = -1; //緊急應變程序(等同災害類別)
|
||
var sheet = workbook.GetSheetAt(sheet_num);
|
||
|
||
//表頭
|
||
IRow header = sheet.GetRow(sheet.FirstRowNum);
|
||
List<int> columns = new List<int>();
|
||
if (header != null)
|
||
{
|
||
for (int i = 0; i < header.LastCellNum; i++)
|
||
{
|
||
ICell cell = header.GetCell(i);
|
||
if (cell != null)
|
||
{
|
||
var header_str = cell.ToString().ToLower();
|
||
if (!string.IsNullOrEmpty(header_str) && header_str == "tags name")
|
||
{
|
||
tags_name_index = i;
|
||
}
|
||
if (!string.IsNullOrEmpty(header_str) && header_str == "系統類別")
|
||
{
|
||
system_category_index = i;
|
||
}
|
||
if (!string.IsNullOrEmpty(header_str) && header_str == "系統程式軟體")
|
||
{
|
||
IRow sub_header = sheet.GetRow(1);
|
||
|
||
for (int j = 0; j < sub_header.LastCellNum; j++)
|
||
{
|
||
ICell sub_cell = sub_header.GetCell(j);
|
||
var sub_header_str = sub_cell.ToString().ToLower();
|
||
if (!string.IsNullOrEmpty(sub_header_str) && sub_header_str == "緊急應變程序")
|
||
{
|
||
disaster_index = j;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (tags_name_index > 0 && system_category_index > 0 && disaster_index > 0)
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//資料
|
||
if (tags_name_index < 0 || system_category_index < 0 || disaster_index < 0)
|
||
{
|
||
List<string> errMsg = new List<string>();
|
||
var result = $@"查無[{keyValuePair.Key}]在[{workbook.GetSheetName(sheet_num)}]分頁的";
|
||
|
||
if (tags_name_index < 0)
|
||
{
|
||
errMsg.Add($@"[tags name]");
|
||
}
|
||
|
||
if (system_category_index < 0)
|
||
{
|
||
errMsg.Add($@"[系統類別]");
|
||
}
|
||
|
||
if (disaster_index < 0)
|
||
{
|
||
errMsg.Add($@"[緊急應變程序]");
|
||
}
|
||
|
||
Dictionary<string, object> deviceImport = new Dictionary<string, object>()
|
||
{
|
||
{ "@device_number", null},
|
||
{ "@device_system_category_layer3", null},
|
||
{ "@device_disaster", null},
|
||
{ "@device_result", result + String.Join("、", errMsg)}
|
||
};
|
||
|
||
deviceImports.Add(deviceImport);
|
||
}
|
||
else
|
||
{
|
||
for (var i = sheet.FirstRowNum + 2; i < sheet.LastRowNum; i++)
|
||
{
|
||
|
||
IRow row = sheet.GetRow(i);
|
||
if (row != null)
|
||
{
|
||
List<string> errMsg = new List<string>();
|
||
Dictionary<string, object> deviceImport = new Dictionary<string, object>();
|
||
|
||
ICell tags_name_cell = row.GetCell(tags_name_index);
|
||
if (tags_name_cell != null)
|
||
{
|
||
var tempData = tags_name_cell.ToString().Trim();
|
||
var system_category = string.Empty;
|
||
var disaster = string.Empty;
|
||
if (!string.IsNullOrEmpty(tempData))
|
||
{
|
||
var arr_tempData = tempData.Split('_');
|
||
|
||
#region tags name驗證條件
|
||
if (string.IsNullOrEmpty(temp_building)) //抓第一筆當作該excel 比對棟別的依據
|
||
{
|
||
temp_building = arr_tempData[0];
|
||
}
|
||
else
|
||
{
|
||
if (temp_building != arr_tempData[0])
|
||
{
|
||
errMsg.Add("資料棟別錯誤");
|
||
}
|
||
}
|
||
|
||
if (arr_tempData.Length != 5)
|
||
{
|
||
errMsg.Add("資料格式錯誤");
|
||
}
|
||
|
||
if (arr_tempData[arr_tempData.Length - 1].Contains('~'))
|
||
{
|
||
errMsg.Add("設備流水號格式錯誤");
|
||
}
|
||
|
||
if (arr_tempData[arr_tempData.Length - 1].Split('~').Length > 2)
|
||
{
|
||
errMsg.Add("設備流水號格式錯誤");
|
||
}
|
||
#endregion
|
||
|
||
#region 系統類別驗證條件
|
||
ICell system_category_cell = row.GetCell(system_category_index);
|
||
if (system_category_cell == null)
|
||
{
|
||
errMsg.Add(@"該設備的[系統類別]未填值");
|
||
}
|
||
else
|
||
{
|
||
system_category = system_category_cell.ToString().Trim();
|
||
if (!string.IsNullOrEmpty(system_category))
|
||
{
|
||
var exist = system_categories_layer3.Exists(x => x.system_value == system_category);
|
||
if (!exist)
|
||
{
|
||
errMsg.Add(@"該設備的[系統類別]不存在");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
errMsg.Add(@"該設備的[系統類別]未填值");
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#region 緊急應變程序驗證條件
|
||
ICell disaster_cell = row.GetCell(disaster_index);
|
||
if (disaster_cell == null)
|
||
{
|
||
errMsg.Add(@"該設備的[緊急應變程序]未填值");
|
||
}
|
||
else
|
||
{
|
||
disaster = disaster_cell.ToString().Trim();
|
||
if (!string.IsNullOrEmpty(disaster))
|
||
{
|
||
if (disaster != "0")
|
||
{
|
||
var exist = disasters.Exists(x => x.system_value == disaster);
|
||
if (!exist)
|
||
{
|
||
errMsg.Add(@"該設備的[緊急應變程序]不存在");
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
errMsg.Add(@"該設備的[緊急應變程序]未填值");
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
if (errMsg.Count > 0)
|
||
{
|
||
deviceImport.Add("@device_number", tempData);
|
||
deviceImport.Add("@device_system_category_layer3", system_category);
|
||
deviceImport.Add("@device_disaster", disaster);
|
||
deviceImport.Add("@device_result", String.Join(", ", errMsg));
|
||
}
|
||
else
|
||
{
|
||
deviceImport.Add("@device_number", tempData);
|
||
deviceImport.Add("@device_system_category_layer3", system_category);
|
||
deviceImport.Add("@device_disaster", disaster);
|
||
deviceImport.Add("@device_result", null);
|
||
}
|
||
|
||
deviceImports.Add(deviceImport);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
deviceImports = deviceImports.Distinct().ToList();
|
||
|
||
//先刪除整份資料表
|
||
var sql = @"IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[device_import_temp]') AND type in (N'U'))
|
||
BEGIN
|
||
DROP TABLE [dbo].[device_import_temp];
|
||
END
|
||
CREATE TABLE [dbo].[device_import_temp](
|
||
[id] [int] IDENTITY(1,1) NOT NULL,
|
||
[device_number] [nvarchar](255) NULL,
|
||
[device_system_category_layer3] [varchar](50) NULL,
|
||
[device_disaster] [varchar](50) NULL,
|
||
[device_result] [nvarchar](255) NULL,
|
||
[created_at] [datetime] NULL,
|
||
CONSTRAINT [PK_device_import_temp] PRIMARY KEY CLUSTERED
|
||
(
|
||
[id] ASC
|
||
))
|
||
ALTER TABLE [dbo].[device_import_temp] ADD CONSTRAINT [DF_device_import_temp_device_disaster] DEFAULT ((0)) FOR [device_disaster]
|
||
ALTER TABLE [dbo].[device_import_temp] ADD CONSTRAINT [DF_device_import_temp_created_at] DEFAULT (getdate()) FOR [created_at]
|
||
";
|
||
await backendRepository.ExecuteSql(sql);
|
||
|
||
//如有發現錯誤,直接insert 至 device_import_temp,不做後續處理
|
||
await backendRepository.AddMutiByCustomTable(deviceImports, "device_import_temp");
|
||
|
||
//var err = deviceImports.Where(x => x.ContainsKey("@device_result")).Select(x => x.Values).ToList();
|
||
var err = deviceImports.SelectMany(x => x).Where(x => x.Key == "@device_result" && x.Value != null).ToList();
|
||
if (err.Count > 0)
|
||
{
|
||
apiResult.Code = "9997";
|
||
apiResult.Msg = "資料內容有誤,請重新匯入。";
|
||
|
||
return apiResult;
|
||
}
|
||
else
|
||
{
|
||
//拆分每一份資料
|
||
List<Dictionary<string, object>> deviceImportChecks = new List<Dictionary<string, object>>(); //檢查OK的列表
|
||
|
||
|
||
foreach (var deviceImport in deviceImports)
|
||
{
|
||
|
||
object device_number = null;
|
||
object device_system_category_layer3 = null;
|
||
object device_disaster = null;
|
||
deviceImport.TryGetValue("@device_number", out device_number);
|
||
deviceImport.TryGetValue("@device_system_category_layer3", out device_system_category_layer3);
|
||
deviceImport.TryGetValue("@device_disaster", out device_disaster);
|
||
|
||
var arr_device_number = device_number.ToString().Split('_');
|
||
|
||
//抓出是否為組數的設備
|
||
var arr_device_number_final_col = arr_device_number[arr_device_number.Length - 1].Contains('~') ? arr_device_number[arr_device_number.Length - 1].Split('~') : null;
|
||
if (arr_device_number_final_col != null && arr_device_number_final_col.Length > 0)
|
||
{
|
||
var start_num = Convert.ToInt32(arr_device_number_final_col[0].Trim());
|
||
var end_num = Convert.ToInt32(arr_device_number_final_col[1].Trim());
|
||
for (var i = start_num; i <= end_num; i++)
|
||
{
|
||
Dictionary<string, object> deviceImportCheck = new Dictionary<string, object>();
|
||
var pre_device_number = String.Join('_', arr_device_number, 0, 4);
|
||
deviceImportCheck.Add("@device_building_tag", arr_device_number[0]); //設備區域
|
||
deviceImportCheck.Add("@device_system_tag", arr_device_number[1]); //設備系統別
|
||
deviceImportCheck.Add("@device_floor_tag", arr_device_number[2]); //設備樓層
|
||
deviceImportCheck.Add("@device_name_tag", arr_device_number[3]); //設備名稱
|
||
|
||
var pad = string.Empty;
|
||
if (i < 10)
|
||
{
|
||
pad = i.ToString().PadLeft(2, '0');
|
||
}
|
||
else
|
||
{
|
||
pad = i.ToString();
|
||
}
|
||
deviceImportCheck.Add("@device_serial_tag", pad); //設備流水號
|
||
|
||
deviceImportCheck.Add("@device_number", pre_device_number + "_" + pad); //設備完整編號
|
||
deviceImportCheck.Add("@device_system_category_layer3", device_system_category_layer3.ToString()); //系統類別(第3層)
|
||
deviceImportCheck.Add("@device_disaster", device_disaster.ToString()); //緊急應變程序
|
||
deviceImportCheck.Add("@is_correct", 0); //驗證是否正確
|
||
|
||
deviceImportChecks.Add(deviceImportCheck);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
Dictionary<string, object> deviceImportCheck = new Dictionary<string, object>();
|
||
var pre_device_number = String.Join('_', arr_device_number, 0, 3);
|
||
deviceImportCheck.Add("@device_building_tag", arr_device_number[0]); //設備區域
|
||
deviceImportCheck.Add("@device_system_tag", arr_device_number[1]); //設備系統別
|
||
deviceImportCheck.Add("@device_floor_tag", arr_device_number[2]); //設備樓層
|
||
deviceImportCheck.Add("@device_name_tag", arr_device_number[3]); //設備名稱
|
||
deviceImportCheck.Add("@device_serial_tag", arr_device_number[4]); //設備流水號
|
||
deviceImportCheck.Add("@device_number", device_number); //設備完整編號
|
||
deviceImportCheck.Add("@device_system_category_layer3", device_system_category_layer3.ToString()); //系統類別(第3層)
|
||
deviceImportCheck.Add("@device_disaster", device_disaster.ToString()); //緊急應變程序
|
||
deviceImportCheck.Add("@is_correct", 0); //驗證是否正確
|
||
|
||
deviceImportChecks.Add(deviceImportCheck);
|
||
}
|
||
|
||
}
|
||
|
||
//針對棟別刪除檢查OK的設備查詢表
|
||
var sDeleteWhere = $@"device_building_tag = '{temp_building}'";
|
||
await backendRepository.PurgeOneByGuidWithCustomDBNameAndTable("device_import_ckeck_temp", sDeleteWhere);
|
||
|
||
//var sql_check = @"IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[device_import_ckeck_temp]') AND type in (N'U'))
|
||
// BEGIN
|
||
// DROP TABLE [dbo].[device_import_ckeck_temp]
|
||
// END
|
||
// CREATE TABLE [dbo].[device_import_ckeck_temp](
|
||
// [id] [int] IDENTITY(1,1) NOT NULL,
|
||
// [device_building_tag] [nvarchar](50) NULL,
|
||
// [device_system_tag] [nvarchar](50) NULL,
|
||
// [device_floor_tag] [nvarchar](50) NULL,
|
||
// [device_kind] [nvarchar](50) NULL,
|
||
// [device_name_tag] [nvarchar](50) NULL,
|
||
// [device_serial_tag] [nvarchar](50) NULL,
|
||
// [device_number] [nvarchar](255) NULL,
|
||
// [device_system_category_layer3] [varchar](50) NULL,
|
||
// [device_disaster] [varchar](50) NULL,
|
||
// [created_at] [datetime] NULL,
|
||
// CONSTRAINT [PK_device_import_ckeck_temp] PRIMARY KEY CLUSTERED
|
||
// (
|
||
// [id] ASC
|
||
// ))
|
||
|
||
// ALTER TABLE [dbo].[device_import_ckeck_temp] ADD CONSTRAINT [DF_device_import_ckeck_temp_device_disaster] DEFAULT ((0)) FOR [device_disaster]
|
||
// ALTER TABLE [dbo].[device_import_ckeck_temp] ADD CONSTRAINT [DF_device_import_ckeck_temp_created_at] DEFAULT (getdate()) FOR [created_at]
|
||
// ";
|
||
//await backendRepository.ExecuteSql(sql_check);
|
||
|
||
//檢查正確才寫入至check_temp資料表
|
||
await backendRepository.AddMutiByCustomTable(deviceImportChecks, "device_import_ckeck_temp");
|
||
}
|
||
|
||
apiResult.Code = "0000";
|
||
apiResult.Msg = "匯入成功";
|
||
#endregion
|
||
}
|
||
catch (Exception exception)
|
||
{
|
||
apiResult.Code = "9999";
|
||
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
|
||
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
|
||
}
|
||
|
||
return apiResult;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 取得設備檢核上方過濾選單
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<ApiResult<List<DeviceCheckFilter>>> GetRawDataCheckFilter()
|
||
{
|
||
ApiResult<List<DeviceCheckFilter>> apiResult = new ApiResult<List<DeviceCheckFilter>>();
|
||
|
||
try
|
||
{
|
||
string sql = $@"
|
||
SELECT
|
||
ct.device_building_tag,
|
||
ct.device_system_tag,
|
||
ct.device_system_category_layer3
|
||
FROM device_import_ckeck_temp ct
|
||
GROUP BY ct.device_building_tag, ct.device_system_tag, ct.device_system_category_layer3
|
||
";
|
||
|
||
var deviceCheckFilterRawDatas = await backendRepository.GetAllAsync<DeviceCheckFilterRawData>(sql);
|
||
|
||
List<DeviceCheckFilter> deviceCheckFilters = new List<DeviceCheckFilter>();
|
||
|
||
var deviceCheckFilterRawData_Group_Building_tag = deviceCheckFilterRawDatas.GroupBy(x => x.Device_building_tag).ToList();
|
||
foreach (var deviceCheckFilterRawData_Building_tag in deviceCheckFilterRawData_Group_Building_tag)
|
||
{
|
||
DeviceCheckFilter deviceCheckFilter = new DeviceCheckFilter();
|
||
deviceCheckFilter.Building_tag = deviceCheckFilterRawData_Building_tag.Key;
|
||
|
||
var sql_amount = @"SELECT COUNT(*) FROM device_import_ckeck_temp WHERE device_building_tag = @Device_building_tag";
|
||
deviceCheckFilter.Building_amount = await backendRepository.GetOneAsync<int>(sql_amount, new { Device_building_tag = deviceCheckFilterRawData_Building_tag.Key });
|
||
|
||
deviceCheckFilter.System_tags = new List<DeviceCheckSystemTag>();
|
||
|
||
var deviceCheckFilterRawData_Group_System_tag = deviceCheckFilterRawData_Building_tag.GroupBy(x => x.Device_system_tag).ToList();
|
||
foreach (var deviceCheckFilterRawData_System_tag in deviceCheckFilterRawData_Group_System_tag)
|
||
{
|
||
DeviceCheckSystemTag deviceCheckSystemTag = new DeviceCheckSystemTag();
|
||
deviceCheckSystemTag.System_tag = deviceCheckFilterRawData_System_tag.Key;
|
||
deviceCheckSystemTag.System_categories = new List<string>();
|
||
|
||
var deviceCheckFilterRawData_Group_System_category = deviceCheckFilterRawData_System_tag.GroupBy(x => x.Device_system_category_layer3).ToList();
|
||
foreach (var deviceCheckFilterRawData_System_category in deviceCheckFilterRawData_Group_System_category)
|
||
{
|
||
deviceCheckSystemTag.System_categories.Add(deviceCheckFilterRawData_System_category.Key);
|
||
}
|
||
|
||
deviceCheckFilter.System_tags.Add(deviceCheckSystemTag);
|
||
}
|
||
|
||
deviceCheckFilters.Add(deviceCheckFilter);
|
||
}
|
||
|
||
|
||
apiResult.Code = "0000";
|
||
apiResult.Data = deviceCheckFilters;
|
||
}
|
||
catch (Exception exception)
|
||
{
|
||
apiResult.Code = "9999";
|
||
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
|
||
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
|
||
}
|
||
|
||
return apiResult;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 資料檢核表格
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<ApiResult<DeviceCheck>> DeviceCheckTableList(PostDeviceCheckFilter post)
|
||
{
|
||
ApiResult<DeviceCheck> apiResult = new ApiResult<DeviceCheck>();
|
||
|
||
try
|
||
{
|
||
string sWhere = "";
|
||
string sSubTableWhere = " WHERE {0}.device_building_tag = @Device_building_tag";
|
||
if (post.Abnormal == "all")
|
||
{ //異常分類 為全選的時候,才可以指定選擇系統別、設備分類
|
||
if (post.System_tag != "all")
|
||
{
|
||
sSubTableWhere += " AND {0}.device_system_tag = @Device_system_tag";
|
||
}
|
||
if (post.System_category != "all")
|
||
{
|
||
sSubTableWhere += " AND {0}.device_system_category_layer3 = @Device_system_category_layer3";
|
||
}
|
||
}
|
||
else
|
||
{
|
||
sWhere += @"WHERE ct.device_number IS NULL AND d.device_number IS NOT NULL
|
||
-- OR ct.device_system_category_layer3 != d.device_system_category_layer3
|
||
-- OR ct.disaster_system_value != d.device_disaster";
|
||
}
|
||
|
||
string sql_temp = $@"
|
||
SELECT
|
||
ct.device_number AS check_temp_device_number,
|
||
ct.device_system_category_layer3 AS check_temp_device_system_category_layer3,
|
||
ct.system_category_system_key AS check_temp_device_system_category_layer3_key,
|
||
ct.disaster_system_value AS check_temp_disaster,
|
||
ct.disaster_system_key AS check_temp_disaster_key,
|
||
d.device_number,
|
||
d.device_system_category_layer3 AS device_system_category_layer3,
|
||
d.system_key AS device_system_category_layer3_key,
|
||
d.device_disaster,
|
||
d.device_disaster_type_text,
|
||
d.device_coordinate,
|
||
CASE
|
||
WHEN ct.device_number = d.device_number
|
||
THEN 0
|
||
ELSE 1
|
||
END AS compare_device_number,
|
||
CASE
|
||
WHEN ct.device_system_category_layer3 = d.device_system_category_layer3
|
||
THEN 0
|
||
ELSE 1
|
||
END AS compare_system_category_layer3,
|
||
CASE
|
||
WHEN ct.disaster_system_value = d.device_disaster
|
||
THEN 0
|
||
ELSE 1
|
||
END AS compare_device_disaster
|
||
FROM (
|
||
SELECT
|
||
ct.* ,
|
||
v.system_type AS system_category_system_type,
|
||
v.system_key AS system_category_system_key,
|
||
v.system_value AS system_category_system_value,
|
||
v2.system_type AS disaster_system_type,
|
||
v2.system_key AS disaster_system_key,
|
||
v2.system_value AS disaster_system_value
|
||
FROM device_import_ckeck_temp ct
|
||
LEFT JOIN variable v ON v.system_type = 'device_system_category_layer3' AND ct.device_system_category_layer3 = v.system_value
|
||
LEFT JOIN variable v2 ON v2.system_type = 'disaster' AND v2.system_value = ct.device_disaster
|
||
{{0}}
|
||
) ct
|
||
FULL JOIN (
|
||
SELECT
|
||
d.* ,
|
||
v.system_type,
|
||
v.system_key,
|
||
v.system_value,
|
||
(SELECT
|
||
STRING_AGG( ISNULL(system_value, ' '), ',')
|
||
FROM device_disaster dd
|
||
JOIN variable v ON v.deleted = 0 AND v.system_type = 'disaster' AND v.system_value = dd.device_system_value
|
||
WHERE dd.device_guid = d.device_guid
|
||
) AS device_disaster,
|
||
(SELECT
|
||
STRING_AGG( ISNULL(system_key, ' '), ',')
|
||
FROM device_disaster dd
|
||
JOIN variable v ON v.deleted = 0 AND v.system_type = 'disaster' AND v.system_value = dd.device_system_value
|
||
WHERE dd.device_guid = d.device_guid
|
||
) AS device_disaster_type_text
|
||
FROM device d
|
||
LEFT JOIN variable v ON v.system_type = 'device_system_category_layer3' AND d.device_system_category_layer3 = v.system_value
|
||
{{1}}
|
||
AND d.deleted = 0
|
||
|
||
)d ON ct.device_number = d.device_number
|
||
{{2}}
|
||
ORDER BY d.device_number DESC
|
||
";
|
||
|
||
var sql = string.Format(sql_temp, string.Format(sSubTableWhere, "ct"), string.Format(sSubTableWhere, "d"), sWhere);
|
||
|
||
var param = new { Device_building_tag = post.Building_tag, Device_system_tag = post.System_tag, Device_system_category_layer3 = post.System_category };
|
||
|
||
var deviceCheckTableList = await backendRepository.GetAllAsync<DeviceCheckTable>(sql, param);
|
||
|
||
sSubTableWhere = " WHERE {0}.device_building_tag = @Device_building_tag";
|
||
|
||
sWhere = @"WHERE ct.device_number IS NULL AND d.device_number IS NOT NULL
|
||
-- OR ct.device_system_category_layer3 != d.device_system_category_layer3
|
||
-- OR ct.disaster_system_value != d.device_disaster";
|
||
|
||
var sql_abnormal_amount = string.Format(sql_temp, string.Format(sSubTableWhere, "ct"), string.Format(sSubTableWhere, "d") + " AND d.deleted = 0", sWhere);
|
||
|
||
var abnormal = await backendRepository.GetAllAsync<DeviceCheckTable>(sql_abnormal_amount, param);
|
||
|
||
var abnormal_amount = abnormal.Count();
|
||
|
||
DeviceCheck deviceCheck = new DeviceCheck();
|
||
deviceCheck.DeviceCheckAmount = abnormal_amount;
|
||
deviceCheck.DeviceCheckTableList = deviceCheckTableList;
|
||
|
||
apiResult.Code = "0000";
|
||
apiResult.Data = deviceCheck;
|
||
}
|
||
catch (Exception exception)
|
||
{
|
||
apiResult.Code = "9999";
|
||
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
|
||
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
|
||
}
|
||
|
||
return apiResult;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 資料檢核表格
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<ApiResult<string>> DeviceCheckReplace(PostDeviceCheckFilter post)
|
||
{
|
||
ApiResult<string> apiResult = new ApiResult<string>();
|
||
|
||
try
|
||
{
|
||
//將該棟別的資料更換為正確
|
||
string sql_update_correct = @"UPDATE device_import_ckeck_temp SET is_correct = 1 WHERE device_building_tag = @Device_building_tag";
|
||
var param = new { Device_building_tag = post.Building_tag };
|
||
await backendRepository.ExecuteSql(sql_update_correct, param);
|
||
|
||
//找出當前在device裡面有的,以供後續取代用
|
||
string sql = @"
|
||
SELECT
|
||
ct.*,
|
||
d.device_guid
|
||
FROM (
|
||
SELECT
|
||
*
|
||
FROM device_import_ckeck_temp ct
|
||
WHERE ct.device_number IN (
|
||
SELECT d.device_number
|
||
FROM device d
|
||
WHERE d.deleted = 0
|
||
AND d.device_building_tag = @Device_building_tag
|
||
)
|
||
) ct
|
||
LEFT JOIN device d ON d.deleted = 0 AND ct.device_number = d.device_number";
|
||
|
||
var check_temp_replaces = await backendRepository.GetAllAsync<Device_import_ckeck_temp_replace>(sql, param);
|
||
|
||
foreach (var check_temp_replace in check_temp_replaces)
|
||
{
|
||
Dictionary<string, object> device_replace = new Dictionary<string, object>()
|
||
{
|
||
{"@device_system_category_layer3", check_temp_replace.Device_system_category_layer3},
|
||
};
|
||
|
||
List<Dictionary<string, object>> device_disaster_dicts = new List<Dictionary<string, object>>()
|
||
{
|
||
{ new Dictionary<string, object>() { { "@device_guid", check_temp_replace.Device_guid }, { "@device_system_value", check_temp_replace.Device_disaster } } }
|
||
};
|
||
|
||
await deviceImportRepository.ReplaceOneDeviceInfo(check_temp_replace.Device_guid, device_replace, device_disaster_dicts);
|
||
}
|
||
|
||
apiResult.Code = "0000";
|
||
apiResult.Msg = "取代成功";
|
||
}
|
||
catch (Exception exception)
|
||
{
|
||
apiResult.Code = "9999";
|
||
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
|
||
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
|
||
}
|
||
|
||
return apiResult;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新設備 3d坐標, forge_dbid
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<ApiResult<string>> ImportDevForCor([FromBody] List<ImportDevForCoo> post)
|
||
{
|
||
ApiResult<string> apiResult = new ApiResult<string>();
|
||
var device_guid_record = "";
|
||
try
|
||
{
|
||
if (post != null)
|
||
{
|
||
if (post.Count > 0)
|
||
{
|
||
//清空device_node資料表
|
||
//await backendRepository.TruncateTable("device_node");
|
||
|
||
//清空 3D 坐標
|
||
await backendRepository.ExecuteSql("update device set device_coordinate_3d = '';");
|
||
await backendRepository.ExecuteSql("update device_node set device_node_coordinate_3d = '';");
|
||
//await backendRepository.UpdateOneByCustomTable(deviceForLight, "device", $@" device_guid = '{device_guid}'");
|
||
|
||
int node_priority = 1;
|
||
|
||
foreach (var idfc in post)
|
||
{
|
||
if (idfc.device_number.IndexOf("_LT_L1") > -1)
|
||
{
|
||
//取得device_guid
|
||
var sWhere = $@" deleted = 0 and device_number = '" + idfc.device_number + "'";
|
||
var device_guid = await backendRepository.GetOneColAsync("device", sWhere, "device_guid");
|
||
if (device_guid == null)
|
||
{
|
||
Logger.LogError("【" + controllerName + "/" + actionName + "】" + "【ERROR:forge匯入不存在device設備】" + idfc.device_number);
|
||
continue;
|
||
}
|
||
|
||
if (device_guid.ToString() != device_guid_record && !string.IsNullOrEmpty(idfc.node.device_coordinate_3d)) // 如果跟前一筆不同,才需要 update device.forge_dbid 與坐標
|
||
{
|
||
device_guid_record = device_guid.ToString();
|
||
node_priority = 1;
|
||
Dictionary<string, object> deviceForLight = new Dictionary<string, object>();
|
||
deviceForLight.Add("@device_coordinate_3d", idfc.node.device_coordinate_3d);
|
||
deviceForLight.Add("@forge_dbid", idfc.forge_dbid);
|
||
deviceForLight.Add("@room_name", idfc.room_name);
|
||
deviceForLight.Add("@updated_at", DateTime.Now);
|
||
await backendRepository.UpdateOneByCustomTable(deviceForLight, "device", $@" device_guid = '{device_guid}'");
|
||
}
|
||
|
||
Dictionary<string, object> device = new Dictionary<string, object>();
|
||
// device.Add("@device_node_guid", Guid.NewGuid());
|
||
//device.Add("@deleted", 0);
|
||
device.Add("@device_guid", device_guid); // 父層由 forge 提供
|
||
device.Add("@device_node_coordinate_3d", (idfc.node == null) ? idfc.device_coordinate_3d: idfc.node.device_coordinate_3d);
|
||
device.Add("@forge_dbid", (idfc.node == null) ? idfc.forge_dbid: idfc.node.forge_dbid);
|
||
//device.Add("@device_number", (idfc.node == null) ? idfc.device_number : idfc.node.device_number);
|
||
device.Add("@priority", node_priority);
|
||
//device.Add("@created_by", myUserInfo.Userinfo_guid);
|
||
//device.Add("@created_at", DateTime.Now);
|
||
|
||
node_priority++;
|
||
await backendRepository.UpdateOneByCustomTable(device, "device_node", $@" device_number = '{idfc.node.device_number}'");
|
||
// await backendRepository.AddOneByCustomTableReturnId(device, "device_node", false);
|
||
}
|
||
else
|
||
{
|
||
Logger.LogError("測試設備匯入:" + idfc.device_number);
|
||
Dictionary<string, object> device = new Dictionary<string, object>();
|
||
device.Add("@device_coordinate_3d", idfc.device_coordinate_3d);
|
||
device.Add("@forge_dbid", idfc.forge_dbid);
|
||
device.Add("@room_name", idfc.room_name);
|
||
device.Add("@updated_at", DateTime.Now);
|
||
await backendRepository.UpdateOneByCustomTable(device, "device", $@" device_number = '{idfc.device_number}'");
|
||
}
|
||
}
|
||
//更新device資料表 room_dbid 欄位
|
||
string sql = @"
|
||
SET SQL_SAFE_UPDATES = 0;
|
||
UPDATE device AS de,
|
||
(
|
||
select f.room_id, f.room_name from forge_room f
|
||
join device d ON f.room_name = d.room_name
|
||
) AS re
|
||
SET de.room_dbid = re.room_id
|
||
WHERE de.room_name = re.room_name;";
|
||
await backendRepository.ExecuteSql(sql);
|
||
}
|
||
apiResult.Code = "0000";
|
||
apiResult.Msg = "編輯成功";
|
||
}
|
||
else
|
||
{
|
||
apiResult.Code = "0001";
|
||
apiResult.Msg = "無資料輸入";
|
||
}
|
||
}
|
||
catch (Exception exception)
|
||
{
|
||
apiResult.Code = "9999";
|
||
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
|
||
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
|
||
}
|
||
|
||
return apiResult;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新forge_room room_id(dbid), room_name
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<ApiResult<string>> ImportForgeRoom([FromBody] List<ImportForgeRoom> post)
|
||
{
|
||
ApiResult<string> apiResult = new ApiResult<string>();
|
||
//var device_guid_record = "";
|
||
try
|
||
{
|
||
if (post != null)
|
||
{
|
||
if (post.Count > 0)
|
||
{
|
||
//清空device_node資料表
|
||
await backendRepository.TruncateTable("forge_room");
|
||
|
||
foreach (var idfc in post)
|
||
{
|
||
// var room_name_arr = idfc.room_name.Split('_');
|
||
string full_name = idfc.room_name;
|
||
char first = full_name[0];
|
||
if (first != 'B' && first != 'R' && first != 'U')
|
||
{
|
||
full_name = 'U' + full_name;
|
||
}
|
||
|
||
//var param = new { floor_name = floor_name };
|
||
|
||
//房間 新增Data至forge_room資料表
|
||
Dictionary<string, object> room = new Dictionary<string, object>();
|
||
room.Add("@room_id", idfc.room_id);
|
||
room.Add("@deleted", 0);
|
||
room.Add("@room_name", full_name);
|
||
room.Add("@created_at", DateTime.Now);
|
||
|
||
await backendRepository.AddOneByCustomTableReturnId(room, "forge_room", false);
|
||
|
||
|
||
}
|
||
|
||
//更新forge_room資料表 building_tag, floor_guid欄位
|
||
string sql = @"
|
||
update forge_room a
|
||
join (
|
||
select building_tag, floor_guid,
|
||
case when right(floor_name, 1) = 'F' then floor_name
|
||
else CONCAT(floor_name, 'F') end floor_name , priority
|
||
from (
|
||
SELECT
|
||
a.building_tag,
|
||
a.floor_guid, a.full_name,
|
||
case when left(a.full_name, 1) = 'B' then a.full_name
|
||
when left(a.full_name, 1) = 'R' then a.full_name
|
||
when left(a.full_name, 1) = 'U' then a.full_name
|
||
else CONCAT('U', a.full_name) end as floor_name,
|
||
a.priority
|
||
FROM floor AS a
|
||
INNER JOIN building AS b ON a.building_tag = b.building_tag
|
||
WHERE a.deleted = 0 AND b.deleted = 0
|
||
)y
|
||
)x on SUBSTRING_INDEX(a.room_name, '_', 1) = x.floor_name
|
||
set a.building_tag = x.building_tag,
|
||
a.floor_guid = x.floor_guid";
|
||
await backendRepository.ExecuteSql(sql);
|
||
}
|
||
apiResult.Code = "0000";
|
||
apiResult.Msg = "編輯成功";
|
||
}
|
||
else
|
||
{
|
||
apiResult.Code = "0001";
|
||
apiResult.Msg = "無資料輸入";
|
||
}
|
||
}
|
||
catch (Exception exception)
|
||
{
|
||
apiResult.Code = "9999";
|
||
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
|
||
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
|
||
}
|
||
|
||
return apiResult;
|
||
}
|
||
}
|
||
}
|