AutoGenerateM55128CNIndexPage.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Data;
  4. using System.Data.SqlClient;
  5. using System.Diagnostics;
  6. using System.Linq;
  7. using System.Text;
  8. using Cache;
  9. using Common;
  10. using HtmlAgilityPack;
  11. using Logger;
  12. using Main.Base;
  13. using Main.Lottery;
  14. using Models;
  15. using Quartz;
  16. namespace Main.Job
  17. {
  18. /// <summary>
  19. /// 自动生成M.55128.CN首页
  20. /// </summary>
  21. public class AutoGenerateM55128CNIndexPage : BaseJob, IJob
  22. {
  23. #region Attribute
  24. /// <summary>
  25. /// 当前作业配置信息
  26. /// </summary>
  27. private JobConfigEntity _config = null;
  28. /// <summary>
  29. /// 日志
  30. /// </summary>
  31. private static LogHelper _logHelper = new LogHelper(typeof(ThematicArticleSpiderJob));
  32. /// <summary>
  33. /// 资讯类别
  34. /// </summary>
  35. private static string[] _zxtypes = { "FC3D", "SSQ", "PL3", "QT" };
  36. /// <summary>
  37. /// 需要展示的开奖号
  38. /// </summary>
  39. private static List<SCCLottery> _lotteryTypeList = new List<SCCLottery>
  40. {
  41. SCCLottery.QGC_SSQ,
  42. SCCLottery.QGC_FC3D,
  43. SCCLottery.QGC_PL3,
  44. SCCLottery.QGC_DLT
  45. };
  46. #region 开奖号相关模板
  47. /// <summary>
  48. /// 开奖整体模板
  49. /// </summary>
  50. private static string kj_item_tmp = @"
  51. <div class='kj-item-title'>
  52. {0}
  53. {1}
  54. </div>
  55. <div class='kj-item-ball'>
  56. <div class='ball-wrapper'>
  57. {2}
  58. </div>
  59. {3}
  60. </div>
  61. <div class='kj-item-bottom'>
  62. <span class='kj-item-bl'>奖池:{4}元</span>
  63. <div class='kj-item-br'>
  64. {5}
  65. {6}
  66. </div>
  67. </div>";
  68. /// <summary>
  69. /// 彩种名称模板
  70. /// </summary>
  71. private static string lottery_name_tmp = "<span class=\"kj-item-name\">{0}</span>";
  72. /// <summary>
  73. /// 期号模板
  74. /// </summary>
  75. private static string lottery_periods_tmp = "<span class=\"kj-item-periods\">第{0}期</span>";
  76. /// <summary>
  77. /// 红球模板
  78. /// </summary>
  79. private static string lottery_redball_tmp = "<span class=\"ball-item redBall\">{0}</span>";
  80. /// <summary>
  81. /// 蓝球模板
  82. /// </summary>
  83. private static string lottery_blueball_tmp = "<span class=\"ball-item blueBall\">{0}</span>";
  84. /// <summary>
  85. /// 奖池模板
  86. /// </summary>
  87. private static string lottery_jackpot_tmp = "<span class=\"kj-item-jackpot\">{0}</span>";
  88. /// <summary>
  89. /// 更多
  90. /// </summary>
  91. private static string more_tmp = "<a href=\"{0}\"><span class=\"more iconfont icon-right\"></span></a>";
  92. /// <summary>
  93. /// 开奖详情链接
  94. /// </summary>
  95. private static string kj_detail_url_tmp = "<a href=\"{0}\"><span class=\"kj-btn\">开奖详情</span></a>";
  96. /// <summary>
  97. /// 开奖走势链接
  98. /// </summary>
  99. private static string kj_zs_url_tmp = "<a href=\"{0}\"><span class=\"kj-btn\">走势图表</span></a>";
  100. /// <summary>
  101. /// 其他地址
  102. /// </summary>
  103. private static Dictionary<SCCLottery, List<string>> other_url = new Dictionary<SCCLottery, List<string>>
  104. {
  105. { SCCLottery.QGC_SSQ,new List<string>{ "https://m.55128.cn/m/kj/ssq.html", "https://m.55128.cn/m/kj/ssq.html", "https://m.55128.cn/m/kjzs/ssq.html"}},
  106. { SCCLottery.QGC_FC3D,new List<string>{ "https://m.55128.cn/m/kj/fc3d.html", "https://m.55128.cn/m/kj/fc3d.html", "https://m.55128.cn/m/kjzs/fc3d.html"}},
  107. { SCCLottery.QGC_PL3,new List<string>{ "https://m.55128.cn/m/kj/pl3.html", "https://m.55128.cn/m/kj/pl3.html", "https://m.55128.cn/m/kjzs/pl3.html"}},
  108. { SCCLottery.QGC_DLT,new List<string>{ "https://m.55128.cn/m/kj/dlt.html", "https://m.55128.cn/m/kj/dlt.html", "https://m.55128.cn/m/kjzs/dlt.html"}},
  109. };
  110. #endregion
  111. #region 资讯相关模板
  112. /// <summary>
  113. /// 资讯模板
  114. /// </summary>
  115. private static string news_tmp = @"
  116. <a href='https://m.55128.cn/m/zx/{0}/{1}.html' class='news-item border-1px-bottom'>
  117. <span class='news-item-text'>{2}</span>
  118. <span class='news-item-time'>{3}</span>
  119. </a>";
  120. #endregion
  121. #endregion
  122. /// <summary>
  123. /// 入口
  124. /// </summary>
  125. /// <param name="context"></param>
  126. public void Execute(IJobExecutionContext context)
  127. {
  128. Logger(typeof(AutoGenerateM55128CNIndexPage), "AutoGenerateM55128CNIndexPage-作业执行入口", () =>
  129. {
  130. _config = this.GetConfigFromDataMap(context);
  131. Trace.WriteLine(_config.Name + "=============开始执行:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
  132. //资讯
  133. Dictionary<string, string> news_dict = InitNewsHtml();
  134. //开奖号
  135. Dictionary<string, string> lottery_dict = InitLotteryHtml();
  136. //特征字符串-待填充的数据
  137. //IEnumerable<KeyValuePair<string, string>> _source = news_dict.Concat(lottery_dict);
  138. foreach (KeyValuePair<string, string> pair in lottery_dict)
  139. {
  140. news_dict.Add(pair.Key, pair.Value);
  141. }
  142. if (news_dict.Count > 0)
  143. {
  144. //最终文件存放路径
  145. string filepath = ConfigHelper.GetValue("FileSavePath") + "\\index.html";
  146. //模板路径
  147. string templatePath = Utils.GetBaseDirectory("\\Template\\home.html");
  148. //临时保存路径
  149. string tempPath = Utils.GetBaseDirectory("\\index.html");
  150. if (Utils.IsExistFile(tempPath))
  151. {
  152. Utils.DeleteFile(tempPath);
  153. }
  154. GenerateStaticFileHelper helper = new GenerateStaticFileHelper(templatePath, tempPath);
  155. bool isSucc = helper.CreateStaticHtmlFile(news_dict);
  156. if (isSucc)
  157. {
  158. //将文件拷贝到最终文件存放目录
  159. if (Utils.IsExistFile(filepath))
  160. {
  161. Utils.DeleteFile(filepath);
  162. }
  163. Utils.CopyFile(tempPath, filepath);
  164. _logHelper.Debug($"生成成功!文件地址:{filepath},时间:{DateTime.Now:yyyy-MM-dd HH:mm:ss}");
  165. }
  166. }
  167. Trace.WriteLine(_config.Name + "=============执行结束:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
  168. }, e =>
  169. {
  170. _logHelper.Error("引发异常:" + e.Message);
  171. }, () =>
  172. {
  173. }, ErrorHandel.Continue);
  174. }
  175. #region 资讯相关
  176. /// <summary>
  177. /// 组装资讯Html
  178. /// </summary>
  179. /// <returns></returns>
  180. private Dictionary<string, string> InitNewsHtml()
  181. {
  182. Dictionary<string, string> dict = new Dictionary<string, string>();
  183. StringBuilder builder = new StringBuilder();
  184. List<NewsPreview> list = Cache.CacheFactory.GetCacheInstance().GetCache<List<NewsPreview>>("InitNewsHtmlCacheKey");
  185. if (list == null || list.Count == 0)
  186. {
  187. list = GetHomeNewsList();
  188. Cache.CacheFactory.GetCacheInstance().WriteCache(list, "InitNewsHtmlCacheKey", DateTime.Now.AddHours(1));
  189. }
  190. if (list.Count > 0)
  191. {
  192. foreach (NewsPreview news in list)
  193. {
  194. string type = news.NewsType;
  195. List<NewsPreviewItem> item = news.NewsPreviewItem;
  196. foreach (NewsPreviewItem previewItem in item)
  197. {
  198. builder.Append(string.Format(news_tmp, type.ToLower(), previewItem.NewsId, previewItem.Title, previewItem.AddTime));
  199. }
  200. dict.Add($"${type}$", builder.ToString());
  201. builder.Clear();
  202. }
  203. }
  204. return dict;
  205. }
  206. /// <summary>
  207. /// 获取首页最新资讯数据
  208. /// </summary>
  209. /// <returns></returns>
  210. private List<NewsPreview> GetHomeNewsList()
  211. {
  212. List<NewsPreview> res = new List<NewsPreview>();
  213. //List<BaseDataItem> dataItems = GetDataItemList().Where(t => _zxtypes.Contains(t.EnCode)).ToList();
  214. Logger(this.GetType(), "GetHomeNewsList-获取首页最新资讯", () =>
  215. {
  216. foreach (string code in _zxtypes)
  217. {
  218. List<BaseNews> news = InitNewsData(code);
  219. if (news.Count > 0)
  220. {
  221. NewsPreview preview = new NewsPreview
  222. {
  223. NewsType = code,
  224. ItemName = news[0].Category
  225. };
  226. //BaseDataItem tmpbaseitme = dataItems.FirstOrDefault(w => w.EnCode == code);
  227. //if (tmpbaseitme != null) preview.ItemName = tmpbaseitme.ItemName;
  228. List<NewsPreviewItem> newsPreviewItem = new List<NewsPreviewItem>();
  229. foreach (BaseNews n in news)
  230. {
  231. NewsPreviewItem preItem = new NewsPreviewItem
  232. {
  233. AddTime = n.CreateDate.ToString("yyyy-MM-dd"),
  234. NewsId = n.PK.ToString(),
  235. Title = n.FullHead,
  236. PeriodsNumber = n.PeriodsNumber
  237. };
  238. newsPreviewItem.Add(preItem);
  239. }
  240. preview.NewsPreviewItem = newsPreviewItem;
  241. res.Add(preview);
  242. }
  243. }
  244. }, e =>
  245. {
  246. Console.WriteLine(e.Message);
  247. });
  248. return res;
  249. }
  250. /// <summary>
  251. /// 查询咨询首页的分类下面最新的5条数据 详情看sql语句
  252. /// </summary>
  253. /// <returns></returns>
  254. private static List<BaseNews> InitNewsData(string code)
  255. {
  256. string strSql = @"SELECT TOP 5 * FROM Base_News WHERE CategoryId in(SELECT
  257. d.ItemDetailId
  258. FROM Base_DataItemDetail d
  259. LEFT JOIN Base_DataItem i ON i.ItemId = d.ItemId
  260. WHERE 1 = 1
  261. AND d.EnabledMark = 1
  262. AND d.DeleteMark = 0
  263. AND i.ItemCode ='{0}'
  264. AND d.ItemValue in('3DYC','P3YC','SSQYC','DLT')
  265. )AND IsDelete = 0 AND TypeId = 1 ORDER BY CreateDate DESC";
  266. string sql = string.Format(strSql, code);
  267. SqlConnection conn = SqlHelper.GetConnection(DbConnectionType.LottomatBaseDB);
  268. DataSet ds = SqlHelper.ExecuteDataset(conn, CommandType.Text, sql);
  269. if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
  270. {
  271. return ds.Tables[0].DataTableToList<BaseNews>();
  272. }
  273. return null;
  274. }
  275. /// <summary>
  276. /// 获取数据字典列表(给绑定下拉框提供的)
  277. /// </summary>
  278. /// <returns></returns>
  279. private List<BaseDataItem> GetDataItemList()
  280. {
  281. string sql = @"SELECT i.ItemId ,
  282. i.ItemCode AS EnCode ,
  283. d.ItemDetailId ,
  284. d.ParentId ,
  285. d.ItemCode ,
  286. d.ItemName ,
  287. d.ItemValue ,
  288. d.QuickQuery ,
  289. d.SimpleSpelling ,
  290. d.IsDefault ,
  291. d.SortCode ,
  292. d.EnabledMark,
  293. d.IsRecommend,
  294. d.IsHot,
  295. d.IsShowHomePage
  296. FROM Base_DataItemDetail d
  297. LEFT JOIN Base_DataItem i ON i.ItemId = d.ItemId
  298. WHERE 1 = 1
  299. AND d.EnabledMark = 1
  300. AND d.DeleteMark = 0
  301. ORDER BY d.SortCode ASC";
  302. SqlConnection conn = SqlHelper.GetConnection(DbConnectionType.LottomatBaseDB);
  303. DataSet ds = SqlHelper.ExecuteDataset(conn, CommandType.Text, sql);
  304. if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
  305. {
  306. List<BaseDataItem> res = ds.Tables[0].DataTableToList<BaseDataItem>();
  307. return res;
  308. }
  309. return null;
  310. }
  311. #endregion
  312. #region 开奖号相关
  313. /// <summary>
  314. /// 组装开奖号Html
  315. /// </summary>
  316. /// <returns></returns>
  317. private Dictionary<string, string> InitLotteryHtml()
  318. {
  319. Dictionary<string, string> dict = new Dictionary<string, string>();
  320. List<LotteryData> list = GetHomeLotteryData();
  321. if (list.Count > 0)
  322. {
  323. StringBuilder builder = new StringBuilder();
  324. foreach (LotteryData data in list)
  325. {
  326. //彩种名称
  327. string lottery_name = string.Format(lottery_name_tmp, data.LotteryName);
  328. //期号
  329. string lottery_periods = string.Format(lottery_periods_tmp, data.Term);
  330. //红球
  331. StringBuilder lottery_redball = new StringBuilder();
  332. if (data.RedBall != null && data.RedBall.Length > 0)
  333. {
  334. for (int i = 0; i < data.RedBall.Length; i++)
  335. {
  336. lottery_redball.Append(string.Format(lottery_redball_tmp, data.RedBall[i]));
  337. }
  338. }
  339. //蓝球
  340. StringBuilder lottery_blueball = new StringBuilder();
  341. if (data.BlueBall != null && data.BlueBall.Length > 0)
  342. {
  343. for (int i = 0; i < data.BlueBall.Length; i++)
  344. {
  345. lottery_blueball.Append(string.Format(lottery_blueball_tmp, data.BlueBall[i]));
  346. }
  347. }
  348. string lottery_ball = lottery_redball.ToString() + lottery_blueball.ToString();
  349. //奖池
  350. string lottery_jackpot = string.Format(lottery_jackpot_tmp, data.MoneyCount == null ? "0.00" : $"{Convert.ToDouble(data.MoneyCount):N2}");
  351. //更多
  352. string more = string.Format(more_tmp, other_url[data.LotteryType][0]);
  353. //开奖详情
  354. string kj_detail_url = string.Format(kj_detail_url_tmp, other_url[data.LotteryType][1]);
  355. //走势图
  356. string kj_zs_url = string.Format(kj_zs_url_tmp, other_url[data.LotteryType][2]);
  357. string kj_item = string.Format(kj_item_tmp, lottery_name, lottery_periods, lottery_ball, more,
  358. lottery_jackpot, kj_detail_url, kj_zs_url);
  359. builder.Append(kj_item);
  360. }
  361. dict.Add("$LotteryItem$", builder.ToString());
  362. }
  363. return dict;
  364. }
  365. /// <summary>
  366. /// 首页开奖信息
  367. /// </summary>
  368. /// <returns></returns>
  369. private List<LotteryData> GetHomeLotteryData()
  370. {
  371. List<LotteryData> qgc = new List<LotteryData>();
  372. //双色球
  373. OpenCode7DTModel ssq = GetLastLotteryItem<OpenCode7DTModel>(SCCLottery.QGC_SSQ);
  374. if (ssq != null)
  375. {
  376. qgc.Add(LottryDataHandle.GetLotteryData(SCCLottery.QGC_SSQ, ssq.Term.ToString().TryToInt32(), ssq.OpenTime, ssq.ID, Array.ConvertAll<string, int>(ssq.GetCodeStr().Split(',').ToArray(), s => s.TryToInt32()), ssq.Spare, "qgc"));
  377. }
  378. //福彩3D
  379. OpenCode3DTModel fc3d = GetLastLotteryItem<OpenCode3DTModel>(SCCLottery.QGC_FC3D);
  380. if (fc3d != null)
  381. {
  382. qgc.Add(LottryDataHandle.GetLotteryData(SCCLottery.QGC_FC3D, fc3d.Term.ToString().TryToInt32(), fc3d.OpenTime, fc3d.ID, Array.ConvertAll<string, int>(fc3d.GetCodeStr().Split(',').ToArray(), s => s.TryToInt32()), fc3d.Spare, "qgc"));
  383. }
  384. //排列3
  385. OpenCode3DTModel pl3 = GetLastLotteryItem<OpenCode3DTModel>(SCCLottery.QGC_PL3);
  386. if (pl3 != null)
  387. {
  388. qgc.Add(LottryDataHandle.GetLotteryData(SCCLottery.QGC_PL3, pl3.Term.ToString().TryToInt32(), pl3.OpenTime, pl3.ID, Array.ConvertAll<string, int>(pl3.GetCodeStr().Split(',').ToArray(), s => s.TryToInt32()), pl3.Spare, "qgc"));
  389. }
  390. //大乐透
  391. OpenCode7DTModel dlt = GetLastLotteryItem<OpenCode7DTModel>(SCCLottery.QGC_DLT);
  392. if (dlt != null)
  393. {
  394. qgc.Add(LottryDataHandle.GetLotteryData(SCCLottery.QGC_DLT, dlt.Term.ToString().TryToInt32(), dlt.OpenTime, dlt.ID, Array.ConvertAll<string, int>(dlt.GetCodeStr().Split(',').ToArray(), s => s.TryToInt32()), dlt.Spare, "qgc"));
  395. }
  396. return qgc;
  397. }
  398. /// <summary>
  399. /// 获取最新一条记录
  400. /// </summary>
  401. /// <param name="lottery">彩种名称</param>
  402. /// <returns></returns>
  403. private T GetLastLotteryItem<T>(SCCLottery lottery) where T : new()
  404. {
  405. var tableName = lottery.GetLotteryTableName();
  406. string LastItemSql = @"SELECT TOP 1 * FROM [dbo].[{0}] WHERE [OpenCode1] != -1 ORDER BY Term DESC ";
  407. SqlConnection conn = SqlHelper.GetConnection(DbConnectionType.LotteryNumber);
  408. string sqlString = string.Format(LastItemSql, tableName);
  409. DataSet ds = SqlHelper.ExecuteDataset(conn, CommandType.Text, sqlString);
  410. if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
  411. {
  412. var result = ds.Tables[0].DataTableToList<T>();
  413. return result[0];
  414. }
  415. return default(T);
  416. }
  417. #endregion
  418. }
  419. }