IPServiceGuide.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. using WingCloudServer.IpOfflineTools.Model;
  2. namespace WingCloudServer.IpOfflineTools.Service
  3. {
  4. /// <summary>
  5. /// 数据处理
  6. /// </summary>
  7. public class IPServiceGuide
  8. {
  9. /// <summary>
  10. /// 文件读取
  11. /// </summary>
  12. /// <param name="sourceFilePath">源文件地址</param>
  13. /// <returns>源数据列表</returns>
  14. public List<IPBasicInfo> ReadFile(string sourceFilePath)
  15. {
  16. var list = new List<IPBasicInfo>();
  17. if (string.IsNullOrEmpty(sourceFilePath))
  18. {
  19. return list;
  20. }
  21. string[] strArray = File.ReadAllLines(sourceFilePath);
  22. for (int i = 0; i < strArray.Length; i++)
  23. {
  24. var tempList = strArray[i].Split(' ').Where(c => !string.IsNullOrEmpty(c)).ToList();
  25. if (tempList?.Count > 0)
  26. {
  27. var model = new IPBasicInfo()
  28. {
  29. BeginIp = tempList[0],
  30. EndIp = tempList[1],
  31. CountryName = tempList[2]
  32. };
  33. list.Add(model);
  34. }
  35. }
  36. return list;
  37. }
  38. /// <summary>
  39. /// 保存读取
  40. /// </summary>
  41. /// <param name="countryList">源数据</param>
  42. /// <param name="savePath">保存文件路径</param>
  43. /// <param name="fileName">保存文件名</param>
  44. /// <param name="pCount">每个文件最多保存条数,如果为0,则保存为一个文件</param>
  45. /// <returns>源数据列表</returns>
  46. public bool WriteFile(List<CountryEntity> countryList, string savePath, string fileName, int pCount = 0)
  47. {
  48. bool result = false;
  49. var resultList = new List<IpEntity>();
  50. foreach(var item in countryList)
  51. {
  52. resultList.AddRange(item.IpList);
  53. }
  54. if (resultList != null && resultList.Count > 0)
  55. {
  56. if (!Directory.Exists(savePath))
  57. {
  58. Directory.CreateDirectory(savePath);
  59. }
  60. if (pCount > 0)
  61. {
  62. var factName = Path.GetFileNameWithoutExtension(fileName);
  63. var factNameExtension = Path.GetExtension(fileName);
  64. var resultLength = resultList.Count;
  65. int fileCount = (resultList.Count / pCount) + ((resultList.Count % pCount) > 0 ? 1: 0);
  66. for (var i = 0; i < fileCount; i++)
  67. {
  68. int index = i * pCount;
  69. int length = pCount;
  70. if (resultLength < (index + pCount))
  71. {
  72. length = resultLength - index;
  73. }
  74. var tempList = resultList.GetRange(index, length);
  75. var json = Newtonsoft.Json.JsonConvert.SerializeObject(tempList);
  76. if (!string.IsNullOrWhiteSpace(json))
  77. {
  78. var tempSavePath = savePath + factName + "_" + i + factNameExtension;
  79. if (File.Exists(tempSavePath))
  80. {
  81. File.Delete(tempSavePath);
  82. }
  83. byte[] fileData = System.Text.Encoding.UTF8.GetBytes(json);
  84. //存储文件
  85. using (var fw = File.Open(tempSavePath, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite))
  86. {
  87. fw.Write(fileData, 0, fileData.Length);
  88. }
  89. }
  90. }
  91. result = true;
  92. }
  93. else
  94. {
  95. var newSavePath = savePath + fileName;
  96. if (File.Exists(newSavePath))
  97. {
  98. File.Delete(newSavePath);
  99. }
  100. var json = Newtonsoft.Json.JsonConvert.SerializeObject(resultList);
  101. if (!string.IsNullOrWhiteSpace(json))
  102. {
  103. byte[] fileData = System.Text.Encoding.UTF8.GetBytes(json);
  104. //存储文件
  105. using (var fw = File.Open(newSavePath, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite))
  106. {
  107. fw.Write(fileData, 0, fileData.Length);
  108. }
  109. result = true;
  110. }
  111. }
  112. }
  113. return result;
  114. }
  115. /// <summary>
  116. /// 从源数据中读取国家信息
  117. /// </summary>
  118. /// <param name="list">源数据</param>
  119. /// <returns>新的国家数据</returns>
  120. public List<CountryEntity> GetCountryFromIpList(List<IPBasicInfo> list)
  121. {
  122. var waitList = new List<CountryEntity>();
  123. var countryEntityList = new List<CountryEntity>();
  124. if (list?.Count > 0)
  125. {
  126. //获取大陆省份和直辖市
  127. var provinceList = CommonHelper.GetProvinceList();
  128. var cityDic = CommonHelper.GetCityDictionary();
  129. //获取所有的国家和地区
  130. var countryList = list.Select(c => c.CountryName).Distinct().ToList();
  131. if (countryList?.Count > 0)
  132. {
  133. //获取所有的省份和国家,区分大陆省份,港澳台,其他国家
  134. var valList = new List<string>();
  135. foreach (var item in provinceList)
  136. {
  137. var tempList = countryList.FindAll(c => c.Contains(item));
  138. valList.AddRange(tempList);
  139. var cityList = cityDic[item];
  140. if (cityList?.Count > 0)
  141. {
  142. foreach (var cityItem in cityList)
  143. {
  144. if (!waitList.Exists(c => c.CountryName == "中国" && c.ProvinceName == item && c.CityName == cityItem))
  145. {
  146. var ipTempEntity = list.Find(d => d.CountryName.Contains(item) && d.CountryName.Contains(cityItem));
  147. if (ipTempEntity == null)
  148. {
  149. continue;
  150. }
  151. var strCityItem = cityItem;
  152. if (item == "北京" || item == "天津" || item == "上海" || item == "重庆")
  153. {
  154. strCityItem = item;
  155. }
  156. var ce = new CountryEntity()
  157. {
  158. CountryName = "中国",
  159. ProvinceName = item,
  160. CityName = strCityItem,
  161. DefaultIp = ipTempEntity.EndIp
  162. };
  163. waitList.Add(ce);
  164. }
  165. }
  166. }
  167. }//大陆省份数据
  168. var otherProviceList = new List<string>()
  169. {
  170. "香港",
  171. "澳门",
  172. "台湾"
  173. };
  174. var otherValList = new List<string>();
  175. foreach (var item in otherProviceList)
  176. {
  177. var tempList = countryList.FindAll(c => c.Contains(item));
  178. otherValList.AddRange(tempList);
  179. if (!waitList.Exists(c => c.CountryName == "中国香港" && c.ProvinceName == item))
  180. {
  181. var ipTempEntity = list.Find(d => d.CountryName.Contains(item));
  182. if (ipTempEntity == null)
  183. {
  184. continue;
  185. }
  186. var ce = new CountryEntity()
  187. {
  188. CountryName = "中国香港",
  189. ProvinceName = item,
  190. CityName = "",
  191. DefaultIp = ipTempEntity.EndIp,
  192. };
  193. waitList.Add(ce);
  194. }
  195. }//港澳台数据
  196. var otherCountryList = countryList.FindAll(c => !valList.Contains(c) && !otherValList.Contains(c));//其他国家的数据
  197. if (otherCountryList?.Count > 0)
  198. {
  199. foreach (var item in otherCountryList)
  200. {
  201. if (!waitList.Exists(c => c.CountryName == "境外" && c.ProvinceName == item))
  202. {
  203. var ipTempEntity = list.Find(d => d.CountryName.Contains(item));
  204. if (ipTempEntity == null)
  205. {
  206. continue;
  207. }
  208. var ce = new CountryEntity()
  209. {
  210. CountryName = "境外",
  211. ProvinceName = item,
  212. CityName = "",
  213. DefaultIp = ipTempEntity.EndIp,
  214. };
  215. waitList.Add(ce);
  216. }
  217. }
  218. }
  219. //封装数据,方便后续处理
  220. if (valList?.Count > 0)
  221. {
  222. var countryEntity = new CountryEntity()
  223. {
  224. CountryName = "中国",
  225. ChildList = valList
  226. };
  227. countryEntityList.Add(countryEntity);
  228. }
  229. if (otherValList?.Count > 0)
  230. {
  231. var countryEntity = new CountryEntity()
  232. {
  233. CountryName = "香港",
  234. ChildList = otherValList
  235. };
  236. countryEntityList.Add(countryEntity);
  237. }
  238. if (otherCountryList?.Count > 0)
  239. {
  240. var countryEntity = new CountryEntity()
  241. {
  242. CountryName = "境外",
  243. ChildList = otherCountryList
  244. };
  245. countryEntityList.Add(countryEntity);
  246. }
  247. }
  248. }
  249. else
  250. {
  251. return new List<CountryEntity>();
  252. }
  253. if (waitList?.Count > 0)
  254. {
  255. foreach (var waitItem in waitList)
  256. {
  257. var tempResult = CommonHelper.GetIpLocationInfo(waitItem.DefaultIp);
  258. waitItem.Lat = tempResult?.location?.lat ?? 0;
  259. waitItem.Lng = tempResult?.location?.lng ?? 0;
  260. }
  261. }
  262. else
  263. {
  264. waitList = new List<CountryEntity>();
  265. }
  266. //计算真实的定位信息
  267. var newCountryInfo = CaculateInfo(countryEntityList, list, waitList);
  268. return newCountryInfo;
  269. }
  270. /// <summary>
  271. /// ip信息计算
  272. /// </summary>
  273. /// <param name="list">源数据</param>
  274. /// <param name="ipList">ip列表</param>
  275. /// <param name="waitList">待处理数据列表</param>
  276. /// <returns>新的国家数据</returns>
  277. private List<CountryEntity> CaculateInfo(List<CountryEntity> oriList, List<IPBasicInfo> ipList, List<CountryEntity> waitList)
  278. {
  279. var resultList = new List<CountryEntity>();
  280. //先计算中国
  281. var chinaEntity = new CountryEntity()
  282. {
  283. CountryName = "中国大陆"
  284. };
  285. var bjTempList = oriList?.Find(c => c.CountryName == "中国")?.ChildList ?? new List<string>();
  286. foreach (var item in bjTempList)
  287. {
  288. var waitInfo = waitList.Find(c => c.CountryName == "中国" && item.Contains(c.ProvinceName) && item.Contains(c.CityName)) ?? new CountryEntity();
  289. var ipTempList = ipList.FindAll(d => d.CountryName == item);
  290. if (ipTempList?.Count > 0)
  291. {
  292. foreach (var ipTempEntity in ipTempList)
  293. {
  294. IpEntity ipInfo = new IpEntity()
  295. {
  296. LongStartIP = CommonHelper.IpToLong(ipTempEntity.BeginIp),
  297. LongEndIP = CommonHelper.IpToLong(ipTempEntity.EndIp),
  298. Lat = waitInfo.Lat,
  299. Lng = waitInfo.Lng,
  300. Country = "CN",
  301. Province = waitInfo.ProvinceName,
  302. City = waitInfo.CityName,
  303. Districts = "",
  304. IsChinaMainland = true,
  305. };
  306. chinaEntity.IpList.Add(ipInfo);
  307. }
  308. }
  309. }
  310. resultList.Add(chinaEntity);
  311. //在计算香港
  312. var hkEntity = new CountryEntity()
  313. {
  314. CountryName = "中国香港"
  315. };
  316. var hkTempList = oriList?.Find(c => c.CountryName == "香港")?.ChildList ?? new List<string>();
  317. foreach (var item in hkTempList)
  318. {
  319. var waitInfo = waitList.Find(c => c.CountryName == "中国香港" && c.ProvinceName == item) ?? new CountryEntity();
  320. var ipTempList = ipList.FindAll(d => d.CountryName == item);
  321. if (ipTempList?.Count > 0)
  322. {
  323. foreach (var ipTempEntity in ipTempList)
  324. {
  325. IpEntity ipInfo = new IpEntity()
  326. {
  327. LongStartIP = CommonHelper.IpToLong(ipTempEntity.BeginIp),
  328. LongEndIP = CommonHelper.IpToLong(ipTempEntity.EndIp),
  329. Lat = waitInfo.Lat,
  330. Lng = waitInfo.Lng,
  331. Country = "HK",
  332. Province = waitInfo.ProvinceName,
  333. City = "",
  334. Districts = "",
  335. IsChinaMainland = false,
  336. };
  337. hkEntity.IpList.Add(ipInfo);
  338. }
  339. }
  340. }
  341. resultList.Add(hkEntity);
  342. //在计算其他,这里就要将经纬度计算,更近的归属于相应的节点
  343. var otherTempList = oriList?.Find(c => c.CountryName != "香港" && c.CountryName != "中国")?.ChildList ?? new List<string>();
  344. var otherEntity = new CountryEntity()
  345. {
  346. CountryName = "境外"
  347. };
  348. foreach (var item in otherTempList)
  349. {
  350. var waitInfo = waitList.Find(c => c.CountryName == "境外" && c.ProvinceName == item) ?? new CountryEntity();
  351. var ipTempList = ipList.FindAll(d => d.CountryName == item);
  352. if (ipTempList?.Count > 0)
  353. {
  354. foreach (var ipTempEntity in ipTempList)
  355. {
  356. IpEntity ipInfo = new IpEntity()
  357. {
  358. LongStartIP = CommonHelper.IpToLong(ipTempEntity.BeginIp),
  359. LongEndIP = CommonHelper.IpToLong(ipTempEntity.EndIp),
  360. Lat = waitInfo.Lat,
  361. Lng = waitInfo.Lng,
  362. Country = "JW",
  363. Province = waitInfo.ProvinceName,
  364. City = "",
  365. Districts = "",
  366. IsChinaMainland = false,
  367. };
  368. otherEntity.IpList.Add(ipInfo);
  369. }
  370. }
  371. }
  372. resultList.Add(otherEntity);
  373. return resultList;
  374. }
  375. }
  376. }