Merge branch 'master' of https://gitea.mjm-staging.developers-homelab.net/BIMS/BIMS
This commit is contained in:
		
						commit
						012bc49651
					
				@ -1653,18 +1653,18 @@ namespace Backend.Controllers
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 取得子系統的device item
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="guid"></param>
 | 
			
		||||
        /// <param name="input"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        [HttpPost]
 | 
			
		||||
        public async Task<ApiResult<List<Device_item>>> GetDeviceItem(string sub_system_tag)
 | 
			
		||||
        public async Task<ApiResult<List<Device_item>>> GetDeviceItem(DeviceItemInput input)
 | 
			
		||||
        {
 | 
			
		||||
            ApiResult<List<Device_item>> apiResult = new ApiResult<List<Device_item>>();
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                string sWhere = "deleted = 0 AND device_name_tag = @Sub_system_tag";
 | 
			
		||||
                string sWhere = "deleted = 0 AND device_name_tag = @Sub_system_tag and device_building_tag = @device_building_tag";
 | 
			
		||||
 | 
			
		||||
                object param = new { Sub_system_tag = sub_system_tag };
 | 
			
		||||
                object param = new { Sub_system_tag = input.sub_system_tag, device_building_tag = input.building_tag };
 | 
			
		||||
 | 
			
		||||
                var deviceItems = await backendRepository.GetAllAsync<Device_item>("device_item", sWhere, param);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -51,19 +51,23 @@ namespace Backend.Controllers
 | 
			
		||||
                var obixApiConfig = new Backend.Models.ObixApiConfig();
 | 
			
		||||
                EDFunction ed = new EDFunction();
 | 
			
		||||
                obixApiConfig.ApiBase = variableObix.Where(x => x.Name == "ApiBase").Select(x => x.Value).FirstOrDefault() + "obix/config/Program/ObixQuery/query/";
 | 
			
		||||
                obixApiConfig.UrlSlot =variableObix.Where(x => x.Name == "url_slot").Select(x => x.Value).FirstOrDefault();
 | 
			
		||||
                //obixApiConfig.UrlSlot =variableObix.Where(x => x.Name == "url_slot").Select(x => x.Value).FirstOrDefault();
 | 
			
		||||
                obixApiConfig.TagQuantity = variableObix.Where(x => x.Name == "tag_quantity").Select(x => x.Value).FirstOrDefault();
 | 
			
		||||
                obixApiConfig.UserName = variableObix.Where(x => x.Name == "UserName").Select(x => x.Value).FirstOrDefault();
 | 
			
		||||
                obixApiConfig.Password = variableObix.Where(x => x.Name == "Password").Select(x => x.Value).FirstOrDefault();
 | 
			
		||||
 | 
			
		||||
                List<Device_value> ds;
 | 
			
		||||
                var ds = new List<Device_value>();
 | 
			
		||||
 | 
			
		||||
                string top100 = "";//" top 100 ";
 | 
			
		||||
                webRequestService svc = new webRequestService();
 | 
			
		||||
                string bql = obixApiConfig.UrlSlot + "bql:select " + top100 + " * from baja:Folder ";
 | 
			
		||||
                //ds = svc.obixQuery("http://192.168.0.136:8080/obix/config/Arena/Program/ObixQuery/query/", bql);
 | 
			
		||||
                //ds = svc.obixQuery("http://localhost:8080/obix/config/Program/ObixQuery/query/", bql);
 | 
			
		||||
                 ds = svc.obixQuery(obixApiConfig.ApiBase, bql, obixApiConfig.TagQuantity, obixApiConfig.UserName, obixApiConfig.Password);//三菱
 | 
			
		||||
                var urlSlots = backendRepository.GetAllAsync<string>("select obixSlot from building where deleted = 0").Result;
 | 
			
		||||
                foreach(var us in urlSlots)
 | 
			
		||||
                {
 | 
			
		||||
                    string bql = us + "bql:select " + top100 + " * from baja:Folder ";
 | 
			
		||||
                    //ds = svc.obixQuery("http://192.168.0.136:8080/obix/config/Arena/Program/ObixQuery/query/", bql);
 | 
			
		||||
                    //ds = svc.obixQuery("http://localhost:8080/obix/config/Program/ObixQuery/query/", bql);
 | 
			
		||||
                    ds.AddRange(svc.obixQuery(obixApiConfig.ApiBase, bql, obixApiConfig.TagQuantity, obixApiConfig.UserName, obixApiConfig.Password));//三菱
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                apiResult.Code = "0000";
 | 
			
		||||
                apiResult.Data = ds;
 | 
			
		||||
@ -93,14 +97,17 @@ namespace Backend.Controllers
 | 
			
		||||
            try
 | 
			
		||||
            { 
 | 
			
		||||
                string ss = ds.Where(x => x.tag_name != "").FirstOrDefault().tag_name;
 | 
			
		||||
                var building = "";
 | 
			
		||||
                var data = ds.Where(x => x.tag_name != "");
 | 
			
		||||
                List<string> building = null;
 | 
			
		||||
                if (tag_quantity == "5")
 | 
			
		||||
                {
 | 
			
		||||
                    building = ss.Split("_")[0];
 | 
			
		||||
                    //building.Add(ss.Split("_")[0]);
 | 
			
		||||
                    building = data.GroupBy(x => x.tag_name.Split("_")[0]).Select(x => x.Key).ToList();
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    building = ss.Split("_")[1];
 | 
			
		||||
                    //building.Add(ss.Split("_")[1]);
 | 
			
		||||
                    building = data.GroupBy(x => x.tag_name.Split("_")[1]).Select(x => x.Key).ToList();
 | 
			
		||||
                } 
 | 
			
		||||
               
 | 
			
		||||
                string LightSwitchLevel = await niagaraDataSynchronizeRepository.getLightSwitchLevel(); //獲取照明開關 是否在 device or device_node 
 | 
			
		||||
@ -135,7 +142,7 @@ namespace Backend.Controllers
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                List<ImpNiaItem> ds;
 | 
			
		||||
                var ds = new List<ImpNiaItem>();
 | 
			
		||||
 | 
			
		||||
                webRequestService svc = new webRequestService();
 | 
			
		||||
 | 
			
		||||
@ -146,12 +153,19 @@ namespace Backend.Controllers
 | 
			
		||||
                obixApiConfig.ApiBase = variableObix.Where(x => x.Name == "ApiBase").Select(x => x.Value).FirstOrDefault();
 | 
			
		||||
                obixApiConfig.UserName = variableObix.Where(x => x.Name == "UserName").Select(x => x.Value).FirstOrDefault();
 | 
			
		||||
                obixApiConfig.Password = variableObix.Where(x => x.Name == "Password").Select(x => x.Value).FirstOrDefault();
 | 
			
		||||
                obixApiConfig.UrlSlot =  variableObix.Where(x => x.Name == "url_slot").Select(x => x.Value).FirstOrDefault();
 | 
			
		||||
                ds = svc.obixHisQuery(obixApiConfig.ApiBase + "obix/config/Program/ObixQuery/query/", obixApiConfig.ApiBase + "obix/histories",obixApiConfig.UrlSlot, obixApiConfig.UserName, 
 | 
			
		||||
                                    obixApiConfig.Password);
 | 
			
		||||
                //obixApiConfig.UrlSlot =  variableObix.Where(x => x.Name == "url_slot").Select(x => x.Value).FirstOrDefault();
 | 
			
		||||
 | 
			
		||||
                var urlSlots = backendRepository.GetAllAsync<string>("select obixSlot from building where deleted = 0").Result;
 | 
			
		||||
                foreach(var us in urlSlots)
 | 
			
		||||
                {
 | 
			
		||||
                    var data = svc.obixHisQuery(obixApiConfig.ApiBase + "obix/config/Program/ObixQuery/query/", obixApiConfig.ApiBase + "obix/histories", us,
 | 
			
		||||
                                obixApiConfig.UserName, obixApiConfig.Password);
 | 
			
		||||
                    ds.AddRange(data);
 | 
			
		||||
                }
 | 
			
		||||
                
 | 
			
		||||
                var buildings = backendRepository.GetAllAsync<string>("select building_tag from building where deleted = 0").Result;
 | 
			
		||||
                apiResult.Code = "0000";
 | 
			
		||||
                apiResult.Data = ds.Where(x => x.device_building_tag == building.building).ToList(); ;
 | 
			
		||||
                apiResult.Data = ds.Where(x => buildings.Contains(x.device_building_tag)).ToList();
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception exception)
 | 
			
		||||
            {
 | 
			
		||||
@ -180,7 +194,7 @@ namespace Backend.Controllers
 | 
			
		||||
                    //string ss = ds.Where(x => x.tag_name != "").FirstOrDefault().tag_name;
 | 
			
		||||
                    //var building = ss.Split("_")[0];
 | 
			
		||||
 | 
			
		||||
                    var building = ds.FirstOrDefault().device_building_tag;
 | 
			
		||||
                    var building = ds.GroupBy(x => x.device_building_tag).Select(x => x.Key).ToList();
 | 
			
		||||
                    await niagaraDataSynchronizeRepository.InsertItemFromNiagara(ds, building); // insert 暫存table import_niagara_item
 | 
			
		||||
                    await niagaraDataSynchronizeRepository.DeviceItemComparison();  //insert  device_item
 | 
			
		||||
                    await niagaraDataSynchronizeRepository.CheckItemDiffFullNameAndCover(); // update device_item.fullname
 | 
			
		||||
 | 
			
		||||
@ -581,14 +581,14 @@ namespace Backend.Controllers
 | 
			
		||||
            ApiResult<List<Device_item>> apiResult = new ApiResult<List<Device_item>>();
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
 | 
			
		||||
                var building_tag = await backendRepository.GetOneAsync<string>($@"select system_value from variable where system_type = 'project_name' and deleted = 0");
 | 
			
		||||
                var sql = @"SELECT di.*
 | 
			
		||||
                            FROM device_item di
 | 
			
		||||
                            JOIN variable sv ON di.device_name_tag = sv.system_value
 | 
			
		||||
                            JOIN variable mv ON sv.system_parent_id = mv.id AND di.device_system_tag = mv.system_value
 | 
			
		||||
                            WHERE sv.id = @id AND di.deleted = @Deleted";
 | 
			
		||||
                            WHERE sv.id = @id AND di.deleted = @Deleted and di.device_building_tag = @building_tag";
 | 
			
		||||
 | 
			
		||||
                object param = new { Deleted = 0, id = id };
 | 
			
		||||
                object param = new { Deleted = 0, id = id, building_tag = building_tag.Split("/")[1] };
 | 
			
		||||
 | 
			
		||||
                var systemSubs = await backendRepository.GetAllAsync<Device_item>(sql, param);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -242,6 +242,10 @@ namespace Backend.Controllers
 | 
			
		||||
            return apiResult;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 獲取專案名稱(東別)
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        [HttpPost]
 | 
			
		||||
        public async Task<ApiResult<Variable>> ProjectName()
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
@ -78,4 +78,10 @@ namespace Backend.Models
 | 
			
		||||
        public string guid { get; set; }
 | 
			
		||||
        public string subguid { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class DeviceItemInput
 | 
			
		||||
    {
 | 
			
		||||
        public string sub_system_tag { get; set; }
 | 
			
		||||
        public string building_tag { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -262,11 +262,11 @@
 | 
			
		||||
                    maxlength: 50,
 | 
			
		||||
                    filterspace: true
 | 
			
		||||
                },
 | 
			
		||||
                build_file_3d_modal: {
 | 
			
		||||
                    required: true, extension: "nwc|nwd"
 | 
			
		||||
                }
 | 
			
		||||
                //build_file_3d_modal: {
 | 
			
		||||
                //    required: true, extension: "nwc|nwd"
 | 
			
		||||
                //}
 | 
			
		||||
            },
 | 
			
		||||
            messages: { build_file_3d_modal: "File must be nwc, nwd" }
 | 
			
		||||
            //messages: { build_file_3d_modal: "File must be nwc, nwd" }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        //#region 儲存區域基本資料
 | 
			
		||||
 | 
			
		||||
@ -1551,7 +1551,8 @@
 | 
			
		||||
                        var selectedSub_system_tag = selected_building_menu.main_system ? selected_building_menu.main_system.sub_system ? selected_building_menu.main_system.sub_system.sub_system_tag : "" : "";
 | 
			
		||||
                        var url = "/DeviceManage/GetDeviceItem";
 | 
			
		||||
                        var send_data = {
 | 
			
		||||
                            sub_system_tag: selectedSub_system_tag
 | 
			
		||||
                            sub_system_tag: selectedSub_system_tag,
 | 
			
		||||
                            building_tag: selected_device_building_tag
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        $.post(url, send_data, function (rel) {
 | 
			
		||||
 | 
			
		||||
@ -83,6 +83,7 @@ namespace BackendWorkerService
 | 
			
		||||
                    #region Repository ª`¤J
 | 
			
		||||
                    services.AddTransient<IBackendRepository, BackendRepository>();
 | 
			
		||||
                    services.AddTransient<IBackgroundServiceRepository, BackgroundServiceRepository>();
 | 
			
		||||
                    services.AddTransient<IBackgroundServiceMsSqlRepository, BackgroundServiceMsSqlRepository>();
 | 
			
		||||
                    services.AddTransient<IFrontendRepository, FrontendRepository>();
 | 
			
		||||
                    services.AddTransient<IBaseRepository, BaseRepository>();
 | 
			
		||||
                    #endregion Repository ª`¤J
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,6 @@
 | 
			
		||||
using Backend.Models;
 | 
			
		||||
using BackendWorkerService.Services.Implement;
 | 
			
		||||
using Dapper;
 | 
			
		||||
using Microsoft.Extensions.Configuration;
 | 
			
		||||
using Microsoft.Extensions.Logging;
 | 
			
		||||
using Microsoft.Extensions.Options;
 | 
			
		||||
@ -25,6 +26,7 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
    {
 | 
			
		||||
        private readonly ILogger<ArchiveElectricMeterDayJob> logger;
 | 
			
		||||
        private readonly IBackgroundServiceRepository backgroundServiceRepository;
 | 
			
		||||
        private readonly IBackgroundServiceMsSqlRepository backgroundServiceMsSqlRepository;
 | 
			
		||||
        protected readonly IDatabaseHelper _databaseHelper;
 | 
			
		||||
        private readonly ILogger<Task_Detail> loggers;
 | 
			
		||||
 | 
			
		||||
@ -32,10 +34,12 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
        public ArchiveElectricMeterDayJob(
 | 
			
		||||
            ILogger<ArchiveElectricMeterDayJob> logger,
 | 
			
		||||
            IBackgroundServiceRepository backgroundServiceRepository,
 | 
			
		||||
            IBackgroundServiceMsSqlRepository backgroundServiceMySqlRepository,
 | 
			
		||||
            IDatabaseHelper databaseHelper, ILogger<Task_Detail> loggers, IBackendRepository backendRepository)
 | 
			
		||||
        {
 | 
			
		||||
            this.logger = logger;
 | 
			
		||||
            this.backgroundServiceRepository = backgroundServiceRepository;
 | 
			
		||||
            this.backgroundServiceMsSqlRepository = backgroundServiceMySqlRepository;
 | 
			
		||||
            this._databaseHelper = databaseHelper;
 | 
			
		||||
            this.loggers = loggers;
 | 
			
		||||
        }
 | 
			
		||||
@ -55,29 +59,47 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
 | 
			
		||||
                    var variableArchive = await backgroundServiceRepository.GetAllAsync<KeyValue>(sqlArchive);
 | 
			
		||||
                    var electricMeterGuid = variableArchive.Where(x => x.Name == "ElectricMeterGuid").Select(x => x.Value).FirstOrDefault();
 | 
			
		||||
                    var waterMeterGuid = variableArchive.Where(x => x.Name == "WaterMeterGuid").Select(x => x.Value).FirstOrDefault();
 | 
			
		||||
 | 
			
		||||
                    #region 找出所有電錶設備
 | 
			
		||||
                    var sWhere = "deleted = 0 AND sub_system_guid = @sub_system_guid";
 | 
			
		||||
                    var sWhere = "deleted = 0 AND device_name_tag = @sub_system_guid";
 | 
			
		||||
                    var electricMeters = await backgroundServiceRepository.GetAllAsync<Device>("device", sWhere, new { sub_system_guid = electricMeterGuid });
 | 
			
		||||
                    var waterMeters = await backgroundServiceRepository.GetAllAsync<Device>("device", sWhere, new { sub_system_guid = waterMeterGuid });
 | 
			
		||||
                    #endregion 找出所有電錶設備
 | 
			
		||||
 | 
			
		||||
                    #region 找出所有電錶系統的點位
 | 
			
		||||
                    var sPointWhere = "deleted = 0 AND sub_system_guid = @sub_system_guid";
 | 
			
		||||
                    var points = await backgroundServiceRepository.GetAllAsync<Device_item>("device_item", sPointWhere, new { sub_system_guid = electricMeterGuid });
 | 
			
		||||
                    var sPointWhere = "deleted = 0 AND device_name_tag = @sub_system_guid";
 | 
			
		||||
                    var electricPoints = await backgroundServiceRepository.GetAllAsync<Device_item>("device_item", sPointWhere, new { sub_system_guid = electricMeterGuid });
 | 
			
		||||
                    var waterPoints = await backgroundServiceRepository.GetAllAsync<Device_item>("device_item", sPointWhere, new { sub_system_guid = waterMeterGuid });
 | 
			
		||||
                    #endregion 找出所有電錶系統的點位
 | 
			
		||||
 | 
			
		||||
                    #region 組合出所有電錶設備點位
 | 
			
		||||
                    List<DeviceNumberPoint> deviceNumberPoints = new List<DeviceNumberPoint>();
 | 
			
		||||
                    List<DeviceNumberPoint> electricDeviceNumberPoints = new List<DeviceNumberPoint>();
 | 
			
		||||
                    foreach (var electricMeter in electricMeters)
 | 
			
		||||
                    {
 | 
			
		||||
                        foreach (var point in points)
 | 
			
		||||
                        foreach (var point in electricPoints)
 | 
			
		||||
                        {
 | 
			
		||||
                            DeviceNumberPoint deviceNumberPoint = new DeviceNumberPoint();
 | 
			
		||||
                            deviceNumberPoint.DeviceNumber = electricMeter.Device_number;
 | 
			
		||||
                            deviceNumberPoint.Point = point.points;
 | 
			
		||||
                            deviceNumberPoint.FullDeviceNumberPoint = string.Format("{0}_{1}", electricMeter.Device_number, point.points);
 | 
			
		||||
 | 
			
		||||
                            deviceNumberPoints.Add(deviceNumberPoint);
 | 
			
		||||
                            electricDeviceNumberPoints.Add(deviceNumberPoint);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    #endregion 組合出所有電錶設備點位
 | 
			
		||||
                    #region 組合出所有水錶設備點位
 | 
			
		||||
                    List<DeviceNumberPoint> waterDeviceNumberPoints = new List<DeviceNumberPoint>();
 | 
			
		||||
                    foreach (var waterMeter in waterMeters)
 | 
			
		||||
                    {
 | 
			
		||||
                        foreach (var point in waterPoints)
 | 
			
		||||
                        {
 | 
			
		||||
                            DeviceNumberPoint deviceNumberPoint = new DeviceNumberPoint();
 | 
			
		||||
                            deviceNumberPoint.DeviceNumber = waterMeter.Device_number;
 | 
			
		||||
                            deviceNumberPoint.Point = point.points;
 | 
			
		||||
                            deviceNumberPoint.FullDeviceNumberPoint = string.Format("{0}_{1}", waterMeter.Device_number, point.points);
 | 
			
		||||
 | 
			
		||||
                            waterDeviceNumberPoints.Add(deviceNumberPoint);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    #endregion 組合出所有電錶設備點位
 | 
			
		||||
@ -118,8 +140,9 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
                            //stopWatch.Start();
 | 
			
		||||
 | 
			
		||||
                            //抓取每個設備的資料
 | 
			
		||||
                            List<Dictionary<string, object>> archiveDayRawDatas = new List<Dictionary<string, object>>();
 | 
			
		||||
                            foreach (var deviceNumberPoint in deviceNumberPoints)
 | 
			
		||||
                            List<Dictionary<string, object>> electericArchiveDayRawDatas = new List<Dictionary<string, object>>();
 | 
			
		||||
                            List<Dictionary<string, object>> waterArchiveDayRawDatas = new List<Dictionary<string, object>>();
 | 
			
		||||
                            foreach (var deviceNumberPoint in electricDeviceNumberPoints)
 | 
			
		||||
                            {
 | 
			
		||||
 | 
			
		||||
                                HttpWebRequest archiveDayRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
 | 
			
		||||
@ -162,7 +185,7 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
                                    archiveDayRawData.Add("@sum_rawdata", 0);
 | 
			
		||||
                                    archiveDayRawData.Add("@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
 | 
			
		||||
 | 
			
		||||
                                    archiveDayRawDatas.Add(archiveDayRawData);
 | 
			
		||||
                                    electericArchiveDayRawDatas.Add(archiveDayRawData);
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                                if (archiveDayJsonResult.ContainsKey("obj")) //表示可以讀取到內容
 | 
			
		||||
@ -170,7 +193,62 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
                                    var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveDayJsonResult);
 | 
			
		||||
                                    if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0)
 | 
			
		||||
                                    {
 | 
			
		||||
                                        archiveDayRawDatas.AddRange(ArrangeRawDatas);
 | 
			
		||||
                                        electericArchiveDayRawDatas.AddRange(ArrangeRawDatas);
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                            foreach (var deviceNumberPoint in waterDeviceNumberPoints)
 | 
			
		||||
                            {
 | 
			
		||||
 | 
			
		||||
                                HttpWebRequest archiveDayRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
 | 
			
		||||
                                //HttpWebRequest archiveDayRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
 | 
			
		||||
                                archiveDayRequest.Method = "POST";
 | 
			
		||||
                                archiveDayRequest.Headers.Add("Authorization", "Basic " + encoded);
 | 
			
		||||
                                archiveDayRequest.PreAuthenticate = true;
 | 
			
		||||
 | 
			
		||||
                                byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter);
 | 
			
		||||
                                using (Stream reqStream = archiveDayRequest.GetRequestStream())
 | 
			
		||||
                                {
 | 
			
		||||
                                    reqStream.Write(byteArray, 0, byteArray.Length);
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                                HttpWebResponse archiveDayResponse = (HttpWebResponse)archiveDayRequest.GetResponse();
 | 
			
		||||
                                var archiveDayResponseContent = new StreamReader(archiveDayResponse.GetResponseStream()).ReadToEnd();
 | 
			
		||||
 | 
			
		||||
                                xmlDocument.LoadXml(archiveDayResponseContent);
 | 
			
		||||
                                string archiveDayJson = JsonConvert.SerializeXmlNode(xmlDocument);
 | 
			
		||||
                                JObject archiveDayJsonResult = (JObject)JsonConvert.DeserializeObject(archiveDayJson);
 | 
			
		||||
 | 
			
		||||
                                if (archiveDayJsonResult.ContainsKey("err")) //抓取錯誤
 | 
			
		||||
                                {
 | 
			
		||||
                                    //logger.LogError("【ArchiveElectricMeterDayJob】【天歸檔】【取得資料失敗】");
 | 
			
		||||
                                    //logger.LogError("【ArchiveElectricMeterDayJob】【天歸檔】【取得資料失敗】[錯誤內容]:{0}", archiveDayJsonResult);
 | 
			
		||||
 | 
			
		||||
                                    Dictionary<string, object> archiveDayRawData = new Dictionary<string, object>();
 | 
			
		||||
                                    archiveDayRawData.Add("@device_number", deviceNumberPoint.DeviceNumber);
 | 
			
		||||
                                    archiveDayRawData.Add("@point", deviceNumberPoint.Point);
 | 
			
		||||
                                    archiveDayRawData.Add("@start_timestamp", startTimestamp.Replace("T", " ").Substring(0, 19));
 | 
			
		||||
                                    archiveDayRawData.Add("@end_timestamp", endTimestamp.Replace("T", " ").Substring(0, 19));
 | 
			
		||||
                                    archiveDayRawData.Add("@is_complete", 0);
 | 
			
		||||
                                    archiveDayRawData.Add("@repeat_times", 0);
 | 
			
		||||
                                    archiveDayRawData.Add("@fail_reason", archiveDayJson);
 | 
			
		||||
 | 
			
		||||
                                    archiveDayRawData.Add("@count_rawdata", 0);
 | 
			
		||||
                                    archiveDayRawData.Add("@min_rawdata", 0);
 | 
			
		||||
                                    archiveDayRawData.Add("@max_rawdata", 0);
 | 
			
		||||
                                    archiveDayRawData.Add("@avg_rawdata", 0);
 | 
			
		||||
                                    archiveDayRawData.Add("@sum_rawdata", 0);
 | 
			
		||||
                                    archiveDayRawData.Add("@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
 | 
			
		||||
 | 
			
		||||
                                    waterArchiveDayRawDatas.Add(archiveDayRawData);
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                                if (archiveDayJsonResult.ContainsKey("obj")) //表示可以讀取到內容
 | 
			
		||||
                                {
 | 
			
		||||
                                    var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveDayJsonResult);
 | 
			
		||||
                                    if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0)
 | 
			
		||||
                                    {
 | 
			
		||||
                                        waterArchiveDayRawDatas.AddRange(ArrangeRawDatas);
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
@ -178,9 +256,53 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
                            //stopWatch.Stop();
 | 
			
		||||
                            //logger.LogInformation("【ArchiveElectricMeterDayJob】【天歸檔】【效能檢驗】[取得資料花費時間]{0} 毫秒", stopWatch.ElapsedMilliseconds);
 | 
			
		||||
 | 
			
		||||
                            if (archiveDayRawDatas.Count() > 0)
 | 
			
		||||
                            if (electericArchiveDayRawDatas.Count() > 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                var sql = $@"BEGIN TRANSACTION;
 | 
			
		||||
                                var sql = $@"
 | 
			
		||||
                                            UPDATE archive_electric_meter_day SET 
 | 
			
		||||
                                                    count_rawdata = @count_rawdata,
 | 
			
		||||
                                                    min_rawdata = @min_rawdata,
 | 
			
		||||
                                                    max_rawdata = @max_rawdata,
 | 
			
		||||
                                                    avg_rawdata = @avg_rawdata,
 | 
			
		||||
                                                    sum_rawdata = @sum_rawdata,
 | 
			
		||||
                                                    is_complete = @is_complete,
 | 
			
		||||
                                                    repeat_times = @repeat_times,
 | 
			
		||||
                                                    fail_reason = @fail_reason,
 | 
			
		||||
                                                    updated_at = @updated_at
 | 
			
		||||
                                                 WHERE device_number = @device_number
 | 
			
		||||
                                                    AND point = @point
 | 
			
		||||
                                                    AND start_timestamp = @start_timestamp;
 | 
			
		||||
 | 
			
		||||
                                            
 | 
			
		||||
                                            INSERT INTO archive_electric_meter_day (
 | 
			
		||||
                                                device_number,
 | 
			
		||||
                                                point,
 | 
			
		||||
                                                start_timestamp,
 | 
			
		||||
                                                end_timestamp,
 | 
			
		||||
                                                count_rawdata,
 | 
			
		||||
                                                min_rawdata,
 | 
			
		||||
                                                max_rawdata,
 | 
			
		||||
                                                avg_rawdata,
 | 
			
		||||
                                                sum_rawdata,
 | 
			
		||||
                                                is_complete,
 | 
			
		||||
                                                repeat_times,
 | 
			
		||||
                                                fail_reason)
 | 
			
		||||
                                            SELECT 
 | 
			
		||||
                                                @device_number,
 | 
			
		||||
                                                @point,
 | 
			
		||||
                                                @start_timestamp,
 | 
			
		||||
                                                @end_timestamp,
 | 
			
		||||
                                                @count_rawdata,
 | 
			
		||||
                                                @min_rawdata,
 | 
			
		||||
                                                @max_rawdata,
 | 
			
		||||
                                                @avg_rawdata,
 | 
			
		||||
                                                @sum_rawdata,
 | 
			
		||||
                                                @is_complete,
 | 
			
		||||
                                                @repeat_times,
 | 
			
		||||
                                                @fail_reason
 | 
			
		||||
                                            WHERE ROW_COUNT() = 0;";
 | 
			
		||||
 | 
			
		||||
                                var mySql = $@"BEGIN TRANSACTION;
 | 
			
		||||
 | 
			
		||||
                                            UPDATE archive_electric_meter_day SET 
 | 
			
		||||
                                                    count_rawdata = @count_rawdata,
 | 
			
		||||
@ -227,8 +349,104 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
                                            END
 | 
			
		||||
 | 
			
		||||
                                        COMMIT TRANSACTION;";
 | 
			
		||||
                                await backgroundServiceRepository.ExecuteSql(sql, archiveDayRawDatas);
 | 
			
		||||
                                
 | 
			
		||||
                                await backgroundServiceRepository.ExecuteSql(sql, electericArchiveDayRawDatas);
 | 
			
		||||
                                await backgroundServiceMsSqlRepository.ExecuteSql(mySql, electericArchiveDayRawDatas);
 | 
			
		||||
                            }
 | 
			
		||||
                            if (waterArchiveDayRawDatas.Count() > 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                var sql = $@"
 | 
			
		||||
                                            UPDATE archive_water_meter_day SET 
 | 
			
		||||
                                                    count_rawdata = @count_rawdata,
 | 
			
		||||
                                                    min_rawdata = @min_rawdata,
 | 
			
		||||
                                                    max_rawdata = @max_rawdata,
 | 
			
		||||
                                                    avg_rawdata = @avg_rawdata,
 | 
			
		||||
                                                    sum_rawdata = @sum_rawdata,
 | 
			
		||||
                                                    is_complete = @is_complete,
 | 
			
		||||
                                                    repeat_times = @repeat_times,
 | 
			
		||||
                                                    fail_reason = @fail_reason,
 | 
			
		||||
                                                    updated_at = @updated_at
 | 
			
		||||
                                                 WHERE device_number = @device_number
 | 
			
		||||
                                                    AND point = @point
 | 
			
		||||
                                                    AND start_timestamp = @start_timestamp;
 | 
			
		||||
 | 
			
		||||
                                            
 | 
			
		||||
                                            INSERT INTO archive_water_meter_day (
 | 
			
		||||
                                                device_number,
 | 
			
		||||
                                                point,
 | 
			
		||||
                                                start_timestamp,
 | 
			
		||||
                                                end_timestamp,
 | 
			
		||||
                                                count_rawdata,
 | 
			
		||||
                                                min_rawdata,
 | 
			
		||||
                                                max_rawdata,
 | 
			
		||||
                                                avg_rawdata,
 | 
			
		||||
                                                sum_rawdata,
 | 
			
		||||
                                                is_complete,
 | 
			
		||||
                                                repeat_times,
 | 
			
		||||
                                                fail_reason)
 | 
			
		||||
                                            SELECT 
 | 
			
		||||
                                                @device_number,
 | 
			
		||||
                                                @point,
 | 
			
		||||
                                                @start_timestamp,
 | 
			
		||||
                                                @end_timestamp,
 | 
			
		||||
                                                @count_rawdata,
 | 
			
		||||
                                                @min_rawdata,
 | 
			
		||||
                                                @max_rawdata,
 | 
			
		||||
                                                @avg_rawdata,
 | 
			
		||||
                                                @sum_rawdata,
 | 
			
		||||
                                                @is_complete,
 | 
			
		||||
                                                @repeat_times,
 | 
			
		||||
                                                @fail_reason
 | 
			
		||||
                                            WHERE ROW_COUNT() = 0;";
 | 
			
		||||
 | 
			
		||||
                                var mySql = $@"BEGIN TRANSACTION;
 | 
			
		||||
 | 
			
		||||
                                            UPDATE archive_water_meter_day SET 
 | 
			
		||||
                                                    count_rawdata = @count_rawdata,
 | 
			
		||||
                                                    min_rawdata = @min_rawdata,
 | 
			
		||||
                                                    max_rawdata = @max_rawdata,
 | 
			
		||||
                                                    avg_rawdata = @avg_rawdata,
 | 
			
		||||
                                                    sum_rawdata = @sum_rawdata,
 | 
			
		||||
                                                    is_complete = @is_complete,
 | 
			
		||||
                                                    repeat_times = @repeat_times,
 | 
			
		||||
                                                    fail_reason = @fail_reason,
 | 
			
		||||
                                                    updated_at = @updated_at
 | 
			
		||||
                                                 WHERE device_number = @device_number
 | 
			
		||||
                                                    AND point = @point
 | 
			
		||||
                                                    AND start_timestamp = @start_timestamp;
 | 
			
		||||
 | 
			
		||||
                                            IF @@ROWCOUNT = 0
 | 
			
		||||
                                            BEGIN
 | 
			
		||||
                                                INSERT INTO archive_water_meter_day (
 | 
			
		||||
                                                    device_number,
 | 
			
		||||
                                                    point,
 | 
			
		||||
                                                    start_timestamp,
 | 
			
		||||
                                                    end_timestamp,
 | 
			
		||||
                                                    count_rawdata,
 | 
			
		||||
                                                    min_rawdata,
 | 
			
		||||
                                                    max_rawdata,
 | 
			
		||||
                                                    avg_rawdata,
 | 
			
		||||
                                                    sum_rawdata,
 | 
			
		||||
                                                    is_complete,
 | 
			
		||||
                                                    repeat_times,
 | 
			
		||||
                                                    fail_reason)
 | 
			
		||||
                                                VALUES (
 | 
			
		||||
                                                    @device_number,
 | 
			
		||||
                                                    @point,
 | 
			
		||||
                                                    @start_timestamp,
 | 
			
		||||
                                                    @end_timestamp,
 | 
			
		||||
                                                    @count_rawdata,
 | 
			
		||||
                                                    @min_rawdata,
 | 
			
		||||
                                                    @max_rawdata,
 | 
			
		||||
                                                    @avg_rawdata,
 | 
			
		||||
                                                    @sum_rawdata,
 | 
			
		||||
                                                    @is_complete,
 | 
			
		||||
                                                    @repeat_times,
 | 
			
		||||
                                                    @fail_reason)
 | 
			
		||||
                                            END
 | 
			
		||||
 | 
			
		||||
                                        COMMIT TRANSACTION;";
 | 
			
		||||
                                await backgroundServiceRepository.ExecuteSql(sql, waterArchiveDayRawDatas);
 | 
			
		||||
                                await backgroundServiceMsSqlRepository.ExecuteSql(mySql, waterArchiveDayRawDatas);
 | 
			
		||||
                            }
 | 
			
		||||
                            await task_Detail.InsertWorkTime_End("ArchiveElectricMeterDayJob", "Day", "任務完成");
 | 
			
		||||
                        }
 | 
			
		||||
@ -263,8 +481,9 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
                            //stopWatch.Start();
 | 
			
		||||
 | 
			
		||||
                            //抓取每個設備的資料
 | 
			
		||||
                            List<Dictionary<string, object>> archiveWeekRawDatas = new List<Dictionary<string, object>>();
 | 
			
		||||
                            foreach (var deviceNumberPoint in deviceNumberPoints)
 | 
			
		||||
                            List<Dictionary<string, object>> electricArchiveWeekRawDatas = new List<Dictionary<string, object>>();
 | 
			
		||||
                            List<Dictionary<string, object>> waterArchiveWeekRawDatas = new List<Dictionary<string, object>>();
 | 
			
		||||
                            foreach (var deviceNumberPoint in electricDeviceNumberPoints)
 | 
			
		||||
                            {
 | 
			
		||||
                                HttpWebRequest archiveWeekRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
 | 
			
		||||
                                //HttpWebRequest archiveWeekRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
 | 
			
		||||
@ -306,7 +525,7 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
                                    archiveWeekRawData.Add("@sum_rawdata", 0);
 | 
			
		||||
                                    archiveWeekRawData.Add("@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
 | 
			
		||||
 | 
			
		||||
                                    archiveWeekRawDatas.Add(archiveWeekRawData);
 | 
			
		||||
                                    electricArchiveWeekRawDatas.Add(archiveWeekRawData);
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                                if (archiveWeekJsonResult.ContainsKey("obj")) //表示可以讀取到內容
 | 
			
		||||
@ -314,7 +533,61 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
                                    var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveWeekJsonResult);
 | 
			
		||||
                                    if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0)
 | 
			
		||||
                                    {
 | 
			
		||||
                                        archiveWeekRawDatas.AddRange(ArrangeRawDatas);
 | 
			
		||||
                                        electricArchiveWeekRawDatas.AddRange(ArrangeRawDatas);
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                            foreach (var deviceNumberPoint in waterDeviceNumberPoints)
 | 
			
		||||
                            {
 | 
			
		||||
                                HttpWebRequest archiveWeekRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
 | 
			
		||||
                                //HttpWebRequest archiveWeekRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
 | 
			
		||||
                                archiveWeekRequest.Method = "POST";
 | 
			
		||||
                                archiveWeekRequest.Headers.Add("Authorization", "Basic " + encoded);
 | 
			
		||||
                                archiveWeekRequest.PreAuthenticate = true;
 | 
			
		||||
 | 
			
		||||
                                byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter);
 | 
			
		||||
                                using (Stream reqStream = archiveWeekRequest.GetRequestStream())
 | 
			
		||||
                                {
 | 
			
		||||
                                    reqStream.Write(byteArray, 0, byteArray.Length);
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                                HttpWebResponse archiveWeekResponse = (HttpWebResponse)archiveWeekRequest.GetResponse();
 | 
			
		||||
                                var archiveWeekResponseContent = new StreamReader(archiveWeekResponse.GetResponseStream()).ReadToEnd();
 | 
			
		||||
 | 
			
		||||
                                xmlDocument.LoadXml(archiveWeekResponseContent);
 | 
			
		||||
                                string archiveWeekJson = JsonConvert.SerializeXmlNode(xmlDocument);
 | 
			
		||||
                                JObject archiveWeekJsonResult = (JObject)JsonConvert.DeserializeObject(archiveWeekJson);
 | 
			
		||||
 | 
			
		||||
                                if (archiveWeekJsonResult.ContainsKey("err")) //抓取錯誤
 | 
			
		||||
                                {
 | 
			
		||||
                                    //logger.LogError("【ArchiveElectricMeterDayJob】【週歸檔】【取得資料失敗】");
 | 
			
		||||
                                    //logger.LogError("【ArchiveElectricMeterDayJob】【週歸檔】【取得資料失敗】[錯誤內容]:{0}", archiveWeekJsonResult);
 | 
			
		||||
 | 
			
		||||
                                    Dictionary<string, object> archiveWeekRawData = new Dictionary<string, object>();
 | 
			
		||||
                                    archiveWeekRawData.Add("@device_number", deviceNumberPoint.DeviceNumber);
 | 
			
		||||
                                    archiveWeekRawData.Add("@point", deviceNumberPoint.Point);
 | 
			
		||||
                                    archiveWeekRawData.Add("@start_timestamp", startTimestamp.Replace("T", " ").Substring(0, 19));
 | 
			
		||||
                                    archiveWeekRawData.Add("@end_timestamp", endTimestamp.Replace("T", " ").Substring(0, 19));
 | 
			
		||||
                                    archiveWeekRawData.Add("@is_complete", 0);
 | 
			
		||||
                                    archiveWeekRawData.Add("@repeat_times", 0);
 | 
			
		||||
                                    archiveWeekRawData.Add("@fail_reason", archiveWeekJson);
 | 
			
		||||
 | 
			
		||||
                                    archiveWeekRawData.Add("@count_rawdata", 0);
 | 
			
		||||
                                    archiveWeekRawData.Add("@min_rawdata", 0);
 | 
			
		||||
                                    archiveWeekRawData.Add("@max_rawdata", 0);
 | 
			
		||||
                                    archiveWeekRawData.Add("@avg_rawdata", 0);
 | 
			
		||||
                                    archiveWeekRawData.Add("@sum_rawdata", 0);
 | 
			
		||||
                                    archiveWeekRawData.Add("@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
 | 
			
		||||
 | 
			
		||||
                                    waterArchiveWeekRawDatas.Add(archiveWeekRawData);
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                                if (archiveWeekJsonResult.ContainsKey("obj")) //表示可以讀取到內容
 | 
			
		||||
                                {
 | 
			
		||||
                                    var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveWeekJsonResult);
 | 
			
		||||
                                    if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0)
 | 
			
		||||
                                    {
 | 
			
		||||
                                        waterArchiveWeekRawDatas.AddRange(ArrangeRawDatas);
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
@ -322,9 +595,55 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
                            //stopWatch.Stop();
 | 
			
		||||
                            //logger.LogInformation("【ArchiveElectricMeterDayJob】【週歸檔】【效能檢驗】[取得資料花費時間]{0} 毫秒", stopWatch.ElapsedMilliseconds);
 | 
			
		||||
 | 
			
		||||
                            if (archiveWeekRawDatas.Count() > 0)
 | 
			
		||||
                            if (electricArchiveWeekRawDatas.Count() > 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                var sql = $@"BEGIN TRANSACTION;
 | 
			
		||||
                                var sql = $@"
 | 
			
		||||
 | 
			
		||||
                                            UPDATE archive_electric_meter_week SET 
 | 
			
		||||
                                                    count_rawdata = @count_rawdata,
 | 
			
		||||
                                                    min_rawdata = @min_rawdata,
 | 
			
		||||
                                                    max_rawdata = @max_rawdata,
 | 
			
		||||
                                                    avg_rawdata = @avg_rawdata,
 | 
			
		||||
                                                    sum_rawdata = @sum_rawdata,
 | 
			
		||||
                                                    is_complete = @is_complete,
 | 
			
		||||
                                                    repeat_times = @repeat_times,
 | 
			
		||||
                                                    fail_reason = @fail_reason,
 | 
			
		||||
                                                    updated_at = @updated_at
 | 
			
		||||
                                                 WHERE device_number = @device_number
 | 
			
		||||
                                                    AND point = @point
 | 
			
		||||
                                                    AND start_timestamp = @start_timestamp;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                                                INSERT INTO archive_electric_meter_week (
 | 
			
		||||
                                                    device_number,
 | 
			
		||||
                                                    point,
 | 
			
		||||
                                                    start_timestamp,
 | 
			
		||||
                                                    end_timestamp,
 | 
			
		||||
                                                    count_rawdata,
 | 
			
		||||
                                                    min_rawdata,
 | 
			
		||||
                                                    max_rawdata,
 | 
			
		||||
                                                    avg_rawdata,
 | 
			
		||||
                                                    sum_rawdata,
 | 
			
		||||
                                                    is_complete,
 | 
			
		||||
                                                    repeat_times,
 | 
			
		||||
                                                    fail_reason)
 | 
			
		||||
                                                SELECT 
 | 
			
		||||
                                                    @device_number,
 | 
			
		||||
                                                    @point,
 | 
			
		||||
                                                    @start_timestamp,
 | 
			
		||||
                                                    @end_timestamp,
 | 
			
		||||
                                                    @count_rawdata,
 | 
			
		||||
                                                    @min_rawdata,
 | 
			
		||||
                                                    @max_rawdata,
 | 
			
		||||
                                                    @avg_rawdata,
 | 
			
		||||
                                                    @sum_rawdata,
 | 
			
		||||
                                                    @is_complete,
 | 
			
		||||
                                                    @repeat_times,
 | 
			
		||||
                                                    @fail_reason
 | 
			
		||||
                                                WHERE ROW_COUNT() = 0;
 | 
			
		||||
                                                ";
 | 
			
		||||
 | 
			
		||||
                                var mySql = $@"BEGIN TRANSACTION;
 | 
			
		||||
 | 
			
		||||
                                            UPDATE archive_electric_meter_week SET 
 | 
			
		||||
                                                    count_rawdata = @count_rawdata,
 | 
			
		||||
@ -371,8 +690,108 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
                                            END
 | 
			
		||||
 | 
			
		||||
                                        COMMIT TRANSACTION;";
 | 
			
		||||
                                await backgroundServiceRepository.ExecuteSql(sql, archiveWeekRawDatas);
 | 
			
		||||
                                
 | 
			
		||||
                                await backgroundServiceRepository.ExecuteSql(sql, electricArchiveWeekRawDatas);
 | 
			
		||||
                                await backgroundServiceMsSqlRepository.ExecuteSql(mySql, electricArchiveWeekRawDatas);
 | 
			
		||||
 | 
			
		||||
                            }
 | 
			
		||||
                            if (waterArchiveWeekRawDatas.Count() > 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                var sql = $@"
 | 
			
		||||
 | 
			
		||||
                                            UPDATE archive_water_meter_week SET 
 | 
			
		||||
                                                    count_rawdata = @count_rawdata,
 | 
			
		||||
                                                    min_rawdata = @min_rawdata,
 | 
			
		||||
                                                    max_rawdata = @max_rawdata,
 | 
			
		||||
                                                    avg_rawdata = @avg_rawdata,
 | 
			
		||||
                                                    sum_rawdata = @sum_rawdata,
 | 
			
		||||
                                                    is_complete = @is_complete,
 | 
			
		||||
                                                    repeat_times = @repeat_times,
 | 
			
		||||
                                                    fail_reason = @fail_reason,
 | 
			
		||||
                                                    updated_at = @updated_at
 | 
			
		||||
                                                 WHERE device_number = @device_number
 | 
			
		||||
                                                    AND point = @point
 | 
			
		||||
                                                    AND start_timestamp = @start_timestamp;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                                                INSERT INTO archive_water_meter_week (
 | 
			
		||||
                                                    device_number,
 | 
			
		||||
                                                    point,
 | 
			
		||||
                                                    start_timestamp,
 | 
			
		||||
                                                    end_timestamp,
 | 
			
		||||
                                                    count_rawdata,
 | 
			
		||||
                                                    min_rawdata,
 | 
			
		||||
                                                    max_rawdata,
 | 
			
		||||
                                                    avg_rawdata,
 | 
			
		||||
                                                    sum_rawdata,
 | 
			
		||||
                                                    is_complete,
 | 
			
		||||
                                                    repeat_times,
 | 
			
		||||
                                                    fail_reason)
 | 
			
		||||
                                                SELECT 
 | 
			
		||||
                                                    @device_number,
 | 
			
		||||
                                                    @point,
 | 
			
		||||
                                                    @start_timestamp,
 | 
			
		||||
                                                    @end_timestamp,
 | 
			
		||||
                                                    @count_rawdata,
 | 
			
		||||
                                                    @min_rawdata,
 | 
			
		||||
                                                    @max_rawdata,
 | 
			
		||||
                                                    @avg_rawdata,
 | 
			
		||||
                                                    @sum_rawdata,
 | 
			
		||||
                                                    @is_complete,
 | 
			
		||||
                                                    @repeat_times,
 | 
			
		||||
                                                    @fail_reason
 | 
			
		||||
                                                WHERE ROW_COUNT() = 0;
 | 
			
		||||
                                                ";
 | 
			
		||||
 | 
			
		||||
                                var mySql = $@"BEGIN TRANSACTION;
 | 
			
		||||
 | 
			
		||||
                                            UPDATE archive_water_meter_week SET 
 | 
			
		||||
                                                    count_rawdata = @count_rawdata,
 | 
			
		||||
                                                    min_rawdata = @min_rawdata,
 | 
			
		||||
                                                    max_rawdata = @max_rawdata,
 | 
			
		||||
                                                    avg_rawdata = @avg_rawdata,
 | 
			
		||||
                                                    sum_rawdata = @sum_rawdata,
 | 
			
		||||
                                                    is_complete = @is_complete,
 | 
			
		||||
                                                    repeat_times = @repeat_times,
 | 
			
		||||
                                                    fail_reason = @fail_reason,
 | 
			
		||||
                                                    updated_at = @updated_at
 | 
			
		||||
                                                 WHERE device_number = @device_number
 | 
			
		||||
                                                    AND point = @point
 | 
			
		||||
                                                    AND start_timestamp = @start_timestamp;
 | 
			
		||||
 | 
			
		||||
                                            IF @@ROWCOUNT = 0
 | 
			
		||||
                                            BEGIN
 | 
			
		||||
                                                INSERT INTO archive_water_meter_week (
 | 
			
		||||
                                                    device_number,
 | 
			
		||||
                                                    point,
 | 
			
		||||
                                                    start_timestamp,
 | 
			
		||||
                                                    end_timestamp,
 | 
			
		||||
                                                    count_rawdata,
 | 
			
		||||
                                                    min_rawdata,
 | 
			
		||||
                                                    max_rawdata,
 | 
			
		||||
                                                    avg_rawdata,
 | 
			
		||||
                                                    sum_rawdata,
 | 
			
		||||
                                                    is_complete,
 | 
			
		||||
                                                    repeat_times,
 | 
			
		||||
                                                    fail_reason)
 | 
			
		||||
                                                VALUES (
 | 
			
		||||
                                                    @device_number,
 | 
			
		||||
                                                    @point,
 | 
			
		||||
                                                    @start_timestamp,
 | 
			
		||||
                                                    @end_timestamp,
 | 
			
		||||
                                                    @count_rawdata,
 | 
			
		||||
                                                    @min_rawdata,
 | 
			
		||||
                                                    @max_rawdata,
 | 
			
		||||
                                                    @avg_rawdata,
 | 
			
		||||
                                                    @sum_rawdata,
 | 
			
		||||
                                                    @is_complete,
 | 
			
		||||
                                                    @repeat_times,
 | 
			
		||||
                                                    @fail_reason)
 | 
			
		||||
                                            END
 | 
			
		||||
 | 
			
		||||
                                        COMMIT TRANSACTION;";
 | 
			
		||||
                                await backgroundServiceRepository.ExecuteSql(sql, waterArchiveWeekRawDatas);
 | 
			
		||||
                                await backgroundServiceMsSqlRepository.ExecuteSql(mySql, waterArchiveWeekRawDatas);
 | 
			
		||||
 | 
			
		||||
                            }
 | 
			
		||||
                            await task_Detail.InsertWorkTime_End("ArchiveElectricMeterDayJob", "Week", "任務完成");
 | 
			
		||||
                        }
 | 
			
		||||
@ -409,8 +828,9 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
                            //stopWatch.Start();
 | 
			
		||||
 | 
			
		||||
                            //抓取每個設備的資料
 | 
			
		||||
                            List<Dictionary<string, object>> archiveMonthRawDatas = new List<Dictionary<string, object>>();
 | 
			
		||||
                            foreach (var deviceNumberPoint in deviceNumberPoints)
 | 
			
		||||
                            List<Dictionary<string, object>> electricArchiveMonthRawDatas = new List<Dictionary<string, object>>();
 | 
			
		||||
                            List<Dictionary<string, object>> waterArchiveMonthRawDatas = new List<Dictionary<string, object>>();
 | 
			
		||||
                            foreach (var deviceNumberPoint in electricDeviceNumberPoints)
 | 
			
		||||
                            {
 | 
			
		||||
                                HttpWebRequest archiveMonthRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
 | 
			
		||||
                                //HttpWebRequest archiveMonthRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
 | 
			
		||||
@ -452,7 +872,7 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
                                    archiveMonthRawData.Add("@sum_rawdata", 0);
 | 
			
		||||
                                    archiveMonthRawData.Add("@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
 | 
			
		||||
 | 
			
		||||
                                    archiveMonthRawDatas.Add(archiveMonthRawData);
 | 
			
		||||
                                    electricArchiveMonthRawDatas.Add(archiveMonthRawData);
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                                if (archiveMonthJsonResult.ContainsKey("obj")) //表示可以讀取到內容
 | 
			
		||||
@ -460,7 +880,61 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
                                    var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveMonthJsonResult);
 | 
			
		||||
                                    if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0)
 | 
			
		||||
                                    {
 | 
			
		||||
                                        archiveMonthRawDatas.AddRange(ArrangeRawDatas);
 | 
			
		||||
                                        electricArchiveMonthRawDatas.AddRange(ArrangeRawDatas);
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                            foreach (var deviceNumberPoint in waterDeviceNumberPoints)
 | 
			
		||||
                            {
 | 
			
		||||
                                HttpWebRequest archiveMonthRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
 | 
			
		||||
                                //HttpWebRequest archiveMonthRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
 | 
			
		||||
                                archiveMonthRequest.Method = "POST";
 | 
			
		||||
                                archiveMonthRequest.Headers.Add("Authorization", "Basic " + encoded);
 | 
			
		||||
                                archiveMonthRequest.PreAuthenticate = true;
 | 
			
		||||
 | 
			
		||||
                                byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter);
 | 
			
		||||
                                using (Stream reqStream = archiveMonthRequest.GetRequestStream())
 | 
			
		||||
                                {
 | 
			
		||||
                                    reqStream.Write(byteArray, 0, byteArray.Length);
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                                HttpWebResponse archiveMonthResponse = (HttpWebResponse)archiveMonthRequest.GetResponse();
 | 
			
		||||
                                var archiveMonthResponseContent = new StreamReader(archiveMonthResponse.GetResponseStream()).ReadToEnd();
 | 
			
		||||
 | 
			
		||||
                                xmlDocument.LoadXml(archiveMonthResponseContent);
 | 
			
		||||
                                string archiveMonthJson = JsonConvert.SerializeXmlNode(xmlDocument);
 | 
			
		||||
                                JObject archiveMonthJsonResult = (JObject)JsonConvert.DeserializeObject(archiveMonthJson);
 | 
			
		||||
 | 
			
		||||
                                if (archiveMonthJsonResult.ContainsKey("err")) //抓取錯誤
 | 
			
		||||
                                {
 | 
			
		||||
                                    //logger.LogError("【ArchiveElectricMeterDayJob】【月歸檔】【取得資料失敗】");
 | 
			
		||||
                                    //logger.LogError("【ArchiveElectricMeterDayJob】【月歸檔】【取得資料失敗】[錯誤內容]:{0}", archiveMonthJsonResult);
 | 
			
		||||
 | 
			
		||||
                                    Dictionary<string, object> archiveMonthRawData = new Dictionary<string, object>();
 | 
			
		||||
                                    archiveMonthRawData.Add("@device_number", deviceNumberPoint.DeviceNumber);
 | 
			
		||||
                                    archiveMonthRawData.Add("@point", deviceNumberPoint.Point);
 | 
			
		||||
                                    archiveMonthRawData.Add("@start_timestamp", startTimestamp.Replace("T", " ").Substring(0, 19));
 | 
			
		||||
                                    archiveMonthRawData.Add("@end_timestamp", endTimestamp.Replace("T", " ").Substring(0, 19));
 | 
			
		||||
                                    archiveMonthRawData.Add("@is_complete", 0);
 | 
			
		||||
                                    archiveMonthRawData.Add("@repeat_times", 0);
 | 
			
		||||
                                    archiveMonthRawData.Add("@fail_reason", archiveMonthJson);
 | 
			
		||||
 | 
			
		||||
                                    archiveMonthRawData.Add("@count_rawdata", 0);
 | 
			
		||||
                                    archiveMonthRawData.Add("@min_rawdata", 0);
 | 
			
		||||
                                    archiveMonthRawData.Add("@max_rawdata", 0);
 | 
			
		||||
                                    archiveMonthRawData.Add("@avg_rawdata", 0);
 | 
			
		||||
                                    archiveMonthRawData.Add("@sum_rawdata", 0);
 | 
			
		||||
                                    archiveMonthRawData.Add("@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
 | 
			
		||||
 | 
			
		||||
                                    waterArchiveMonthRawDatas.Add(archiveMonthRawData);
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                                if (archiveMonthJsonResult.ContainsKey("obj")) //表示可以讀取到內容
 | 
			
		||||
                                {
 | 
			
		||||
                                    var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveMonthJsonResult);
 | 
			
		||||
                                    if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0)
 | 
			
		||||
                                    {
 | 
			
		||||
                                        waterArchiveMonthRawDatas.AddRange(ArrangeRawDatas);
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
@ -468,9 +942,52 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
                            //stopWatch.Stop();
 | 
			
		||||
                            //logger.LogInformation("【ArchiveElectricMeterDayJob】【月歸檔效能檢驗】[取得資料花費時間]{0} 毫秒", stopWatch.ElapsedMilliseconds);
 | 
			
		||||
 | 
			
		||||
                            if (archiveMonthRawDatas.Count() > 0)
 | 
			
		||||
                            if (electricArchiveMonthRawDatas.Count() > 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                var sql = $@"BEGIN TRANSACTION;
 | 
			
		||||
                                var sql = $@"
 | 
			
		||||
                                            UPDATE archive_electric_meter_month SET 
 | 
			
		||||
                                                    count_rawdata = @count_rawdata,
 | 
			
		||||
                                                    min_rawdata = @min_rawdata,
 | 
			
		||||
                                                    max_rawdata = @max_rawdata,
 | 
			
		||||
                                                    avg_rawdata = @avg_rawdata,
 | 
			
		||||
                                                    sum_rawdata = @sum_rawdata,
 | 
			
		||||
                                                    is_complete = @is_complete,
 | 
			
		||||
                                                    repeat_times = @repeat_times,
 | 
			
		||||
                                                    fail_reason = @fail_reason,
 | 
			
		||||
                                                    updated_at = @updated_at
 | 
			
		||||
                                                 WHERE device_number = @device_number
 | 
			
		||||
                                                    AND point = @point
 | 
			
		||||
                                                    AND start_timestamp = @start_timestamp;
 | 
			
		||||
 | 
			
		||||
                                                INSERT INTO archive_electric_meter_month (
 | 
			
		||||
                                                    device_number,
 | 
			
		||||
                                                    point,
 | 
			
		||||
                                                    start_timestamp,
 | 
			
		||||
                                                    end_timestamp,
 | 
			
		||||
                                                    count_rawdata,
 | 
			
		||||
                                                    min_rawdata,
 | 
			
		||||
                                                    max_rawdata,
 | 
			
		||||
                                                    avg_rawdata,
 | 
			
		||||
                                                    sum_rawdata,
 | 
			
		||||
                                                    is_complete,
 | 
			
		||||
                                                    repeat_times,
 | 
			
		||||
                                                    fail_reason)
 | 
			
		||||
                                                SELECT
 | 
			
		||||
                                                    @device_number,
 | 
			
		||||
                                                    @point,
 | 
			
		||||
                                                    @start_timestamp,
 | 
			
		||||
                                                    @end_timestamp,
 | 
			
		||||
                                                    @count_rawdata,
 | 
			
		||||
                                                    @min_rawdata,
 | 
			
		||||
                                                    @max_rawdata,
 | 
			
		||||
                                                    @avg_rawdata,
 | 
			
		||||
                                                    @sum_rawdata,
 | 
			
		||||
                                                    @is_complete,
 | 
			
		||||
                                                    @repeat_times,
 | 
			
		||||
                                                    @fail_reason
 | 
			
		||||
                                                WHERE ROW_COUNT() = 0;";
 | 
			
		||||
 | 
			
		||||
                                var mySql = $@"BEGIN TRANSACTION;
 | 
			
		||||
 | 
			
		||||
                                            UPDATE archive_electric_meter_month SET 
 | 
			
		||||
                                                    count_rawdata = @count_rawdata,
 | 
			
		||||
@ -517,7 +1034,103 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
                                            END
 | 
			
		||||
 | 
			
		||||
                                        COMMIT TRANSACTION;";
 | 
			
		||||
                                await backgroundServiceRepository.ExecuteSql(sql, archiveMonthRawDatas);
 | 
			
		||||
                                await backgroundServiceRepository.ExecuteSql(sql, electricArchiveMonthRawDatas);
 | 
			
		||||
                                await backgroundServiceMsSqlRepository.ExecuteSql(mySql, electricArchiveMonthRawDatas);
 | 
			
		||||
                            }
 | 
			
		||||
                            if (waterArchiveMonthRawDatas.Count() > 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                var sql = $@"
 | 
			
		||||
                                            UPDATE archive_water_meter_month SET 
 | 
			
		||||
                                                    count_rawdata = @count_rawdata,
 | 
			
		||||
                                                    min_rawdata = @min_rawdata,
 | 
			
		||||
                                                    max_rawdata = @max_rawdata,
 | 
			
		||||
                                                    avg_rawdata = @avg_rawdata,
 | 
			
		||||
                                                    sum_rawdata = @sum_rawdata,
 | 
			
		||||
                                                    is_complete = @is_complete,
 | 
			
		||||
                                                    repeat_times = @repeat_times,
 | 
			
		||||
                                                    fail_reason = @fail_reason,
 | 
			
		||||
                                                    updated_at = @updated_at
 | 
			
		||||
                                                 WHERE device_number = @device_number
 | 
			
		||||
                                                    AND point = @point
 | 
			
		||||
                                                    AND start_timestamp = @start_timestamp;
 | 
			
		||||
 | 
			
		||||
                                                INSERT INTO archive_water_meter_month (
 | 
			
		||||
                                                    device_number,
 | 
			
		||||
                                                    point,
 | 
			
		||||
                                                    start_timestamp,
 | 
			
		||||
                                                    end_timestamp,
 | 
			
		||||
                                                    count_rawdata,
 | 
			
		||||
                                                    min_rawdata,
 | 
			
		||||
                                                    max_rawdata,
 | 
			
		||||
                                                    avg_rawdata,
 | 
			
		||||
                                                    sum_rawdata,
 | 
			
		||||
                                                    is_complete,
 | 
			
		||||
                                                    repeat_times,
 | 
			
		||||
                                                    fail_reason)
 | 
			
		||||
                                                SELECT
 | 
			
		||||
                                                    @device_number,
 | 
			
		||||
                                                    @point,
 | 
			
		||||
                                                    @start_timestamp,
 | 
			
		||||
                                                    @end_timestamp,
 | 
			
		||||
                                                    @count_rawdata,
 | 
			
		||||
                                                    @min_rawdata,
 | 
			
		||||
                                                    @max_rawdata,
 | 
			
		||||
                                                    @avg_rawdata,
 | 
			
		||||
                                                    @sum_rawdata,
 | 
			
		||||
                                                    @is_complete,
 | 
			
		||||
                                                    @repeat_times,
 | 
			
		||||
                                                    @fail_reason
 | 
			
		||||
                                                WHERE ROW_COUNT() = 0;";
 | 
			
		||||
 | 
			
		||||
                                var mySql = $@"BEGIN TRANSACTION;
 | 
			
		||||
 | 
			
		||||
                                            UPDATE archive_water_meter_month SET 
 | 
			
		||||
                                                    count_rawdata = @count_rawdata,
 | 
			
		||||
                                                    min_rawdata = @min_rawdata,
 | 
			
		||||
                                                    max_rawdata = @max_rawdata,
 | 
			
		||||
                                                    avg_rawdata = @avg_rawdata,
 | 
			
		||||
                                                    sum_rawdata = @sum_rawdata,
 | 
			
		||||
                                                    is_complete = @is_complete,
 | 
			
		||||
                                                    repeat_times = @repeat_times,
 | 
			
		||||
                                                    fail_reason = @fail_reason,
 | 
			
		||||
                                                    updated_at = @updated_at
 | 
			
		||||
                                                 WHERE device_number = @device_number
 | 
			
		||||
                                                    AND point = @point
 | 
			
		||||
                                                    AND start_timestamp = @start_timestamp;
 | 
			
		||||
 | 
			
		||||
                                            IF @@ROWCOUNT = 0
 | 
			
		||||
                                            BEGIN
 | 
			
		||||
                                                INSERT INTO archive_water_meter_month (
 | 
			
		||||
                                                    device_number,
 | 
			
		||||
                                                    point,
 | 
			
		||||
                                                    start_timestamp,
 | 
			
		||||
                                                    end_timestamp,
 | 
			
		||||
                                                    count_rawdata,
 | 
			
		||||
                                                    min_rawdata,
 | 
			
		||||
                                                    max_rawdata,
 | 
			
		||||
                                                    avg_rawdata,
 | 
			
		||||
                                                    sum_rawdata,
 | 
			
		||||
                                                    is_complete,
 | 
			
		||||
                                                    repeat_times,
 | 
			
		||||
                                                    fail_reason)
 | 
			
		||||
                                                VALUES (
 | 
			
		||||
                                                    @device_number,
 | 
			
		||||
                                                    @point,
 | 
			
		||||
                                                    @start_timestamp,
 | 
			
		||||
                                                    @end_timestamp,
 | 
			
		||||
                                                    @count_rawdata,
 | 
			
		||||
                                                    @min_rawdata,
 | 
			
		||||
                                                    @max_rawdata,
 | 
			
		||||
                                                    @avg_rawdata,
 | 
			
		||||
                                                    @sum_rawdata,
 | 
			
		||||
                                                    @is_complete,
 | 
			
		||||
                                                    @repeat_times,
 | 
			
		||||
                                                    @fail_reason)
 | 
			
		||||
                                            END
 | 
			
		||||
 | 
			
		||||
                                        COMMIT TRANSACTION;";
 | 
			
		||||
                                await backgroundServiceRepository.ExecuteSql(sql, waterArchiveMonthRawDatas);
 | 
			
		||||
                                await backgroundServiceMsSqlRepository.ExecuteSql(mySql, waterArchiveMonthRawDatas);
 | 
			
		||||
                            }
 | 
			
		||||
                            await task_Detail.InsertWorkTime_End("ArchiveElectricMeterDayJob", "Month", "任務完成");
 | 
			
		||||
                        }
 | 
			
		||||
@ -532,13 +1145,13 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
 | 
			
		||||
                    #region 補償機制
 | 
			
		||||
                    //取得連線字串
 | 
			
		||||
                    if(await task_Detail.GetNeedWorkTask("ArchiveElectricMeterDayJob", "Compensate"))
 | 
			
		||||
                    if (await task_Detail.GetNeedWorkTask("ArchiveElectricMeterDayJob", "Compensate"))
 | 
			
		||||
                    {
 | 
			
		||||
                        try
 | 
			
		||||
                        {
 | 
			
		||||
                            await task_Detail.InsertWorkTime("ArchiveElectricMeterDayJob", "Compensate", "任務開始");
 | 
			
		||||
                            ProcEletricMeterService procEletricMeterService = new ProcEletricMeterService(_databaseHelper.GetMSSqlConnectionString());
 | 
			
		||||
                            procEletricMeterService.ArchiveData();
 | 
			
		||||
                            ProcEletricMeterService procEletricMeterService = new ProcEletricMeterService(backgroundServiceRepository, backgroundServiceMsSqlRepository);
 | 
			
		||||
                            await procEletricMeterService.ArchiveData();
 | 
			
		||||
                            await task_Detail.InsertWorkTime_End("ArchiveElectricMeterDayJob", "Compensate", "任務完成");
 | 
			
		||||
                        }
 | 
			
		||||
                        catch(Exception ex)
 | 
			
		||||
@ -547,13 +1160,7 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
                            logger.LogError("【ArchiveElectricMeterDayJob】【補償機制】【任務失敗】");
 | 
			
		||||
                            logger.LogError("【ArchiveElectricMeterDayJob】【補償機制】【任務失敗】[Exception]:{0}", ex.ToString());
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                        
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                    
 | 
			
		||||
                    #endregion 補償機制
 | 
			
		||||
 | 
			
		||||
                    await task_Detail.InsertWorkTime_End("ArchiveElectricMeterDayJob", "All","任務完成");
 | 
			
		||||
 | 
			
		||||
@ -16,6 +16,7 @@ using System.Xml;
 | 
			
		||||
using System.Xml.Serialization;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using NCrontab;
 | 
			
		||||
using BackendWorkerService.Services.Implement;
 | 
			
		||||
 | 
			
		||||
namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
{
 | 
			
		||||
@ -82,7 +83,18 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
            Task_Detail task_Detail = new Task_Detail(loggers, backendRepository);
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                var obixApiConfig = new ObixApiConfig();
 | 
			
		||||
                string encoded = string.Empty;
 | 
			
		||||
                #region 取得obix 設定
 | 
			
		||||
                var sqlObix = $@"SELECT system_value as Value, system_key as Name FROM variable WHERE deleted = 0 AND system_type = 'obixConfig'";
 | 
			
		||||
 | 
			
		||||
                var variableObix = await backgroundServiceRepository.GetAllAsync<KeyValue>(sqlObix);
 | 
			
		||||
                obixApiConfig.ApiBase = variableObix.Where(x => x.Name == "ApiBase").Select(x => x.Value).FirstOrDefault();
 | 
			
		||||
                obixApiConfig.UserName = variableObix.Where(x => x.Name == "UserName").Select(x => x.Value).FirstOrDefault();
 | 
			
		||||
                obixApiConfig.Password = variableObix.Where(x => x.Name == "Password").Select(x => x.Value).FirstOrDefault();
 | 
			
		||||
 | 
			
		||||
                encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(obixApiConfig.UserName + ":" + obixApiConfig.Password));
 | 
			
		||||
                #endregion 取得obix 設定
 | 
			
		||||
                //取得氣象預報
 | 
			
		||||
                if (await task_Detail.GetNeedWorkTask("WeatherAPI", "api_weateher"))
 | 
			
		||||
                {
 | 
			
		||||
@ -211,7 +223,7 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
                                var val = RainValue(observation.Alert.MsgType, observation.Alert.Info[0].Headline);
 | 
			
		||||
                                if (val < 5)
 | 
			
		||||
                                {
 | 
			
		||||
                                    var ReStr = Fetch_PostWithJSONFormat("http://60.251.164.125:8080/obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_MET1/SeverityLEVL_RAIN/set", val.ToString());
 | 
			
		||||
                                    var ReStr = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_MET1/SeverityLEVL_RAIN/set", val.ToString());
 | 
			
		||||
                                    UpdatedNiagara("api_rain", ReStr, id);
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
@ -232,8 +244,8 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
                                { "@msgType", observation.Alert.MsgType},
 | 
			
		||||
                                { "@headline", observation.Alert.Info.Headline},
 | 
			
		||||
                                { "@areaDesc", area},
 | 
			
		||||
                                { "@onset", observation.Alert.Info.Onset},
 | 
			
		||||
                                { "@expires", observation.Alert.Info.Expires},
 | 
			
		||||
                                { "@onset", observation.Alert.Info.Onset.ToString("yyyy-MM-dd HH:mm:ss")},
 | 
			
		||||
                                { "@expires", observation.Alert.Info.Expires.ToString("yyyy-MM-dd HH:mm:ss")},
 | 
			
		||||
                                { "@created_by", "system"},
 | 
			
		||||
                                { "@created_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")},
 | 
			
		||||
                            };
 | 
			
		||||
@ -243,7 +255,7 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
                                var val = RainValue(observation.Alert.MsgType, observation.Alert.Info.Headline);
 | 
			
		||||
                                if (val < 5)
 | 
			
		||||
                                {
 | 
			
		||||
                                    var ReStr = Fetch_PostWithJSONFormat("http://60.251.164.125:8080/obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_MET1/SeverityLEVL_RAIN/set", val.ToString());
 | 
			
		||||
                                    var ReStr = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_MET1/SeverityLEVL_RAIN/set", val.ToString());
 | 
			
		||||
                                    UpdatedNiagara("api_rain", ReStr, id);
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
@ -296,7 +308,7 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
                                if (observation.Alert.Info[0].Urgency != null && observation.Alert.Info[0].Urgency != "Expected")
 | 
			
		||||
                                {
 | 
			
		||||
 | 
			
		||||
                                    var ReStr = Fetch_PostWithJSONFormat("http://60.251.164.125:8080/obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_MET2/SeverityLEVL_Typhoon/set", observation.Alert.Info[0].Urgency);
 | 
			
		||||
                                    var ReStr = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_MET2/SeverityLEVL_Typhoon/set", observation.Alert.Info[0].Urgency);
 | 
			
		||||
                                    UpdatedNiagara("api_typhoon", ReStr, id);
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
@ -317,8 +329,8 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
                                { "@areaDesc", area},
 | 
			
		||||
                                { "@urgency",observation.Alert.Info.Urgency},
 | 
			
		||||
                                { "@severity",observation.Alert.Info.Severity},
 | 
			
		||||
                                { "@onset", observation.Alert.Info.Onset},
 | 
			
		||||
                                { "@expires", observation.Alert.Info.Expires},
 | 
			
		||||
                                { "@onset", observation.Alert.Info.Onset.ToString("yyyy-MM-dd HH:mm:ss")},
 | 
			
		||||
                                { "@expires", observation.Alert.Info.Expires.ToString("yyyy-MM-dd HH:mm:ss")},
 | 
			
		||||
                                { "@created_by", "system"},
 | 
			
		||||
                                { "@created_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")},
 | 
			
		||||
                            };
 | 
			
		||||
@ -328,7 +340,7 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
                                if (observation.Alert.Info.Urgency != null && observation.Alert.Info.Urgency != "Expected")
 | 
			
		||||
                                {
 | 
			
		||||
 | 
			
		||||
                                    var ReStr = Fetch_PostWithJSONFormat("http://60.251.164.125:8080/obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_MET2/SeverityLEVL_Typhoon/set", observation.Alert.Info.Urgency);
 | 
			
		||||
                                    var ReStr = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_MET2/SeverityLEVL_Typhoon/set", observation.Alert.Info.Urgency);
 | 
			
		||||
                                    UpdatedNiagara("api_typhoon", ReStr, id);
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
@ -353,8 +365,8 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
                        var UVUri = "https://opendata.cwb.gov.tw/api/v1/rest/datastore/E-A0015-001?Authorization=CWB-EA24220B-DDCC-4188-84E5-AD37A0E03F80&format=JSON&areaName=%E8%87%BA%E5%8C%97%E5%B8%82";
 | 
			
		||||
                        HttpResponseMessage response = client.GetAsync(UVUri).Result;
 | 
			
		||||
                        String jsonUVs = response.Content.ReadAsStringAsync().Result.ToString();
 | 
			
		||||
                        var observation = JsonConvert.DeserializeObject<Root2>(jsonUVs);
 | 
			
		||||
                        if (observation.Success != "true")
 | 
			
		||||
                        var observation = QuickType.Welcome.FromJson(jsonUVs);
 | 
			
		||||
                        if (!observation.Success)
 | 
			
		||||
                        {
 | 
			
		||||
                            logger.LogInformation("【WeatherAPIJob】【取得地震觀測資料不正確】");
 | 
			
		||||
                        }
 | 
			
		||||
@ -362,7 +374,7 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
                        {
 | 
			
		||||
                            logger.LogInformation("【WeatherAPIJob】【開始存入地震觀測到資料庫】");
 | 
			
		||||
                            List<Dictionary<string, object>> EarthquakeAPIdbS = new List<Dictionary<string, object>>();
 | 
			
		||||
                            var nowNo = await backendRepository.GetOneAsync<int>("select iif( Max(earthquakeNo) is null ,0,Max(earthquakeNo)) earthquakeNo from api_earthquake where newEarthquake = 1");
 | 
			
		||||
                            var nowNo = await backendRepository.GetOneAsync<int>("select if( Max(earthquakeNo) is null ,0,Max(earthquakeNo)) earthquakeNo from api_earthquake where newEarthquake = 1");
 | 
			
		||||
                            foreach (var a in observation.Records.Earthquake)
 | 
			
		||||
                            {
 | 
			
		||||
                                if (a.EarthquakeNo <= nowNo)
 | 
			
		||||
@ -371,8 +383,8 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
                                    {
 | 
			
		||||
                                        { "@earthquakeNo", a.EarthquakeNo},
 | 
			
		||||
                                        { "@newEarthquake", 0},
 | 
			
		||||
                                        { "@originTime", a.EarthquakeInfo.OriginTime},
 | 
			
		||||
                                        { "@magnitudeValue", a.EarthquakeInfo.Magnitude.MagnitudeValue},
 | 
			
		||||
                                        { "@originTime", DateTime.Parse(a.EarthquakeInfo.OriginTime.ToString(), System.Globalization.CultureInfo.CurrentCulture)},
 | 
			
		||||
                                        { "@magnitudeValue", a.EarthquakeInfo.EarthquakeMagnitude.MagnitudeValue},
 | 
			
		||||
                                        { "@areaName", null},
 | 
			
		||||
                                        { "@areaIntensity", null},
 | 
			
		||||
                                        { "@created_by", "system"},
 | 
			
		||||
@ -383,22 +395,22 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
                                }
 | 
			
		||||
                                else
 | 
			
		||||
                                {
 | 
			
		||||
                                    if (a.Intensity.ShakingArea.Count > 0)
 | 
			
		||||
                                    if (a.Intensity.ShakingArea.Length > 0)
 | 
			
		||||
                                    {
 | 
			
		||||
                                        Dictionary<string, object> EarthquakeAPIdb = new Dictionary<string, object>()
 | 
			
		||||
                                        {
 | 
			
		||||
                                            { "@earthquakeNo", a.EarthquakeNo},
 | 
			
		||||
                                            { "@newEarthquake", 1},
 | 
			
		||||
                                            { "@originTime", a.EarthquakeInfo.OriginTime},
 | 
			
		||||
                                            { "@magnitudeValue", a.EarthquakeInfo.Magnitude.MagnitudeValue},
 | 
			
		||||
                                            { "@areaName", a.Intensity.ShakingArea[0].AreaName},
 | 
			
		||||
                                            { "@areaIntensity", a.Intensity.ShakingArea[0].AreaIntensity.Value},
 | 
			
		||||
                                            { "@originTime", DateTime.Parse(a.EarthquakeInfo.OriginTime.ToString(), System.Globalization.CultureInfo.CurrentCulture)},
 | 
			
		||||
                                            { "@magnitudeValue", a.EarthquakeInfo.EarthquakeMagnitude.MagnitudeValue},
 | 
			
		||||
                                            { "@areaName", a.Intensity.ShakingArea[0].CountyName},
 | 
			
		||||
                                            { "@areaIntensity", a.Intensity.ShakingArea[0].AreaIntensity},
 | 
			
		||||
                                            { "@created_by", "system"},
 | 
			
		||||
                                            { "@created_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")},
 | 
			
		||||
                                        };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                                        var Nag = Fetch_PostWithJSONFormat("http://60.251.164.125:8080/obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_GEO/SeverityLEVL_LMI/set", a.Intensity.ShakingArea[0].AreaIntensity.Value.ToString());
 | 
			
		||||
                                        var Nag = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_GEO/SeverityLEVL_LMI/set", a.Intensity.ShakingArea[0].AreaIntensity.ToString());
 | 
			
		||||
 | 
			
		||||
                                        if (Nag.Contains("err"))
 | 
			
		||||
                                        {
 | 
			
		||||
@ -418,15 +430,15 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
                                        {
 | 
			
		||||
                                            { "@earthquakeNo", a.EarthquakeNo},
 | 
			
		||||
                                            { "@newEarthquake", 1},
 | 
			
		||||
                                            { "@originTime", a.EarthquakeInfo.OriginTime},
 | 
			
		||||
                                            { "@magnitudeValue", a.EarthquakeInfo.Magnitude.MagnitudeValue},
 | 
			
		||||
                                            { "@originTime", DateTime.Parse(a.EarthquakeInfo.OriginTime.ToString(), System.Globalization.CultureInfo.CurrentCulture)},
 | 
			
		||||
                                            { "@magnitudeValue", a.EarthquakeInfo.EarthquakeMagnitude.MagnitudeValue},
 | 
			
		||||
                                            { "@areaName", null},
 | 
			
		||||
                                            { "@areaIntensity", null},
 | 
			
		||||
                                            { "@created_by", "system"},
 | 
			
		||||
                                            { "@created_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")},
 | 
			
		||||
                                        };
 | 
			
		||||
 | 
			
		||||
                                        var Nag = Fetch_PostWithJSONFormat("http://60.251.164.125:8080/obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_GEO/SeverityLEVL_LMI/set", "NULL");
 | 
			
		||||
                                        var Nag = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_GEO/SeverityLEVL_LMI/set", "NULL");
 | 
			
		||||
                                        if (Nag.Contains("err"))
 | 
			
		||||
                                        {
 | 
			
		||||
                                            EarthquakeAPIdb.Add("@niagara", Nag);
 | 
			
		||||
@ -458,23 +470,23 @@ namespace BackendWorkerService.Quartz.Jobs
 | 
			
		||||
                                    weather_type,
 | 
			
		||||
                                    get_value
 | 
			
		||||
                            FROM api_weateher
 | 
			
		||||
                            where id in (select MAX(id) from api_weateher where start_time < GETDATE() group by weather_type)
 | 
			
		||||
                            where id in (select MAX(id) from api_weateher where start_time < NOW() group by weather_type)
 | 
			
		||||
                            order by start_time desc";
 | 
			
		||||
                        var types = await backendRepository.GetAllAsync<ShowWeather>(sql);
 | 
			
		||||
                        var T = types.Where(a => a.weather_type == "T").FirstOrDefault();
 | 
			
		||||
                        var RbT = Fetch_PostWithJSONFormat("http://60.251.164.125:8080/obix/config/Arena/D2/CWB/L110/OPD/D2_CWB_L110_OPD_element/T/set", T.get_value);
 | 
			
		||||
                        var RbT = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/OPD/D2_CWB_L110_OPD_element/T/set", T.get_value);
 | 
			
		||||
                        UpdatedNiagara("api_weateher", RbT, T.id);
 | 
			
		||||
 | 
			
		||||
                        var RH = types.Where(a => a.weather_type == "RH").FirstOrDefault();
 | 
			
		||||
                        var RHT = Fetch_PostWithJSONFormat("http://60.251.164.125:8080/obix/config/Arena/D2/CWB/L110/OPD/D2_CWB_L110_OPD_element/RH/set", RH.get_value);
 | 
			
		||||
                        var RHT = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/OPD/D2_CWB_L110_OPD_element/RH/set", RH.get_value);
 | 
			
		||||
                        UpdatedNiagara("api_weateher", RHT, RH.id);
 | 
			
		||||
 | 
			
		||||
                        var PoP12h = types.Where(a => a.weather_type == "PoP12h").FirstOrDefault();
 | 
			
		||||
                        var PoP12hT = Fetch_PostWithJSONFormat("http://60.251.164.125:8080/obix/config/Arena/D2/CWB/L110/OPD/D2_CWB_L110_OPD_element/PoP6h/set", PoP12h.get_value);
 | 
			
		||||
                        var PoP12hT = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/OPD/D2_CWB_L110_OPD_element/PoP6h/set", PoP12h.get_value);
 | 
			
		||||
                        UpdatedNiagara("api_weateher", PoP12hT, PoP12h.id);
 | 
			
		||||
 | 
			
		||||
                        var Wx = types.Where(a => a.weather_type == "Wx").FirstOrDefault();
 | 
			
		||||
                        var WxT = Fetch_PostWithJSONFormat("http://60.251.164.125:8080/obix/config/Arena/D2/CWB/L110/OPD/D2_CWB_L110_OPD_element/Wx/set", Wx.get_value);
 | 
			
		||||
                        var WxT = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/OPD/D2_CWB_L110_OPD_element/Wx/set", Wx.get_value);
 | 
			
		||||
                        UpdatedNiagara("api_weateher", WxT, Wx.id);
 | 
			
		||||
                        await task_Detail.InsertWorkTime_End("WeatherAPI", "set_weather");
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										640
									
								
								BackendWorkerService/Services/Implement/Quicktype.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										640
									
								
								BackendWorkerService/Services/Implement/Quicktype.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,640 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
// <auto-generated />
 | 
			
		||||
//
 | 
			
		||||
// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
 | 
			
		||||
//
 | 
			
		||||
//    using QuickType;
 | 
			
		||||
//
 | 
			
		||||
//    var welcome = Welcome.FromJson(jsonString);
 | 
			
		||||
 | 
			
		||||
namespace QuickType
 | 
			
		||||
{
 | 
			
		||||
    using System;
 | 
			
		||||
    using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
    using System.Globalization;
 | 
			
		||||
    using Newtonsoft.Json;
 | 
			
		||||
    using Newtonsoft.Json.Converters;
 | 
			
		||||
 | 
			
		||||
    public partial class Welcome
 | 
			
		||||
    {
 | 
			
		||||
        [JsonProperty("success")]
 | 
			
		||||
        [JsonConverter(typeof(ParseStringConverter))]
 | 
			
		||||
        public bool Success { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("result")]
 | 
			
		||||
        public Result Result { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("records")]
 | 
			
		||||
        public Records Records { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public partial class Records
 | 
			
		||||
    {
 | 
			
		||||
        [JsonProperty("datasetDescription")]
 | 
			
		||||
        public DatasetDescription DatasetDescription { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("Earthquake")]
 | 
			
		||||
        public Earthquake[] Earthquake { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public partial class Earthquake
 | 
			
		||||
    {
 | 
			
		||||
        [JsonProperty("EarthquakeNo")]
 | 
			
		||||
        public long EarthquakeNo { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("ReportType")]
 | 
			
		||||
        public DatasetDescription ReportType { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("ReportColor")]
 | 
			
		||||
        public ReportColor ReportColor { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("ReportContent")]
 | 
			
		||||
        public string ReportContent { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("ReportImageURI")]
 | 
			
		||||
        public Uri ReportImageUri { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("ReportRemark")]
 | 
			
		||||
        public ReportRemark ReportRemark { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("Web")]
 | 
			
		||||
        public Uri Web { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("ShakemapImageURI")]
 | 
			
		||||
        public Uri ShakemapImageUri { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("EarthquakeInfo")]
 | 
			
		||||
        public EarthquakeInfo EarthquakeInfo { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("Intensity")]
 | 
			
		||||
        public Intensity Intensity { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public partial class EarthquakeInfo
 | 
			
		||||
    {
 | 
			
		||||
        [JsonProperty("OriginTime")]
 | 
			
		||||
        public DateTimeOffset OriginTime { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("Source")]
 | 
			
		||||
        public Source Source { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("FocalDepth")]
 | 
			
		||||
        public double FocalDepth { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("Epicenter")]
 | 
			
		||||
        public Epicenter Epicenter { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("EarthquakeMagnitude")]
 | 
			
		||||
        public EarthquakeMagnitude EarthquakeMagnitude { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public partial class EarthquakeMagnitude
 | 
			
		||||
    {
 | 
			
		||||
        [JsonProperty("MagnitudeType")]
 | 
			
		||||
        public MagnitudeType MagnitudeType { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("MagnitudeValue")]
 | 
			
		||||
        public double MagnitudeValue { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public partial class Epicenter
 | 
			
		||||
    {
 | 
			
		||||
        [JsonProperty("Location")]
 | 
			
		||||
        public string Location { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("EpicenterLatitude")]
 | 
			
		||||
        public double EpicenterLatitude { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("EpicenterLongitude")]
 | 
			
		||||
        public double EpicenterLongitude { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public partial class Intensity
 | 
			
		||||
    {
 | 
			
		||||
        [JsonProperty("ShakingArea")]
 | 
			
		||||
        public ShakingArea[] ShakingArea { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public partial class ShakingArea
 | 
			
		||||
    {
 | 
			
		||||
        [JsonProperty("AreaDesc")]
 | 
			
		||||
        public string AreaDesc { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("CountyName")]
 | 
			
		||||
        public string CountyName { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("InfoStatus", NullValueHandling = NullValueHandling.Ignore)]
 | 
			
		||||
        public InfoStatus? InfoStatus { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("AreaIntensity")]
 | 
			
		||||
        public AreaIntensityEnum AreaIntensity { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("EqStation")]
 | 
			
		||||
        public EqStation[] EqStation { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public partial class EqStation
 | 
			
		||||
    {
 | 
			
		||||
        [JsonProperty("pga", NullValueHandling = NullValueHandling.Ignore)]
 | 
			
		||||
        public Pga Pga { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("pgv", NullValueHandling = NullValueHandling.Ignore)]
 | 
			
		||||
        public Pga Pgv { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("StationName")]
 | 
			
		||||
        public string StationName { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("StationID")]
 | 
			
		||||
        public string StationId { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("InfoStatus", NullValueHandling = NullValueHandling.Ignore)]
 | 
			
		||||
        public InfoStatus? InfoStatus { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("BackAzimuth")]
 | 
			
		||||
        public double BackAzimuth { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("EpicenterDistance")]
 | 
			
		||||
        public double EpicenterDistance { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("SeismicIntensity")]
 | 
			
		||||
        public AreaIntensityEnum SeismicIntensity { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("StationLatitude")]
 | 
			
		||||
        public double StationLatitude { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("StationLongitude")]
 | 
			
		||||
        public double StationLongitude { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("WaveImageURI", NullValueHandling = NullValueHandling.Ignore)]
 | 
			
		||||
        public Uri WaveImageUri { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public partial class Pga
 | 
			
		||||
    {
 | 
			
		||||
        [JsonProperty("unit")]
 | 
			
		||||
        public Unit Unit { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("EWComponent")]
 | 
			
		||||
        public double EwComponent { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("NSComponent")]
 | 
			
		||||
        public double NsComponent { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("VComponent")]
 | 
			
		||||
        public double VComponent { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("IntScaleValue")]
 | 
			
		||||
        public double IntScaleValue { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public partial class Result
 | 
			
		||||
    {
 | 
			
		||||
        [JsonProperty("resource_id")]
 | 
			
		||||
        public string ResourceId { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("fields")]
 | 
			
		||||
        public Field[] Fields { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public partial class Field
 | 
			
		||||
    {
 | 
			
		||||
        [JsonProperty("id")]
 | 
			
		||||
        public string Id { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("type")]
 | 
			
		||||
        public TypeEnum Type { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public enum DatasetDescription { 地震報告 };
 | 
			
		||||
 | 
			
		||||
    public enum MagnitudeType { 芮氏規模 };
 | 
			
		||||
 | 
			
		||||
    public enum Source { 中央氣象局 };
 | 
			
		||||
 | 
			
		||||
    public enum AreaIntensityEnum { The1級, The2級, The3級, The4級 };
 | 
			
		||||
 | 
			
		||||
    public enum InfoStatus { Observe };
 | 
			
		||||
 | 
			
		||||
    public enum Unit { Gal, Kine };
 | 
			
		||||
 | 
			
		||||
    public enum ReportColor { 綠色 };
 | 
			
		||||
 | 
			
		||||
    public enum ReportRemark { 本報告係中央氣象局地震觀測網即時地震資料地震速報之結果 };
 | 
			
		||||
 | 
			
		||||
    public enum TypeEnum { Float, Integer, String, Timestamp };
 | 
			
		||||
 | 
			
		||||
    public partial class Welcome
 | 
			
		||||
    {
 | 
			
		||||
        public static Welcome FromJson(string json) => JsonConvert.DeserializeObject<Welcome>(json, QuickType.Converter.Settings);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class Serialize
 | 
			
		||||
    {
 | 
			
		||||
        public static string ToJson(this Welcome self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal static class Converter
 | 
			
		||||
    {
 | 
			
		||||
        public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
 | 
			
		||||
        {
 | 
			
		||||
            MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
 | 
			
		||||
            DateParseHandling = DateParseHandling.None,
 | 
			
		||||
            Converters =
 | 
			
		||||
            {
 | 
			
		||||
                MagnitudeTypeConverter.Singleton,
 | 
			
		||||
                SourceConverter.Singleton,
 | 
			
		||||
                AreaIntensityEnumConverter.Singleton,
 | 
			
		||||
                InfoStatusConverter.Singleton,
 | 
			
		||||
                UnitConverter.Singleton,
 | 
			
		||||
                ReportColorConverter.Singleton,
 | 
			
		||||
                ReportRemarkConverter.Singleton,
 | 
			
		||||
                DatasetDescriptionConverter.Singleton,
 | 
			
		||||
                TypeEnumConverter.Singleton,
 | 
			
		||||
                new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
 | 
			
		||||
            },
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal class MagnitudeTypeConverter : JsonConverter
 | 
			
		||||
    {
 | 
			
		||||
        public override bool CanConvert(Type t) => t == typeof(MagnitudeType) || t == typeof(MagnitudeType?);
 | 
			
		||||
 | 
			
		||||
        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
 | 
			
		||||
        {
 | 
			
		||||
            if (reader.TokenType == JsonToken.Null) return null;
 | 
			
		||||
            var value = serializer.Deserialize<string>(reader);
 | 
			
		||||
            if (value == "芮氏規模")
 | 
			
		||||
            {
 | 
			
		||||
                return MagnitudeType.芮氏規模;
 | 
			
		||||
            }
 | 
			
		||||
            throw new Exception("Cannot unmarshal type MagnitudeType");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
 | 
			
		||||
        {
 | 
			
		||||
            if (untypedValue == null)
 | 
			
		||||
            {
 | 
			
		||||
                serializer.Serialize(writer, null);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            var value = (MagnitudeType)untypedValue;
 | 
			
		||||
            if (value == MagnitudeType.芮氏規模)
 | 
			
		||||
            {
 | 
			
		||||
                serializer.Serialize(writer, "芮氏規模");
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            throw new Exception("Cannot marshal type MagnitudeType");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static readonly MagnitudeTypeConverter Singleton = new MagnitudeTypeConverter();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal class SourceConverter : JsonConverter
 | 
			
		||||
    {
 | 
			
		||||
        public override bool CanConvert(Type t) => t == typeof(Source) || t == typeof(Source?);
 | 
			
		||||
 | 
			
		||||
        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
 | 
			
		||||
        {
 | 
			
		||||
            if (reader.TokenType == JsonToken.Null) return null;
 | 
			
		||||
            var value = serializer.Deserialize<string>(reader);
 | 
			
		||||
            if (value == "中央氣象局")
 | 
			
		||||
            {
 | 
			
		||||
                return Source.中央氣象局;
 | 
			
		||||
            }
 | 
			
		||||
            throw new Exception("Cannot unmarshal type Source");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
 | 
			
		||||
        {
 | 
			
		||||
            if (untypedValue == null)
 | 
			
		||||
            {
 | 
			
		||||
                serializer.Serialize(writer, null);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            var value = (Source)untypedValue;
 | 
			
		||||
            if (value == Source.中央氣象局)
 | 
			
		||||
            {
 | 
			
		||||
                serializer.Serialize(writer, "中央氣象局");
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            throw new Exception("Cannot marshal type Source");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static readonly SourceConverter Singleton = new SourceConverter();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal class AreaIntensityEnumConverter : JsonConverter
 | 
			
		||||
    {
 | 
			
		||||
        public override bool CanConvert(Type t) => t == typeof(AreaIntensityEnum) || t == typeof(AreaIntensityEnum?);
 | 
			
		||||
 | 
			
		||||
        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
 | 
			
		||||
        {
 | 
			
		||||
            if (reader.TokenType == JsonToken.Null) return null;
 | 
			
		||||
            var value = serializer.Deserialize<string>(reader);
 | 
			
		||||
            switch (value)
 | 
			
		||||
            {
 | 
			
		||||
                case "1級":
 | 
			
		||||
                    return AreaIntensityEnum.The1級;
 | 
			
		||||
                case "2級":
 | 
			
		||||
                    return AreaIntensityEnum.The2級;
 | 
			
		||||
                case "3級":
 | 
			
		||||
                    return AreaIntensityEnum.The3級;
 | 
			
		||||
                case "4級":
 | 
			
		||||
                    return AreaIntensityEnum.The4級;
 | 
			
		||||
            }
 | 
			
		||||
            throw new Exception("Cannot unmarshal type AreaIntensityEnum");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
 | 
			
		||||
        {
 | 
			
		||||
            if (untypedValue == null)
 | 
			
		||||
            {
 | 
			
		||||
                serializer.Serialize(writer, null);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            var value = (AreaIntensityEnum)untypedValue;
 | 
			
		||||
            switch (value)
 | 
			
		||||
            {
 | 
			
		||||
                case AreaIntensityEnum.The1級:
 | 
			
		||||
                    serializer.Serialize(writer, "1級");
 | 
			
		||||
                    return;
 | 
			
		||||
                case AreaIntensityEnum.The2級:
 | 
			
		||||
                    serializer.Serialize(writer, "2級");
 | 
			
		||||
                    return;
 | 
			
		||||
                case AreaIntensityEnum.The3級:
 | 
			
		||||
                    serializer.Serialize(writer, "3級");
 | 
			
		||||
                    return;
 | 
			
		||||
                case AreaIntensityEnum.The4級:
 | 
			
		||||
                    serializer.Serialize(writer, "4級");
 | 
			
		||||
                    return;
 | 
			
		||||
            }
 | 
			
		||||
            throw new Exception("Cannot marshal type AreaIntensityEnum");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static readonly AreaIntensityEnumConverter Singleton = new AreaIntensityEnumConverter();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal class InfoStatusConverter : JsonConverter
 | 
			
		||||
    {
 | 
			
		||||
        public override bool CanConvert(Type t) => t == typeof(InfoStatus) || t == typeof(InfoStatus?);
 | 
			
		||||
 | 
			
		||||
        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
 | 
			
		||||
        {
 | 
			
		||||
            if (reader.TokenType == JsonToken.Null) return null;
 | 
			
		||||
            var value = serializer.Deserialize<string>(reader);
 | 
			
		||||
            if (value == "observe")
 | 
			
		||||
            {
 | 
			
		||||
                return InfoStatus.Observe;
 | 
			
		||||
            }
 | 
			
		||||
            throw new Exception("Cannot unmarshal type InfoStatus");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
 | 
			
		||||
        {
 | 
			
		||||
            if (untypedValue == null)
 | 
			
		||||
            {
 | 
			
		||||
                serializer.Serialize(writer, null);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            var value = (InfoStatus)untypedValue;
 | 
			
		||||
            if (value == InfoStatus.Observe)
 | 
			
		||||
            {
 | 
			
		||||
                serializer.Serialize(writer, "observe");
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            throw new Exception("Cannot marshal type InfoStatus");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static readonly InfoStatusConverter Singleton = new InfoStatusConverter();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal class UnitConverter : JsonConverter
 | 
			
		||||
    {
 | 
			
		||||
        public override bool CanConvert(Type t) => t == typeof(Unit) || t == typeof(Unit?);
 | 
			
		||||
 | 
			
		||||
        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
 | 
			
		||||
        {
 | 
			
		||||
            if (reader.TokenType == JsonToken.Null) return null;
 | 
			
		||||
            var value = serializer.Deserialize<string>(reader);
 | 
			
		||||
            switch (value)
 | 
			
		||||
            {
 | 
			
		||||
                case "gal":
 | 
			
		||||
                    return Unit.Gal;
 | 
			
		||||
                case "kine":
 | 
			
		||||
                    return Unit.Kine;
 | 
			
		||||
            }
 | 
			
		||||
            throw new Exception("Cannot unmarshal type Unit");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
 | 
			
		||||
        {
 | 
			
		||||
            if (untypedValue == null)
 | 
			
		||||
            {
 | 
			
		||||
                serializer.Serialize(writer, null);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            var value = (Unit)untypedValue;
 | 
			
		||||
            switch (value)
 | 
			
		||||
            {
 | 
			
		||||
                case Unit.Gal:
 | 
			
		||||
                    serializer.Serialize(writer, "gal");
 | 
			
		||||
                    return;
 | 
			
		||||
                case Unit.Kine:
 | 
			
		||||
                    serializer.Serialize(writer, "kine");
 | 
			
		||||
                    return;
 | 
			
		||||
            }
 | 
			
		||||
            throw new Exception("Cannot marshal type Unit");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static readonly UnitConverter Singleton = new UnitConverter();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal class ReportColorConverter : JsonConverter
 | 
			
		||||
    {
 | 
			
		||||
        public override bool CanConvert(Type t) => t == typeof(ReportColor) || t == typeof(ReportColor?);
 | 
			
		||||
 | 
			
		||||
        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
 | 
			
		||||
        {
 | 
			
		||||
            if (reader.TokenType == JsonToken.Null) return null;
 | 
			
		||||
            var value = serializer.Deserialize<string>(reader);
 | 
			
		||||
            if (value == "綠色")
 | 
			
		||||
            {
 | 
			
		||||
                return ReportColor.綠色;
 | 
			
		||||
            }
 | 
			
		||||
            throw new Exception("Cannot unmarshal type ReportColor");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
 | 
			
		||||
        {
 | 
			
		||||
            if (untypedValue == null)
 | 
			
		||||
            {
 | 
			
		||||
                serializer.Serialize(writer, null);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            var value = (ReportColor)untypedValue;
 | 
			
		||||
            if (value == ReportColor.綠色)
 | 
			
		||||
            {
 | 
			
		||||
                serializer.Serialize(writer, "綠色");
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            throw new Exception("Cannot marshal type ReportColor");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static readonly ReportColorConverter Singleton = new ReportColorConverter();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal class ReportRemarkConverter : JsonConverter
 | 
			
		||||
    {
 | 
			
		||||
        public override bool CanConvert(Type t) => t == typeof(ReportRemark) || t == typeof(ReportRemark?);
 | 
			
		||||
 | 
			
		||||
        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
 | 
			
		||||
        {
 | 
			
		||||
            if (reader.TokenType == JsonToken.Null) return null;
 | 
			
		||||
            var value = serializer.Deserialize<string>(reader);
 | 
			
		||||
            if (value == "本報告係中央氣象局地震觀測網即時地震資料地震速報之結果。")
 | 
			
		||||
            {
 | 
			
		||||
                return ReportRemark.本報告係中央氣象局地震觀測網即時地震資料地震速報之結果;
 | 
			
		||||
            }
 | 
			
		||||
            throw new Exception("Cannot unmarshal type ReportRemark");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
 | 
			
		||||
        {
 | 
			
		||||
            if (untypedValue == null)
 | 
			
		||||
            {
 | 
			
		||||
                serializer.Serialize(writer, null);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            var value = (ReportRemark)untypedValue;
 | 
			
		||||
            if (value == ReportRemark.本報告係中央氣象局地震觀測網即時地震資料地震速報之結果)
 | 
			
		||||
            {
 | 
			
		||||
                serializer.Serialize(writer, "本報告係中央氣象局地震觀測網即時地震資料地震速報之結果。");
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            throw new Exception("Cannot marshal type ReportRemark");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static readonly ReportRemarkConverter Singleton = new ReportRemarkConverter();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal class DatasetDescriptionConverter : JsonConverter
 | 
			
		||||
    {
 | 
			
		||||
        public override bool CanConvert(Type t) => t == typeof(DatasetDescription) || t == typeof(DatasetDescription?);
 | 
			
		||||
 | 
			
		||||
        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
 | 
			
		||||
        {
 | 
			
		||||
            if (reader.TokenType == JsonToken.Null) return null;
 | 
			
		||||
            var value = serializer.Deserialize<string>(reader);
 | 
			
		||||
            if (value == "地震報告")
 | 
			
		||||
            {
 | 
			
		||||
                return DatasetDescription.地震報告;
 | 
			
		||||
            }
 | 
			
		||||
            throw new Exception("Cannot unmarshal type DatasetDescription");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
 | 
			
		||||
        {
 | 
			
		||||
            if (untypedValue == null)
 | 
			
		||||
            {
 | 
			
		||||
                serializer.Serialize(writer, null);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            var value = (DatasetDescription)untypedValue;
 | 
			
		||||
            if (value == DatasetDescription.地震報告)
 | 
			
		||||
            {
 | 
			
		||||
                serializer.Serialize(writer, "地震報告");
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            throw new Exception("Cannot marshal type DatasetDescription");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static readonly DatasetDescriptionConverter Singleton = new DatasetDescriptionConverter();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal class TypeEnumConverter : JsonConverter
 | 
			
		||||
    {
 | 
			
		||||
        public override bool CanConvert(Type t) => t == typeof(TypeEnum) || t == typeof(TypeEnum?);
 | 
			
		||||
 | 
			
		||||
        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
 | 
			
		||||
        {
 | 
			
		||||
            if (reader.TokenType == JsonToken.Null) return null;
 | 
			
		||||
            var value = serializer.Deserialize<string>(reader);
 | 
			
		||||
            switch (value)
 | 
			
		||||
            {
 | 
			
		||||
                case "Float":
 | 
			
		||||
                    return TypeEnum.Float;
 | 
			
		||||
                case "Integer":
 | 
			
		||||
                    return TypeEnum.Integer;
 | 
			
		||||
                case "String":
 | 
			
		||||
                    return TypeEnum.String;
 | 
			
		||||
                case "Timestamp":
 | 
			
		||||
                    return TypeEnum.Timestamp;
 | 
			
		||||
            }
 | 
			
		||||
            throw new Exception("Cannot unmarshal type TypeEnum");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
 | 
			
		||||
        {
 | 
			
		||||
            if (untypedValue == null)
 | 
			
		||||
            {
 | 
			
		||||
                serializer.Serialize(writer, null);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            var value = (TypeEnum)untypedValue;
 | 
			
		||||
            switch (value)
 | 
			
		||||
            {
 | 
			
		||||
                case TypeEnum.Float:
 | 
			
		||||
                    serializer.Serialize(writer, "Float");
 | 
			
		||||
                    return;
 | 
			
		||||
                case TypeEnum.Integer:
 | 
			
		||||
                    serializer.Serialize(writer, "Integer");
 | 
			
		||||
                    return;
 | 
			
		||||
                case TypeEnum.String:
 | 
			
		||||
                    serializer.Serialize(writer, "String");
 | 
			
		||||
                    return;
 | 
			
		||||
                case TypeEnum.Timestamp:
 | 
			
		||||
                    serializer.Serialize(writer, "Timestamp");
 | 
			
		||||
                    return;
 | 
			
		||||
            }
 | 
			
		||||
            throw new Exception("Cannot marshal type TypeEnum");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static readonly TypeEnumConverter Singleton = new TypeEnumConverter();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal class ParseStringConverter : JsonConverter
 | 
			
		||||
    {
 | 
			
		||||
        public override bool CanConvert(Type t) => t == typeof(bool) || t == typeof(bool?);
 | 
			
		||||
 | 
			
		||||
        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
 | 
			
		||||
        {
 | 
			
		||||
            if (reader.TokenType == JsonToken.Null) return null;
 | 
			
		||||
            var value = serializer.Deserialize<string>(reader);
 | 
			
		||||
            bool b;
 | 
			
		||||
            if (Boolean.TryParse(value, out b))
 | 
			
		||||
            {
 | 
			
		||||
                return b;
 | 
			
		||||
            }
 | 
			
		||||
            throw new Exception("Cannot unmarshal type bool");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
 | 
			
		||||
        {
 | 
			
		||||
            if (untypedValue == null)
 | 
			
		||||
            {
 | 
			
		||||
                serializer.Serialize(writer, null);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            var value = (bool)untypedValue;
 | 
			
		||||
            var boolString = value ? "true" : "false";
 | 
			
		||||
            serializer.Serialize(writer, boolString);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static readonly ParseStringConverter Singleton = new ParseStringConverter();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -7,23 +7,40 @@
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  "BackgroundServiceCron": {
 | 
			
		||||
    "ExecutionBackgroundServicePlanJob": "0 0 2 * * ?",
 | 
			
		||||
    "MessageNotificationJob": "0 0 2 * * ?",
 | 
			
		||||
    "DataDeliveryJob": "0 0 2 * * ?",
 | 
			
		||||
    "RegularUpdateDBTableJob": "0 0 2 * * ?",
 | 
			
		||||
    "ParkingJob": "0 0 2 * * ?",
 | 
			
		||||
    "ArchiveElectricMeterHourJob": "0 0 2 * * ?",
 | 
			
		||||
    "ArchiveElectricMeterDayJob": "0 0 2 * * ?",
 | 
			
		||||
    "ExecutionBackgroundServicePlanJob": "0 0 1 * * ?",
 | 
			
		||||
    "MessageNotificationJob": "0 0 1 * * ?",
 | 
			
		||||
    "DataDeliveryJob": "0 0 1 * * ?",
 | 
			
		||||
    "RegularUpdateDBTableJob": "0 0 1 * * ?",
 | 
			
		||||
    "ParkingJob": "0 0 1 * * ?",
 | 
			
		||||
    "ArchiveElectricMeterHourJob": "0 0 1 * * ?",
 | 
			
		||||
    "ArchiveElectricMeterDayJob": "0 0 1 * * ?",
 | 
			
		||||
    "WeatherAPIJob": "0/5 * * * * ?"
 | 
			
		||||
  },
 | 
			
		||||
  "DBConfig": {
 | 
			
		||||
    //"MySqlDBConfig": {
 | 
			
		||||
    //  "Server": "TNi6aupYHPZT8ZU177KTKw==", //172.16.220.251
 | 
			
		||||
    //  "Port": "mkF51jVbg40V5K5eTh2Ckw==",
 | 
			
		||||
    //  "Database": "VvfWH/59gQguY2eA2xBCug==",
 | 
			
		||||
    //  "Root": "IV8Ec1Ng2AWAnkBafXy2kg==",
 | 
			
		||||
    //  "Password": "Jue6jMFRi11meN6xbdKwDA=="
 | 
			
		||||
    //},
 | 
			
		||||
    "MySqlDBConfig": {
 | 
			
		||||
      "Server": "TNi6aupYHPZT8ZU177KTKw==", //172.16.220.251
 | 
			
		||||
      "Port": "mkF51jVbg40V5K5eTh2Ckw==",
 | 
			
		||||
      "Database": "VvfWH/59gQguY2eA2xBCug==",
 | 
			
		||||
      "Root": "IV8Ec1Ng2AWAnkBafXy2kg==",
 | 
			
		||||
      "Password": "Jue6jMFRi11meN6xbdKwDA=="
 | 
			
		||||
      "Server": "FYlY+w0XDIz+jmF2rlZWJw==", //0.201
 | 
			
		||||
      "Port": "js2LutKe+rdjzdxMPQUrvQ==",
 | 
			
		||||
      //"Database": "VJB2XC+lAtzuHObDGMVOAA==", //30  
 | 
			
		||||
      //"Database": "IgYBsgG2VLKKxFb64j7LOA==", //wsp
 | 
			
		||||
      "Database": "7gWfmZ28HGIJZbxEbK+0yg==", //tpe_dome_dome
 | 
			
		||||
      //"Database": "siTUcDaC/g2yGTMFWD72Kg==", //tpe_dome_hotel
 | 
			
		||||
      "Root": "SzdxEgaJJ7tcTCrUl2zKsA==",
 | 
			
		||||
      "Password": "FVAPxztxpY4gJJKQ/se4bQ=="
 | 
			
		||||
    },
 | 
			
		||||
    "MSSqlDBConfig": {
 | 
			
		||||
      "Server": "bJm+UAtbeaTjDmp/A5ep2w==", //0.130
 | 
			
		||||
      "Port": "S5cUXKnKOacFtFy9+0dtpw==",
 | 
			
		||||
      "Database": "VvfWH/59gQguY2eA2xBCug==", //taipei_dome 
 | 
			
		||||
      "Root": "sD8GZ9UPiIQGU6dU011/4A==",
 | 
			
		||||
      "Password": "0O24es2ZRF5uoJ4aU+YCdg=="
 | 
			
		||||
    }
 | 
			
		||||
    //"MSSqlDBConfig": {   //greencloud.fic.com.tw,1433
 | 
			
		||||
    //  "Server": "ueFp+VFb200lhh1Uctc97WH0/tX6tfXYU2v1oxCWuuM=",
 | 
			
		||||
    //  "Port": "S5cUXKnKOacFtFy9+0dtpw==",
 | 
			
		||||
@ -31,13 +48,13 @@
 | 
			
		||||
    //  "Root": "+plVKQ+enAqt7BYV2uMQng==",
 | 
			
		||||
    //  "Password": "0O24es2ZRF5uoJ4aU+YCdg=="
 | 
			
		||||
    //}
 | 
			
		||||
    "MSSqlDBConfig": {
 | 
			
		||||
      "Server": "zp3Nilx0PISEEC4caZWqCg==", //172.16.220.250
 | 
			
		||||
      "Port": "7puf4kd9qJ/q0fq2QASWeQ==",
 | 
			
		||||
      "Database": "VvfWH/59gQguY2eA2xBCug==",
 | 
			
		||||
      "Root": "sD8GZ9UPiIQGU6dU011/4A==",
 | 
			
		||||
      "Password": "Jue6jMFRi11meN6xbdKwDA=="
 | 
			
		||||
    }
 | 
			
		||||
    //"MSSqlDBConfig": {
 | 
			
		||||
    //  "Server": "zp3Nilx0PISEEC4caZWqCg==", //172.16.220.250
 | 
			
		||||
    //  "Port": "7puf4kd9qJ/q0fq2QASWeQ==",
 | 
			
		||||
    //  "Database": "VvfWH/59gQguY2eA2xBCug==",
 | 
			
		||||
    //  "Root": "sD8GZ9UPiIQGU6dU011/4A==",
 | 
			
		||||
    //  "Password": "Jue6jMFRi11meN6xbdKwDA=="
 | 
			
		||||
    //}
 | 
			
		||||
 | 
			
		||||
  },
 | 
			
		||||
  "SMTPConfig": {
 | 
			
		||||
 | 
			
		||||
@ -14,13 +14,30 @@
 | 
			
		||||
    "RegularUpdateDBTableJob": "0 0 2 * * ?"
 | 
			
		||||
  },
 | 
			
		||||
  "DBConfig": {
 | 
			
		||||
    //"MySqlDBConfig": {
 | 
			
		||||
    //  "Server": "FYlY+w0XDIz+jmF2rlZWJw==", //0.201
 | 
			
		||||
    //  "Port": "js2LutKe+rdjzdxMPQUrvQ==",
 | 
			
		||||
    //  "Database": "VJB2XC+lAtzuHObDGMVOAA==", //30
 | 
			
		||||
    //  "Root": "SzdxEgaJJ7tcTCrUl2zKsA==",
 | 
			
		||||
    //  "Password": "FVAPxztxpY4gJJKQ/se4bQ=="
 | 
			
		||||
    //},
 | 
			
		||||
    "MySqlDBConfig": {
 | 
			
		||||
      "Server": "FYlY+w0XDIz+jmF2rlZWJw==", //0.201
 | 
			
		||||
      "Port": "js2LutKe+rdjzdxMPQUrvQ==",
 | 
			
		||||
      "Database": "VJB2XC+lAtzuHObDGMVOAA==", //30
 | 
			
		||||
      //"Database": "VJB2XC+lAtzuHObDGMVOAA==", //30  
 | 
			
		||||
      //"Database": "IgYBsgG2VLKKxFb64j7LOA==", //wsp
 | 
			
		||||
      "Database": "7gWfmZ28HGIJZbxEbK+0yg==", //tpe_dome_dome
 | 
			
		||||
      //"Database": "siTUcDaC/g2yGTMFWD72Kg==", //tpe_dome_hotel
 | 
			
		||||
      "Root": "SzdxEgaJJ7tcTCrUl2zKsA==",
 | 
			
		||||
      "Password": "FVAPxztxpY4gJJKQ/se4bQ=="
 | 
			
		||||
    },
 | 
			
		||||
    "MSSqlDBConfig": {
 | 
			
		||||
      "Server": "bJm+UAtbeaTjDmp/A5ep2w==", //0.130
 | 
			
		||||
      "Port": "S5cUXKnKOacFtFy9+0dtpw==",
 | 
			
		||||
      "Database": "VvfWH/59gQguY2eA2xBCug==", //taipei_dome 
 | 
			
		||||
      "Root": "sD8GZ9UPiIQGU6dU011/4A==",
 | 
			
		||||
      "Password": "0O24es2ZRF5uoJ4aU+YCdg=="
 | 
			
		||||
    }
 | 
			
		||||
    //"MSSqlDBConfig": {
 | 
			
		||||
    //  "Server": "avZg8PA8C9GVgYZBgEKzCg==",
 | 
			
		||||
    //  "Port": "lJA0KPkG6RvFfTgWiXFyUw==",
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										192
									
								
								BackendWorkerService/root/PowerfulRain.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										192
									
								
								BackendWorkerService/root/PowerfulRain.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,192 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<alert xmlns="urn:oasis:names:tc:emergency:cap:1.2">
 | 
			
		||||
    
 | 
			
		||||
    <identifier>CWB-Weather_extremely-rain_202305081515001</identifier>
 | 
			
		||||
    <sender>weather@cwb.gov.tw</sender>
 | 
			
		||||
    <sent>2023-05-08T15:21:31+08:00</sent>
 | 
			
		||||
    <status>Actual</status>
 | 
			
		||||
    <msgType>Cancel</msgType>
 | 
			
		||||
    <scope>Public</scope>
 | 
			
		||||
    <references>weather@cwb.gov.tw,CWB-Weather_extremely-rain_202305081030001,2023-05-08T10:37:48+08:00 weather@cwb.gov.tw,CWB-Weather_extremely-rain_202305080840001,2023-05-08T08:51:11+08:00</references>
 | 
			
		||||
    <info>
 | 
			
		||||
        <language>zh-TW</language>
 | 
			
		||||
        <category>Met</category>
 | 
			
		||||
        <event>降雨</event>
 | 
			
		||||
        <urgency>Past</urgency>
 | 
			
		||||
        <severity>Minor</severity>
 | 
			
		||||
        <certainty>Observed</certainty>
 | 
			
		||||
        <eventCode>
 | 
			
		||||
            <valueName>profile:CAP-TWP:Event:1.0</valueName>
 | 
			
		||||
            <value>rainfall</value>
 | 
			
		||||
        </eventCode>
 | 
			
		||||
        <effective>2023-05-08T15:15:00+08:00</effective>
 | 
			
		||||
        <onset>2023-05-08T15:17:00+08:00</onset>
 | 
			
		||||
        <expires>2023-05-08T15:31:31+08:00</expires>
 | 
			
		||||
        <senderName>中央氣象局</senderName>
 | 
			
		||||
        <headline>解除大雨特報</headline>
 | 
			
		||||
        <description>
 | 
			
		||||
由於降雨趨於緩和,發生大雨的機率降低,故解除大雨特報;今(8)日屏東及臺東山區仍有局部較大雨勢發生,請注意。
 | 
			
		||||
        </description>
 | 
			
		||||
        <instruction></instruction>
 | 
			
		||||
        <web>https://www.cwb.gov.tw/V8/C/P/Warning/FIFOWS.html</web>
 | 
			
		||||
        <parameter>
 | 
			
		||||
            <valueName>alert_title</valueName>
 | 
			
		||||
            <value>大雨特報</value>
 | 
			
		||||
        </parameter>
 | 
			
		||||
        
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>基隆市</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>10017</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>臺北市</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>63</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>新北市</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>65</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>桃園市</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>68</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>新竹市</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>10018</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>新竹縣</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>10004</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>苗栗縣</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>10005</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>臺中市</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>66</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>彰化縣</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>10007</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>雲林縣</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>10009</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>南投縣</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>10008</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>嘉義縣</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>10010</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>嘉義市</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>10020</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>臺南市</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>67</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>高雄市</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>64</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>屏東縣</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>10013</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>宜蘭縣</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>10002</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>花蓮縣</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>10015</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>臺東縣</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>10014</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>澎湖縣</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>10016</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>金門縣</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>09020</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>連江縣</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>09007</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
    </info>
 | 
			
		||||
</alert>
 | 
			
		||||
							
								
								
									
										197
									
								
								BackendWorkerService/root/Typhoon.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								BackendWorkerService/root/Typhoon.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,197 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<alert xmlns="urn:oasis:names:tc:emergency:cap:1.2">
 | 
			
		||||
    
 | 
			
		||||
    <identifier>CWB-Weather_typhoon-warning_202210162030001</identifier>
 | 
			
		||||
    <sender>weather@cwb.gov.tw</sender>
 | 
			
		||||
    <sent>2022-10-16T20:20:41+08:00</sent>
 | 
			
		||||
    <status>Actual</status>
 | 
			
		||||
    <msgType>Cancel</msgType>
 | 
			
		||||
    <scope>Public</scope>
 | 
			
		||||
    <references>weather@cwb.gov.tw,CWB-Weather_typhoon-warning_202210161730001,2022-10-16T17:20:00+08:00</references>
 | 
			
		||||
    <info>
 | 
			
		||||
        <language>zh-TW</language>
 | 
			
		||||
        <category>Met</category>
 | 
			
		||||
        <event>颱風</event>
 | 
			
		||||
        <urgency>Past</urgency>
 | 
			
		||||
        <severity>Minor</severity>
 | 
			
		||||
        <certainty>Observed</certainty>
 | 
			
		||||
        <eventCode>
 | 
			
		||||
            <valueName>profile:CAP-TWP:Event:1.0</valueName>
 | 
			
		||||
            <value>typhoon</value>
 | 
			
		||||
        </eventCode>
 | 
			
		||||
        <effective>2022-10-16T20:30:00+08:00</effective>
 | 
			
		||||
        <onset>2022-10-16T20:30:00+08:00</onset>
 | 
			
		||||
        <expires>2022-10-16T20:40:00+08:00</expires>
 | 
			
		||||
        <senderName>中央氣象局</senderName>
 | 
			
		||||
        <headline>解除颱風警報</headline>
 | 
			
		||||
        <description>
 | 
			
		||||
[颱風動態]
 | 
			
		||||
根據最新資料顯示,第20號颱風已增強為中度颱風,中心目前在鵝鑾鼻西南方海面,向西南西移動,對巴士海峽近海的威脅已解除。
 | 
			
		||||
 | 
			
		||||
[注意事項]
 | 
			
		||||
*今(16日)晚至明(17)日巴士海峽及臺灣附近各海面風浪仍偏大,各沿海地區(含蘭嶼、綠島)及澎湖、金門、馬祖有長浪發生的機率,請避免前往海邊活動。*今(16日)晚雲林以北、恆春半島沿海空曠地區及澎湖、馬祖易有9至10級強陣風,東半部、嘉義、臺南沿海空曠地區及蘭嶼、綠島、金門亦有較強陣風;明(17)日臺南以北沿海空曠地區、蘭嶼、綠島、澎湖、金門、馬祖易有9至12級強陣風,東半部沿海地區及西半部地區有8至9級強陣風,路樹、懸掛物、招牌等物品宜加強固定,外出活動、機車騎士行車或行經高架橋車輛,請特別注意安全。*自15日0時至16日20時出現較大累積雨量如下:臺北市擎天崗989.0毫米,宜蘭縣樂水分校973.5毫米,新北市汐止579.5毫米,基隆市五堵578.0毫米,桃園市嘎拉賀555.0毫米,新竹縣西丘斯山478.0毫米,臺中市南湖圈谷394.5毫米,花蓮縣和平林道361.0毫米。*本警報單之颱風半徑為平均半徑,第20號颱風之7級風暴風半徑北半象限約220公里,南半象限約180公里,平均半徑約為200公里。颱風詳細特性請參考本局颱風輔助說明(https://www.cwb.gov.tw/Data/typhoon/TY_ PDF.pdf)。*此為第20號颱風警報最後一次報告。
 | 
			
		||||
 | 
			
		||||
        </description>
 | 
			
		||||
        <instruction></instruction>
 | 
			
		||||
        <web>https://www.cwb.gov.tw/V8/C/P/Warning/FIFOWS.html</web>
 | 
			
		||||
        <parameter>
 | 
			
		||||
            <valueName>alert_title</valueName>
 | 
			
		||||
            <value>颱風警報</value>
 | 
			
		||||
        </parameter>
 | 
			
		||||
        
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>基隆市</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>10017</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>臺北市</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>63</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>新北市</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>65</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>桃園市</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>68</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>新竹市</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>10018</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>新竹縣</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>10004</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>苗栗縣</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>10005</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>臺中市</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>66</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>彰化縣</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>10007</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>雲林縣</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>10009</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>南投縣</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>10008</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>嘉義縣</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>10010</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>嘉義市</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>10020</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>臺南市</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>67</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>高雄市</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>64</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>屏東縣</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>10013</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>宜蘭縣</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>10002</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>花蓮縣</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>10015</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>臺東縣</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>10014</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>澎湖縣</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>10016</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>金門縣</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>09020</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
        <area>
 | 
			
		||||
            <areaDesc>連江縣</areaDesc>
 | 
			
		||||
            <geocode>
 | 
			
		||||
                <valueName>Taiwan_Geocode_103</valueName>
 | 
			
		||||
                <value>09007</value>
 | 
			
		||||
            </geocode>
 | 
			
		||||
        </area>
 | 
			
		||||
    </info>
 | 
			
		||||
</alert>
 | 
			
		||||
@ -44,25 +44,29 @@ namespace FrontendWebApi.ApiControllers
 | 
			
		||||
                var sql = $@"
 | 
			
		||||
                            SELECT
 | 
			
		||||
                            (
 | 
			
		||||
		                        SELECT TOP(1) w.get_value
 | 
			
		||||
		                        SELECT w.get_value
 | 
			
		||||
		                        FROM api_weateher w
 | 
			
		||||
		                        WHERE w.weather_type = 'Wx' AND @DateNow BETWEEN w.start_time AND w.end_time ORDER BY created_at DESC
 | 
			
		||||
                                limit 1
 | 
			
		||||
	                        ) AS WxText,
 | 
			
		||||
	                        (
 | 
			
		||||
		                        SELECT TOP(1) wd.WeatherKey
 | 
			
		||||
		                        SELECT wd.WeatherKey
 | 
			
		||||
		                        FROM api_weateher w
 | 
			
		||||
		                        LEFT JOIN weather_description wd ON w.get_value = wd.WeatherValue
 | 
			
		||||
		                        WHERE w.weather_type = 'WxV' AND @DateNow BETWEEN w.start_time AND w.end_time ORDER BY created_at DESC
 | 
			
		||||
                                limit 1
 | 
			
		||||
	                        ) AS Wx,
 | 
			
		||||
	                        (
 | 
			
		||||
		                        SELECT TOP(1) w.get_value
 | 
			
		||||
		                        SELECT w.get_value
 | 
			
		||||
		                        FROM api_weateher w
 | 
			
		||||
		                        WHERE w.weather_type = 'T' AND @DateNow < w.start_time
 | 
			
		||||
                                limit 1
 | 
			
		||||
	                        ) AS Temp,
 | 
			
		||||
	                        (
 | 
			
		||||
		                        SELECT TOP(1) w.get_value
 | 
			
		||||
		                        SELECT w.get_value
 | 
			
		||||
		                        FROM api_weateher w
 | 
			
		||||
		                        WHERE w.weather_type = 'RH' AND @DateNow < w.start_time
 | 
			
		||||
                                limit 1
 | 
			
		||||
	                        ) AS RH
 | 
			
		||||
                        ";
 | 
			
		||||
                var dateNow = DateTime.Now.ToString("yyyy-MM-dd HH:mm:00");
 | 
			
		||||
@ -163,86 +167,84 @@ namespace FrontendWebApi.ApiControllers
 | 
			
		||||
            }
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
 | 
			
		||||
                var buildmenusql = await backendRepository.GetAllAsync<BuildMenuSql>(@$"
 | 
			
		||||
                select 
 | 
			
		||||
                    me.* ,
 | 
			
		||||
                    b.full_name bfull_name,
 | 
			
		||||
                    b.ip_address,
 | 
			
		||||
                    b.priority bpriority,
 | 
			
		||||
                    ma.full_name mafull_name,
 | 
			
		||||
                    ma.priority mapriority,
 | 
			
		||||
                    ma.code,
 | 
			
		||||
                    sub.full_name subfull_name,
 | 
			
		||||
                    sub.priority subpriority
 | 
			
		||||
		                me.* ,
 | 
			
		||||
		                b.full_name bfull_name,
 | 
			
		||||
		                b.ip_address,
 | 
			
		||||
		                b.priority bpriority,
 | 
			
		||||
		                v1.system_key mafull_name,
 | 
			
		||||
		                v1.system_priority mapriority,
 | 
			
		||||
		                v1.system_value,
 | 
			
		||||
		                v2.system_key subfull_name,
 | 
			
		||||
		                v2.system_priority subpriority
 | 
			
		||||
                from building_menu me
 | 
			
		||||
                left join building b on b.building_guid = me.building_guid 
 | 
			
		||||
                left join main_system ma on ma.main_system_guid = me.main_system_guid
 | 
			
		||||
                left join sub_system sub on sub.sub_system_guid = me.sub_system_guid 
 | 
			
		||||
                left join building b on b.building_tag = me.building_tag
 | 
			
		||||
                left join variable v1 on me.main_system_tag = v1.system_value and v1.deleted = 0 and v1.system_type = 'device_system_category_layer2'
 | 
			
		||||
                left join variable v2 on me.sub_system_tag = v2.system_value and v2.deleted = 0 and v2.system_type = 'device_system_category_layer3'
 | 
			
		||||
                inner join (
 | 
			
		||||
                    SELECT 
 | 
			
		||||
                        ap.building_guid,
 | 
			
		||||
                        ap.ShowView
 | 
			
		||||
                    FROM
 | 
			
		||||
                    (
 | 
			
		||||
                        SELECT *
 | 
			
		||||
                        FROM role_auth ra
 | 
			
		||||
                        WHERE ra.role_guid = (SELECT ui.role_guid from userinfo ui where account = @Account)
 | 
			
		||||
                    ) ra
 | 
			
		||||
			        left join auth_page ap on ra.AuthCode = ap.AuthCode
 | 
			
		||||
			        where ap.AuthType = 1
 | 
			
		||||
                ) shower on shower.building_guid = me.building_guid and shower.ShowView = me.sub_system_guid
 | 
			
		||||
                order by b.priority, ma.priority,sub.priority, sub.created_at DESC", new { Account = account });
 | 
			
		||||
		                SELECT 
 | 
			
		||||
				            ap.building_tag,
 | 
			
		||||
				            ap.ShowView
 | 
			
		||||
		                FROM
 | 
			
		||||
		                (
 | 
			
		||||
				            SELECT *
 | 
			
		||||
				            FROM role_auth ra
 | 
			
		||||
				            WHERE ra.role_guid = (SELECT ui.role_guid from userinfo ui where account = @Account)
 | 
			
		||||
		                ) ra
 | 
			
		||||
                left join auth_page ap on ra.AuthCode = ap.AuthCode
 | 
			
		||||
                where ap.AuthType = 1
 | 
			
		||||
                ) shower on shower.building_tag = me.building_tag and shower.ShowView = v2.id
 | 
			
		||||
                order by b.priority, v1.system_priority, v2.system_priority, v2.created_at DESC", new { Account = account });
 | 
			
		||||
 | 
			
		||||
                var floorsql = await backendRepository.GetAllAsync<Floorsql>(@"
 | 
			
		||||
                select * from (select * from sub_system_floor ssf where ssf.deleted = 0 and ssf.status = 0) a
 | 
			
		||||
                left join floor on floor.floor_guid = a.floor_guid order by floor.priority");
 | 
			
		||||
                left join floor on floor.full_name = a.floor_tag order by floor.priority;");
 | 
			
		||||
 | 
			
		||||
                var common = await backendRepository.GetAllAsync<KeyValue>($@"select ap.building_guid Name,ap.ShowView Value from auth_page ap
 | 
			
		||||
                var common = await backendRepository.GetAllAsync<KeyValue>($@"select ap.building_tag Name,ap.ShowView Value from auth_page ap
 | 
			
		||||
                    left join role_auth ra on ra.AuthCode = ap.AuthCode
 | 
			
		||||
                    right join userinfo ui on ui.role_guid = ra.role_guid
 | 
			
		||||
                    where SUBSTRING(ap.AuthCode,1,1) = 'C' and ui.account = '{account}'
 | 
			
		||||
                    ");
 | 
			
		||||
                ");
 | 
			
		||||
 | 
			
		||||
                var building = buildmenusql.GroupBy(a => a.building_guid).ToList();
 | 
			
		||||
                var building = buildmenusql.GroupBy(a => a.building_tag).ToList();
 | 
			
		||||
 | 
			
		||||
                List<Building> buildingMenus = new List<Building>();
 | 
			
		||||
                foreach (var menu in building)
 | 
			
		||||
                {
 | 
			
		||||
                    Building building1 = new Building()
 | 
			
		||||
                    {
 | 
			
		||||
                        building_guid = menu.Select(a => a.building_guid).FirstOrDefault(),
 | 
			
		||||
                        full_name = menu.Select(a => a.bfull_name).FirstOrDefault(),
 | 
			
		||||
                        ip_address = menu.Select(a => a.ip_address).FirstOrDefault(),
 | 
			
		||||
                        priority = menu.Select(a => a.bpriority).FirstOrDefault(),
 | 
			
		||||
                        device_building_tag = menu.Select(a => a.device_building_tag).FirstOrDefault(),
 | 
			
		||||
                        building_tag = menu.Select(a => a.device_building_tag).FirstOrDefault(),
 | 
			
		||||
                        main_system = new List<Main_system>(),
 | 
			
		||||
                        common = new List<string>()
 | 
			
		||||
                    };
 | 
			
		||||
                    var commonlist = common.Where(a => a.Name == building1.building_guid).Select(a => a.Value).ToList();
 | 
			
		||||
                    var commonlist = common.Where(a => a.Name == building1.building_tag).Select(a => a.Value).ToList();
 | 
			
		||||
                    building1.common = commonlist;
 | 
			
		||||
                    var mainsystem = menu.GroupBy(a => a.main_system_guid).ToList();
 | 
			
		||||
                    var mainsystem = menu.GroupBy(a => a.main_system_tag).ToList();
 | 
			
		||||
                    foreach (var ma in mainsystem)
 | 
			
		||||
                    {
 | 
			
		||||
                        Main_system main_System = new Main_system()
 | 
			
		||||
                        {
 | 
			
		||||
                            code = ma.Select(a => a.code).FirstOrDefault(),
 | 
			
		||||
                            main_system_guid = ma.Select(a => a.main_system_guid).FirstOrDefault(),
 | 
			
		||||
                            main_system_tag = ma.Select(a => a.main_system_tag).FirstOrDefault(),
 | 
			
		||||
                            full_name = ma.Select(a => a.mafull_name).FirstOrDefault(),
 | 
			
		||||
                            priority = ma.Select(a => a.mapriority).FirstOrDefault(),
 | 
			
		||||
                            Sub_system = new List<Sub_systemGuid>()
 | 
			
		||||
                        };
 | 
			
		||||
                        var subsystem = ma.GroupBy(a => a.sub_system_guid).ToList();
 | 
			
		||||
                        var subsystem = ma.GroupBy(a => a.sub_system_tag).ToList();
 | 
			
		||||
                        foreach (var sub in subsystem)
 | 
			
		||||
                        {
 | 
			
		||||
                            Sub_systemGuid sub_System = new Sub_systemGuid()
 | 
			
		||||
                            {
 | 
			
		||||
                                sub_system_guid = sub.Select(a => a.sub_system_guid).FirstOrDefault(),
 | 
			
		||||
                                sub_system_tag = sub.Select(a => a.sub_system_tag).FirstOrDefault(),
 | 
			
		||||
                                full_name = sub.Select(a => a.subfull_name).FirstOrDefault(),
 | 
			
		||||
                                priority = sub.Select(a => a.subpriority).FirstOrDefault(),
 | 
			
		||||
                                device_system_tag = sub.Select(a => a.device_system_tag).FirstOrDefault(),
 | 
			
		||||
                                OpenTab = sub.Select(a => a.OpenTab).FirstOrDefault(),
 | 
			
		||||
                                system_url = sub.Select(a => a.system_url).FirstOrDefault()
 | 
			
		||||
                                system_url = sub.Select(a => a.left_system_url).FirstOrDefault()
 | 
			
		||||
                            };
 | 
			
		||||
                            main_System.Sub_system.Add(sub_System);
 | 
			
		||||
                        }
 | 
			
		||||
@ -279,26 +281,26 @@ namespace FrontendWebApi.ApiControllers
 | 
			
		||||
            }
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                var sub_system = await backendRepository.GetOneAsync<BuildMenuSql>(@$"select ss.full_name subfull_name,me.* from building_menu me
 | 
			
		||||
                left join sub_system ss on ss.sub_system_tag = me.sub_system_tag
 | 
			
		||||
                where me.building_tag = '{get.building_tag}' and me.main_system_tag = '{get.main_system_tag}' and me.sub_system_tag = '{get.sub_system_tag}' order by ss.priority");
 | 
			
		||||
                var sub_system = await backendRepository.GetOneAsync<BuildMenuSql>(@$"select v.system_key subfull_name,me.* from building_menu me
 | 
			
		||||
                left join variable v on v.system_value = me.sub_system_tag and v.system_type = 'device_system_category_layer3' and v.deleted = 0 
 | 
			
		||||
                where me.building_tag = '{get.building_tag}' and me.main_system_tag = '{get.main_system_tag}' and me.sub_system_tag = '{get.sub_system_tag}' order by v.system_priority");
 | 
			
		||||
 | 
			
		||||
                List<Floor> Floors = new List<Floor>();
 | 
			
		||||
                var floorsql = await backendRepository.GetAllAsync<Floorsql>($@"
 | 
			
		||||
                select * from (select * from sub_system_floor ssf where ssf.deleted = 0 and ssf.status = 0 and ssf.building_tag = '{get.building_tag}' and ssf.main_system_guid = '{get.main_system_tag}' and ssf.sub_system_tag = '{get.sub_system_tag}') a
 | 
			
		||||
                left join floor on floor.floor_guid = a.floor_guid order by floor.priority");
 | 
			
		||||
                select * from (select * from sub_system_floor ssf where ssf.deleted = 0 and ssf.status = 0 and ssf.building_tag = '{get.building_tag}' and ssf.main_system_tag = '{get.main_system_tag}' and ssf.sub_system_tag = '{get.sub_system_tag}') a
 | 
			
		||||
                left join floor on floor.full_name = a.floor_tag order by floor.priority");
 | 
			
		||||
                Sub_system sub_System = new Sub_system()
 | 
			
		||||
                {
 | 
			
		||||
                    sub_system_guid = sub_system.sub_system_guid,
 | 
			
		||||
                    system_url = sub_system.system_url,
 | 
			
		||||
                    drawing = sub_system.drawing,
 | 
			
		||||
                    sub_system_tag = sub_system.sub_system_tag,
 | 
			
		||||
                    left_system_url = sub_system.left_system_url,
 | 
			
		||||
                    left_drawing = sub_system.left_drawing,
 | 
			
		||||
                    Floors = new List<Floor>(),
 | 
			
		||||
                    full_name = sub_system.subfull_name,
 | 
			
		||||
                    icon_click = sub_system.icon_click,
 | 
			
		||||
                    icon_click_url = sub_system.icon_click_url,
 | 
			
		||||
                    planimetric_click = sub_system.planimetric_click,
 | 
			
		||||
                    planimetric_floor_guid = sub_system.planimetric_floor_guid,
 | 
			
		||||
                    riser_diagram_url = sub_system.riser_diagram_url,
 | 
			
		||||
                    left_icon_click = sub_system.left_icon_click,
 | 
			
		||||
                    left_icon_click_url = sub_system.left_icon_click_url,
 | 
			
		||||
                    left_planimetric_click = sub_system.left_planimetric_click,
 | 
			
		||||
                    left_planimetric_floor_guid = sub_system.left_planimetric_floor_guid,
 | 
			
		||||
                    left_riser_diagram_url = sub_system.left_riser_diagram_url,
 | 
			
		||||
                    priority = sub_system.subpriority
 | 
			
		||||
                };
 | 
			
		||||
                foreach (var floor in floorsql)
 | 
			
		||||
@ -307,6 +309,7 @@ namespace FrontendWebApi.ApiControllers
 | 
			
		||||
                    {
 | 
			
		||||
                        devices = null,
 | 
			
		||||
                        floor_guid = floor.floor_guid,
 | 
			
		||||
                        Floor_map_name = floor.Floor_map_name,
 | 
			
		||||
                        full_name = floor.full_name,
 | 
			
		||||
                        InitMapName = floor.InitMapName,
 | 
			
		||||
                        priority = floor.priority
 | 
			
		||||
@ -378,11 +381,11 @@ namespace FrontendWebApi.ApiControllers
 | 
			
		||||
                string sql = $@"
 | 
			
		||||
                    SELECT
 | 
			
		||||
                        device_building_tag,
 | 
			
		||||
                        device_system_tag
 | 
			
		||||
                        sub_system_tag
 | 
			
		||||
                    FROM building_menu
 | 
			
		||||
                    WHERE building_guid = @building_guid
 | 
			
		||||
                    AND main_system_guid = @main_system_guid
 | 
			
		||||
                    AND sub_system_guid = @sub_system_guid
 | 
			
		||||
                    WHERE building_tag = @building_tag
 | 
			
		||||
                    AND main_system_tag = @main_system_tag
 | 
			
		||||
                    AND sub_system_tag = @sub_system_tag
 | 
			
		||||
                ";
 | 
			
		||||
 | 
			
		||||
                var tagName = await backendRepository.GetOneAsync<BuildingSystemTagName>(sql, post);
 | 
			
		||||
@ -513,13 +516,14 @@ namespace FrontendWebApi.ApiControllers
 | 
			
		||||
                                    END AS device_master_number,
 | 
			
		||||
                                    dm.device_master_full_name,
 | 
			
		||||
                                    dm.device_master_icon,
 | 
			
		||||
                                    bm.icon_click,
 | 
			
		||||
                                    bm.icon_click_url,
 | 
			
		||||
                                    bm.icon_click_url_width,
 | 
			
		||||
                                    bm.icon_click_url_height,
 | 
			
		||||
                                    bm.left_icon_click,
 | 
			
		||||
                                    bm.left_icon_click_url,
 | 
			
		||||
                                    bm.left_icon_click_url_width,
 | 
			
		||||
                                    bm.left_icon_click_url_height,
 | 
			
		||||
                                    di.full_name as point_name,
 | 
			
		||||
                                    di.points,
 | 
			
		||||
                                    di.is_bool as points_is_bool
 | 
			
		||||
                                    di.is_bool as points_is_bool,
 | 
			
		||||
                                    f.floor_guid
 | 
			
		||||
                                    from device d 
 | 
			
		||||
                                    left join device_kind dk on d.device_building_tag = dk.device_building_tag 
 | 
			
		||||
                                                            and d.device_system_tag = dk.device_system_tag
 | 
			
		||||
@ -530,6 +534,7 @@ namespace FrontendWebApi.ApiControllers
 | 
			
		||||
                                    left join device_item di ON d.device_name_tag = di.device_name_tag 
 | 
			
		||||
                                                              AND di.deleted = 0 
 | 
			
		||||
                                                              AND di.is_show_riserDiagram = 1
 | 
			
		||||
                                    left join floor f on d.device_floor_tag = f.full_name and f.deleted = 0
 | 
			
		||||
                                    {disasterjoinsql}
 | 
			
		||||
                                    LEFT JOIN building_menu bm ON d.device_building_tag = bm.building_tag AND d.device_system_tag = bm.main_system_tag AND d.device_name_tag = bm.sub_system_tag
 | 
			
		||||
                                    where d.deleted = 0 and d.device_building_tag = '{post.building_tag}' {sWhere}
 | 
			
		||||
@ -685,5 +690,37 @@ namespace FrontendWebApi.ApiControllers
 | 
			
		||||
            return Ok(apiResult);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [HttpPost]
 | 
			
		||||
        [Route("api/GetAllfloor")]
 | 
			
		||||
        public async Task<ActionResult<ApiResult<List<Floor>>>> GetAllfloor(string building_tag)
 | 
			
		||||
        {
 | 
			
		||||
            ApiResult<List<Floor>> apiResult = new ApiResult<List<Floor>>(jwt_str);
 | 
			
		||||
            if (!jwtlife)
 | 
			
		||||
            {
 | 
			
		||||
                apiResult.Code = "5000";
 | 
			
		||||
                return BadRequest(apiResult);
 | 
			
		||||
            }
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                string sWhere = $@"
 | 
			
		||||
                      SELECT 
 | 
			
		||||
	                    floor_guid,full_name,building_tag
 | 
			
		||||
                      FROM floor
 | 
			
		||||
                      where building_tag = @building_tag and deleted = 0 order by priority";
 | 
			
		||||
                var floor = await backendRepository.GetAllAsync<Floor>(sWhere, new { building_tag = building_tag });
 | 
			
		||||
 | 
			
		||||
                apiResult.Data = floor;
 | 
			
		||||
                apiResult.Code = "0000";
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception exception)
 | 
			
		||||
            {
 | 
			
		||||
                apiResult.Code = "9999";
 | 
			
		||||
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
 | 
			
		||||
                return Ok(apiResult);
 | 
			
		||||
            }
 | 
			
		||||
            return Ok(apiResult);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										805
									
								
								FrontendWebApi/ApiControllers/HiNetController.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										805
									
								
								FrontendWebApi/ApiControllers/HiNetController.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,805 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Net;
 | 
			
		||||
using System.Net.Sockets;
 | 
			
		||||
using System.Runtime.InteropServices;
 | 
			
		||||
using Microsoft.AspNetCore.Mvc;
 | 
			
		||||
using Microsoft.Extensions.Logging;
 | 
			
		||||
using FrontendWebApi.Models;
 | 
			
		||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
/// HiNet 企業簡訊 API for .NetCore 2.0
 | 
			
		||||
/// Web         : https://sms.hinet.net
 | 
			
		||||
/// Email       : hiair@hinet.net
 | 
			
		||||
/// 
 | 
			
		||||
/// Changelog   :
 | 
			
		||||
///               2018/04/19 - 初版
 | 
			
		||||
/// </summary>
 | 
			
		||||
 | 
			
		||||
namespace FrontendWebApi.ApiControllers
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Request類別 
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    enum RequestType : byte
 | 
			
		||||
    {
 | 
			
		||||
        LOGIN = 0,
 | 
			
		||||
        SEND = 1,
 | 
			
		||||
        QUERY = 2,
 | 
			
		||||
        SENDLONG = 11,
 | 
			
		||||
        QUERYLONG = 12,
 | 
			
		||||
        SENDFOREIGN = 15,
 | 
			
		||||
        CANCEL = 16,
 | 
			
		||||
        CANCELLONG = 17,
 | 
			
		||||
        SENDFOREIGNLONG = 18
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 訊息編碼
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    enum MsgCoding : byte
 | 
			
		||||
    {
 | 
			
		||||
        BIG5 = 1,
 | 
			
		||||
        BINARY = 2,
 | 
			
		||||
        UCS2 = 3,
 | 
			
		||||
        UTF8 = 4
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 其他定數常數 
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    enum MsgConst : byte
 | 
			
		||||
    {
 | 
			
		||||
        UNUSED = 0
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 資料長度定義 
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    enum LENGTH : int
 | 
			
		||||
    {
 | 
			
		||||
        RESPSET = 80,
 | 
			
		||||
        REQSET = 100,
 | 
			
		||||
        CONTENT = 160,
 | 
			
		||||
        REQUEST = 266,
 | 
			
		||||
        RESPONSE = 244,
 | 
			
		||||
        SMS_LEN = 70,
 | 
			
		||||
        ASCII_SMS_LEN = 159,
 | 
			
		||||
        LONG_ASCII_MSG_LEN = 153,
 | 
			
		||||
        LONG_MSG_LEN = 67,
 | 
			
		||||
        MAX_LONG_SPLIT = 10
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Serializable]
 | 
			
		||||
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 傳送資料到hiAirV2的資料結構 
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    struct MsgRequest
 | 
			
		||||
    {
 | 
			
		||||
        public byte type;           //訊息型態
 | 
			
		||||
        public byte coding;         //訊息編碼種類
 | 
			
		||||
        public byte priority;       //訊息優先權
 | 
			
		||||
        public byte countryCode;    //手機國碼
 | 
			
		||||
        public byte setLen;         //set[] 訊息內容的長度
 | 
			
		||||
        public byte contentLen;     //content[]訊息內容的長度
 | 
			
		||||
 | 
			
		||||
        // 訊息相關資料設定
 | 
			
		||||
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)LENGTH.REQSET)]
 | 
			
		||||
        public byte[] set;
 | 
			
		||||
 | 
			
		||||
        // 簡訊內容
 | 
			
		||||
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)LENGTH.CONTENT)]
 | 
			
		||||
        public byte[] content;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Serializable]
 | 
			
		||||
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 從hiAirV2接收資料的資料結構 
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    struct MsgResponse
 | 
			
		||||
    {
 | 
			
		||||
        public byte code;           //回傳訊息代碼
 | 
			
		||||
        public byte coding;         //訊息編碼種類
 | 
			
		||||
        public byte setLen;         //set[] 訊息內容的長度
 | 
			
		||||
        public byte contentLen;     //content[]訊息內容的長度
 | 
			
		||||
 | 
			
		||||
        // 訊息相關資料
 | 
			
		||||
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)LENGTH.RESPSET)]
 | 
			
		||||
        public byte[] set;
 | 
			
		||||
 | 
			
		||||
        // MessageID或其他文字描述
 | 
			
		||||
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)LENGTH.CONTENT)]
 | 
			
		||||
        public byte[] content;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// HiNet企業簡訊 Hiair .Net Core API
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class HiNetController : MyBaseApiController<GraphManageController>
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        public Socket socket;
 | 
			
		||||
 | 
			
		||||
        // 傳送型態
 | 
			
		||||
        private const String SEND_NOW = "01";         //即時傳送
 | 
			
		||||
        private const String SEND_EXPIRE = "02";         //截止重送時間
 | 
			
		||||
        private const String SEND_RESERVE = "03";         //預約傳送
 | 
			
		||||
        private const String SEND_RESERVE_EXPIRE = "04";         //預約傳送+截止重送時間
 | 
			
		||||
 | 
			
		||||
        // 回覆結果的訊息說明
 | 
			
		||||
        private StringBuilder retMessage = new StringBuilder();
 | 
			
		||||
 | 
			
		||||
        public HiNetController() { }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 將MsgRequest結構轉為byte array
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="req">MsgRequest結構</param>
 | 
			
		||||
        /// <returns>byte array</returns>
 | 
			
		||||
        byte[] encode(MsgRequest req)
 | 
			
		||||
        {
 | 
			
		||||
            int size = Marshal.SizeOf(req);
 | 
			
		||||
            byte[] buf = new byte[size];
 | 
			
		||||
 | 
			
		||||
            IntPtr ptr = Marshal.AllocHGlobal(size);
 | 
			
		||||
            Marshal.StructureToPtr(req, ptr, true);
 | 
			
		||||
            Marshal.Copy(ptr, buf, 0, size);
 | 
			
		||||
            Marshal.FreeHGlobal(ptr);
 | 
			
		||||
            return buf;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 將byte array轉為MsgResponse結構
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="buf">byte array</param>
 | 
			
		||||
        /// <returns>MsgResponse結構</returns>
 | 
			
		||||
        MsgResponse decode(byte[] buf)
 | 
			
		||||
        {
 | 
			
		||||
            MsgResponse rep = new MsgResponse();
 | 
			
		||||
            int size = buf.Length;
 | 
			
		||||
 | 
			
		||||
            IntPtr ptr = Marshal.AllocHGlobal(size);
 | 
			
		||||
            Marshal.Copy(buf, 0, ptr, size);
 | 
			
		||||
            rep = (MsgResponse)Marshal.PtrToStructure(ptr, rep.GetType());
 | 
			
		||||
            Marshal.FreeHGlobal(ptr);
 | 
			
		||||
            return rep;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 建立與hiAirV2的連線
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="serverName">Server IP</param>
 | 
			
		||||
        /// <param name="port">Server Port</param>
 | 
			
		||||
        /// <param name="userID">登入帳號</param>
 | 
			
		||||
        /// <param name="passwd">登入密碼</param>
 | 
			
		||||
        /// <returns> 0表示連線正常,-3,-4表示異常或斷線。其餘回傳值請參考規格書</returns>
 | 
			
		||||
        public int StartCon(String serverName, int port, String userID, String passwd)
 | 
			
		||||
        {
 | 
			
		||||
            // 回傳值變數
 | 
			
		||||
            int ret = 0;
 | 
			
		||||
 | 
			
		||||
            int timeout = 1000 * 60; //60sec
 | 
			
		||||
 | 
			
		||||
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
 | 
			
		||||
            socket.ReceiveTimeout = timeout;
 | 
			
		||||
            socket.SendTimeout = timeout;
 | 
			
		||||
 | 
			
		||||
            // 將資料清空
 | 
			
		||||
            retMessage.Clear();
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                socket.Connect(serverName, port);
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception ex)
 | 
			
		||||
            {
 | 
			
		||||
                System.Diagnostics.Debug.WriteLine(ex.Message);
 | 
			
		||||
                retMessage = new StringBuilder("Socket Create Error!");
 | 
			
		||||
                return -3;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // 設定登入帳號與密碼 
 | 
			
		||||
            String msgSet = String.Format("{0}\0{1}\0", userID, passwd);
 | 
			
		||||
            String msgContent = String.Empty;
 | 
			
		||||
 | 
			
		||||
            // 設定Request資料
 | 
			
		||||
            MsgRequest req = new MsgRequest();
 | 
			
		||||
            req.type = (byte)RequestType.LOGIN;
 | 
			
		||||
            req.coding = (byte)MsgCoding.BIG5;
 | 
			
		||||
            req.priority = (byte)MsgConst.UNUSED;
 | 
			
		||||
            req.countryCode = (byte)MsgConst.UNUSED;
 | 
			
		||||
            req.setLen = (byte)msgSet.Length;
 | 
			
		||||
            req.contentLen = (byte)msgContent.Length;
 | 
			
		||||
            req.set = Encoding.ASCII.GetBytes(msgSet.PadRight((int)LENGTH.REQSET, '\0'));
 | 
			
		||||
            req.content = Encoding.ASCII.GetBytes(msgContent.PadRight((int)LENGTH.CONTENT, '\0'));
 | 
			
		||||
 | 
			
		||||
            // 傳送與接收資料
 | 
			
		||||
            ret = sendToserver(req);
 | 
			
		||||
 | 
			
		||||
            return ret;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 立即傳送文字簡訊 
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="mobileNum">門號</param>
 | 
			
		||||
        /// <param name="SMSMessage">簡訊內容</param>
 | 
			
		||||
        /// <returns>0表示訊息成功傳送至主機,其餘回傳值請參考規格書</returns>
 | 
			
		||||
        public int SendMsg(String mobileNum, String SMSMessage)
 | 
			
		||||
        {
 | 
			
		||||
            return this.Send(mobileNum, SMSMessage, String.Empty, String.Empty);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 預約傳送文字簡訊 
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="mobileNum">門號</param>
 | 
			
		||||
        /// <param name="SMSMessage">簡訊內容</param>
 | 
			
		||||
        /// <param name="reserveTime">預約傳送時間,格式yymmddhhmmss</param>
 | 
			
		||||
        /// <returns>0表示訊息成功傳送至主機,其餘回傳值請參考規格書</returns>
 | 
			
		||||
        public int SendMsg_Reserve(String mobileNum, String SMSMessage, String reserveTime)
 | 
			
		||||
        {
 | 
			
		||||
            return this.Send(mobileNum, SMSMessage, reserveTime, String.Empty);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 立即傳送文字簡訊加重送截止時間 
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="mobileNum">門號</param>
 | 
			
		||||
        /// <param name="SMSMessage">簡訊內容</param>
 | 
			
		||||
        /// <param name="expireTime">重送截止時間,單位分鐘0001 ~ 1440</param>
 | 
			
		||||
        /// <returns>0表示訊息成功傳送至主機,其餘回傳值請參考規格書</returns>
 | 
			
		||||
        public int SendMsg_Expire(String mobileNum, String SMSMessage, String expireTime)
 | 
			
		||||
        {
 | 
			
		||||
            return this.Send(mobileNum, SMSMessage, String.Empty, expireTime);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 預約傳送文字簡訊加重送截止時間 
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="mobileNum">門號</param>
 | 
			
		||||
        /// <param name="SMSMessage">簡訊內容</param>
 | 
			
		||||
        /// <param name="reserveTime">預約傳送時間,格式yymmddhhmmss</param>
 | 
			
		||||
        /// <param name="expireTime">重送截止時間,單位分鐘0001 ~ 1440</param>
 | 
			
		||||
        /// <returns>0表示訊息成功傳送至主機,其餘回傳值請參考規格書</returns>
 | 
			
		||||
        public int SendMsg_Reserve_Expire(String mobileNum, String SMSMessage, String reserveTime, String expireTime)
 | 
			
		||||
        {
 | 
			
		||||
            return this.Send(mobileNum, SMSMessage, reserveTime, expireTime);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 傳送文字簡訊(封裝程式僅供內部呼叫用)
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="mobileNum">門號</param>
 | 
			
		||||
        /// <param name="SMSMessage">簡訊內容</param>
 | 
			
		||||
        /// <param name="reserveTime">預約傳送時間,格式yymmddhhmmss</param>
 | 
			
		||||
        /// <param name="expireTime">重送截止時間,單位分鐘0001 ~ 1440</param>
 | 
			
		||||
        /// <returns>0表示訊息成功傳送至主機,其餘回傳值請參考規格書</returns>
 | 
			
		||||
        private int Send(String mobileNum, String SMSMessage, String reserveTime, String expireTime)
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
            int ret = 0;
 | 
			
		||||
            retMessage.Clear();
 | 
			
		||||
 | 
			
		||||
            byte[] utf8 = Encoding.UTF8.GetBytes(SMSMessage);
 | 
			
		||||
            byte[] ucs2 = Encoding.GetEncoding("UTF-16BE").GetBytes(SMSMessage);
 | 
			
		||||
 | 
			
		||||
            int contentLength = 0;
 | 
			
		||||
 | 
			
		||||
            MsgRequest req = new MsgRequest();
 | 
			
		||||
 | 
			
		||||
            // 若UTF8 Bytes長度與原資料長度相等,表示為純英數字
 | 
			
		||||
            if (utf8.Length == SMSMessage.Length)
 | 
			
		||||
            {  //純英數
 | 
			
		||||
                req.coding = (byte)MsgCoding.BIG5;
 | 
			
		||||
                contentLength = SMSMessage.Length;
 | 
			
		||||
                if (SMSMessage.Length > (int)LENGTH.ASCII_SMS_LEN)
 | 
			
		||||
                {
 | 
			
		||||
                    retMessage = new StringBuilder("message content length exceeded");
 | 
			
		||||
                    return -5;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                req.coding = (byte)MsgCoding.UCS2;  //非純英數
 | 
			
		||||
                contentLength = ucs2.Length;
 | 
			
		||||
 | 
			
		||||
                if (SMSMessage.Length > (int)LENGTH.SMS_LEN)
 | 
			
		||||
                {
 | 
			
		||||
                    retMessage = new StringBuilder("message content length exceeded");
 | 
			
		||||
                    return -5;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // 帶+號為國外文字簡訊,否則為國內簡訊
 | 
			
		||||
            byte msgType = mobileNum.StartsWith("+") ? (byte)RequestType.SENDFOREIGN : (byte)RequestType.SEND;
 | 
			
		||||
 | 
			
		||||
            String msgSet;
 | 
			
		||||
 | 
			
		||||
            if (String.IsNullOrEmpty(reserveTime) && String.IsNullOrEmpty(expireTime) == false)
 | 
			
		||||
            {
 | 
			
		||||
                // 立即傳送       
 | 
			
		||||
                msgSet = String.Format("{0}\0{1}\0{2}\0", mobileNum, SEND_EXPIRE, expireTime);
 | 
			
		||||
            }
 | 
			
		||||
            else if (String.IsNullOrEmpty(reserveTime) == false && String.IsNullOrEmpty(expireTime))
 | 
			
		||||
            {
 | 
			
		||||
                // 立即傳送加重送截止時間 
 | 
			
		||||
                msgSet = String.Format("{0}\0{1}\0{2}\0", mobileNum, SEND_RESERVE, reserveTime);
 | 
			
		||||
            }
 | 
			
		||||
            else if (String.IsNullOrEmpty(reserveTime) == false && String.IsNullOrEmpty(expireTime) == false)
 | 
			
		||||
            {
 | 
			
		||||
                // 預約傳送
 | 
			
		||||
                msgSet = String.Format("{0}\0{1}\0{2}\0{3}\0", mobileNum, SEND_RESERVE_EXPIRE, reserveTime, expireTime);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                // 預約傳送加重送截止時間
 | 
			
		||||
                msgSet = String.Format("{0}\0{1}\0", mobileNum, SEND_NOW);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // 設定Request資料
 | 
			
		||||
            req.type = msgType;
 | 
			
		||||
            req.priority = (byte)MsgConst.UNUSED;
 | 
			
		||||
            req.countryCode = (byte)MsgConst.UNUSED;
 | 
			
		||||
            req.setLen = (byte)msgSet.Length;
 | 
			
		||||
            req.contentLen = (byte)contentLength;
 | 
			
		||||
            req.set = Encoding.ASCII.GetBytes(msgSet.PadRight((int)LENGTH.REQSET, '\0'));
 | 
			
		||||
            if (req.coding == (byte)MsgCoding.UCS2)
 | 
			
		||||
            {
 | 
			
		||||
                //非純英數字以UCS2 byte傳送
 | 
			
		||||
                req.content = Encoding.GetEncoding("UTF-16BE").GetBytes(SMSMessage.PadRight((int)LENGTH.CONTENT, '\0'));
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                //純英數字以BIG5 byte傳送
 | 
			
		||||
                req.content = Encoding.ASCII.GetBytes(SMSMessage.PadRight((int)LENGTH.CONTENT, '\0'));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // 傳送與接收資料
 | 
			
		||||
            ret = this.sendToserver(req);
 | 
			
		||||
 | 
			
		||||
            return ret;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 立即傳送長簡訊
 | 
			
		||||
        /// <para/>長簡訊中文每個分則長度為67個字,純英數字每個為則為153個字。
 | 
			
		||||
        /// <para/>若中文簡訊沒大於70個字,或是純英數字沒大於159個字,請使用一般簡訊SendMsg相關Method。
 | 
			
		||||
        /// <para/>否則將被拆為多則傳送或依實際使用則數計費
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="mobileNum">門號</param>
 | 
			
		||||
        /// <param name="SMSMessage">簡訊內容</param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        public int SendMsg_Long(String mobileNum, String SMSMessage)
 | 
			
		||||
        {
 | 
			
		||||
            return this.SendLong(mobileNum, SMSMessage, String.Empty, String.Empty);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 傳送長簡訊加重送期限
 | 
			
		||||
        /// <para/>長簡訊中文每個分則長度為67個字,純英數字每個為則為153個字。
 | 
			
		||||
        /// <para/>若中文簡訊沒大於70個字,或是純英數字沒大於159個字,請使用一般簡訊SendMsg相關Method。
 | 
			
		||||
        /// <para/>否則將被拆為多則傳送或依實際使用則數計費
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="mobileNum">門號</param>
 | 
			
		||||
        /// <param name="SMSMessage">簡訊內容</param>
 | 
			
		||||
        /// <param name="expireTime">重送截止時間,單位分鐘0001 ~ 1440</param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        public int SendMsg_Long_Expire(String mobileNum, String SMSMessage, String expireTime)
 | 
			
		||||
        {
 | 
			
		||||
            return this.SendLong(mobileNum, SMSMessage, String.Empty, expireTime);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 傳送長簡訊加預約時間
 | 
			
		||||
        /// <para/>長簡訊中文每個分則長度為67個字,純英數字每個為則為153個字。
 | 
			
		||||
        /// <para/>若中文簡訊沒大於70個字,或是純英數字沒大於159個字,請使用一般簡訊SendMsg相關Method。
 | 
			
		||||
        /// <para/>否則將被拆為多則傳送或依實際使用則數計費
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="mobileNum">門號</param>
 | 
			
		||||
        /// <param name="SMSMessage">簡訊內容</param>
 | 
			
		||||
        /// <param name="reserveTime">預約傳送時間,格式yymmddhhmmss</param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        public int SendMsg_Long_Reserve(String mobileNum, String SMSMessage, String reserveTime)
 | 
			
		||||
        {
 | 
			
		||||
            return this.SendLong(mobileNum, SMSMessage, reserveTime, String.Empty);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 傳送長簡訊加預約時間與重送期限
 | 
			
		||||
        /// <para/>長簡訊中文每個分則長度為67個字,純英數字每個為則為153個字。
 | 
			
		||||
        /// <para/>若中文簡訊沒大於70個字,或是純英數字沒大於159個字,請使用一般簡訊SendMsg相關Method。
 | 
			
		||||
        /// <para/>否則將被拆為多則傳送或依實際使用則數計費
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="mobileNum">門號</param>
 | 
			
		||||
        /// <param name="SMSMessage">簡訊內容</param>
 | 
			
		||||
        /// <param name="reserveTime">預約傳送時間,格式yymmddhhmmss</param>
 | 
			
		||||
        /// <param name="expireTime">重送截止時間,單位分鐘0001 ~ 1440</param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        public int SendMsg_Long_Reserve_Expire(String mobileNum, String SMSMessage, String reserveTime, String expireTime)
 | 
			
		||||
        {
 | 
			
		||||
            return this.SendLong(mobileNum, SMSMessage, reserveTime, expireTime);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 傳送長簡訊(封裝程式僅供內部呼叫用)
 | 
			
		||||
        /// <para/>長簡訊中文每個分則長度為67個字,純英數字每個為則為153個字。
 | 
			
		||||
        /// <para/>若中文簡訊沒大於70個字,或是純英數字沒大於159個字,請使用一般簡訊SendMsg*。
 | 
			
		||||
        /// <para/>否則將被拆為多則傳送或依實際使用則數計費
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="mobileNum">門號</param>
 | 
			
		||||
        /// <param name="SMSMessage">簡訊內容</param>
 | 
			
		||||
        /// <param name="reserveTime">預約傳送時間,格式yymmddhhmmss</param>
 | 
			
		||||
        /// <param name="expireTime">重送截止時間,單位分鐘0001 ~ 1440</param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        private int SendLong(String mobileNum, String SMSMessage, String reserveTime, String expireTime)
 | 
			
		||||
        {
 | 
			
		||||
            int ret = 0;
 | 
			
		||||
            retMessage.Clear();
 | 
			
		||||
 | 
			
		||||
            byte[] utf8 = Encoding.UTF8.GetBytes(SMSMessage);
 | 
			
		||||
            byte[] ucs2 = Encoding.GetEncoding("UTF-16BE").GetBytes(SMSMessage);
 | 
			
		||||
            int msg_len = 0;
 | 
			
		||||
 | 
			
		||||
            MsgCoding coding;
 | 
			
		||||
            if (utf8.Length == SMSMessage.Length)
 | 
			
		||||
            {
 | 
			
		||||
                coding = MsgCoding.BIG5;
 | 
			
		||||
                msg_len = (int)LENGTH.LONG_ASCII_MSG_LEN;   // 純英數字每則分則最長153個字
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                coding = MsgCoding.UCS2;
 | 
			
		||||
                msg_len = (int)LENGTH.LONG_MSG_LEN; // 非純英數字每則分則最長67個字
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // 計算需要拆成多少則分則
 | 
			
		||||
            double n = Math.Ceiling((double)SMSMessage.Length / (double)msg_len);
 | 
			
		||||
            double numOfMsg = Math.Round(n);
 | 
			
		||||
 | 
			
		||||
            // 需要發送numOfMsg+1則
 | 
			
		||||
            for (int cnt = 0; cnt <= numOfMsg; cnt++)
 | 
			
		||||
            {
 | 
			
		||||
 | 
			
		||||
                if (cnt == 0)
 | 
			
		||||
                {
 | 
			
		||||
                    // 第一則發送metadata
 | 
			
		||||
 | 
			
		||||
                    MsgRequest req = new MsgRequest();
 | 
			
		||||
                    // 判斷是否為國外門號
 | 
			
		||||
                    req.type = mobileNum.StartsWith("+") ? (byte)RequestType.SENDFOREIGNLONG : (byte)RequestType.SENDLONG;
 | 
			
		||||
 | 
			
		||||
                    String msgSet;
 | 
			
		||||
                    if (String.IsNullOrEmpty(reserveTime) && String.IsNullOrEmpty(expireTime) == false)
 | 
			
		||||
                    {
 | 
			
		||||
                        // 立即傳送       
 | 
			
		||||
                        msgSet = String.Format("{0}\0{1}\0{2}\0", mobileNum, SEND_EXPIRE, expireTime);
 | 
			
		||||
                    }
 | 
			
		||||
                    else if (String.IsNullOrEmpty(reserveTime) == false && String.IsNullOrEmpty(expireTime))
 | 
			
		||||
                    {
 | 
			
		||||
                        // 立即傳送加重送截止時間 
 | 
			
		||||
                        msgSet = String.Format("{0}\0{1}\0{2}\0", mobileNum, SEND_RESERVE, reserveTime);
 | 
			
		||||
                    }
 | 
			
		||||
                    else if (String.IsNullOrEmpty(reserveTime) == false && String.IsNullOrEmpty(expireTime) == false)
 | 
			
		||||
                    {
 | 
			
		||||
                        // 預約傳送
 | 
			
		||||
                        msgSet = String.Format("{0}\0{1}\0{2}\0{3}\0", mobileNum, SEND_RESERVE_EXPIRE, reserveTime, expireTime);
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        // 預約傳送加重送截止時間
 | 
			
		||||
                        msgSet = String.Format("{0}\0{1}\0", mobileNum, SEND_NOW);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // 第一則用不到
 | 
			
		||||
                    String msgContent = String.Format("\0");
 | 
			
		||||
 | 
			
		||||
                    req.coding = (byte)coding;
 | 
			
		||||
                    req.priority = (byte)MsgConst.UNUSED;
 | 
			
		||||
                    req.countryCode = (byte)MsgConst.UNUSED;
 | 
			
		||||
                    req.setLen = (byte)msgSet.Length;
 | 
			
		||||
                    req.contentLen = (byte)numOfMsg;    // 填通數
 | 
			
		||||
                    req.set = Encoding.ASCII.GetBytes(msgSet.PadRight((int)LENGTH.REQSET, '\0'));
 | 
			
		||||
                    req.content = Encoding.ASCII.GetBytes(msgContent.PadRight((int)LENGTH.CONTENT, '\0'));
 | 
			
		||||
 | 
			
		||||
                    ret = sendToserver(req);
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    // 第二則開始送簡訊內容
 | 
			
		||||
                    MsgRequest req = new MsgRequest();
 | 
			
		||||
                    req.type = (byte)cnt;   // 填第幾通
 | 
			
		||||
                    req.coding = (byte)coding;
 | 
			
		||||
                    req.priority = (byte)MsgConst.UNUSED;
 | 
			
		||||
                    req.countryCode = (byte)MsgConst.UNUSED;
 | 
			
		||||
 | 
			
		||||
                    // 用不到
 | 
			
		||||
                    String msgSet = String.Format("\0");
 | 
			
		||||
                    req.setLen = (byte)msgSet.Length;
 | 
			
		||||
                    req.set = Encoding.ASCII.GetBytes(msgSet.PadRight((int)LENGTH.REQSET, '\0'));
 | 
			
		||||
 | 
			
		||||
                    // 取分則內容
 | 
			
		||||
                    String partial_msg;
 | 
			
		||||
                    try
 | 
			
		||||
                    {
 | 
			
		||||
                        partial_msg = SMSMessage.Substring((cnt - 1) * msg_len, msg_len);
 | 
			
		||||
                    }
 | 
			
		||||
                    catch
 | 
			
		||||
                    {
 | 
			
		||||
                        // ArgumentOutOfRangeException: 超過指定長度就取到字串結尾
 | 
			
		||||
                        partial_msg = SMSMessage.Substring((cnt - 1) * msg_len);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (req.coding == (byte)MsgCoding.UCS2)
 | 
			
		||||
                    {
 | 
			
		||||
                        // 非純英數字以UCS2 byte傳送
 | 
			
		||||
                        byte[] buf = Encoding.GetEncoding("UTF-16BE").GetBytes(partial_msg);
 | 
			
		||||
                        req.content = Encoding.GetEncoding("UTF-16BE").GetBytes(partial_msg.PadRight((int)LENGTH.CONTENT, '\0'));
 | 
			
		||||
                        req.contentLen = (byte)buf.Length;
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        // 純英數字以BIG5 byte傳送
 | 
			
		||||
                        byte[] buf = Encoding.ASCII.GetBytes(partial_msg);
 | 
			
		||||
                        req.content = Encoding.ASCII.GetBytes(partial_msg.PadRight((int)LENGTH.CONTENT, '\0'));
 | 
			
		||||
                        req.contentLen = (byte)buf.Length;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    ret = sendToserver(req);
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (ret != 0)
 | 
			
		||||
                {
 | 
			
		||||
                    // 若中途有錯誤直接中斷迴圈不送
 | 
			
		||||
                    System.Diagnostics.Debug.WriteLine(String.Format("SendLong() Exit => {0} : {1}", ret, retMessage));
 | 
			
		||||
                    return ret;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return ret;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 傳送與接收資料
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="req">Request結構</param>
 | 
			
		||||
        /// <returns>回應代碼</returns>
 | 
			
		||||
        private int sendToserver(MsgRequest req)
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
            int ret;
 | 
			
		||||
            retMessage.Clear();
 | 
			
		||||
 | 
			
		||||
            // 將MsgRequest結構轉byte array後傳送
 | 
			
		||||
            byte[] data = encode(req);
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                int sent = socket.Send(data);
 | 
			
		||||
                if (sent != (int)LENGTH.REQUEST)
 | 
			
		||||
                {
 | 
			
		||||
                    retMessage = new StringBuilder("Socket Send Data Error!");
 | 
			
		||||
                    System.Diagnostics.Debug.WriteLine("sent length:" + sent);
 | 
			
		||||
                    return -4;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            catch
 | 
			
		||||
            {
 | 
			
		||||
                retMessage = new StringBuilder("Socket Send Data Error!");
 | 
			
		||||
                return -4;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            // 將接收到的byte arry轉為MsgResponse結構
 | 
			
		||||
            byte[] buf = new byte[(int)LENGTH.RESPONSE];
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                int recv = socket.Receive(buf);
 | 
			
		||||
                if (recv != (int)LENGTH.RESPONSE)
 | 
			
		||||
                {
 | 
			
		||||
                    retMessage = new StringBuilder("Socket Receive Data Error!");
 | 
			
		||||
                    System.Diagnostics.Debug.WriteLine("recv length:" + recv);
 | 
			
		||||
                    return -4;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            catch
 | 
			
		||||
            {
 | 
			
		||||
                retMessage = new StringBuilder("Socket Receive Data Error!");
 | 
			
		||||
                return -4;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            MsgResponse rep = decode(buf);
 | 
			
		||||
            // 回傳代碼
 | 
			
		||||
            ret = rep.code;
 | 
			
		||||
            // 回傳的文字描述或MessageID
 | 
			
		||||
            retMessage = new StringBuilder(Encoding.ASCII.GetString(rep.content).TrimEnd((Char)0));
 | 
			
		||||
 | 
			
		||||
            System.Diagnostics.Debug.WriteLine(String.Format("sendToServer() result => {0} : {1}", ret, retMessage));
 | 
			
		||||
 | 
			
		||||
            return ret;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 查詢一般簡訊狀態
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="messageID">訊息ID</param>
 | 
			
		||||
        /// <returns>0表示訊息已成功送達對方,其餘回傳值請參考規格書</returns>
 | 
			
		||||
        public int QueryMsg(String messageID)
 | 
			
		||||
        {
 | 
			
		||||
            retMessage.Clear();
 | 
			
		||||
 | 
			
		||||
            return this.Query(RequestType.QUERY, messageID);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 查詢長簡訊狀態
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="messageID">訊息ID</param>
 | 
			
		||||
        /// <returns>0表示訊息已成功送達對方,其餘回傳值請參考規格書</returns>
 | 
			
		||||
        public int QueryLongMsg(String messageID)
 | 
			
		||||
        {
 | 
			
		||||
            retMessage.Clear();
 | 
			
		||||
 | 
			
		||||
            return this.Query(RequestType.QUERYLONG, messageID);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 查詢簡訊狀態
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="type">查詢類別</param>
 | 
			
		||||
        /// <param name="messageID">訊息ID</param>
 | 
			
		||||
        /// <returns>0表示訊息已成功送達對方,其餘回傳值請參考規格書</returns>
 | 
			
		||||
        private int Query(RequestType type, String messageID)
 | 
			
		||||
        {
 | 
			
		||||
            int ret = 0;
 | 
			
		||||
            retMessage.Clear();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            String msgSet = String.Format("{0}\0", messageID);
 | 
			
		||||
            String msgContent = String.Empty;
 | 
			
		||||
 | 
			
		||||
            // 設定Request資料
 | 
			
		||||
            MsgRequest req = new MsgRequest();
 | 
			
		||||
            req.type = (byte)type;
 | 
			
		||||
            req.coding = (byte)MsgCoding.BIG5;
 | 
			
		||||
            req.priority = (byte)MsgConst.UNUSED;
 | 
			
		||||
            req.countryCode = (byte)MsgConst.UNUSED;
 | 
			
		||||
            req.setLen = (byte)msgSet.Length;
 | 
			
		||||
            req.contentLen = (byte)msgContent.Length;
 | 
			
		||||
            req.set = Encoding.ASCII.GetBytes(msgSet.PadRight((int)LENGTH.REQSET, '\0'));
 | 
			
		||||
            req.content = Encoding.ASCII.GetBytes(msgContent.PadRight((int)LENGTH.CONTENT, '\0'));
 | 
			
		||||
 | 
			
		||||
            ret = sendToserver(req);
 | 
			
		||||
            return ret;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 取消預約一般簡訊 
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="messageID">訊息ID</param>
 | 
			
		||||
        /// <returns>0表示訊息已取消成功,其餘回傳值請參考規格書</returns>
 | 
			
		||||
        public int CancelMsg(String messageID)
 | 
			
		||||
        {
 | 
			
		||||
            retMessage.Clear();
 | 
			
		||||
 | 
			
		||||
            return this.Cancel(RequestType.CANCEL, messageID);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 取消預約長簡訊
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="messageID">訊息ID</param>
 | 
			
		||||
        /// <returns>0表示訊息已取消成功,其餘回傳值請參考規格書</returns>
 | 
			
		||||
        public int CancelLongMsg(String messageID)
 | 
			
		||||
        {
 | 
			
		||||
            retMessage.Clear();
 | 
			
		||||
 | 
			
		||||
            return this.Cancel(RequestType.CANCELLONG, messageID);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 取消預約簡訊(封裝程式僅供內部呼叫用)
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="type">預約類別</param>
 | 
			
		||||
        /// <param name="messageID">訊息ID</param>
 | 
			
		||||
        /// <returns>0表示訊息已取消成功,其餘回傳值請參考規格書</returns>
 | 
			
		||||
        private int Cancel(RequestType type, String messageID)
 | 
			
		||||
        {
 | 
			
		||||
            int ret = 0;
 | 
			
		||||
            retMessage.Clear();
 | 
			
		||||
 | 
			
		||||
            String msgSet = String.Format("{0}\0", messageID);
 | 
			
		||||
            String msgContent = String.Empty;
 | 
			
		||||
 | 
			
		||||
            // 設定Request資料
 | 
			
		||||
            MsgRequest req = new MsgRequest();
 | 
			
		||||
            req.type = (byte)type;
 | 
			
		||||
            req.coding = (byte)MsgCoding.BIG5;
 | 
			
		||||
            req.priority = (byte)MsgConst.UNUSED;
 | 
			
		||||
            req.countryCode = (byte)MsgConst.UNUSED;
 | 
			
		||||
            req.setLen = (byte)msgSet.Length;
 | 
			
		||||
            req.contentLen = (byte)msgContent.Length;
 | 
			
		||||
            req.set = Encoding.ASCII.GetBytes(msgSet.PadRight((int)LENGTH.REQSET, '\0'));
 | 
			
		||||
            req.content = Encoding.ASCII.GetBytes(msgContent.PadRight((int)LENGTH.CONTENT, '\0'));
 | 
			
		||||
 | 
			
		||||
            ret = sendToserver(req);
 | 
			
		||||
            return ret;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 取得描述文字或MessageID
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <returns>文字或MessageID</returns>
 | 
			
		||||
        public String Get_Message()
 | 
			
		||||
        {
 | 
			
		||||
            return this.retMessage.ToString();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 與簡訊主機中斷連線
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public void EndCon()
 | 
			
		||||
        {
 | 
			
		||||
            retMessage.Clear();
 | 
			
		||||
            if (socket.Connected)
 | 
			
		||||
            {
 | 
			
		||||
                socket.Disconnect(false);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// hinet發送信息
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="input"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        [HttpPost]
 | 
			
		||||
        [Route("api/HiNetMsg")]
 | 
			
		||||
        public ActionResult<ApiResult<string>> HiNetMsg(HiNetInput input)
 | 
			
		||||
        {
 | 
			
		||||
            ApiResult<string> apiResult = new ApiResult<string>(jwt_str);
 | 
			
		||||
            //if (!jwtlife)
 | 
			
		||||
            //{
 | 
			
		||||
            //    apiResult.Code = "5000";
 | 
			
		||||
            //    return BadRequest(apiResult);
 | 
			
		||||
            //}
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                var hiair = new HiNetController();
 | 
			
		||||
                int retCode = hiair.StartCon("202.39.54.130", 8000, "airtest6", "95929ALz");
 | 
			
		||||
                string retContent = string.Empty;
 | 
			
		||||
                if (retCode == 0)
 | 
			
		||||
                {
 | 
			
		||||
                    //發送文字簡訊並回傳狀態碼
 | 
			
		||||
                    retCode = hiair.SendMsg(input.Number, input.Msg);
 | 
			
		||||
                    //取得messageID或文字描述
 | 
			
		||||
                    retContent = hiair.Get_Message();
 | 
			
		||||
                    apiResult.Data = retCode + " : " + retContent;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    apiResult.Code = "5000";
 | 
			
		||||
                    apiResult.Msg = retCode + " : " + retContent;
 | 
			
		||||
                    return BadRequest(apiResult);
 | 
			
		||||
                }
 | 
			
		||||
                this.EndCon();
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception exception)
 | 
			
		||||
            {
 | 
			
		||||
                apiResult.Code = "9999";
 | 
			
		||||
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
 | 
			
		||||
                return Ok(apiResult);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return Ok(apiResult);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -26,15 +26,18 @@ namespace FrontendWebApi.ApiControllers
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IBackendRepository backendRepository;
 | 
			
		||||
        private readonly IFrontendRepository frontendRepository;
 | 
			
		||||
        private readonly IBackgroundServiceMsSqlRepository backgroundServiceMsSqlRepository;
 | 
			
		||||
 | 
			
		||||
        public HistoryController
 | 
			
		||||
        (
 | 
			
		||||
            IBackendRepository backendRepository,
 | 
			
		||||
            IFrontendRepository frontendRepository
 | 
			
		||||
            IFrontendRepository frontendRepository,
 | 
			
		||||
            IBackgroundServiceMsSqlRepository backgroundServiceMsSqlRepository
 | 
			
		||||
        )
 | 
			
		||||
        {
 | 
			
		||||
            this.backendRepository = backendRepository;
 | 
			
		||||
            this.frontendRepository = frontendRepository;
 | 
			
		||||
            this.backgroundServiceMsSqlRepository = backgroundServiceMsSqlRepository;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
@ -206,11 +209,11 @@ namespace FrontendWebApi.ApiControllers
 | 
			
		||||
                        join variable v1 on v1.id = v2.system_parent_id and v1.system_type = @main_system_type
 | 
			
		||||
                        join device d on v1.system_value = d.device_system_tag and v2.system_value = d.device_name_tag and d.deleted = 0 and  d.visible = 1
 | 
			
		||||
                        join device_item di  on  d.device_system_tag=di.device_system_tag and d.device_name_tag=di.device_name_tag 
 | 
			
		||||
                        and   di.is_link = 1
 | 
			
		||||
                        and di.is_link = 1 and di.is_show_history = 1
 | 
			
		||||
                        where c.account = @account
 | 
			
		||||
                        order by v1.system_priority, v2.system_priority", new { @account = myUser.account, @sub_system_type = sub_system_type, @main_system_type = main_system_type });
 | 
			
		||||
                var dbbuilding = await frontendRepository.GetAllAsync<History_Build>(
 | 
			
		||||
                    @$"select distinct d.building_guid,d.full_name,d.priority from role_auth a
 | 
			
		||||
                    @$"select distinct d.building_tag,d.full_name,d.priority from role_auth a
 | 
			
		||||
                        join auth_page b on a.AuthCode = b.AuthCode
 | 
			
		||||
                        join userinfo c on c.role_guid = a.role_guid
 | 
			
		||||
                        join building d on d.building_tag = b.building_tag
 | 
			
		||||
@ -335,7 +338,7 @@ namespace FrontendWebApi.ApiControllers
 | 
			
		||||
                wheres.Add("d.deleted = 0");
 | 
			
		||||
                if (postDevice.SelectBuildings != null && postDevice.SelectBuildings.Count() > 0)
 | 
			
		||||
                {
 | 
			
		||||
                    wheres.Add("d.building_guid in @builds");
 | 
			
		||||
                    wheres.Add("d.device_building_tag in @builds");
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (postDevice.SelectFloors != null && postDevice.SelectFloors.Count() > 0)
 | 
			
		||||
@ -345,7 +348,7 @@ namespace FrontendWebApi.ApiControllers
 | 
			
		||||
 | 
			
		||||
                if (postDevice.SelectSub != null && postDevice.SelectSub.Count() > 0)
 | 
			
		||||
                {
 | 
			
		||||
                    wheres.Add("d.sub_system_guid in @syss");
 | 
			
		||||
                    wheres.Add("d.device_name_tag in @syss");
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (!string.IsNullOrEmpty(postDevice.Device_name))
 | 
			
		||||
@ -358,18 +361,17 @@ namespace FrontendWebApi.ApiControllers
 | 
			
		||||
                var sql = $@"SELECT
 | 
			
		||||
                                a.device_guid,
 | 
			
		||||
                                b.full_name building_name,
 | 
			
		||||
                                c.full_name main_name,
 | 
			
		||||
                                d.full_name sub_name,
 | 
			
		||||
                                d.full_name sub_name,
 | 
			
		||||
                                v1.system_key main_name,
 | 
			
		||||
                                v2.system_key sub_name,
 | 
			
		||||
                                a.full_name device_name,
 | 
			
		||||
                                a.device_number
 | 
			
		||||
                            from (SELECT * 
 | 
			
		||||
                                    FROM device d
 | 
			
		||||
                                    WHERE {wheres_str}) a
 | 
			
		||||
                            join building b on b.building_guid = a.building_guid
 | 
			
		||||
                            join main_system c on c.main_system_guid = a.main_system_guid
 | 
			
		||||
                            join sub_system d on d.sub_system_guid = a.sub_system_guid
 | 
			
		||||
                            order by b.priority,c.priority,d.priority,a.priority";
 | 
			
		||||
                            join building b on b.building_tag = a.device_building_tag
 | 
			
		||||
                            join variable v1 on v1.system_value = a.device_system_tag and v1.deleted = 0 and v1.system_type = 'device_system_category_layer2'
 | 
			
		||||
                            join variable v2 on v2.system_value = a.device_name_tag and v2.deleted = 0 and v2.system_type = 'device_system_category_layer3'
 | 
			
		||||
                            order by b.priority,v1.system_priority,v2.system_priority,a.priority";
 | 
			
		||||
 | 
			
		||||
                var dbDevice = await backendRepository.GetAllAsync<History_GetDevice>(sql, new { builds = postDevice.SelectBuildings, floor_guid = postDevice.SelectFloors, syss = postDevice.SelectSub, device_name = postDevice.Device_name });
 | 
			
		||||
                apiResult.Data = dbDevice;
 | 
			
		||||
@ -404,11 +406,11 @@ namespace FrontendWebApi.ApiControllers
 | 
			
		||||
                var dbDevice = await backendRepository.GetAllAsync<History_PostItem>(
 | 
			
		||||
                    @$"select c.full_name building_name,b.device_number,b.full_name device_name,a.full_name item_name,a.points,a.unit 
 | 
			
		||||
                        from device_item a
 | 
			
		||||
                        join device b on a.sub_system_guid = b.sub_system_guid
 | 
			
		||||
                        join building c on c.building_guid = b.building_guid
 | 
			
		||||
                        join sub_system d on d.sub_system_guid = b.sub_system_guid
 | 
			
		||||
                        join main_system e on e.main_system_guid = b.main_system_guid
 | 
			
		||||
                        where a.deleted = 0 and b.deleted = 0 and d.deleted = 0 and e.deleted = 0
 | 
			
		||||
                        join device b on a.device_system_tag = b.device_system_tag
 | 
			
		||||
                        join building c on c.building_tag = b.device_building_tag
 | 
			
		||||
                        join variable v1 on v1.system_value = b.device_system_tag and v1.deleted = 0 and v1.system_type = 'device_system_category_layer2'
 | 
			
		||||
                        join variable v2 on v2.system_value = b.device_name_tag and v2.deleted = 0 and v2.system_type = 'device_system_category_layer3'
 | 
			
		||||
                        where a.deleted = 0 and b.deleted = 0 and v2.deleted = 0 and v1.deleted = 0
 | 
			
		||||
                        and a.unit is not null and b.device_number in @Device_number
 | 
			
		||||
                        order by c.priority,b.priority
 | 
			
		||||
                        "
 | 
			
		||||
@ -445,29 +447,29 @@ namespace FrontendWebApi.ApiControllers
 | 
			
		||||
            {
 | 
			
		||||
                var sql = $@"
 | 
			
		||||
                            SELECT
 | 
			
		||||
                             rc.combination_guid,
 | 
			
		||||
                             rc.full_name AS combination_full_name,
 | 
			
		||||
                             rcd.device_guid,
 | 
			
		||||
                             d.device_number,
 | 
			
		||||
                             d.full_name AS Device_full_name,
 | 
			
		||||
                             b.full_name AS Building_full_name,
 | 
			
		||||
                             ms.full_name AS Main_system_full_name,
 | 
			
		||||
                             ss.full_name AS Sub_system_full_name
 | 
			
		||||
                            FROM realtime_combination_detail rcd
 | 
			
		||||
                            LEFT JOIN 
 | 
			
		||||
                            (SELECT
 | 
			
		||||
                                rc.*
 | 
			
		||||
                             FROM realtime_combination rc
 | 
			
		||||
                             WHERE building_guid = @building_guid
 | 
			
		||||
                                AND userinfo_guid = @userinfo_guid
 | 
			
		||||
                            ) rc ON rcd.combination_guid = rc.combination_guid
 | 
			
		||||
                            JOIN device d ON d.deleted = 0 AND d.device_guid = rcd.device_guid
 | 
			
		||||
                            JOIN building b ON b.deleted = 0 AND b.building_guid = d.building_guid
 | 
			
		||||
                            JOIN main_system ms ON ms.deleted = 0 AND ms.main_system_guid = d.main_system_guid
 | 
			
		||||
                            JOIN sub_system ss ON ss.deleted = 0 AND ss.sub_system_guid = d.sub_system_guid
 | 
			
		||||
                            WHERE rc.deleted = 0";
 | 
			
		||||
	                            rc.combination_guid,
 | 
			
		||||
	                            rc.full_name AS combination_full_name,
 | 
			
		||||
	                            rcd.device_guid,
 | 
			
		||||
	                            d.device_number,
 | 
			
		||||
	                            d.full_name AS Device_full_name,
 | 
			
		||||
	                            b.full_name AS Building_full_name,
 | 
			
		||||
	                            v1.system_key AS Main_system_full_name,
 | 
			
		||||
	                            v2.system_key AS Sub_system_full_name
 | 
			
		||||
	                        FROM realtime_combination_detail rcd
 | 
			
		||||
	                        LEFT JOIN 
 | 
			
		||||
	                        (SELECT
 | 
			
		||||
			                        rc.*
 | 
			
		||||
	                            FROM realtime_combination rc
 | 
			
		||||
	                            WHERE building_tag = @building_tag
 | 
			
		||||
			                        AND userinfo_guid = @userinfo_guid
 | 
			
		||||
	                        ) rc ON rcd.combination_guid = rc.combination_guid
 | 
			
		||||
	                        JOIN device d ON d.deleted = 0 AND d.device_guid = rcd.device_guid
 | 
			
		||||
	                        JOIN building b ON b.deleted = 0 AND b.building_tag = d.device_building_tag
 | 
			
		||||
	                        JOIN variable v1 ON v1.deleted = 0 AND v1.system_value = d.device_system_tag and v1.system_type = 'device_system_category_layer2'
 | 
			
		||||
	                        JOIN variable v2 ON v2.deleted = 0 AND v2.system_value = d.device_name_tag and v2.system_type = 'device_system_category_layer3'
 | 
			
		||||
	                        WHERE rc.deleted = 0";
 | 
			
		||||
 | 
			
		||||
                var rawDatas = await frontendRepository.GetAllAsync<RealTimeCombinationRawData>(sql, new { building_guid = post.building_guid, userinfo_guid = myUser.userinfo_guid });
 | 
			
		||||
                var rawDatas = await frontendRepository.GetAllAsync<RealTimeCombinationRawData>(sql, new { building_tag = post.building_tag, userinfo_guid = myUser.userinfo_guid });
 | 
			
		||||
 | 
			
		||||
                var rawDatas_groups = rawDatas.GroupBy(x => x.Combination_guid).ToList();
 | 
			
		||||
 | 
			
		||||
@ -536,7 +538,7 @@ namespace FrontendWebApi.ApiControllers
 | 
			
		||||
                    combination = new Dictionary<string, object>()
 | 
			
		||||
                        {
 | 
			
		||||
                            { "@combination_guid", guid},
 | 
			
		||||
                            { "@building_guid", post.Building_guid},
 | 
			
		||||
                            { "@building_tag", post.Building_tag},
 | 
			
		||||
                            { "@userinfo_guid", myUser.userinfo_guid},
 | 
			
		||||
                            { "@full_name", post.Full_name},
 | 
			
		||||
                            { "@created_by", myUser.userinfo_guid}
 | 
			
		||||
@ -808,17 +810,17 @@ namespace FrontendWebApi.ApiControllers
 | 
			
		||||
            {
 | 
			
		||||
                #region 取得區域樓層
 | 
			
		||||
                var sqlBuildingFloor = $@"SELECT
 | 
			
		||||
                                            b.building_guid,
 | 
			
		||||
                                            b.building_tag,
 | 
			
		||||
                                            b.full_name AS building_name,
 | 
			
		||||
                                            b.priority,
 | 
			
		||||
                                            f.floor_guid,
 | 
			
		||||
                                            f.full_name AS floor_name,
 | 
			
		||||
                                            f.priority
 | 
			
		||||
                                          FROM building b
 | 
			
		||||
                                          JOIN floor f ON f.deleted = 0 AND f.building_guid = b.building_guid
 | 
			
		||||
                                          WHERE b.building_guid IN (
 | 
			
		||||
                                          JOIN floor f ON f.deleted = 0 AND f.building_tag = b.building_tag
 | 
			
		||||
                                          WHERE b.building_tag IN (
 | 
			
		||||
                                                            SELECT
 | 
			
		||||
                                                                ap.building_guid
 | 
			
		||||
                                                                ap.building_tag
 | 
			
		||||
                                                            FROM role_auth ra
 | 
			
		||||
                                                            JOIN auth_page ap ON ra.AuthCode = ap.AuthCode
 | 
			
		||||
                                                            JOIN userinfo u ON u.role_guid = ra.role_guid WHERE u.account = @Account
 | 
			
		||||
@ -827,7 +829,7 @@ namespace FrontendWebApi.ApiControllers
 | 
			
		||||
 | 
			
		||||
                var buildingFloorRawDatas = await frontendRepository.GetAllAsync<BuildingFloorRawData>(sqlBuildingFloor, post);
 | 
			
		||||
 | 
			
		||||
                var buildingFloorRawDatas_GroupBy_building_guid = buildingFloorRawDatas.GroupBy(x => x.building_guid).ToList();
 | 
			
		||||
                var buildingFloorRawDatas_GroupBy_building_guid = buildingFloorRawDatas.GroupBy(x => x.building_tag).ToList();
 | 
			
		||||
 | 
			
		||||
                List<History_Build> history_Builds = new List<History_Build>();
 | 
			
		||||
                foreach (var buildingFloorRawData in buildingFloorRawDatas_GroupBy_building_guid)
 | 
			
		||||
@ -846,7 +848,7 @@ namespace FrontendWebApi.ApiControllers
 | 
			
		||||
 | 
			
		||||
                    History_Build history_Build = new History_Build()
 | 
			
		||||
                    {
 | 
			
		||||
                        building_guid = buildingFloorRawData.Key,
 | 
			
		||||
                        building_tag = buildingFloorRawData.Key,
 | 
			
		||||
                        full_name = buildingFloorRawData.First().building_name,
 | 
			
		||||
                        history_Floors = history_Floors
 | 
			
		||||
                    };
 | 
			
		||||
@ -856,22 +858,19 @@ namespace FrontendWebApi.ApiControllers
 | 
			
		||||
                #endregion
 | 
			
		||||
 | 
			
		||||
                #region 取得系統大小類
 | 
			
		||||
                var sqlMainSubSystem = $@"SELECT
 | 
			
		||||
                                            ms.main_system_guid,
 | 
			
		||||
                                            ms.full_name AS main_name,
 | 
			
		||||
                                            ss.sub_system_guid,
 | 
			
		||||
                                            ss.full_name AS sub_name
 | 
			
		||||
                                        FROM sub_system ss
 | 
			
		||||
                                        JOIN main_system ms ON ms.deleted = 0 AND ss.main_system_guid = ms.main_system_guid
 | 
			
		||||
                                        WHERE ss.deleted = 0
 | 
			
		||||
                                        AND ss.sub_system_guid IN (
 | 
			
		||||
                                                                SELECT
 | 
			
		||||
                                                                    ap.ShowView
 | 
			
		||||
                                                                FROM role_auth ra
 | 
			
		||||
                                                                JOIN auth_page ap ON ra.AuthCode = ap.AuthCode
 | 
			
		||||
                                                                JOIN userinfo u ON u.role_guid = ra.role_guid WHERE u.account = @Account
 | 
			
		||||
                                                                )
 | 
			
		||||
                                        ORDER BY ms.priority, ss.priority";
 | 
			
		||||
                var sqlMainSubSystem = $@"select 
 | 
			
		||||
                                            v1.system_value as main_system_tag, v1.system_key as main_name, v2.system_value as sub_system_tag, v2.system_key as sub_name
 | 
			
		||||
                                            from variable v2 
 | 
			
		||||
                                            inner join variable v1 on v2.system_parent_id = v1.id
 | 
			
		||||
                                            where v2.deleted = 0 and
 | 
			
		||||
                                            v2.system_value in (
 | 
			
		||||
	                                            select ap.ShowView
 | 
			
		||||
	                                            from role_auth ra
 | 
			
		||||
	                                            inner join auth_page ap on ra.AuthCode = ap.AuthCode
 | 
			
		||||
	                                            inner join userinfo ui on ra.role_guid = ui.role_guid
 | 
			
		||||
	                                            where ui.account = @Account
 | 
			
		||||
                                            )
 | 
			
		||||
                                            order by v1.system_priority, v2.system_priority;";
 | 
			
		||||
 | 
			
		||||
                var mainSubSystemRawDatas = await frontendRepository.GetAllAsync<HistoryDBMainSub>(sqlMainSubSystem, post);
 | 
			
		||||
 | 
			
		||||
@ -956,30 +955,30 @@ namespace FrontendWebApi.ApiControllers
 | 
			
		||||
                var device_numbers = post.HistoryItems.Select(x => x.Device_number_point.Split(":")[0]).Distinct().ToList();
 | 
			
		||||
 | 
			
		||||
                //依據被選擇的設備找出相對應資料
 | 
			
		||||
                var sqlDeviceItemInfo = $@"SELECT
 | 
			
		||||
                                b.full_name AS building_name,
 | 
			
		||||
                                ms.full_name AS Main_system_name,
 | 
			
		||||
                                ss.full_name AS Sub_system_name,
 | 
			
		||||
                                temp.device_number,
 | 
			
		||||
                                temp.device_name,
 | 
			
		||||
                                temp.full_name AS item_name,
 | 
			
		||||
                                temp.points,
 | 
			
		||||
                                temp.unit
 | 
			
		||||
                                FROM ( SELECT
 | 
			
		||||
                                        di.*,
 | 
			
		||||
                                        d.building_guid,
 | 
			
		||||
                                        d.main_system_guid,
 | 
			
		||||
                                        -- d.sub_system_guid,
 | 
			
		||||
                                        d.device_number,
 | 
			
		||||
                                        d.full_name AS device_name,
 | 
			
		||||
                                        d.priority
 | 
			
		||||
                                        FROM device_item di
 | 
			
		||||
                                        JOIN device d ON d.deleted = 0 AND di.sub_system_guid = d.sub_system_guid
 | 
			
		||||
                                        WHERE di.deleted = 0 AND di.unit IS NOT NULL AND d.device_number IN @Device_number) temp
 | 
			
		||||
                                JOIN building b ON b.deleted = 0 AND temp.building_guid = b.building_guid
 | 
			
		||||
                                JOIN main_system ms ON ms.deleted = 0 AND temp.main_system_guid = ms.main_system_guid
 | 
			
		||||
                                JOIN sub_system ss ON ss.deleted = 0 AND temp.sub_system_guid = ss.sub_system_guid
 | 
			
		||||
                                ORDER BY b.priority, ms.priority, ss.priority, temp.priority";
 | 
			
		||||
                var sqlDeviceItemInfo = $@"select 
 | 
			
		||||
	                                        b.full_name as building_name,
 | 
			
		||||
	                                        v1.system_key as Main_system_name,
 | 
			
		||||
	                                        v2.system_key as Sub_system_name,
 | 
			
		||||
	                                        temp.device_number,
 | 
			
		||||
	                                        temp.device_name,
 | 
			
		||||
	                                        temp.full_name as item_name,
 | 
			
		||||
	                                        temp.points,
 | 
			
		||||
	                                        temp.unit
 | 
			
		||||
                                        from (
 | 
			
		||||
	                                        select 
 | 
			
		||||
		                                        di.*,
 | 
			
		||||
		                                        d.device_building_tag,
 | 
			
		||||
		                                        d.device_number,
 | 
			
		||||
		                                        d.full_name as device_name,
 | 
			
		||||
		                                        d.priority
 | 
			
		||||
	                                        from device_item di
 | 
			
		||||
	                                        inner join device d on di.device_name_tag = d.device_name_tag and d.deleted = 0
 | 
			
		||||
	                                        where di.deleted = 0 and di.unit is not null and d.device_number IN @Device_number
 | 
			
		||||
                                        ) temp
 | 
			
		||||
                                        inner join building b on temp.device_building_tag = b.building_tag and b.deleted = 0
 | 
			
		||||
                                        inner join variable v1 on temp.device_system_tag = v1.system_value and v1.deleted = 0 and v1.system_type = 'device_system_category_layer2'
 | 
			
		||||
                                        inner join variable v2 on temp.device_name_tag = v2.system_value and v2.deleted = 0 and v2.system_type = 'device_system_category_layer3'
 | 
			
		||||
                                        order by b.priority, v1.system_priority, v2.system_priority, temp.priority";
 | 
			
		||||
 | 
			
		||||
                var device_item_infos = await frontendRepository.GetAllAsync<DeviceItemInfo>(sqlDeviceItemInfo, new { Device_number = device_numbers });
 | 
			
		||||
 | 
			
		||||
@ -1087,5 +1086,57 @@ namespace FrontendWebApi.ApiControllers
 | 
			
		||||
            }
 | 
			
		||||
            return Ok(apiResult);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 即使歷史資料(前7天)
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="input"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        [HttpPost]
 | 
			
		||||
        [Route("api/HistoryRealTime")]
 | 
			
		||||
        public async Task<ActionResult<ApiResult<List<HistoryRealTimeOutput>>>> GetHistoryRealTime ([FromBody] HistoryRealTimeInput input)
 | 
			
		||||
        {
 | 
			
		||||
            ApiResult<List<HistoryRealTimeOutput>> apiResult = new ApiResult<List<HistoryRealTimeOutput>>(jwt_str);
 | 
			
		||||
            apiResult.Data = new List<HistoryRealTimeOutput>();
 | 
			
		||||
            if (!jwtlife)
 | 
			
		||||
            {
 | 
			
		||||
                apiResult.Code = "5000";
 | 
			
		||||
                return BadRequest(apiResult);
 | 
			
		||||
            }
 | 
			
		||||
            if (input.tableDeviceName.Count == 0)
 | 
			
		||||
            {
 | 
			
		||||
                apiResult.Code = "9998";
 | 
			
		||||
                apiResult.Msg = "沒有設備被選擇";
 | 
			
		||||
                return BadRequest(apiResult);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                List<string> tableName = new List<string>();
 | 
			
		||||
                foreach (var dn in input.tableDeviceName)
 | 
			
		||||
                {
 | 
			
		||||
                    tableName.AddRange(await backgroundServiceMsSqlRepository.GetAllAsync<string>($"select table_name from INFORMATION_SCHEMA.TABLES where table_name like '{dn}%'"));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (tableName.Count > 0)
 | 
			
		||||
                {
 | 
			
		||||
                    foreach (var tn in tableName)
 | 
			
		||||
                    {
 | 
			
		||||
                        var sql = $@"select timestamp as timeStamp, round(value, 2) as value from {tn} where replace(convert(varchar, [timestamp], 111), '/', '-') >= @startTime and replace(convert(varchar, [timestamp], 111), '/', '-') <= @endTime ordr by timestamp";
 | 
			
		||||
                        apiResult.Data.AddRange(
 | 
			
		||||
                            await backgroundServiceMsSqlRepository.GetAllAsync<HistoryRealTimeOutput>(sql, new { startTime = input.startTime, endTime = input.endTime })
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception exception)
 | 
			
		||||
            {
 | 
			
		||||
                apiResult.Code = "9999";
 | 
			
		||||
                apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
 | 
			
		||||
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
 | 
			
		||||
                return Ok(apiResult);
 | 
			
		||||
            }
 | 
			
		||||
            return Ok(apiResult);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										608
									
								
								FrontendWebApi/ApiControllers/HydroMeterController.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										608
									
								
								FrontendWebApi/ApiControllers/HydroMeterController.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,608 @@
 | 
			
		||||
using FrontendWebApi.Models;
 | 
			
		||||
using Microsoft.AspNetCore.Mvc;
 | 
			
		||||
using Microsoft.Extensions.Logging;
 | 
			
		||||
using NPOI.SS.UserModel;
 | 
			
		||||
using NPOI.XSSF.UserModel;
 | 
			
		||||
using Repository.BackendRepository.Interface;
 | 
			
		||||
using Repository.FrontendRepository.Interface;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace FrontendWebApi.ApiControllers
 | 
			
		||||
{
 | 
			
		||||
    public class HydroMeterController : MyBaseApiController<HydroMeterController>
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IBackendRepository backendRepository;
 | 
			
		||||
        private readonly IFrontendRepository frontendRepository;
 | 
			
		||||
 | 
			
		||||
        public HydroMeterController(IBackendRepository backendRepository, IFrontendRepository frontendRepository)
 | 
			
		||||
        {
 | 
			
		||||
            this.backendRepository = backendRepository;
 | 
			
		||||
            this.frontendRepository = frontendRepository;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 電表
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="input"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        [HttpPost]
 | 
			
		||||
        [Route("api/ElectricList")]
 | 
			
		||||
        public async Task<ActionResult<ApiResult<List<HydroMeterOutput>>>> ElectricList([FromBody] HydroMeterInput input)
 | 
			
		||||
        {
 | 
			
		||||
            ApiResult<List<HydroMeterOutput>> apiResult = new ApiResult<List<HydroMeterOutput>>(jwt_str);
 | 
			
		||||
            if (!jwtlife)
 | 
			
		||||
            {
 | 
			
		||||
                apiResult.Code = "5000";
 | 
			
		||||
                return BadRequest(apiResult);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            string tableType = "day week month year";
 | 
			
		||||
            if (input.building_tag == null)
 | 
			
		||||
            {
 | 
			
		||||
                apiResult.Code = "9999";
 | 
			
		||||
                apiResult.Msg = "棟別沒有被選取";
 | 
			
		||||
                return BadRequest(apiResult);
 | 
			
		||||
            }
 | 
			
		||||
            else if (input.tableType == null || !tableType.Contains(input.tableType))
 | 
			
		||||
            {
 | 
			
		||||
                apiResult.Code = "9999";
 | 
			
		||||
                apiResult.Msg = "表單類別錯誤";
 | 
			
		||||
                return BadRequest(apiResult);
 | 
			
		||||
            }
 | 
			
		||||
            else if (input.floor_tag.Count == 0)
 | 
			
		||||
            {
 | 
			
		||||
                apiResult.Code = "0000";
 | 
			
		||||
                apiResult.Data = new List<HydroMeterOutput>() { };
 | 
			
		||||
                return Ok(apiResult);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                var startTime = input.tableType == "day" || input.tableType == "week"
 | 
			
		||||
                                ? input.startTime + "-01"
 | 
			
		||||
                                : input.tableType == "month" || input.tableType == "year" ? input.startTime + "-01-01"
 | 
			
		||||
                                : null;
 | 
			
		||||
                var endTime = input.tableType == "day" || input.tableType == "week" 
 | 
			
		||||
                                ? input.startTime.Split("-")[0] + "-" + (Int32.Parse(input.startTime.Split("-")[1]) + 1).ToString().PadLeft(2, '0') + "-01"
 | 
			
		||||
                                : input.tableType == "month" ? (Int32.Parse(input.startTime.Split("-")[0]) + 1) + "-01-01"
 | 
			
		||||
                                : input.tableType == "year" ? input.endTime + "-01-01"
 | 
			
		||||
                                : null;
 | 
			
		||||
                string sqlWhere = "";
 | 
			
		||||
                string sqlGroup = "";
 | 
			
		||||
                string sqlAvgRawData = "";
 | 
			
		||||
                if (input.floor_tag.Count > 0)
 | 
			
		||||
                    sqlWhere = $@" and substring_index(substring_index(device_number, '_', 3), '_', -1) in @floor_tag ";
 | 
			
		||||
 | 
			
		||||
                if (input.tableType == "year")
 | 
			
		||||
                {
 | 
			
		||||
                    sqlGroup = $@" group by year(start_timestamp), year(end_timestamp), device_number ";
 | 
			
		||||
                    sqlAvgRawData = " round(avg(avg_rawdata), 2) as avg_rawdata, year(start_timestamp) as start_timestamp, year(end_timestamp) as end_timestamp ";
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                    sqlAvgRawData = " round(avg_rawdata, 2) as avg_rawdata, start_timestamp, end_timestamp ";
 | 
			
		||||
 | 
			
		||||
                var table = input.tableType == "year" ? "archive_electric_meter_day" : "archive_electric_meter_" + input.tableType;
 | 
			
		||||
                var dateFormat = input.tableType == "day" || input.tableType == "week" ? "%Y-%m-%d" : input.tableType == "month" ? "%Y-%m" : input.tableType == "year" ? "%Y" : null;
 | 
			
		||||
                var sql = $@"set @i = -1;
 | 
			
		||||
                            select fd.device_number, aemm.avg_rawdata, DATE_FORMAT(fd.date, @dateFormat) as timestamp
 | 
			
		||||
                            from (
 | 
			
		||||
	                            select *
 | 
			
		||||
	                            from (
 | 
			
		||||
		                            (
 | 
			
		||||
			                            SELECT DATE(ADDDATE(@startTime, INTERVAL @i:=@i+1 {input.tableType})) AS date
 | 
			
		||||
                                        FROM {table}
 | 
			
		||||
			                            HAVING @i < TIMESTAMPDIFF({input.tableType}, @startTime, ADDDATE(@endTime, INTERVAL -1 DAY))
 | 
			
		||||
		                            ) d,
 | 
			
		||||
		                            (   
 | 
			
		||||
                                        select device_number
 | 
			
		||||
                                        from {table}
 | 
			
		||||
                                        where start_timestamp >= @startTime and end_timestamp < @endTime and point = 'KWH' and SUBSTRING_INDEX(device_number, '_', 1) = @building_tag 
 | 
			
		||||
                                        {sqlWhere} 
 | 
			
		||||
                                        group by device_number
 | 
			
		||||
                                    ) dn
 | 
			
		||||
	                            )
 | 
			
		||||
                            ) fd
 | 
			
		||||
                            left join (
 | 
			
		||||
	                            select device_number, {sqlAvgRawData}
 | 
			
		||||
		                            from {table}
 | 
			
		||||
 		                            where start_timestamp >= @startTime and end_timestamp < @endTime and point = 'KWH' and SUBSTRING_INDEX(device_number, '_', 1) = @building_tag
 | 
			
		||||
                                    {sqlWhere} {sqlGroup}
 | 
			
		||||
                            ) aemm on aemm.start_timestamp >= fd.date and aemm.end_timestamp < DATE_ADD(fd.date, INTERVAL +1 {input.tableType}) and aemm.device_number = fd.device_number
 | 
			
		||||
                            order by fd.device_number, fd.date";
 | 
			
		||||
                var rawData = await backendRepository.GetAllAsync<HydroMeterRawDataOutput>(sql,
 | 
			
		||||
                                new { startTime = startTime, endtime = endTime, building_tag = input.building_tag, floor_tag = input.floor_tag, dateFormat = dateFormat });
 | 
			
		||||
                var list = rawData
 | 
			
		||||
                            .GroupBy(x => new { building_tag = x.device_number.Split("_")[0], floor_tag = x.device_number.Split("_")[2], device_serial_tag = x.device_number.Split("_")[4] })
 | 
			
		||||
                            .Select(x => new HydroMeterOutput { building_tag = x.Key.building_tag, floor_tag = x.Key.floor_tag, device_serial_tag = x.Key.device_serial_tag })
 | 
			
		||||
                            .ToList();
 | 
			
		||||
 | 
			
		||||
                foreach (var l in list)
 | 
			
		||||
                {
 | 
			
		||||
                    l.rawData = new List<HydroMeterRawDataOutput>();
 | 
			
		||||
                    l.rawData.AddRange(
 | 
			
		||||
                        rawData.Where(x => x.device_number.Split("_")[0] == l.building_tag && x.device_number.Split("_")[2] == l.floor_tag && x.device_number.Split("_")[4] == l.device_serial_tag)
 | 
			
		||||
                    );
 | 
			
		||||
                    l.building_name = await backendRepository.GetOneAsync<string>("select full_name from building where building_tag = @building_tag and deleted = 0",
 | 
			
		||||
                                        new { building_tag = l.building_tag });
 | 
			
		||||
                    l.total = l.rawData.Sum(x => x.avg_rawdata).ToString();
 | 
			
		||||
                    l.price = input.price.HasValue 
 | 
			
		||||
                                ? (Math.Round(input.price.Value, 2)).ToString() 
 | 
			
		||||
                                : Math.Round((await backendRepository.GetOneAsync<decimal>("select system_value from variable where system_type = 'ElectricPrice' and deleted = 0")), 2).ToString();
 | 
			
		||||
                    l.total_price = Math.Round((Decimal.Parse(l.total) * Decimal.Parse(l.price)), 2).ToString();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                apiResult.Code = "0000";
 | 
			
		||||
                apiResult.Data = list;
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception exception)
 | 
			
		||||
            {
 | 
			
		||||
                apiResult.Code = "9999";
 | 
			
		||||
                apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
 | 
			
		||||
                string json = System.Text.Json.JsonSerializer.Serialize(input);
 | 
			
		||||
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
 | 
			
		||||
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
 | 
			
		||||
            }
 | 
			
		||||
            return apiResult;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 水表
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="input"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        [HttpPost]
 | 
			
		||||
        [Route("api/WaterList")]
 | 
			
		||||
        public async Task<ActionResult<ApiResult<List<HydroMeterOutput>>>> WaterList([FromBody] HydroMeterInput input)
 | 
			
		||||
        {
 | 
			
		||||
            ApiResult<List<HydroMeterOutput>> apiResult = new ApiResult<List<HydroMeterOutput>>(jwt_str);
 | 
			
		||||
            if (!jwtlife)
 | 
			
		||||
            {
 | 
			
		||||
                apiResult.Code = "5000";
 | 
			
		||||
                return BadRequest(apiResult);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            string tableType = "day week month year";
 | 
			
		||||
            if (input.building_tag == null)
 | 
			
		||||
            {
 | 
			
		||||
                apiResult.Code = "9999";
 | 
			
		||||
                apiResult.Msg = "棟別沒有被選取";
 | 
			
		||||
                return BadRequest(apiResult);
 | 
			
		||||
            }
 | 
			
		||||
            else if (input.tableType == null || !tableType.Contains(input.tableType))
 | 
			
		||||
            {
 | 
			
		||||
                apiResult.Code = "9999";
 | 
			
		||||
                apiResult.Msg = "表單類別錯誤";
 | 
			
		||||
                return BadRequest(apiResult);
 | 
			
		||||
            }
 | 
			
		||||
            else if (input.floor_tag.Count == 0)
 | 
			
		||||
            {
 | 
			
		||||
                apiResult.Code = "0000";
 | 
			
		||||
                apiResult.Data = new List<HydroMeterOutput>() { };
 | 
			
		||||
                return Ok(apiResult);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                var startTime = input.tableType == "day" || input.tableType == "week"
 | 
			
		||||
                                ? input.startTime + "-01"
 | 
			
		||||
                                : input.tableType == "month" || input.tableType == "year" ? input.startTime + "-01-01"
 | 
			
		||||
                                : null;
 | 
			
		||||
                var endTime = input.tableType == "day" || input.tableType == "week"
 | 
			
		||||
                                ? input.startTime.Split("-")[0] + "-" + (Int32.Parse(input.startTime.Split("-")[1]) + 1).ToString().PadLeft(2, '0') + "-01"
 | 
			
		||||
                                : input.tableType == "month" ? (Int32.Parse(input.startTime.Split("-")[0]) + 1) + "-01-01"
 | 
			
		||||
                                : input.tableType == "year" ? input.endTime + "-01-01"
 | 
			
		||||
                                : null;
 | 
			
		||||
                string sqlWhere = "";
 | 
			
		||||
                string sqlGroup = "";
 | 
			
		||||
                string sqlAvgRawData = "";
 | 
			
		||||
                if (input.floor_tag.Count > 0)
 | 
			
		||||
                    sqlWhere = $@" and substring_index(substring_index(device_number, '_', 3), '_', -1) in @floor_tag ";
 | 
			
		||||
 | 
			
		||||
                if (input.tableType == "year")
 | 
			
		||||
                {
 | 
			
		||||
                    sqlGroup = $@" group by year(start_timestamp), year(end_timestamp), device_number ";
 | 
			
		||||
                    sqlAvgRawData = " round(avg(avg_rawdata), 2) as avg_rawdata, year(start_timestamp) as start_timestamp, year(end_timestamp) as end_timestamp ";
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                    sqlAvgRawData = " round(avg_rawdata, 2) as avg_rawdata, start_timestamp, end_timestamp ";
 | 
			
		||||
 | 
			
		||||
                var table = input.tableType == "year" ? "archive_water_meter_day" : "archive_water_meter_" + input.tableType;
 | 
			
		||||
                var dateFormat = input.tableType == "day" || input.tableType == "week" ? "%Y-%m-%d" : input.tableType == "month" ? "%Y-%m" : input.tableType == "year" ? "%Y" : null;
 | 
			
		||||
                var sql = $@"set @i = -1;
 | 
			
		||||
                            select fd.device_number, aemm.avg_rawdata, DATE_FORMAT(fd.date, @dateFormat) as timestamp
 | 
			
		||||
                            from (
 | 
			
		||||
	                            select *
 | 
			
		||||
	                            from (
 | 
			
		||||
		                            (
 | 
			
		||||
			                            SELECT DATE(ADDDATE(@startTime, INTERVAL @i:=@i+1 {input.tableType})) AS date
 | 
			
		||||
                                        FROM {table}
 | 
			
		||||
			                            HAVING @i < TIMESTAMPDIFF({input.tableType}, @startTime, ADDDATE(@endTime, INTERVAL -1 DAY))
 | 
			
		||||
		                            ) d,
 | 
			
		||||
		                            (   
 | 
			
		||||
                                        select device_number
 | 
			
		||||
                                        from {table}
 | 
			
		||||
                                        where start_timestamp >= @startTime and end_timestamp < @endTime and point = 'RCV' and SUBSTRING_INDEX(device_number, '_', 1) = @building_tag 
 | 
			
		||||
                                        {sqlWhere} 
 | 
			
		||||
                                        group by device_number
 | 
			
		||||
                                    ) dn
 | 
			
		||||
	                            )
 | 
			
		||||
                            ) fd
 | 
			
		||||
                            left join (
 | 
			
		||||
	                            select device_number, {sqlAvgRawData}
 | 
			
		||||
		                            from {table}
 | 
			
		||||
 		                            where start_timestamp >= @startTime and end_timestamp < @endTime and point = 'RCV' and SUBSTRING_INDEX(device_number, '_', 1) = @building_tag
 | 
			
		||||
                                    {sqlWhere} {sqlGroup}
 | 
			
		||||
                            ) aemm on aemm.start_timestamp >= fd.date and aemm.end_timestamp < DATE_ADD(fd.date, INTERVAL +1 {input.tableType}) and aemm.device_number = fd.device_number
 | 
			
		||||
                            order by fd.device_number, fd.date";
 | 
			
		||||
 | 
			
		||||
                var rawData = await backendRepository.GetAllAsync<HydroMeterRawDataOutput>(sql,
 | 
			
		||||
                            new { startTime = startTime, endTime = endTime, building_tag = input.building_tag, floor_tag = input.floor_tag, dateFormat = dateFormat });
 | 
			
		||||
                var list = rawData
 | 
			
		||||
                            .GroupBy(x => new { building_tag = x.device_number.Split("_")[0], floor_tag = x.device_number.Split("_")[2], device_serial_tag = x.device_number.Split("_")[4] })
 | 
			
		||||
                            .Select(x => new HydroMeterOutput { building_tag = x.Key.building_tag, floor_tag = x.Key.floor_tag, device_serial_tag = x.Key.device_serial_tag })
 | 
			
		||||
                            .ToList();
 | 
			
		||||
 | 
			
		||||
                foreach (var l in list)
 | 
			
		||||
                {
 | 
			
		||||
                    l.rawData = new List<HydroMeterRawDataOutput>();
 | 
			
		||||
                    l.rawData.AddRange(
 | 
			
		||||
                        rawData.Where(x => x.device_number.Split("_")[0] == l.building_tag && x.device_number.Split("_")[2] == l.floor_tag && x.device_number.Split("_")[4] == l.device_serial_tag)
 | 
			
		||||
                    );
 | 
			
		||||
                    l.building_name = await backendRepository.GetOneAsync<string>("select full_name from building where building_tag = @building_tag and deleted = 0",
 | 
			
		||||
                                        new { building_tag = l.building_tag });
 | 
			
		||||
                    l.total = l.rawData.Sum(x => x.avg_rawdata).ToString();
 | 
			
		||||
                    l.price = input.price.HasValue
 | 
			
		||||
                                ? (Math.Round(input.price.Value, 2)).ToString()
 | 
			
		||||
                                : Math.Round((await backendRepository.GetOneAsync<decimal>("select system_value from variable where system_type = 'WaterPrice' and deleted = 0")), 2).ToString();
 | 
			
		||||
                    l.total_price = Math.Round((Decimal.Parse(l.total) * Decimal.Parse(l.price)), 2).ToString();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                apiResult.Code = "0000";
 | 
			
		||||
                apiResult.Data = list;
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception exception)
 | 
			
		||||
            {
 | 
			
		||||
                apiResult.Code = "9999";
 | 
			
		||||
                apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
 | 
			
		||||
                string json = System.Text.Json.JsonSerializer.Serialize(input);
 | 
			
		||||
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
 | 
			
		||||
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
 | 
			
		||||
            }
 | 
			
		||||
            return apiResult;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 水電表費用
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="input"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        [HttpPost]
 | 
			
		||||
        [Route("api/HydroMeterPrice")]
 | 
			
		||||
        public async Task<ActionResult<ApiResult<decimal>>> Price([FromBody] HydroMeterPriceInput input)
 | 
			
		||||
        {
 | 
			
		||||
            ApiResult<decimal> apiResult = new ApiResult<decimal>(jwt_str);
 | 
			
		||||
            if (!jwtlife)
 | 
			
		||||
            {
 | 
			
		||||
                apiResult.Code = "5000";
 | 
			
		||||
                return BadRequest(apiResult);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                apiResult.Code = "0000";
 | 
			
		||||
                apiResult.Data = await backendRepository.GetOneAsync<decimal>($@"select system_value from variable where system_type = '{input.type}Price' and deleted = 0");
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception exception)
 | 
			
		||||
            {
 | 
			
		||||
                apiResult.Code = "9999";
 | 
			
		||||
                apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
 | 
			
		||||
                string json = System.Text.Json.JsonSerializer.Serialize(input);
 | 
			
		||||
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
 | 
			
		||||
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
 | 
			
		||||
            }
 | 
			
		||||
            return apiResult;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [HttpPost]
 | 
			
		||||
        [Route("api/ExportElectricList")]
 | 
			
		||||
        public FileResult OpeExportExcelElec([FromBody] HydroMeterInput input)
 | 
			
		||||
        {
 | 
			
		||||
            var result = this.ElectricList(input).Result.Value.Data.ToList();
 | 
			
		||||
 | 
			
		||||
            var workbook = new XSSFWorkbook();
 | 
			
		||||
            #region excel設定
 | 
			
		||||
            IFont font12 = workbook.CreateFont();
 | 
			
		||||
            font12.FontName = "新細明體";
 | 
			
		||||
            font12.FontHeightInPoints = 12;
 | 
			
		||||
            ICellStyle style12 = workbook.CreateCellStyle();
 | 
			
		||||
            style12.SetFont(font12);
 | 
			
		||||
            style12.Alignment = HorizontalAlignment.Center;
 | 
			
		||||
            style12.VerticalAlignment = VerticalAlignment.Center;
 | 
			
		||||
            IFont font12Times = workbook.CreateFont();
 | 
			
		||||
            font12Times.FontName = "Times New Roman";
 | 
			
		||||
            font12Times.FontHeightInPoints = 12;
 | 
			
		||||
            IFont font18 = workbook.CreateFont();
 | 
			
		||||
            font18.FontName = "新細明體";
 | 
			
		||||
            font18.FontHeightInPoints = 18;
 | 
			
		||||
            font18.IsBold = true;
 | 
			
		||||
            ICellStyle styleTitle18 = workbook.CreateCellStyle();
 | 
			
		||||
            styleTitle18.SetFont(font18);
 | 
			
		||||
            styleTitle18.Alignment = HorizontalAlignment.Center;
 | 
			
		||||
            styleTitle18.VerticalAlignment = VerticalAlignment.Center;
 | 
			
		||||
            ICellStyle styleLeft12 = workbook.CreateCellStyle();
 | 
			
		||||
            styleLeft12.SetFont(font12);
 | 
			
		||||
            styleLeft12.Alignment = HorizontalAlignment.Left;
 | 
			
		||||
            styleLeft12.VerticalAlignment = VerticalAlignment.Center;
 | 
			
		||||
            ICellStyle styleLine12 = workbook.CreateCellStyle();
 | 
			
		||||
            styleLine12.SetFont(font12);
 | 
			
		||||
            styleLine12.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;
 | 
			
		||||
            styleLine12.VerticalAlignment = VerticalAlignment.Center;
 | 
			
		||||
            styleLine12.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
 | 
			
		||||
            styleLine12.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
 | 
			
		||||
            styleLine12.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
 | 
			
		||||
            styleLine12.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
 | 
			
		||||
            ICellStyle stylein12 = workbook.CreateCellStyle();
 | 
			
		||||
            stylein12.SetFont(font12Times);
 | 
			
		||||
            stylein12.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Left;
 | 
			
		||||
            stylein12.VerticalAlignment = VerticalAlignment.Center;
 | 
			
		||||
            stylein12.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
 | 
			
		||||
            stylein12.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
 | 
			
		||||
            stylein12.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
 | 
			
		||||
            stylein12.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
 | 
			
		||||
            stylein12.WrapText = true;
 | 
			
		||||
            #endregion
 | 
			
		||||
 | 
			
		||||
            var sheet = workbook.CreateSheet("電表報表");
 | 
			
		||||
            int RowPosition = 0;
 | 
			
		||||
            if (result.Count > 0)
 | 
			
		||||
            {
 | 
			
		||||
                #region set cell
 | 
			
		||||
                IRow row = sheet.CreateRow(RowPosition);
 | 
			
		||||
                sheet.SetColumnWidth(0, 4 * 160 * 12);
 | 
			
		||||
                sheet.SetColumnWidth(1, 4 * 160 * 12);
 | 
			
		||||
                sheet.SetColumnWidth(2, 4 * 160 * 12);
 | 
			
		||||
 | 
			
		||||
                int i = 0;
 | 
			
		||||
                ICell cell = row.CreateCell(i++);
 | 
			
		||||
                cell.SetCellValue("東別");
 | 
			
		||||
                cell.CellStyle = styleLine12;
 | 
			
		||||
                cell = row.CreateCell(i++);
 | 
			
		||||
                cell.SetCellValue("樓層");
 | 
			
		||||
                cell.CellStyle = styleLine12;
 | 
			
		||||
                cell = row.CreateCell(i++);
 | 
			
		||||
                cell.SetCellValue("設備");
 | 
			
		||||
                cell.CellStyle = styleLine12;
 | 
			
		||||
            
 | 
			
		||||
                foreach (var rr in result.FirstOrDefault().rawData)
 | 
			
		||||
                {
 | 
			
		||||
                    cell = row.CreateCell(i++);
 | 
			
		||||
                    cell.SetCellValue(rr.timeStamp);
 | 
			
		||||
                    cell.CellStyle = styleLine12;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                cell = row.CreateCell(i++);
 | 
			
		||||
                cell.SetCellValue("小計");
 | 
			
		||||
                cell.CellStyle = styleLine12;
 | 
			
		||||
                cell = row.CreateCell(i++);
 | 
			
		||||
                cell.SetCellValue("單價");
 | 
			
		||||
                cell.CellStyle = styleLine12;
 | 
			
		||||
                cell = row.CreateCell(i++);
 | 
			
		||||
                cell.SetCellValue("金額總計");
 | 
			
		||||
                cell.CellStyle = styleLine12;
 | 
			
		||||
                #endregion
 | 
			
		||||
 | 
			
		||||
                foreach (var r in result)
 | 
			
		||||
                {
 | 
			
		||||
                    RowPosition += 1;
 | 
			
		||||
                    int k = 3;
 | 
			
		||||
                    row = sheet.CreateRow(RowPosition);
 | 
			
		||||
                    for (int j = 0; j <= i; j++)
 | 
			
		||||
                    {
 | 
			
		||||
                        cell = row.CreateCell(j);
 | 
			
		||||
                        if (j == 0)
 | 
			
		||||
                        {
 | 
			
		||||
                            cell.SetCellValue(r.building_name);
 | 
			
		||||
                        }
 | 
			
		||||
                        if (j == 1)
 | 
			
		||||
                        {
 | 
			
		||||
                            cell.SetCellValue(r.floor_tag);
 | 
			
		||||
                        }
 | 
			
		||||
                        if (j == 2)
 | 
			
		||||
                        {
 | 
			
		||||
                            cell.SetCellValue(r.device_serial_tag);
 | 
			
		||||
                        }
 | 
			
		||||
                        
 | 
			
		||||
                        if (j == 3)
 | 
			
		||||
                        {
 | 
			
		||||
                            foreach (var rr in r.rawData)
 | 
			
		||||
                            {
 | 
			
		||||
                                cell.SetCellValue(rr.avg_rawdata.ToString());
 | 
			
		||||
                                j++;
 | 
			
		||||
                                k++;
 | 
			
		||||
                                cell = row.CreateCell(j);
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        
 | 
			
		||||
                        if (j == k)
 | 
			
		||||
                        {
 | 
			
		||||
                            cell.SetCellValue(r.total);
 | 
			
		||||
                        }
 | 
			
		||||
                        if (j == k+1)
 | 
			
		||||
                        {
 | 
			
		||||
                            cell.SetCellValue(r.price);
 | 
			
		||||
                        }
 | 
			
		||||
                        if (j == k+2)
 | 
			
		||||
                        {
 | 
			
		||||
                            cell.SetCellValue(r.total_price);
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        cell.CellStyle = style12;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var ms = new NpoiMemoryStream
 | 
			
		||||
            {
 | 
			
		||||
                AllowClose = false
 | 
			
		||||
            };
 | 
			
		||||
            workbook.Write(ms);
 | 
			
		||||
            ms.Flush();
 | 
			
		||||
            ms.Seek(0, SeekOrigin.Begin);
 | 
			
		||||
 | 
			
		||||
            return File(ms, "application/vnd.ms-excel", "電表報表.xlsx");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [HttpGet]
 | 
			
		||||
        [Route("api/ExportWaterList")]
 | 
			
		||||
        public FileResult OpeExportExcelWater([FromBody] HydroMeterInput input)
 | 
			
		||||
        {
 | 
			
		||||
            var result = this.WaterList(input).Result.Value.Data.ToList();
 | 
			
		||||
 | 
			
		||||
            var workbook = new XSSFWorkbook();
 | 
			
		||||
            #region excel設定
 | 
			
		||||
            IFont font12 = workbook.CreateFont();
 | 
			
		||||
            font12.FontName = "新細明體";
 | 
			
		||||
            font12.FontHeightInPoints = 12;
 | 
			
		||||
            ICellStyle style12 = workbook.CreateCellStyle();
 | 
			
		||||
            style12.SetFont(font12);
 | 
			
		||||
            style12.Alignment = HorizontalAlignment.Center;
 | 
			
		||||
            style12.VerticalAlignment = VerticalAlignment.Center;
 | 
			
		||||
            IFont font12Times = workbook.CreateFont();
 | 
			
		||||
            font12Times.FontName = "Times New Roman";
 | 
			
		||||
            font12Times.FontHeightInPoints = 12;
 | 
			
		||||
            IFont font18 = workbook.CreateFont();
 | 
			
		||||
            font18.FontName = "新細明體";
 | 
			
		||||
            font18.FontHeightInPoints = 18;
 | 
			
		||||
            font18.IsBold = true;
 | 
			
		||||
            ICellStyle styleTitle18 = workbook.CreateCellStyle();
 | 
			
		||||
            styleTitle18.SetFont(font18);
 | 
			
		||||
            styleTitle18.Alignment = HorizontalAlignment.Center;
 | 
			
		||||
            styleTitle18.VerticalAlignment = VerticalAlignment.Center;
 | 
			
		||||
            ICellStyle styleLeft12 = workbook.CreateCellStyle();
 | 
			
		||||
            styleLeft12.SetFont(font12);
 | 
			
		||||
            styleLeft12.Alignment = HorizontalAlignment.Left;
 | 
			
		||||
            styleLeft12.VerticalAlignment = VerticalAlignment.Center;
 | 
			
		||||
            ICellStyle styleLine12 = workbook.CreateCellStyle();
 | 
			
		||||
            styleLine12.SetFont(font12);
 | 
			
		||||
            styleLine12.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;
 | 
			
		||||
            styleLine12.VerticalAlignment = VerticalAlignment.Center;
 | 
			
		||||
            styleLine12.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
 | 
			
		||||
            styleLine12.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
 | 
			
		||||
            styleLine12.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
 | 
			
		||||
            styleLine12.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
 | 
			
		||||
            ICellStyle stylein12 = workbook.CreateCellStyle();
 | 
			
		||||
            stylein12.SetFont(font12Times);
 | 
			
		||||
            stylein12.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Left;
 | 
			
		||||
            stylein12.VerticalAlignment = VerticalAlignment.Center;
 | 
			
		||||
            stylein12.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
 | 
			
		||||
            stylein12.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
 | 
			
		||||
            stylein12.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
 | 
			
		||||
            stylein12.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
 | 
			
		||||
            stylein12.WrapText = true;
 | 
			
		||||
            #endregion
 | 
			
		||||
 | 
			
		||||
            var sheet = workbook.CreateSheet("電表報表");
 | 
			
		||||
            int RowPosition = 0;
 | 
			
		||||
            if (result.Count > 0)
 | 
			
		||||
            {
 | 
			
		||||
                #region set cell
 | 
			
		||||
                IRow row = sheet.CreateRow(RowPosition);
 | 
			
		||||
                sheet.SetColumnWidth(0, 4 * 160 * 12);
 | 
			
		||||
                sheet.SetColumnWidth(1, 4 * 160 * 12);
 | 
			
		||||
                sheet.SetColumnWidth(2, 4 * 160 * 12);
 | 
			
		||||
 | 
			
		||||
                int i = 0;
 | 
			
		||||
                ICell cell = row.CreateCell(i++);
 | 
			
		||||
                cell.SetCellValue("東別");
 | 
			
		||||
                cell.CellStyle = styleLine12;
 | 
			
		||||
                cell = row.CreateCell(i++);
 | 
			
		||||
                cell.SetCellValue("樓層");
 | 
			
		||||
                cell.CellStyle = styleLine12;
 | 
			
		||||
                cell = row.CreateCell(i++);
 | 
			
		||||
                cell.SetCellValue("設備");
 | 
			
		||||
                cell.CellStyle = styleLine12;
 | 
			
		||||
 | 
			
		||||
                foreach (var rr in result.FirstOrDefault().rawData)
 | 
			
		||||
                {
 | 
			
		||||
                    cell = row.CreateCell(i++);
 | 
			
		||||
                    cell.SetCellValue(rr.timeStamp);
 | 
			
		||||
                    cell.CellStyle = styleLine12;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                cell = row.CreateCell(i++);
 | 
			
		||||
                cell.SetCellValue("小計");
 | 
			
		||||
                cell.CellStyle = styleLine12;
 | 
			
		||||
                cell = row.CreateCell(i++);
 | 
			
		||||
                cell.SetCellValue("單價");
 | 
			
		||||
                cell.CellStyle = styleLine12;
 | 
			
		||||
                cell = row.CreateCell(i++);
 | 
			
		||||
                cell.SetCellValue("金額總計");
 | 
			
		||||
                cell.CellStyle = styleLine12;
 | 
			
		||||
                #endregion
 | 
			
		||||
 | 
			
		||||
                foreach (var r in result)
 | 
			
		||||
                {
 | 
			
		||||
                    RowPosition += 1;
 | 
			
		||||
                    int k = 3;
 | 
			
		||||
                    row = sheet.CreateRow(RowPosition);
 | 
			
		||||
                    for (int j = 0; j <= i; j++)
 | 
			
		||||
                    {
 | 
			
		||||
                        cell = row.CreateCell(j);
 | 
			
		||||
                        if (j == 0)
 | 
			
		||||
                        {
 | 
			
		||||
                            cell.SetCellValue(r.building_name);
 | 
			
		||||
                        }
 | 
			
		||||
                        if (j == 1)
 | 
			
		||||
                        {
 | 
			
		||||
                            cell.SetCellValue(r.floor_tag);
 | 
			
		||||
                        }
 | 
			
		||||
                        if (j == 2)
 | 
			
		||||
                        {
 | 
			
		||||
                            cell.SetCellValue(r.device_serial_tag);
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        if (j == 3)
 | 
			
		||||
                        {
 | 
			
		||||
                            foreach (var rr in r.rawData)
 | 
			
		||||
                            {
 | 
			
		||||
                                cell.SetCellValue(rr.avg_rawdata.ToString());
 | 
			
		||||
                                j++;
 | 
			
		||||
                                k++;
 | 
			
		||||
                                cell = row.CreateCell(j);
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        if (j == k)
 | 
			
		||||
                        {
 | 
			
		||||
                            cell.SetCellValue(r.total);
 | 
			
		||||
                        }
 | 
			
		||||
                        if (j == k + 1)
 | 
			
		||||
                        {
 | 
			
		||||
                            cell.SetCellValue(r.price);
 | 
			
		||||
                        }
 | 
			
		||||
                        if (j == k + 2)
 | 
			
		||||
                        {
 | 
			
		||||
                            cell.SetCellValue(r.total_price);
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        cell.CellStyle = style12;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var ms = new NpoiMemoryStream
 | 
			
		||||
            {
 | 
			
		||||
                AllowClose = false
 | 
			
		||||
            };
 | 
			
		||||
            workbook.Write(ms);
 | 
			
		||||
            ms.Flush();
 | 
			
		||||
            ms.Seek(0, SeekOrigin.Begin);
 | 
			
		||||
 | 
			
		||||
            return File(ms, "application/vnd.ms-excel", "水表報表.xlsx");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -79,18 +79,18 @@ namespace FrontendWebApi.ApiControllers
 | 
			
		||||
                    jwt_str = jwt.GenerateToken(jwtLoing).token;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            //if (myUser.exp <= DateTime.Now.AddHours(-8).AddMinutes(10).Subtract(new DateTime(1970, 1, 1)).TotalSeconds)
 | 
			
		||||
            //{
 | 
			
		||||
            //    jwtlife = true;
 | 
			
		||||
            //    JwtLogin jwtLoing = new JwtLogin()
 | 
			
		||||
            //    {
 | 
			
		||||
            //        account ="webUser",
 | 
			
		||||
            //        email = "webUser@gmail.com",
 | 
			
		||||
            //        full_name = "webUser",
 | 
			
		||||
            //        userinfo_guid = "6ac24708-3a40-4199-88c5-22df310cd1a8"
 | 
			
		||||
            //    };
 | 
			
		||||
            //    jwt_str = jwt.GenerateToken(jwtLoing).token;
 | 
			
		||||
            //} 
 | 
			
		||||
            if (myUser.exp <= DateTime.Now.AddHours(-8).AddMinutes(10).Subtract(new DateTime(1970, 1, 1)).TotalSeconds)
 | 
			
		||||
            {
 | 
			
		||||
                jwtlife = true;
 | 
			
		||||
                JwtLogin jwtLoing = new JwtLogin()
 | 
			
		||||
                {
 | 
			
		||||
                    account = "webUser",
 | 
			
		||||
                    email = "webUser@gmail.com",
 | 
			
		||||
                    full_name = "webUser",
 | 
			
		||||
                    userinfo_guid = "6ac24708-3a40-4199-88c5-22df310cd1a8"
 | 
			
		||||
                };
 | 
			
		||||
                jwt_str = jwt.GenerateToken(jwtLoing).token;
 | 
			
		||||
            }
 | 
			
		||||
            base.OnActionExecuting(filterContext);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -21,36 +21,35 @@ namespace FrontendWebApi.Models
 | 
			
		||||
 | 
			
		||||
    public class Buildingsql
 | 
			
		||||
    {
 | 
			
		||||
        public string building_guid { get; set; }
 | 
			
		||||
        public string building_tag { get; set; }
 | 
			
		||||
        public string bfull_name { get; set; }
 | 
			
		||||
        public string ip_address { get; set; }
 | 
			
		||||
        public int bpriority { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
    public class BuildMenuSql : Buildingsql
 | 
			
		||||
    {
 | 
			
		||||
        public string main_system_guid { get; set; }
 | 
			
		||||
        public string sub_system_guid { get; set; }
 | 
			
		||||
        public byte drawing { get; set; }
 | 
			
		||||
        public byte icon_click { get; set; }
 | 
			
		||||
        public string icon_click_url { get; set; }
 | 
			
		||||
        public string system_url { get; set; }
 | 
			
		||||
        public string main_system_tag { get; set; }
 | 
			
		||||
        public string sub_system_tag { get; set; }
 | 
			
		||||
        public byte left_drawing { get; set; }
 | 
			
		||||
        public byte left_icon_click { get; set; }
 | 
			
		||||
        public string left_icon_click_url { get; set; }
 | 
			
		||||
        public string left_system_url { get; set; }
 | 
			
		||||
        public string mafull_name { get; set; }
 | 
			
		||||
        public int mapriority { get; set; }
 | 
			
		||||
        public string code { get; set; }
 | 
			
		||||
        public string subfull_name { get; set; }
 | 
			
		||||
        public int subpriority { get; set; }
 | 
			
		||||
        public byte planimetric_click { get; set; }
 | 
			
		||||
        public string planimetric_floor_guid { get; set; }
 | 
			
		||||
        public string riser_diagram_url { get; set; }
 | 
			
		||||
        public byte left_planimetric_click { get; set; }
 | 
			
		||||
        public string left_planimetric_floor_guid { get; set; }
 | 
			
		||||
        public string left_riser_diagram_url { get; set; }
 | 
			
		||||
        public string device_building_tag { get; set; }
 | 
			
		||||
        public string device_system_tag { get; set; }
 | 
			
		||||
        public byte OpenTab { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
    public class Floorsql : Floor
 | 
			
		||||
    {
 | 
			
		||||
        public string main_system_guid { get; set; }
 | 
			
		||||
        public string sub_system_guid { get; set; }
 | 
			
		||||
        public string building_guid { get; set; }
 | 
			
		||||
        public string main_system_tag { get; set; }
 | 
			
		||||
        public string sub_system_tag { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
    public class Devicesql : Device
 | 
			
		||||
    {
 | 
			
		||||
@ -72,17 +71,16 @@ namespace FrontendWebApi.Models
 | 
			
		||||
 | 
			
		||||
    public class Building
 | 
			
		||||
    {
 | 
			
		||||
        public string building_guid { get; set; }
 | 
			
		||||
        public string building_tag { get; set; }
 | 
			
		||||
        public string full_name { get; set; }
 | 
			
		||||
        public string ip_address { get; set; }
 | 
			
		||||
        public int priority { get; set; }
 | 
			
		||||
        public string device_building_tag { get; set; }
 | 
			
		||||
        public List<Main_system> main_system { get; set; }
 | 
			
		||||
        public List<string> common { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
    public class Main_system
 | 
			
		||||
    {
 | 
			
		||||
        public string main_system_guid { get; set; }
 | 
			
		||||
        public string main_system_tag { get; set; }
 | 
			
		||||
        public string full_name { get; set; }
 | 
			
		||||
        public int priority { get; set; }
 | 
			
		||||
        public string code { get; set; }
 | 
			
		||||
@ -90,7 +88,7 @@ namespace FrontendWebApi.Models
 | 
			
		||||
    }
 | 
			
		||||
    public class Sub_systemGuid
 | 
			
		||||
    {
 | 
			
		||||
        public string sub_system_guid { get; set; }
 | 
			
		||||
        public string sub_system_tag { get; set; }
 | 
			
		||||
        public string full_name { get; set; }
 | 
			
		||||
        public int priority { get; set; }
 | 
			
		||||
        public string device_system_tag { get; set; }
 | 
			
		||||
@ -99,23 +97,22 @@ namespace FrontendWebApi.Models
 | 
			
		||||
    }
 | 
			
		||||
    public class Sub_system
 | 
			
		||||
    {
 | 
			
		||||
        public string sub_system_guid { get; set; }
 | 
			
		||||
        public string sub_system_tag { get; set; }
 | 
			
		||||
        public string full_name { get; set; }
 | 
			
		||||
        public int priority { get; set; }
 | 
			
		||||
        public byte drawing { get; set; }
 | 
			
		||||
        public byte icon_click { get; set; }
 | 
			
		||||
        public string icon_click_url { get; set; }
 | 
			
		||||
        public string system_url { get; set; }
 | 
			
		||||
        public byte left_drawing { get; set; }
 | 
			
		||||
        public byte left_icon_click { get; set; }
 | 
			
		||||
        public string left_icon_click_url { get; set; }
 | 
			
		||||
        public string left_system_url { get; set; }
 | 
			
		||||
        public List<Floor> Floors { get; set; }
 | 
			
		||||
        public byte planimetric_click { get; set; }
 | 
			
		||||
        public string planimetric_floor_guid { get; set; }
 | 
			
		||||
        public string riser_diagram_url { get; set; }
 | 
			
		||||
        public byte left_planimetric_click { get; set; }
 | 
			
		||||
        public string left_planimetric_floor_guid { get; set; }
 | 
			
		||||
        public string left_riser_diagram_url { get; set; }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
    public class Floor
 | 
			
		||||
    {
 | 
			
		||||
        public string floor_guid { get; set; }
 | 
			
		||||
 | 
			
		||||
        public string building_tag { get; set; }
 | 
			
		||||
        public string full_name { get; set; }
 | 
			
		||||
        public string InitMapName { get; set; }
 | 
			
		||||
@ -126,20 +123,19 @@ namespace FrontendWebApi.Models
 | 
			
		||||
 | 
			
		||||
    public class PostTagName
 | 
			
		||||
    {
 | 
			
		||||
        public string building_guid { get; set; }
 | 
			
		||||
        public string main_system_guid { get; set; }
 | 
			
		||||
        public string sub_system_guid { get; set; }
 | 
			
		||||
        public string building_tag { get; set; }
 | 
			
		||||
        public string main_system_tag { get; set; }
 | 
			
		||||
        public string sub_system_tag { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class BuildingSystemTagName
 | 
			
		||||
    {
 | 
			
		||||
        public string device_building_tag { get; set; }
 | 
			
		||||
        public string device_system_tag { get; set; }
 | 
			
		||||
        public string sub_system_tag { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class DeviceFloor : Device
 | 
			
		||||
    {
 | 
			
		||||
        public string floor_guid { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										12
									
								
								FrontendWebApi/Models/HiNet.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								FrontendWebApi/Models/HiNet.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,12 @@
 | 
			
		||||
namespace FrontendWebApi.Models
 | 
			
		||||
{
 | 
			
		||||
    public class HiNet
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class HiNetInput
 | 
			
		||||
    { 
 | 
			
		||||
        public string Msg { get; set; }
 | 
			
		||||
        public string Number { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -96,7 +96,7 @@ namespace FrontendWebApi.Models
 | 
			
		||||
    }
 | 
			
		||||
    public class BuildingFloorRawData
 | 
			
		||||
    {
 | 
			
		||||
        public string building_guid { get; set; }
 | 
			
		||||
        public string building_tag { get; set; }
 | 
			
		||||
        public string building_name { get; set; }
 | 
			
		||||
        public string floor_guid { get; set; }
 | 
			
		||||
        public string floor_name { get; set; }
 | 
			
		||||
@ -110,7 +110,7 @@ namespace FrontendWebApi.Models
 | 
			
		||||
 | 
			
		||||
    public class History_Build
 | 
			
		||||
    {
 | 
			
		||||
        public string building_guid { get; set; }
 | 
			
		||||
        public string building_tag { get; set; }
 | 
			
		||||
        public string full_name { get; set; }
 | 
			
		||||
        public List<History_Floor> history_Floors { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
@ -195,7 +195,7 @@ namespace FrontendWebApi.Models
 | 
			
		||||
    public class PostRealTimeCombination
 | 
			
		||||
    {
 | 
			
		||||
        public string account { get; set; }
 | 
			
		||||
        public string building_guid { get; set; }
 | 
			
		||||
        public string building_tag { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class RealTimeCombinationRawData
 | 
			
		||||
@ -238,7 +238,7 @@ namespace FrontendWebApi.Models
 | 
			
		||||
 | 
			
		||||
    public class PostSaveRealTimeCombination
 | 
			
		||||
    {
 | 
			
		||||
        public string Building_guid { get; set; }
 | 
			
		||||
        public string Building_tag { get; set; }
 | 
			
		||||
        public string Combination_guid { get; set; }
 | 
			
		||||
        public byte Save_type { get; set; }
 | 
			
		||||
        public string Full_name { get; set; }
 | 
			
		||||
@ -295,4 +295,17 @@ namespace FrontendWebApi.Models
 | 
			
		||||
        public string dateType { get; set; }
 | 
			
		||||
        public string type { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class HistoryRealTimeInput
 | 
			
		||||
    {
 | 
			
		||||
        public List<string> tableDeviceName { get; set; }
 | 
			
		||||
        public string startTime { get; set; }
 | 
			
		||||
        public string endTime { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class HistoryRealTimeOutput
 | 
			
		||||
    {
 | 
			
		||||
        public double value { get; set; }
 | 
			
		||||
        public DateTime timeStamp { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										44
									
								
								FrontendWebApi/Models/HydroMeter.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								FrontendWebApi/Models/HydroMeter.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,44 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Security.Cryptography.X509Certificates;
 | 
			
		||||
 | 
			
		||||
namespace FrontendWebApi.Models
 | 
			
		||||
{
 | 
			
		||||
    public class HydroMeter
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class HydroMeterInput
 | 
			
		||||
    { 
 | 
			
		||||
        public string tableType { get; set; } //day, week, month, year
 | 
			
		||||
        public string building_tag { get; set; }
 | 
			
		||||
        public List<string> floor_tag { get; set; }
 | 
			
		||||
        public string startTime { get; set; }
 | 
			
		||||
        public string endTime { get; set; }
 | 
			
		||||
        public decimal? price { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class HydroMeterOutput
 | 
			
		||||
    {
 | 
			
		||||
        public string building_name { get; set; }
 | 
			
		||||
        public string building_tag { get; set; }
 | 
			
		||||
        public string floor_tag { get; set; }
 | 
			
		||||
        public string device_serial_tag { get; set; }
 | 
			
		||||
        public string total { get; set; }
 | 
			
		||||
        public string price { get; set; }
 | 
			
		||||
        public string total_price { get; set; }
 | 
			
		||||
        public List<HydroMeterRawDataOutput> rawData { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class HydroMeterRawDataOutput
 | 
			
		||||
    {
 | 
			
		||||
        public string timeStamp { get; set; }
 | 
			
		||||
        public string device_number { get; set; }
 | 
			
		||||
        public decimal avg_rawdata { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class HydroMeterPriceInput
 | 
			
		||||
    {
 | 
			
		||||
        public string type { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -91,6 +91,7 @@ namespace FrontendWebApi
 | 
			
		||||
            services.AddTransient<IBackendRepository, BackendRepository>();
 | 
			
		||||
            services.AddTransient<IFrontendRepository, FrontendRepository>();
 | 
			
		||||
            services.AddTransient<IBaseRepository, BaseRepository>();
 | 
			
		||||
            services.AddTransient<IBackgroundServiceMsSqlRepository, BackgroundServiceMsSqlRepository>();
 | 
			
		||||
            #endregion Repository ª`¤J
 | 
			
		||||
 | 
			
		||||
            #region JWT ª`¤J
 | 
			
		||||
 | 
			
		||||
@ -29,6 +29,13 @@
 | 
			
		||||
      "Root": "SzdxEgaJJ7tcTCrUl2zKsA==",
 | 
			
		||||
      "Password": "FVAPxztxpY4gJJKQ/se4bQ=="
 | 
			
		||||
    },
 | 
			
		||||
    "MSSqlDBConfig": {
 | 
			
		||||
      "Server": "bJm+UAtbeaTjDmp/A5ep2w==", //0.130
 | 
			
		||||
      "Port": "S5cUXKnKOacFtFy9+0dtpw==",
 | 
			
		||||
      "Database": "VvfWH/59gQguY2eA2xBCug==", //taipei_dome 
 | 
			
		||||
      "Root": "sD8GZ9UPiIQGU6dU011/4A==",
 | 
			
		||||
      "Password": "0O24es2ZRF5uoJ4aU+YCdg=="
 | 
			
		||||
    }
 | 
			
		||||
    //"MSSqlDBConfig": {
 | 
			
		||||
    //  "Server": "avZg8PA8C9GVgYZBgEKzCg==",
 | 
			
		||||
    //  "Port": "lJA0KPkG6RvFfTgWiXFyUw==",
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,18 @@
 | 
			
		||||
using Repository.BackendRepository.Interface;
 | 
			
		||||
using Repository.Helper;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Repository.BackendRepository.Implement
 | 
			
		||||
{
 | 
			
		||||
    public class BackgroundServiceMsSqlRepository : BackendRepository, IBackgroundServiceMsSqlRepository
 | 
			
		||||
    {
 | 
			
		||||
        public BackgroundServiceMsSqlRepository(IDatabaseHelper databaseHelper) : base(databaseHelper)
 | 
			
		||||
        {
 | 
			
		||||
            UseDB = "MSSQL";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -27,7 +27,7 @@ namespace Repository.BackendRepository.Implement
 | 
			
		||||
        /// <param name="ds"></param>
 | 
			
		||||
        /// <param name="building"></param> 
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        public async Task InsertNiagaraTagList(List<Device_value> ds, string building, string tag_quantity)
 | 
			
		||||
        public async Task InsertNiagaraTagList(List<Device_value> ds, List<string> building, string tag_quantity)
 | 
			
		||||
        {
 | 
			
		||||
            using (IDbConnection conn = GetDbConnection())
 | 
			
		||||
            {
 | 
			
		||||
@ -36,25 +36,28 @@ namespace Repository.BackendRepository.Implement
 | 
			
		||||
                {
 | 
			
		||||
                    try
 | 
			
		||||
                    {
 | 
			
		||||
                        string sql = @"CREATE TABLE IF NOT EXISTS `import_niagara_tag` (
 | 
			
		||||
                                 `id` int(11) NOT NULL AUTO_INCREMENT,
 | 
			
		||||
                                 `db_tags` varchar(50) DEFAULT NULL,
 | 
			
		||||
                                 `niagara_tags` varchar(50) DEFAULT NULL,
 | 
			
		||||
                                 `device_area_tag` varchar(50) DEFAULT NULL,
 | 
			
		||||
                                 `device_building_tag` varchar(50) DEFAULT NULL,
 | 
			
		||||
                                 `device_system_tag` varchar(50) DEFAULT NULL,
 | 
			
		||||
                                 `device_name_tag` varchar(50) DEFAULT NULL,
 | 
			
		||||
                                 `device_floor_tag` varchar(50) DEFAULT NULL,
 | 
			
		||||
                                 `device_master_tag` varchar(50) DEFAULT NULL,
 | 
			
		||||
                                 `device_last_name_tag` varchar(50) DEFAULT NULL,
 | 
			
		||||
                                 `device_serial_tag` varchar(50) DEFAULT NULL,
 | 
			
		||||
                                 `atDateTime` datetime(1) DEFAULT NULL,
 | 
			
		||||
                                 `is_used` smallint(1) DEFAULT 0,
 | 
			
		||||
                                 PRIMARY KEY (`id`)
 | 
			
		||||
                               ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;";
 | 
			
		||||
                        await conn.ExecuteAsync(sql);
 | 
			
		||||
                        sql = "delete from import_niagara_tag where device_building_tag = '" + building + "'";
 | 
			
		||||
                        await conn.ExecuteAsync(sql);
 | 
			
		||||
                        foreach(var b in building)
 | 
			
		||||
                        {
 | 
			
		||||
                            string sql = @"CREATE TABLE IF NOT EXISTS `import_niagara_tag` (
 | 
			
		||||
                                     `id` int(11) NOT NULL AUTO_INCREMENT,
 | 
			
		||||
                                     `db_tags` varchar(50) DEFAULT NULL,
 | 
			
		||||
                                     `niagara_tags` varchar(50) DEFAULT NULL,
 | 
			
		||||
                                     `device_area_tag` varchar(50) DEFAULT NULL,
 | 
			
		||||
                                     `device_building_tag` varchar(50) DEFAULT NULL,
 | 
			
		||||
                                     `device_system_tag` varchar(50) DEFAULT NULL,
 | 
			
		||||
                                     `device_name_tag` varchar(50) DEFAULT NULL,
 | 
			
		||||
                                     `device_floor_tag` varchar(50) DEFAULT NULL,
 | 
			
		||||
                                     `device_master_tag` varchar(50) DEFAULT NULL,
 | 
			
		||||
                                     `device_last_name_tag` varchar(50) DEFAULT NULL,
 | 
			
		||||
                                     `device_serial_tag` varchar(50) DEFAULT NULL,
 | 
			
		||||
                                     `atDateTime` datetime(1) DEFAULT NULL,
 | 
			
		||||
                                     `is_used` smallint(1) DEFAULT 0,
 | 
			
		||||
                                     PRIMARY KEY (`id`)
 | 
			
		||||
                                   ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;";
 | 
			
		||||
                            await conn.ExecuteAsync(sql);
 | 
			
		||||
                            sql = "delete from import_niagara_tag where device_building_tag = '" + b + "'";
 | 
			
		||||
                            await conn.ExecuteAsync(sql);
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        //N4資料groupBy後放入import_niagara_tag資料表
 | 
			
		||||
                        var ds2 = ds.GroupBy(x => new
 | 
			
		||||
@ -170,7 +173,7 @@ namespace Repository.BackendRepository.Implement
 | 
			
		||||
        /// <param name="building"></param>
 | 
			
		||||
      
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        public async Task InsertItemFromNiagara(List<ImpNiaItem> ds, string building)
 | 
			
		||||
        public async Task InsertItemFromNiagara(List<ImpNiaItem> ds, List<string> building)
 | 
			
		||||
        {
 | 
			
		||||
            using (IDbConnection conn = GetDbConnection())
 | 
			
		||||
            {
 | 
			
		||||
@ -180,21 +183,24 @@ namespace Repository.BackendRepository.Implement
 | 
			
		||||
                    try
 | 
			
		||||
                    {
 | 
			
		||||
                        #region 刪除 import_niagara_item資料表中選取的棟別
 | 
			
		||||
                        string sql = @"CREATE TABLE IF NOT EXISTS `import_niagara_item` (
 | 
			
		||||
                              `id` int(11) NOT NULL AUTO_INCREMENT,
 | 
			
		||||
                              `device_area_tag` varchar(50) DEFAULT NULL,
 | 
			
		||||
                              `device_building_tag` varchar(50) DEFAULT NULL,
 | 
			
		||||
                              `device_system_tag` varchar(50) DEFAULT NULL,
 | 
			
		||||
                              `device_name_tag` varchar(50) DEFAULT NULL,
 | 
			
		||||
                              `device_point_name` varchar(50) DEFAULT NULL,
 | 
			
		||||
                              `check_status` varchar(50) DEFAULT NULL,
 | 
			
		||||
                              `parent_path` varchar(50) DEFAULT NULL,
 | 
			
		||||
                              `full_name` varchar(50) DEFAULT NULL,
 | 
			
		||||
                              PRIMARY KEY (`id`)
 | 
			
		||||
                            ) ENGINE=InnoDB AUTO_INCREMENT=59 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;";
 | 
			
		||||
                        await conn.ExecuteAsync(sql);
 | 
			
		||||
                        sql = "delete from import_niagara_item where device_building_tag = '" + building + "'";
 | 
			
		||||
                        await conn.ExecuteAsync(sql);
 | 
			
		||||
                        foreach(var b in building)
 | 
			
		||||
                        {
 | 
			
		||||
                            string sql = @"CREATE TABLE IF NOT EXISTS `import_niagara_item` (
 | 
			
		||||
                                  `id` int(11) NOT NULL AUTO_INCREMENT,
 | 
			
		||||
                                  `device_area_tag` varchar(50) DEFAULT NULL,
 | 
			
		||||
                                  `device_building_tag` varchar(50) DEFAULT NULL,
 | 
			
		||||
                                  `device_system_tag` varchar(50) DEFAULT NULL,
 | 
			
		||||
                                  `device_name_tag` varchar(50) DEFAULT NULL,
 | 
			
		||||
                                  `device_point_name` varchar(50) DEFAULT NULL,
 | 
			
		||||
                                  `check_status` varchar(50) DEFAULT NULL,
 | 
			
		||||
                                  `parent_path` varchar(50) DEFAULT NULL,
 | 
			
		||||
                                  `full_name` varchar(50) DEFAULT NULL,
 | 
			
		||||
                                  PRIMARY KEY (`id`)
 | 
			
		||||
                                ) ENGINE=InnoDB AUTO_INCREMENT=59 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;";
 | 
			
		||||
                            await conn.ExecuteAsync(sql);
 | 
			
		||||
                            sql = "delete from import_niagara_item where device_building_tag = '" + b + "'";
 | 
			
		||||
                            await conn.ExecuteAsync(sql);
 | 
			
		||||
                        }
 | 
			
		||||
                        #endregion
 | 
			
		||||
                        ds = ds.GroupBy(x => new {
 | 
			
		||||
                            device_area_tag = x.device_area_tag,
 | 
			
		||||
@ -270,7 +276,7 @@ namespace Repository.BackendRepository.Implement
 | 
			
		||||
            using (IDbConnection conn = GetDbConnection())
 | 
			
		||||
            {
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                using (TransactionScope scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
 | 
			
		||||
                using (TransactionScope scope = new TransactionScope((TransactionScopeOption)TransactionScopeAsyncFlowOption.Enabled, new TimeSpan(0, 0, 200)))
 | 
			
		||||
                {
 | 
			
		||||
                    try
 | 
			
		||||
                    {
 | 
			
		||||
@ -398,19 +404,21 @@ namespace Repository.BackendRepository.Implement
 | 
			
		||||
                        }
 | 
			
		||||
                        #endregion
 | 
			
		||||
 | 
			
		||||
                            //device有,niagara沒有,is_link 更新成 0
 | 
			
		||||
                            sb.Append($@" SET SQL_SAFE_UPDATES = 0;
 | 
			
		||||
                              UPDATE device d LEFT JOIN import_niagara_tag m ON d.device_number = m.niagara_tags
 | 
			
		||||
                              SET d.is_link = 0
 | 
			
		||||
                              WHERE m.niagara_tags IS NULL;");
 | 
			
		||||
                        await conn.ExecuteAsync(sb.ToString());
 | 
			
		||||
                        //device有,niagara沒有,is_link 更新成 0
 | 
			
		||||
                        sb.Append($@" SET SQL_SAFE_UPDATES = 0;
 | 
			
		||||
                            UPDATE device d
 | 
			
		||||
                            SET d.is_link = 0
 | 
			
		||||
                            WHERE d.is_link = 1 and not exists (select niagara_tags from import_niagara_tag where niagara_tags = d.device_number);");
 | 
			
		||||
                        await conn.ExecuteAsync(sb.ToString(), commandTimeout: 100);
 | 
			
		||||
 | 
			
		||||
                        sb.Clear();
 | 
			
		||||
 | 
			
		||||
                        // device_node 有, niagara沒有, is_link 更新成 0
 | 
			
		||||
                        sb.Append($@" SET SQL_SAFE_UPDATES = 0;
 | 
			
		||||
                              UPDATE device_node d LEFT JOIN import_niagara_tag m ON d.device_number = m.niagara_tags
 | 
			
		||||
                              UPDATE device_node d
 | 
			
		||||
                              SET d.is_link = 0
 | 
			
		||||
                              WHERE m.niagara_tags IS NULL;");
 | 
			
		||||
                        await conn.ExecuteAsync(sb.ToString());
 | 
			
		||||
                              WHERE d.is_link = 1 and not exists (select niagara_tags from import_niagara_tag where niagara_tags = d.device_number);");
 | 
			
		||||
                        await conn.ExecuteAsync(sb.ToString(), commandTimeout: 100);
 | 
			
		||||
                    }
 | 
			
		||||
                    catch (Exception exception)
 | 
			
		||||
                    {
 | 
			
		||||
@ -463,7 +471,7 @@ namespace Repository.BackendRepository.Implement
 | 
			
		||||
                                    isBool = 1;
 | 
			
		||||
                                }
 | 
			
		||||
                                sb.Append($@"insert device_item(deleted, points, is_show, is_show_riserDiagram, is_controll, is_bool, is_show_history, is_link, 
 | 
			
		||||
                                    device_system_tag, device_name_tag, full_name, parent_path, created_at, updated_at)
 | 
			
		||||
                                    device_system_tag, device_name_tag, device_building_tag, full_name, parent_path, created_at, updated_at)
 | 
			
		||||
                                    VALUES (0, '" +
 | 
			
		||||
                                            data.device_point_name + "', 1, 0, " +
 | 
			
		||||
                                            isControll + "," +
 | 
			
		||||
@ -472,6 +480,7 @@ namespace Repository.BackendRepository.Implement
 | 
			
		||||
                                            ", 1, '" +
 | 
			
		||||
                                            data.device_system_tag + "', '" +
 | 
			
		||||
                                            data.device_name_tag + "', '" +
 | 
			
		||||
                                            data.device_building_tag + "', '" +
 | 
			
		||||
                                            data.full_name + "', '" +
 | 
			
		||||
                                            data.parent_path + "', " +
 | 
			
		||||
                                            "now(), now());");
 | 
			
		||||
@ -738,7 +747,7 @@ namespace Repository.BackendRepository.Implement
 | 
			
		||||
            using (IDbConnection conn = GetDbConnection())
 | 
			
		||||
            {
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                using (TransactionScope scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
 | 
			
		||||
                using (TransactionScope scope = new TransactionScope((TransactionScopeOption)TransactionScopeAsyncFlowOption.Enabled, new TimeSpan (0, 0, 200)))
 | 
			
		||||
                {
 | 
			
		||||
                    try
 | 
			
		||||
                    {
 | 
			
		||||
@ -746,7 +755,7 @@ namespace Repository.BackendRepository.Implement
 | 
			
		||||
                        sb.Append("update device d inner JOIN import_niagara_tag m ON m.niagara_tags = d.device_number " +
 | 
			
		||||
                            "set d.full_name=m.device_full_name " +
 | 
			
		||||
                            "where m.device_full_name<>d.full_name;");
 | 
			
		||||
                        await conn.ExecuteAsync(sb.ToString());
 | 
			
		||||
                        await conn.ExecuteAsync(sb.ToString(), commandTimeout: 200);
 | 
			
		||||
                    }
 | 
			
		||||
                    catch (Exception exception)
 | 
			
		||||
                    {
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,12 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Repository.BackendRepository.Interface
 | 
			
		||||
{
 | 
			
		||||
    public interface IBackgroundServiceMsSqlRepository : IBackendRepository
 | 
			
		||||
    {
 | 
			
		||||
        
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -12,7 +12,7 @@ namespace Repository.BackendRepository.Interface
 | 
			
		||||
        /// <param name="ds"></param>
 | 
			
		||||
        /// <param name="building"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        Task InsertNiagaraTagList(List<Device_value> ds, string building, string tag_quantity);
 | 
			
		||||
        Task InsertNiagaraTagList(List<Device_value> ds, List<string> building, string tag_quantity);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
@ -27,7 +27,7 @@ namespace Repository.BackendRepository.Interface
 | 
			
		||||
        /// <param name="ds"></param>
 | 
			
		||||
        /// <param name="building"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        Task InsertItemFromNiagara(List<ImpNiaItem> ds, string building);
 | 
			
		||||
        Task InsertItemFromNiagara(List<ImpNiaItem> ds, List<string> building);
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 比對 device
 | 
			
		||||
        /// </summary>
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user