Browse Source

取得IOT資料時追加IP分析地理位置(途中)

jeff 3 months ago
parent
commit
de6f3fe6ac

+ 2 - 1
TEAMModelBI/Controllers/BICommon/BINoticeController.cs

@@ -916,6 +916,7 @@ namespace TEAMModelBI.Controllers.BICommon
             var cosmosClient = _azureCosmos.GetCosmosClient();
             var cosmosClientCsv2 = _azureCosmos.GetCosmosClient(name: "CoreServiceV2");
             bool isChina = (_option.Location.Contains("China")) ? true : false;
+            List<string> comeRemoveStr = GeoRegion.comeRemoveStr;
             if (isChina) countryId = "CN";
             List<AreaInfo> geoInfos = new(); //輸出:地理位置為單位
             List<AreaInfo> tmidInfos = new(); //輸出:TMID為單位
@@ -2031,6 +2032,6 @@ namespace TEAMModelBI.Controllers.BICommon
             public string url { get; set; }
         }
         //地區要去除的特殊字
-        public List<string> comeRemoveStr = new List<string>() { "省", "市", "区", "州", "县", "旗", "盟", "回族", "藏族", "羌族", "哈尼族", "彝族", "壮族", "苗族", "自治", "地區", "區", "縣" };
+        //public List<string> comeRemoveStr = new List<string>() { "省", "市", "区", "州", "县", "旗", "盟", "回族", "藏族", "羌族", "哈尼族", "彝族", "壮族", "苗族", "自治", "地區", "區", "縣" };
     }
 }

+ 132 - 1
TEAMModelBI/Controllers/BITest/TestController.cs

@@ -68,6 +68,9 @@ using Azure.Messaging.ServiceBus.Administration;
 using static TEAMModelOS.SDK.CoreAPIHttpService;
 using System.Xml;
 using System.Drawing.Printing;
+using TEAMModelOS.SDK.DI.IPIP;
+using Microsoft.International.Converters.TraditionalChineseToSimplifiedConverter;
+using static TEAMModelOS.SDK.Extension.GeoRegion;
 
 namespace TEAMModelBI.Controllers.BITest
 {
@@ -87,7 +90,8 @@ namespace TEAMModelBI.Controllers.BITest
         private readonly CoreAPIHttpService _coreAPIHttpService;
         private readonly IHttpClientFactory _httpClient;
         private IPSearcher _ipSearcher;
-        public TestController(IPSearcher ipSearcher, AzureCosmosFactory azureCosmos, AzureStorageFactory azureStorage, AzureRedisFactory azureRedis, DingDing dingDing, IOptionsSnapshot<Option> option, IWebHostEnvironment hostingEnvironment, IConfiguration configuration, CoreAPIHttpService coreAPIHttpService, IHttpClientFactory httpClient)
+        private readonly City _city;
+        public TestController(IPSearcher ipSearcher, AzureCosmosFactory azureCosmos, AzureStorageFactory azureStorage, AzureRedisFactory azureRedis, DingDing dingDing, IOptionsSnapshot<Option> option, IWebHostEnvironment hostingEnvironment, IConfiguration configuration, CoreAPIHttpService coreAPIHttpService, IHttpClientFactory httpClient, City city)
         {
             _azureCosmos = azureCosmos;
             _azureStorage = azureStorage;
@@ -98,6 +102,7 @@ namespace TEAMModelBI.Controllers.BITest
             _configuration = configuration;
             _coreAPIHttpService = coreAPIHttpService;
             _httpClient = httpClient; _ipSearcher = ipSearcher;
+            _city = city;
         }
 
         /// <summary>
@@ -2045,6 +2050,132 @@ namespace TEAMModelBI.Controllers.BITest
             return Ok(new { state = 200, result });
         }
 
+        /// <summary>
+        /// IP轉換地理位置
+        /// </summary>
+        /// <param name="jsonElement"></param>
+        /// <returns></returns>
+        [ProducesDefaultResponseType]
+        [HttpPost("getGeoFromIpTest")]
+        public async Task<IActionResult> getGeoFromIpTest(JsonElement jsonElement)
+        {
+            string ip = (jsonElement.TryGetProperty("ip", out JsonElement _ip)) ? _ip.ToString() : string.Empty;
+            string lang = (jsonElement.TryGetProperty("lang", out JsonElement _lang)) ? _lang.ToString() : "zh-tw";
+            var ipInfo = _city.find(ip, "CN");
+
+            regiondata regionData = GetRegionData(); //取得國省市區地理資訊架構
+            List<string> comeRemoveStr = GeoRegion.comeRemoveStr;
+            ///國字典製作
+            var geoCountryIdNameDic = new Dictionary<string, string>();
+            foreach (KeyValuePair<string, regionbase> item in regionData.country)
+            {
+                geoCountryIdNameDic.Add(item.Value.code, item.Value.name);
+            }
+            ///省字典製作
+            var geoProvinceIdNameDic = new Dictionary<string, string>();
+            foreach (KeyValuePair<string, regionbase> item in regionData.province["CN"])
+            {
+                geoProvinceIdNameDic.Add(item.Value.code, item.Value.name);
+            }
+            ///市字典製作
+            var geoCityIdNameDic = new Dictionary<string, Dictionary<string, string>>();
+            geoCityIdNameDic.Add("TW", new Dictionary<string, string>());
+            geoCityIdNameDic.Add("CN", new Dictionary<string, string>());
+            List<string> municipalityId = GeoRegion.municipalityId; //大陸直轄市的省ID
+            foreach (var itemCountry in regionData.city)
+            {
+                if(itemCountry.Key.Equals("TW"))
+                {
+                    foreach (var itemCity in regionData.city["TW"]["tw"])
+                    {
+                        geoCityIdNameDic["TW"].Add(itemCity.Value.code, itemCity.Value.name);
+                    }
+                }
+                else if(itemCountry.Key.Equals("CN"))
+                {
+                    foreach (var itemProvince in regionData.city["CN"])
+                    {
+                        string provinceIdTmp = itemProvince.Key;
+                        foreach (var itemCity in regionData.city["CN"][provinceIdTmp])
+                        {
+                            geoCityIdNameDic["CN"].Add(itemCity.Value.code, itemCity.Value.name);
+                        }
+                    }
+                }
+            }
+
+            List<string> ipToGeoList = ipInfo.ToList();
+            IotTeachingData.Geo geo = new IotTeachingData.Geo();
+            if (ipToGeoList[0].Equals("中国") && ipToGeoList[1].Equals("台湾"))
+            {
+                geo.countryId = "TW";
+                geo.countryName = geoCountryIdNameDic["TW"];
+                comeRemoveStr.ForEach(c => { geo.countryName = geo.countryName.Replace(c, ""); });
+                string cityNameTmp = ipToGeoList[2];
+                if (!string.IsNullOrWhiteSpace(cityNameTmp))
+                {
+                    cityNameTmp = ChineseConverter.Convert(cityNameTmp, ChineseConversionDirection.SimplifiedToTraditional);
+                    comeRemoveStr.ForEach(c => { cityNameTmp = cityNameTmp.Replace(c, ""); });
+                    var cityDicRow = geoCityIdNameDic["TW"].FirstOrDefault(c => c.Value.Contains(cityNameTmp));
+                    if (!cityDicRow.Equals(default(KeyValuePair<string, string>)))
+                    {
+                        geo.cityId = cityDicRow.Key;
+                        geo.cityName = cityDicRow.Value;
+                        comeRemoveStr.ForEach(c => { geo.cityName = geo.cityName.Replace(c, ""); });
+                    }
+                }   
+            }
+            else if(ipToGeoList[0].Equals("中国"))
+            {
+                geo.countryId = "CN";
+                geo.countryName = geoCountryIdNameDic["CN"];
+                string provinceNameTmp = ipToGeoList[1];
+                comeRemoveStr.ForEach(p => { provinceNameTmp = provinceNameTmp.Replace(p, ""); });
+                var provinceDicRow = geoProvinceIdNameDic.FirstOrDefault(p => p.Value.Contains(provinceNameTmp));
+                if (!provinceDicRow.Equals(default(KeyValuePair<string, string>)))
+                {
+                    geo.provinceId = provinceDicRow.Key;
+                    geo.provinceName = provinceDicRow.Value;
+                    comeRemoveStr.ForEach(c => { geo.provinceName = geo.provinceName.Replace(c, ""); });
+                }
+                string cityNameTmp = ipToGeoList[2];
+                if(!string.IsNullOrWhiteSpace(cityNameTmp))
+                {
+                    comeRemoveStr.ForEach(c => { cityNameTmp = cityNameTmp.Replace(c, ""); });
+                    if (!string.IsNullOrWhiteSpace(geo.provinceId) && municipalityId.Contains(geo.provinceId)) ///直轄市處理
+                    {
+                        var cityDicFromRegion = regionData.city["CN"][geo.provinceId].First();
+                        string cityId = cityDicFromRegion.Key;
+                        geo.cityId = cityId;
+                        geo.cityName = geoCityIdNameDic["CN"][cityId];
+                    }
+                    else ///非直轄市
+                    {
+                        var cityDicRow = geoCityIdNameDic["CN"].FirstOrDefault(c => c.Value.Contains(cityNameTmp));
+                        if (!cityDicRow.Equals(default(KeyValuePair<string, string>)))
+                        {
+                            geo.cityId = cityDicRow.Key;
+                            geo.cityName = cityDicRow.Value;
+                            comeRemoveStr.ForEach(c => { geo.cityName = geo.cityName.Replace(c, ""); });
+                        }
+                    }
+                }
+            }
+            else
+            {
+                string countryNameTmp = ipToGeoList[0];
+                countryNameTmp = ChineseConverter.Convert(countryNameTmp, ChineseConversionDirection.SimplifiedToTraditional);
+                var countryDicRow = geoCountryIdNameDic.FirstOrDefault(c => c.Value.Contains(countryNameTmp));
+                if (!countryDicRow.Equals(default(KeyValuePair<string, string>)))
+                {
+                    geo.countryId = countryDicRow.Key;
+                    geo.countryName = countryDicRow.Value;
+                }
+            }
+
+            return Ok(new { state = 200, geo, geoFromIp = ipToGeoList });
+        }
+
         public class linqTest
         {
             public string id { get; set; }

+ 1 - 1
TEAMModelBI/Controllers/RepairApi/SchoolRepController.cs

@@ -624,7 +624,7 @@ namespace TEAMModelBI.Controllers.RepairApi
                     {
                         string m = date.Substring(0, 2);
                         string d = date.Substring(2, 2);
-                        await BIProdAnalysis.BICreatDailyAnalData(_azureRedis, _azureCosmosClient, _azureCosmosClientCsv2, _azureCosmosClientCsv2Read, _dingDing, _city, y, m, d);
+                        await BIProdAnalysis.BICreatDailyAnalData(_azureRedis, _azureCosmosClient, _azureCosmosClientCsv2, _azureCosmosClientCsv2Read, _dingDing, _city, _option.Location, y, m, d);
                         resultKeys.Add($"{key}");
                     }
                 }

+ 2 - 0
TEAMModelBI/Startup.cs

@@ -26,6 +26,7 @@ using TEAMModelOS.SDK.Models;
 using VueCliMiddleware;
 using System.Net.Http;
 using TEAMModelOS.Filter;
+using TEAMModelOS.SDK.DI.IPIP;
 
 namespace TEAMModelBI
 {
@@ -131,6 +132,7 @@ namespace TEAMModelBI
             services.AddSnowflakeId(Convert.ToInt64(Configuration.GetValue<string>("Option:LocationNum")), 1);
             services.AddHttpClient();
             services.AddHttpClient<DingDing>();
+            services.AddSingleton(new City(@"Services/ipip.ipdb"));
             //services.AddCoreAPIHttpService(Configuration);
             services.AddHttpClient<CoreAPIHttpService>().ConfigureHttpMessageHandlerBuilder(builder =>
             {

+ 2 - 1
TEAMModelOS.Function/IESTimerTrigger.cs

@@ -143,8 +143,9 @@ namespace TEAMModelOS.Function
             var y = $"{datetime.Year}";
             var m = datetime.Month >= 10 ? $"{datetime.Month}" : $"0{datetime.Month}";
             var d = datetime.Day >= 10 ? $"{datetime.Day}" : $"0{datetime.Day}";
+            string? local = Environment.GetEnvironmentVariable("Option:Location");
             //生成學校IOT數據
-            await BIProdAnalysis.BICreatDailyAnalData(_azureRedis, _azureCosmosClient, _azureCosmosClientCsv2, _azureCosmosClientCsv2CnRead, _dingDing, _city, y, m, d);
+            await BIProdAnalysis.BICreatDailyAnalData(_azureRedis, _azureCosmosClient, _azureCosmosClientCsv2, _azureCosmosClientCsv2CnRead, _dingDing, _city, local, y, m, d);
             //刪除三個月以前的Redis數據 [待做]
         }
     }

+ 22 - 0
TEAMModelOS.SDK/Models/Cosmos/Common/IotTeachingData.cs

@@ -97,6 +97,10 @@ namespace TEAMModelOS.SDK.Models.Cosmos
         /// </summary>
         public string ip { get; set; }
         /// <summary>
+        /// 地理位置
+        /// </summary>
+        public Geo geo { get; set; }
+        /// <summary>
         /// 版本
         /// </summary>
         /// [例]ex. 5.0.21.0000 -> 500210000
@@ -181,6 +185,24 @@ namespace TEAMModelOS.SDK.Models.Cosmos
         /// 有使用最小化模式 0:false 1:true
         /// </summary>
         public string useMiniMode { get; set; }
+        /// <summary>
+        /// 地理資訊 (由IP分析)
+        /// </summary>
+        public class Geo
+        {
+            public string countryId { get; set; }
+            public string countryName { get; set; }
+            public string provinceId { get; set; }
+            public string provinceName { get; set; }
+            public string cityId { get; set; }
+            public string cityName { get; set; }
+            public string distId { get; set; }
+            public string distName { get; set; }
+        }
+        /// <summary>
+        /// 由IP轉換工具直譯的地理資訊
+        /// </summary>
+        public List<string> GeoFromIp { get; set; }
     }
 
     /// <summary>

+ 27 - 7
TEAMModelOS.SDK/Models/Service/BI/BIProdAnalysis.cs

@@ -14,6 +14,7 @@ using TEAMModelOS.SDK.Extension;
 using TEAMModelOS.SDK.Models.Cosmos;
 using TEAMModelOS.SDK.Models.Cosmos.BI.BISchool;
 using TEAMModelOS.SDK.DI.IPIP;
+using Microsoft.International.Converters.TraditionalChineseToSimplifiedConverter;
 
 namespace TEAMModelOS.SDK.Models.Service.BI
 {
@@ -31,9 +32,9 @@ namespace TEAMModelOS.SDK.Models.Service.BI
         /// <param name="m">月(2位數)</param>
         /// <param name="d">日(2位數)</param>
         /// <returns></returns>
-        public static async Task BICreatDailyAnalData(AzureRedisFactory _azureRedis, CosmosClient _azureCosmosClient, CosmosClient _azureCosmosClientCsv2, CosmosClient _azureCosmosClientCsv2CnRead, DingDing _dingDing, City _city, string y, string m, string d)
+        public static async Task BICreatDailyAnalData(AzureRedisFactory _azureRedis, CosmosClient _azureCosmosClient, CosmosClient _azureCosmosClientCsv2, CosmosClient _azureCosmosClientCsv2CnRead, DingDing _dingDing, City _city, string _location, string y, string m, string d)
         {
-            List<IotTeachingData> IotTeachingDataList = await BIGetDailyRedisProdAnalData(_azureRedis, _azureCosmosClientCsv2, _dingDing, _city, y, m, d); //取得Redis IOT 每日資訊
+            List<IotTeachingData> IotTeachingDataList = await BIGetDailyRedisProdAnalData(_azureRedis, _azureCosmosClientCsv2, _dingDing, _city, _location, y, m, d); //取得Redis IOT 每日資訊
             await CreatIes5ProdAnalData(_azureRedis, _azureCosmosClient, _azureCosmosClientCsv2CnRead, _dingDing, y, m, d, IotTeachingDataList); //生成學校CosmosDB年月日統計資料
             await CreatTmidProdAnalData(_azureRedis, _azureCosmosClient, _dingDing, y, m, d, IotTeachingDataList); //生成TMID CosmosDB年月日統計資料
         }
@@ -47,7 +48,7 @@ namespace TEAMModelOS.SDK.Models.Service.BI
         /// <param name="m">月(2位數)</param>
         /// <param name="d">日(2位數)</param>
         /// <returns></returns>
-        public static async Task<List<IotTeachingData>> BIGetDailyRedisProdAnalData(AzureRedisFactory _azureRedis, CosmosClient _azureCosmosClientCsv2, DingDing _dingDing, City _city, string y, string m, string d)
+        public static async Task<List<IotTeachingData>> BIGetDailyRedisProdAnalData(AzureRedisFactory _azureRedis, CosmosClient _azureCosmosClientCsv2, DingDing _dingDing, City _city, string _location, string y, string m, string d)
         {
             List<IotTeachingData> IotTeachingDataList = new List<IotTeachingData>();
             try
@@ -113,10 +114,29 @@ namespace TEAMModelOS.SDK.Models.Service.BI
                             IotTeachingData.peerStuParticipationT = (tdata.Length > 41 && !string.IsNullOrWhiteSpace(tdata[41])) ? Convert.ToInt32(tdata[41]) : 0; //互評學生參與總次數
                             IotTeachingData.useTransMode = (tdata.Length > 42 && !string.IsNullOrWhiteSpace(tdata[42])) ? tdata[42] : "0"; //有使用透明模式
                             IotTeachingData.useMiniMode = (tdata.Length > 43 && !string.IsNullOrWhiteSpace(tdata[43])) ? tdata[43] : "0"; //有使用最小化模式 
-                            if(!string.IsNullOrWhiteSpace(IotTeachingData.ip)) ///IP分析地理位置
+
+                            string geoString = string.Empty;
+                            if (!string.IsNullOrWhiteSpace(IotTeachingData.ip)) ///IP分析地理位置
                             {
                                 var ipInfo = _city.find(IotTeachingData.ip, "CN");
+                                //輸出結果修正 ※將輸出結果轉為國省市ID [待做]
+                                List<string> ipInfoList = ipInfo.ToList();
+                                if (ipInfoList[0].Equals("中国") && ipInfoList[1].Equals("台湾"))
+                                {
+                                    ipInfoList.RemoveAt(0);
+                                }
+                               
+                                foreach(string resultRow in ipInfoList)
+                                {
+                                    geoString += resultRow;
+                                }
+                                string location = Environment.GetEnvironmentVariable("Option:Location");
+                                if (_location.Contains("Global"))
+                                {
+                                    geoString = ChineseConverter.Convert(geoString, ChineseConversionDirection.SimplifiedToTraditional);
+                                }
                             }
+                            
 
                             IotTeachingDataList.Add(IotTeachingData);
                             if(!string.IsNullOrWhiteSpace(IotTeachingData.tmid))
@@ -1268,9 +1288,9 @@ namespace TEAMModelOS.SDK.Models.Service.BI
             return result;
         }
 
-        public static List<string> GetGeoFromIp(string ip)
-        {
+        //public static List<string> GetGeoFromIp(string ip)
+        //{
 
-        }
+        //}
     }
 }

+ 6 - 1
TEAMModelOS/Controllers/Client/HiTAControlller.cs

@@ -180,10 +180,15 @@ namespace TEAMModelOS.Controllers.Client
             string school_name = string.Empty; //學校名稱 為空值,核心邏輯會去取IES5學校名稱補上
             string grant_type = (request.TryGetProperty("grant_type", out JsonElement _grant_type)) ? _grant_type.ToString() : string.Empty; //request:申請加入學校教師
             if(string.IsNullOrWhiteSpace(grant_type)) return BadRequest();
+            List<string> allowGrantType = new List<string>() { "request", "join", "invite" }; //invite:學校邀請 request:老師申請 join:成為學校老師
 
             //呼叫老師申請或同意邀請加入學校 核心邏輯
             var teacherIESService = new TeacherIES();
-            var result = await teacherIESService.JoinSchoolServiceAsync(cosmosClient, _coreAPIHttpService, _dingDing, _option, _environment, _configuration, grant_type, id, name, picture, school_code, school_name);
+            bool result = false;
+            if (allowGrantType.Contains(grant_type))
+            {
+                result = await teacherIESService.JoinSchoolServiceAsync(cosmosClient, _coreAPIHttpService, _dingDing, _option, _environment, _configuration, grant_type, id, name, picture, school_code, school_name);
+            }
             if (result) return Ok(new { status = System.Net.HttpStatusCode.OK, err = string.Empty });
             else return Ok(new { status = System.Net.HttpStatusCode.NotFound, err = "Join school fail." });
         }