You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1408 lines
59 KiB

  1. using log4net;
  2. using CounsellorBL.Helper;
  3. using MonumentDefine;
  4. using Newtonsoft.Json;
  5. using Newtonsoft.Json.Linq;
  6. using OT.COM.ArsenalDB;
  7. using SoldierData.EnterprizeV4;
  8. using System;
  9. using System.Collections.Generic;
  10. using System.Linq;
  11. using System.Net.Http;
  12. using static MonumentDefine.Enums;
  13. using System.Text;
  14. using GroupBuyParser;
  15. namespace CounsellorBL.Helper
  16. {
  17. /// <summary>
  18. /// 類別名稱:Mailer
  19. /// 類別說明:
  20. /// 起始作者:
  21. /// 起始日期:
  22. /// 最新修改人:
  23. /// 最新修改日:
  24. /// </summary>
  25. public class FbRestHelper : DBService
  26. {
  27. private static ILog _inst = null;
  28. private static ILog Logger
  29. {
  30. get
  31. {
  32. if (_inst == null)
  33. {
  34. _inst = LogManager.GetLogger(typeof(FbRestHelper));
  35. }
  36. return _inst;
  37. }
  38. }
  39. public override string MainTable => null;
  40. #region 類別
  41. /// <summary>
  42. /// Fb留言資料
  43. /// </summary>
  44. private class FbCommentData
  45. {
  46. public List<data> data { get; set; }
  47. public JObject paging { get; set; }
  48. }
  49. private class data
  50. {
  51. public DateTime created_time { get; set; }
  52. public from from { get; set; }
  53. public string message { get; set; }
  54. public string id { get; set; }
  55. public parent parent { get; set; }
  56. public int comment_count { get; set; }
  57. }
  58. private class from
  59. {
  60. public string name { get; set; }
  61. public string id { get; set; }
  62. public Picture picture { get; set; }
  63. public class Picture
  64. {
  65. public PictureData data { get; set; }
  66. public class PictureData
  67. {
  68. public string url { get; set; }
  69. }
  70. }
  71. }
  72. private class parent
  73. {
  74. public string id { get; set; }
  75. }
  76. /// <summary>
  77. /// Fb 延長token
  78. /// </summary>
  79. private class FbToken
  80. {
  81. public string access_token { get; set; }
  82. public string type { get; set; }
  83. }
  84. /// <summary>
  85. /// Fb token 驗證
  86. /// </summary>
  87. public class FbTokenVerification
  88. {
  89. public VerificationContent data { get; set; }
  90. }
  91. public class VerificationContent
  92. {
  93. public string app_id { get; set; }
  94. public string type { get; set; }
  95. public int data_access_expires_at { get; set; }
  96. //public error error { get; set; }
  97. public int expires_at { get; set; }
  98. public bool is_valid { get; set; }
  99. public string user_id { get; set; }
  100. }
  101. private class error
  102. {
  103. public int code { get; set; }
  104. public string message { get; set; }
  105. public int subcode { get; set; }
  106. }
  107. /// <summary>
  108. /// FB API get token response information
  109. /// </summary>
  110. public class FbGetTokenEntity
  111. {
  112. public string access_token { get; set; }
  113. public string token_type { get; set; }
  114. public string expires_in { get; set; }
  115. }
  116. APIURLHelper ApiUrlHelper = new APIURLHelper();
  117. /// <summary>
  118. /// fb 貼文
  119. /// </summary>
  120. public class FbGetPost
  121. {
  122. public List<FbGetPostdata> data { get; set; }
  123. public JObject paging { get; set; }
  124. }
  125. public class FbGetPostdata
  126. {
  127. public string id { get; set; }
  128. public string message { get; set; }
  129. public string full_picture { get; set; }
  130. public string source { get; set; }
  131. public DateTime updated_time { get; set; }
  132. public DateTime created_time { get; set; }
  133. }
  134. public class UserInfo
  135. {
  136. public string name { get; set; }
  137. public string email { get; set; }
  138. public string link { get; set; }
  139. public string birthday { get; set; }
  140. public string gender { get; set; }
  141. public Picture picture { get; set; }
  142. public string id { get; set; }
  143. public class Picture
  144. {
  145. public PictureData data { get; set; }
  146. public class PictureData
  147. {
  148. public string url { get; set; }
  149. }
  150. }
  151. }
  152. public class PushPost
  153. {
  154. public string id { get; set; }
  155. }
  156. #endregion
  157. public enum CommentStatus
  158. {
  159. /// <summary>
  160. /// 無問題 (綠)
  161. /// </summary>
  162. OK = 1,
  163. /// <summary>
  164. /// 有問題【無數量】【無分店】【無產品】【數字有更新】 (紅)
  165. /// </summary>
  166. InvalidFormat = 2,
  167. /// <summary>
  168. /// 會員無登入系統 (橘)
  169. /// </summary>
  170. UnknownMember = 3,
  171. /// <summary>
  172. /// 黑名單或其他回覆的留言 (黑)
  173. /// </summary>
  174. Duplicate = 4,
  175. /// <summary>
  176. /// 已轉成訂單,不顯示其中
  177. /// </summary>
  178. TransferOrder = 9
  179. }
  180. class CommentModel
  181. {
  182. public string uid { get; set; }
  183. public string group_user_id { get; set; }
  184. public string comment { get; set; }
  185. public DateTime comment_time { get; set; }
  186. }
  187. #region FbAPI
  188. // 針對應用程式 可以使用{應用程式ID}|{應用程式密鑰}
  189. /// <summary>
  190. /// 上傳貼文的POST
  191. /// </summary>
  192. /// <param name="authorizationToken"></param>
  193. /// <param name="message"></param>
  194. /// <param name="path">圖片路徑</param>
  195. public string CallFbPostPushAPI(string authorizationToken, string message, string groupId, List<string> path, out string o_sPostFBID)
  196. {
  197. string sMsg = null;
  198. string sPostFBID = null;
  199. Logger.Info($"CallFbPostPushAPI start groupId={groupId}");
  200. if (path != null)
  201. {
  202. path.ForEach(p =>
  203. {
  204. Logger.Info($"CallFbPostPushAPI path={p}");
  205. });
  206. }
  207. try
  208. {
  209. do
  210. {
  211. // 送出資料
  212. string uri = string.Format("https://graph.facebook.com/v8.0/{0}/feed", groupId);
  213. var lsData = new List<APIHelper.DataContent>()
  214. {
  215. new APIHelper.DataContent { Key = "access_token" , Type = typeof(StringContent) , Content = authorizationToken },
  216. new APIHelper.DataContent { Key = "message", Type = typeof(StringContent), Content = message },
  217. new APIHelper.DataContent { Key = "published", Type = typeof(StringContent), Content = "false" }
  218. };
  219. Logger.Info($"CallFbPostPushAPI f2 uri={uri}");
  220. if (path != null && path.Any())
  221. {
  222. int i = 0;
  223. path.ForEach(x =>
  224. {
  225. if (x != null)
  226. {
  227. lsData.Add(new APIHelper.DataContent { Key = $"attached_media[{i}]", Type = typeof(StringContent), Content = "{\"media_fbid\":" + x + "}" });
  228. }
  229. i++;
  230. });
  231. }
  232. Logger.Info($"CallFbPostPushAPI f3 uri={uri}");
  233. sMsg = APIHelper.BasePost(uri, null, lsData, out HttpResponseMessage responseMessage);
  234. if (sMsg != null)
  235. {
  236. Logger.Error(sMsg);
  237. break;
  238. }
  239. Logger.Info($"CallFbPostPushAPI responseMessage.IsSuccessStatusCode = {responseMessage.IsSuccessStatusCode}");
  240. if (responseMessage.IsSuccessStatusCode)
  241. {
  242. var fb_error = GetFbApiError(responseMessage);
  243. if (!string.IsNullOrWhiteSpace(fb_error))
  244. {
  245. sMsg = fb_error;
  246. Logger.Error($"CallFbPostPushAPI f7");
  247. Logger.Error($"CallFbPostPushAPI sMsg={sMsg}");
  248. break;
  249. }
  250. Logger.Info($"CallFbPostPushAPI f6");
  251. string sContent = responseMessage.Content.ReadAsStringAsync().Result;
  252. Logger.Info($"CallFbPostPushAPI f6 sContent={sContent}");
  253. sPostFBID = JsonConvert.DeserializeObject<PushPost>(sContent).id;
  254. Logger.Info($"CallFbPostPushAPI f6 sPostFBID={sPostFBID}");
  255. }
  256. else
  257. {
  258. Logger.Error($"CallFbPostPushAPI f7");
  259. sMsg = JsonConvert.SerializeObject(responseMessage);
  260. Logger.Error($"CallFbPostPushAPI sMsg={sMsg}");
  261. break;
  262. }
  263. }
  264. while (false);
  265. }
  266. catch (Exception ex)
  267. {
  268. sMsg = ex.Message;
  269. Logger.Error($"Exception={sMsg}");
  270. }
  271. o_sPostFBID = sPostFBID;
  272. Logger.Info($"CallFbPostPushAPI end groupId={groupId}");
  273. return sMsg;
  274. }
  275. /// <summary>
  276. /// 上傳圖片的POST
  277. /// </summary>
  278. /// <param name="authorizationToken"></param>
  279. /// <param name="message"></param>
  280. /// <param name="path">圖片路徑</param>
  281. public string CallFbPicturePushAPI(string authorizationToken, string groupId, string path, out string o_sPicID)
  282. {
  283. string sMsg = null;
  284. string sPicID = null;
  285. Logger.Info($"CallFbPicturePushAPI start groupId={groupId} path={path}");
  286. try
  287. {
  288. do
  289. {
  290. // 送出資料
  291. //string uri = string.Format("https://graph.facebook.com/v7.0/{0}/photos", groupId);
  292. //Logger.Info($"CallFbPicturePushAPI uri = {uri}");
  293. //var lsData = new List<APIHelper.DataContent>()
  294. //{
  295. // new APIHelper.DataContent { Key = "access_token" , Type = typeof(StringContent) , Content = authorizationToken },
  296. // new APIHelper.DataContent { Key = "url", Type = typeof(StringContent), Content = path },
  297. // new APIHelper.DataContent { Key = "published", Type = typeof(StringContent), Content = "false" },
  298. // new APIHelper.DataContent { Key = "attempt", Type = typeof(StringContent), Content = "3" }
  299. //};
  300. // 送出資料
  301. string uri = string.Format("https://graph.facebook.com/v7.0/{0}/photos?access_token={1}", groupId, authorizationToken);
  302. Logger.Info($"CallFbPicturePushAPI uri = {uri}");
  303. var lsData = new List<APIHelper.DataContent>()
  304. {
  305. //new APIHelper.DataContent { Key = "access_token" , Type = typeof(StringContent) , Content = authorizationToken },
  306. new APIHelper.DataContent { Key = "url", Type = typeof(StringContent), Content = path },
  307. new APIHelper.DataContent { Key = "published", Type = typeof(StringContent), Content = "false" },
  308. new APIHelper.DataContent { Key = "attempt", Type = typeof(StringContent), Content = "3" },
  309. new APIHelper.DataContent { Key = "suppress_http_code", Type = typeof(StringContent), Content = "1" },
  310. new APIHelper.DataContent { Key = "format", Type = typeof(StringContent), Content = "json" },
  311. new APIHelper.DataContent { Key = "pretty", Type = typeof(StringContent), Content = "0" },
  312. //new APIHelper.DataContent { Key = "debug", Type = typeof(StringContent), Content = "all" },
  313. new APIHelper.DataContent { Key = "transport", Type = typeof(StringContent), Content = "cors" },
  314. };
  315. sMsg = APIHelper.BasePost(uri, null, lsData, out HttpResponseMessage responseMessage);
  316. if (sMsg != null)
  317. {
  318. Logger.Error($"CallFbPicturePushAPI uri = {uri} sMsg={sMsg}");
  319. break;
  320. }
  321. if (responseMessage.IsSuccessStatusCode)
  322. {
  323. var fb_error = GetFbApiError(responseMessage);
  324. if (!string.IsNullOrWhiteSpace(fb_error))
  325. {
  326. sMsg = fb_error;
  327. Logger.Error($"CallFbPicturePushAPI f7");
  328. Logger.Error($"CallFbPicturePushAPI sMsg={sMsg}");
  329. break;
  330. }
  331. string sContent = responseMessage.Content.ReadAsStringAsync().Result;
  332. Logger.Info($"CallFbPicturePushAPI sContent={sContent}");
  333. sPicID = JsonConvert.DeserializeObject<PushPost>(sContent).id;
  334. Logger.Info($"CallFbPicturePushAPI sPicID={sPicID}");
  335. }
  336. else
  337. {
  338. Logger.Error($"CallFbPicturePushAPI f7");
  339. sMsg = JsonConvert.SerializeObject(responseMessage);
  340. Logger.Error($"CallFbPicturePushAPI sMsg={sMsg}");
  341. break;
  342. }
  343. }
  344. while (false);
  345. }
  346. catch (Exception ex)
  347. {
  348. sMsg = ex.Message;
  349. Logger.Error($"CallFbPicturePushAPI exception={sMsg}");
  350. }
  351. o_sPicID = sPicID;
  352. Logger.Info($"CallFbPicturePushAPI end groupId={groupId} path={path} sResult={sPicID}");
  353. return sMsg;
  354. }
  355. /// <summary>
  356. /// 貼文的Get(抓貼文、圖片、影片)
  357. /// </summary>
  358. /// <param name="authorizationToken"></param>
  359. /// <param name="message"></param>
  360. /// <param name="path">圖片路徑</param>
  361. public bool CallFbPostGetAPI(string authorizationToken, string groupId)
  362. {
  363. // 送出資料 取1000筆資料
  364. string uri = string.Format("https://graph.facebook.com/v7.0/{0}/feed?fields=full_picture,message,source,updated_time,created_time&limit=1000&", groupId);
  365. var dicData = new Dictionary<string, string>()
  366. {
  367. { "access_token", authorizationToken }
  368. };
  369. APIHelper.BaseGet(uri, null, dicData, out HttpResponseMessage responseMessage);
  370. if (responseMessage.IsSuccessStatusCode)
  371. {
  372. GetFbPostData(JsonConvert.DeserializeObject<FbGetPost>(responseMessage.Content.ReadAsStringAsync().Result));
  373. }
  374. return responseMessage.IsSuccessStatusCode;
  375. }
  376. /// <summary>
  377. /// 貼文的Get(抓貼文、圖片、影片)
  378. /// </summary>
  379. /// <param name="authorizationToken"></param>
  380. /// <param name="message"></param>
  381. /// <param name="path">圖片路徑</param>
  382. public string CallFbGetInformation(string authorizationToken, out UserInfo userInfo)
  383. {
  384. userInfo = null;
  385. string sMsg = null;
  386. do
  387. {
  388. try
  389. {
  390. // 送出資料 取1000筆資料
  391. string uri = "https://graph.facebook.com/v7.0/me";
  392. var dicData = new Dictionary<string, string>()
  393. {
  394. { "access_token", authorizationToken },
  395. { "fields","name,email,link,picture.type(normal),birthday,gender"}
  396. };
  397. var lsData = new List<APIHelper.DataContent>()
  398. {
  399. //new APIHelper.DataContent { Key = "access_token" , Type = typeof(StringContent) , Content = authorizationToken },
  400. new APIHelper.DataContent { Key = "access_token", Type = typeof(StringContent), Content = authorizationToken },
  401. new APIHelper.DataContent { Key = "fields", Type = typeof(StringContent), Content = "name,email,link,picture.type(normal),birthday,gender" },
  402. };
  403. sMsg = APIHelper.BasePost(uri, null, lsData, out HttpResponseMessage responseMessage);
  404. if (responseMessage.IsSuccessStatusCode)
  405. {
  406. sMsg = GetFbApiError(responseMessage);
  407. if (!string.IsNullOrWhiteSpace(sMsg))
  408. {
  409. break;
  410. }
  411. userInfo = JsonConvert.DeserializeObject<UserInfo>(responseMessage.Content.ReadAsStringAsync().Result);
  412. }
  413. }
  414. catch (Exception ex)
  415. {
  416. throw ;
  417. }
  418. } while (false);
  419. return sMsg;
  420. }
  421. /// <summary>
  422. /// 貼文的Get(抓貼文、圖片、影片)
  423. /// </summary>
  424. /// <param name="authorizationToken"></param>
  425. /// <param name="message"></param>
  426. /// <param name="path">圖片路徑</param>
  427. public FbGetPost CallFbPostGetDataAPI(string authorizationToken, string groupId, int grabDate_ = 0)
  428. {
  429. if (grabDate_ == 0 || grabDate_ > 30)
  430. grabDate_ = 30;// 30日為預設天數
  431. // 送出資料 撈取30天內之文章 並重複取至無資料
  432. string uri = string.Format("https://graph.facebook.com/v7.0/{0}/feed?fields=full_picture,message,source,updated_time,created_time&limit=100&since={1}&",
  433. groupId,
  434. DateTime.Now.AddDays(-grabDate_).ToString("yyyy-MM-dd")
  435. );
  436. FbGetPost rawResult = null;
  437. FbGetPost result = new FbGetPost() { data = new List<FbGetPostdata>(), paging = new JObject() };
  438. bool isOver = false;
  439. var dicData = new Dictionary<string, string>()
  440. {
  441. { "access_token", authorizationToken }
  442. };
  443. while (!isOver)
  444. {
  445. APIHelper.BaseGet(uri, null, dicData, out HttpResponseMessage responseMessage);
  446. if (responseMessage.IsSuccessStatusCode)
  447. {
  448. rawResult = JsonConvert.DeserializeObject<FbGetPost>(responseMessage.Content.ReadAsStringAsync().Result);
  449. result.data.AddRange(rawResult.data);
  450. uri = rawResult.paging != null ? rawResult.paging["next"].ToString() : null;
  451. if (rawResult.data.Count == 0)
  452. {
  453. isOver = true;
  454. }
  455. }
  456. else
  457. {
  458. isOver = true;
  459. }
  460. }
  461. return result;
  462. }
  463. /// <summary>
  464. /// 貼文的Get(抓單篇貼文)
  465. /// </summary>
  466. /// <param name="authorizationToken"></param>
  467. /// <param name="message"></param>
  468. /// <param name="path">圖片路徑</param>
  469. public FbGetPostdata CallSingleFbPostGetDataAPI(string authorizationToken, string postId)
  470. {
  471. string uri = string.Format("https://graph.facebook.com/v7.0/{0}?fields=created_time&", postId);
  472. FbGetPost result = new FbGetPost() { data = new List<FbGetPostdata>(), paging = new JObject() };
  473. var dicData = new Dictionary<string, string>()
  474. {
  475. { "access_token", authorizationToken }
  476. };
  477. FbGetPostdata rawResult = null;
  478. APIHelper.BaseGet(uri, null, dicData, out HttpResponseMessage responseMessage);
  479. if (responseMessage.IsSuccessStatusCode)
  480. {
  481. rawResult = JsonConvert.DeserializeObject<FbGetPostdata>(responseMessage.Content.ReadAsStringAsync().Result);
  482. }
  483. return rawResult;
  484. }
  485. /// <summary>
  486. /// 取回留言的Get
  487. /// </summary>
  488. /// <param name="authorizationToken"></param>
  489. /// <param name="message"></param>
  490. /// <param name="path">圖片路徑</param>
  491. public bool CallFbCommentGetAPI(string articleId, string authorizationToken, string postId, out List<tb_grp_comment> comments)
  492. {
  493. // 送出資料
  494. string uri = string.Format("https://graph.facebook.com/v7.0/{0}/comments?filter=stream&fields={1}&access_token={2}&limit={3}", postId, "id,created_time,from{name,id,picture},message,parent,comment_count", authorizationToken, "150");
  495. FbCommentData rawResult = null;
  496. FbCommentData result = new FbCommentData() { data = new List<data>(), paging = new JObject() };
  497. bool isOver = false;
  498. while (!isOver)
  499. {
  500. APIHelper.BaseGet(uri, null, new Dictionary<string, string>(), out HttpResponseMessage responseMessage);
  501. if (responseMessage.IsSuccessStatusCode)
  502. {
  503. var fb_error = GetFbApiError(responseMessage);
  504. if (!string.IsNullOrWhiteSpace(fb_error))
  505. {
  506. Logger.Error($"{nameof(CallFbCommentGetAPI)} FB API response error message: {fb_error} ");
  507. }
  508. rawResult = JsonConvert.DeserializeObject<FbCommentData>(responseMessage.Content.ReadAsStringAsync().Result);
  509. result.data.AddRange(rawResult.data);
  510. uri = rawResult.paging != null && rawResult.paging.ContainsKey("next") ? rawResult.paging["next"].ToString() : null;
  511. if (rawResult.data.Count == 0 || uri == null)
  512. {
  513. isOver = true;
  514. }
  515. }
  516. else
  517. {
  518. var error = $"{nameof(CallFbCommentGetAPI)} Error, ReasonPhrase:{responseMessage.ReasonPhrase} hrmResult.Headers.WwwAuthenticate:{responseMessage.Headers.WwwAuthenticate} ";
  519. Logger.Error(error);
  520. isOver = true;
  521. }
  522. }
  523. if (result.data.Count > 0)
  524. {
  525. string sMsg = GetFCommentsData(articleId, result, postId, out comments);
  526. // 儲存出錯
  527. if (sMsg != null)
  528. {
  529. comments = null;
  530. }
  531. }
  532. else
  533. {
  534. comments = null;
  535. }
  536. return true;
  537. }
  538. /// <summary>
  539. /// 延長token
  540. /// </summary>
  541. /// <param name="authorizationToken"></param>
  542. /// <param name="message"></param>
  543. /// <param name="path">圖片路徑</param>
  544. public bool CallFbLongTokenGetAPI(string authorizationToken, string client_id, string client_secret)
  545. {
  546. // 送出資料
  547. string uri = "https://graph.facebook.com/oauth/access_token?";
  548. var dicData = new Dictionary<string, string>()
  549. {
  550. { "grant_type", "fb_exchange_token" },
  551. { "client_id", client_id },
  552. { "client_secret", client_secret },
  553. { "fb_exchange_token", authorizationToken },
  554. };
  555. APIHelper.BaseGet(uri, null, dicData, out HttpResponseMessage responseMessage);
  556. if (responseMessage.IsSuccessStatusCode)
  557. {
  558. var responseData = JsonConvert.DeserializeObject<FbToken>(responseMessage.Content.ReadAsStringAsync().Result);
  559. }
  560. return responseMessage.IsSuccessStatusCode;
  561. }
  562. /// <summary>
  563. /// 驗證token, 可改用 Function FbApiCheckToken
  564. /// </summary>
  565. /// <param name="authorizationToken"></param>
  566. /// <param name="message"></param>
  567. /// <param name="path">圖片路徑</param>
  568. public string CallFbCheckTokenGetAPI(string authorizationToken, string client_id, string client_secret, out int status)
  569. {
  570. // 送出資料
  571. status = 0; // 預設0: 正常 1: 即將到期 2: 驗證失敗
  572. string uri = "https://graph.facebook.com/debug_token?";
  573. var dicData = new Dictionary<string, string>()
  574. {
  575. { "input_token", authorizationToken },
  576. { "access_token", string.Format("{0}|{1}",client_id,client_secret) },
  577. };
  578. APIHelper.BaseGet(uri, null, dicData, out HttpResponseMessage responseMessage);
  579. if (responseMessage.IsSuccessStatusCode)
  580. {
  581. var responseData = JsonConvert.DeserializeObject<FbTokenVerification>(responseMessage.Content.ReadAsStringAsync().Result);
  582. if (responseData.data.is_valid)
  583. {
  584. var timeStamp = responseData.data.expires_at - Convert.ToInt32(DateTime.UtcNow.AddHours(8).Subtract(new DateTime(1970, 1, 1)).TotalSeconds);
  585. if (timeStamp > 20 * 86400) // 20天
  586. {
  587. return null;
  588. }
  589. else
  590. {
  591. status = 1;
  592. return "Token即將到期";
  593. }
  594. }
  595. else
  596. {
  597. status = 2;
  598. return "Token驗證失敗";
  599. }
  600. }
  601. else
  602. {
  603. status = 2;
  604. return "Request失敗";
  605. }
  606. }
  607. /// <summary>
  608. /// Send FB Message
  609. /// </summary>
  610. /// <param name="messenger_id_"></param>
  611. /// <param name="message_"></param>
  612. /// <param name="access_token_"></param>
  613. /// <param name="errorHandle_"></param>
  614. /// <returns></returns>
  615. public void SendMessage(ref string messenger_id_, ref string message_, ref string access_token_, Action<HttpResponseMessage> successHandle_, Action<HttpResponseMessage, string> errorHandle_)
  616. {
  617. string url = ApiUrlHelper.SendMessage(access_token_);
  618. var dataContents = new
  619. {
  620. recipient = new { id = messenger_id_ },
  621. messaging_type = "MESSAGE_TAG",
  622. message = new { text = message_ },
  623. tag = "POST_PURCHASE_UPDATE"
  624. };
  625. SendPostFbApi(url, dataContents, successHandle_, errorHandle_);
  626. }
  627. /// <summary>
  628. ///
  629. /// </summary>
  630. /// <returns></returns>
  631. public void CheckAccessToken(ref string access_token_, Action<HttpResponseMessage> successHandle_, Action<HttpResponseMessage, string> errorHandle_)
  632. {
  633. string url = ApiUrlHelper.CheckAccessToken(access_token_);
  634. SendGetFbApi(url, successHandle_, errorHandle_);
  635. }
  636. public void GetUserAccessToken(ref string user_access_token_, ref string app_id_, ref string app_secret_, Action<HttpResponseMessage> successHandle_, Action<HttpResponseMessage, string> errorHandle_)
  637. {
  638. string url = ApiUrlHelper.GetUserAccessToken(user_access_token_, app_id_, app_secret_);
  639. SendGetFbApi(url, successHandle_, errorHandle_);
  640. }
  641. public void GetPageAccessToken(ref string user_id_, ref string long_lived_user_access_token, Action<HttpResponseMessage> successHandle_, Action<HttpResponseMessage, string> errorHandle_)
  642. {
  643. string url = ApiUrlHelper.GetPageAccessToken(user_id_, long_lived_user_access_token);
  644. SendGetFbApi(url, successHandle_, errorHandle_);
  645. }
  646. #endregion
  647. #region 專案獨有
  648. ///// <summary>
  649. ///// 貼文資料新增到SQL
  650. ///// </summary>
  651. ///// <param name="state"></param>
  652. ///// <returns></returns>
  653. private void GetFbPostData(FbGetPost fbGetPost)
  654. {
  655. ArsenalInterface ai;
  656. List<Command> lCmds = new List<Command>();
  657. // 取社團
  658. QueryJsonElementCollection lBlocks = new QueryJsonElementCollection();
  659. QueryJsonElement qjeOrigin = lBlocks.GetInst();
  660. qjeOrigin.table = tb_grp_group.TABLENAME;
  661. qjeOrigin.displaycols = new List<string>() { tb_grp_group.CN_UID, tb_grp_group.CN_FB_GROUP_ID };
  662. qjeOrigin.wherecols = new WhereNode(tb_grp_group.CN_FB_GROUP_ID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_grp_group), fbGetPost.data[0].id.Split("_")[0]);
  663. lBlocks.Add(qjeOrigin);
  664. var sMsg = MakeSelectJoinByBlocks(lBlocks, out Command cRes);
  665. ai = ArsenalDBMgr.GetInst(cRes);
  666. List<tb_grp_group> group = ai.RunQueryList<tb_grp_group>(cRes);
  667. // 取貼文資料
  668. lBlocks.Clear();
  669. QueryJsonElement qjeArticle = lBlocks.GetInst();
  670. qjeArticle.table = tb_grp_article.TABLENAME;
  671. qjeArticle.displaycols = new List<string>() { tb_grp_article.CN_UID, tb_grp_article.CN_GROUP_UID, tb_grp_article.CN_FB_ARTICLE_ID };
  672. qjeArticle.wherecols = new WhereNode(tb_grp_article.CN_GROUP_UID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_grp_article), group.First().uid);
  673. lBlocks.Add(qjeArticle);
  674. sMsg = MakeSelectJoinByBlocks(lBlocks, out Command cArt);
  675. ai = ArsenalDBMgr.GetInst(cArt);
  676. List<tb_grp_article> article = ai.RunQueryList<tb_grp_article>(cArt);
  677. // 取媒體資料
  678. lBlocks.Clear();
  679. QueryJsonElement qjeArticleMedia = lBlocks.GetInst();
  680. qjeArticleMedia.table = tb_grp_article_media.TABLENAME;
  681. qjeArticleMedia.displaycols = new List<string>() { tb_grp_article_media.CN_UID, tb_grp_article_media.CN_ARTICLE_UID, tb_grp_article_media.CN_MEDIA_ID, tb_grp_article_media.CN_URI };
  682. lBlocks.Add(qjeArticleMedia);
  683. sMsg = MakeSelectJoinByBlocks(lBlocks, out Command cMedia);
  684. ai = ArsenalDBMgr.GetInst(cMedia);
  685. List<tb_grp_article_media> lsmedia = ai.RunQueryList<tb_grp_article_media>(cMedia);
  686. fbGetPost.data.ForEach(x =>
  687. {
  688. var uid = string.Empty;
  689. // 如果貼文存在則更新 否則新增
  690. if (!article.Any(y => y.fb_article_id == x.id))
  691. {
  692. uid = Guid.NewGuid().ToString();
  693. tb_grp_article cNew = new tb_grp_article()
  694. {
  695. uid = uid,
  696. group_uid = group.First().uid,
  697. message = x.message,
  698. post_status = (int)EPostStatus.EPS_FETCH_FROM_FB,
  699. fb_article_id = x.id,
  700. release_date = x.created_time
  701. };
  702. lCmds.Add(Command.SetupInsertCmd(cNew));
  703. }
  704. else
  705. {
  706. uid = article.First(y => y.fb_article_id == x.id).uid;
  707. tb_grp_article cWhere = new tb_grp_article() { uid = uid };
  708. tb_grp_article cUpdate = new tb_grp_article()
  709. {
  710. group_uid = group.First().uid,
  711. message = x.message,
  712. post_status = (int)EPostStatus.EPS_FETCH_FROM_FB,
  713. fb_article_id = x.id,
  714. release_date = x.created_time
  715. };
  716. lCmds.Add(Command.SetupUpdateCmd(cUpdate, cWhere));
  717. }
  718. if (!lsmedia.Any(y => y.uri == x.full_picture) && x.full_picture != null)
  719. {
  720. tb_grp_article_media media = new tb_grp_article_media()
  721. {
  722. article_uid = uid,
  723. uri = x.full_picture,
  724. type = BLWording.MediaType.Photo,
  725. status_flag = (int)MediaType.GetFb
  726. };
  727. lCmds.Add(Command.SetupInsertCmd(media));
  728. }
  729. if (!lsmedia.Any(y => y.uri == x.full_picture) && x.source != null)
  730. {
  731. tb_grp_article_media media = new tb_grp_article_media()
  732. {
  733. article_uid = uid,
  734. uri = x.source,
  735. type = BLWording.MediaType.Video,
  736. status_flag = (int)MediaType.GetFb
  737. };
  738. lCmds.Add(Command.SetupInsertCmd(media));
  739. }
  740. });
  741. if (lCmds.Any())
  742. {
  743. ai = ArsenalDBMgr.GetInst(lCmds[0], GetDefaultSystemColumnInfo());
  744. ai.RunEditCmds(lCmds);
  745. sMsg = GetLastErrorCode(lCmds);
  746. }
  747. }
  748. /// <summary>
  749. /// 貼文留言存進SQL
  750. /// </summary>
  751. /// <param name="fbGetPost"></param>
  752. /// <param name="id"></param>
  753. private string GetFCommentsData(string articleId, FbCommentData fbGetPost, string post_id, out List<tb_grp_comment> comments)
  754. {
  755. // 沒有留言
  756. if (fbGetPost.data.Count == 0)
  757. {
  758. comments = null;
  759. return null;
  760. }
  761. List<Command> lCmds = new List<Command>();
  762. // 用文章 ID取文章 data
  763. var article = GetArticleByPostID(articleId);
  764. comments = new List<tb_grp_comment>();
  765. // 取回原先的留言
  766. List<tb_grp_comment> originComments = GetComments(article.uid);
  767. // 如果先前已有匯入留言,已匯入過的留言不再重複匯入
  768. List<string> existFbCommentID = originComments.Select(x => x.fb_comment_id).ToList();
  769. // 取回該社團可以取貨的地點
  770. var branches = GetBranches(article.group_uid).ToDictionary(x => x.uid, x => x.branch_name);
  771. var products = GetProducts(article.uid);
  772. // 會員預設取貨地點(中文)的對應表,沒設定取貨地點不會放進列表
  773. var memberDefaultBranchDict = GetMembers(post_id.Split('_')[0])
  774. .Where(x => !string.IsNullOrEmpty(x.default_branch) && branches.ContainsKey(x.default_branch))
  775. .ToDictionary(x => x.group_user_id, x => branches[x.default_branch]);
  776. // 將名稱以['A', 'B'...]這樣依序產生,如果產品有3個,就要放入['A', 'B', 'C']
  777. List<GroupBuyParser.ProductInfo> productInfoNames = new List<GroupBuyParser.ProductInfo>();
  778. //productInfoNames = products.Select((x, i) => new GroupBuyParser.ProductInfo
  779. //{
  780. // Name = x.name ?? "",
  781. // Specifications = string.IsNullOrEmpty(x.specification) ? null : x.specification.Split(',', StringSplitOptions.RemoveEmptyEntries)
  782. //}).ToList();
  783. var productInfos = products.Select((x, i) => new GroupBuyParser.ProductInfo
  784. {
  785. Name = ((char)('A' + x.seq)).ToString(),
  786. Specifications = string.IsNullOrEmpty(x.specification) ? null : x.specification.Split(',', StringSplitOptions.RemoveEmptyEntries).OrderByDescending(x => x.Count()).ToArray()
  787. }).ToList();
  788. //var productInfos = productInfoNames.Concat(productInfosChar).ToList();
  789. Logger.Info($"開始解析貼文 文章ID: {article.uid} 設定: {JsonConvert.SerializeObject(productInfos)}");
  790. var parser = new GroupBuyParser.GroupBuyParser
  791. {
  792. Settings = new GroupBuyParser.ParserSettings
  793. {
  794. Products = productInfos,
  795. Branches = branches.Values.ToList()
  796. }
  797. };
  798. StringBuilder parseCommentErrorLog = new StringBuilder();
  799. foreach (var item in fbGetPost.data)
  800. {
  801. // 沒有留言就不處理
  802. if (string.IsNullOrEmpty(item.message))
  803. {
  804. continue;
  805. }
  806. // 判斷已經重複的ID
  807. if (existFbCommentID.Contains(item.id))
  808. {
  809. continue;
  810. }
  811. // 判斷是否為回覆留言
  812. string parentUid = null;
  813. if (item.parent != null)
  814. {
  815. parentUid = item.parent.id;
  816. }
  817. // 如果取不回fb_id(使用者沒有允許應用程式查看貼文)仍要處理
  818. string group_user_id = item.from?.id;
  819. string json = "";
  820. int status = 0;
  821. // 傳入該會員預設取貨地點(非會員則為null)
  822. string defaultBranch = null;
  823. if (!string.IsNullOrEmpty(group_user_id) && memberDefaultBranchDict.ContainsKey(group_user_id))
  824. {
  825. defaultBranch = memberDefaultBranchDict[group_user_id];
  826. }
  827. var parseData = new GroupBuyParser.ParserData
  828. {
  829. Text = item.message,
  830. DefaultBranch = defaultBranch
  831. };
  832. parser.Parse(parseData);
  833. if (parseData.Success)
  834. {
  835. bool isProductCorrect = true;
  836. foreach (var product in parseData.Product.ToList())
  837. {
  838. if (product.Name == "I")
  839. {
  840. isProductCorrect = false;
  841. break;
  842. }
  843. }
  844. if (isProductCorrect) // 名稱有I 不Insert進資料庫
  845. {
  846. json = JsonConvert.SerializeObject(parseData.Product);
  847. status = (int)CommentStatus.OK;
  848. }
  849. else
  850. {
  851. status = (int)CommentStatus.InvalidFormat;
  852. }
  853. }
  854. else
  855. {
  856. status = (int)CommentStatus.InvalidFormat;
  857. // 增加log紀錄確認解析失敗的原因
  858. parseCommentErrorLog.AppendLine($"解析貼文失敗 姓名: {item.from?.name} 內容: {item.message} 原因: {parseData.ErrorMessage}");
  859. }
  860. if (string.IsNullOrEmpty(group_user_id))
  861. {
  862. status = (int)CommentStatus.UnknownMember;
  863. }
  864. else if (!memberDefaultBranchDict.ContainsKey(group_user_id))
  865. {
  866. status = (int)CommentStatus.UnknownMember;
  867. }
  868. else if (comments.Any(x => x.group_user_id == group_user_id)) // 是否有重複留言
  869. {
  870. status = (int)CommentStatus.Duplicate;
  871. }
  872. if (parentUid != null)
  873. {
  874. status = (int)CommentStatus.Duplicate;
  875. }
  876. tb_grp_comment cNew = new tb_grp_comment
  877. {
  878. uid = Guid.NewGuid().ToString(),
  879. article_uid = article.uid,
  880. origin_comment = item.message,
  881. comment = json,
  882. group_user_id = group_user_id,
  883. comment_time = item.created_time,
  884. fb_comment_id = item.id,
  885. status = status,
  886. user_name = item.from?.name,
  887. user_picture = item.from?.picture.data.url,
  888. parent_comment_id = parentUid == null ? null : parentUid
  889. };
  890. comments.Add(cNew);
  891. }
  892. if (parseCommentErrorLog.Length != 0)
  893. {
  894. // 參考原本寫法, 解析貼文失敗訊息標記為Info
  895. parseCommentErrorLog.Insert(0, Environment.NewLine);
  896. Logger.Info(parseCommentErrorLog.ToString());
  897. }
  898. // 沒有新增任何留言就不處理
  899. if (comments.Count == 0)
  900. {
  901. return null;
  902. }
  903. lCmds.AddRange(comments.Select(x => Command.SetupInsertCmd(x)));
  904. var ai = ArsenalDBMgr.GetInst(lCmds[0], GetDefaultSystemColumnInfo());
  905. ai.RunEditCmds(lCmds);
  906. var sMsg = GetLastErrorCode(lCmds);
  907. return sMsg;
  908. }
  909. /// <summary>
  910. /// 將留言轉成訂單(結單)
  911. /// </summary>
  912. /// <param name="article_uid"></param>
  913. public string CheckOrder(string article_uid, JArray jData)
  914. {
  915. // 貼文資料
  916. var article = GetArticle(article_uid);
  917. // 商品資料
  918. var productData = GetProducts(article_uid).OrderBy(x => x.seq).ToArray();
  919. // 貼文對應的群組UID
  920. var groupUid = article.group_uid;
  921. // 取得社團成員ID對應的UID
  922. var fb_group_id = article.fb_article_id.Split('_')[0];
  923. var memberDict = GetMembers(fb_group_id).ToDictionary(x => x.group_user_id, x => x.uid);
  924. // 分店的對應表
  925. var branchDict = GetBranches(groupUid).ToDictionary(x => x.branch_name, x => x.uid);
  926. // 取回過去的訂單主檔
  927. var IsOrderMaster = GetOrderMasters(article_uid);
  928. // 如果過去已經有結單,使用同一個order_code,反之取回新的訂單編號(這不就是article_uid嗎?)
  929. var orderCode = IsOrderMaster.Any() ? IsOrderMaster.First().order_code : GetOrderCode();
  930. var orderName = IsOrderMaster.Any() ? IsOrderMaster.First().name : article.name; // 有結單過的貼文使用舊名稱
  931. var orderMasterDic = new Dictionary<string, tb_ord_order_master>();
  932. // 再次結單屬於新的order_master
  933. // 先取回所有留言
  934. var comments = GetComments(article_uid);
  935. // 留言解析成功的才更新
  936. List<CommentModel> data = new List<CommentModel>();
  937. foreach (JToken token in jData)
  938. {
  939. Dictionary<string, object> dicData = token.ToObject<Dictionary<string, object>>();
  940. var commentData = comments.Where(x => x.status != (int)CommentStatus.TransferOrder && !string.IsNullOrEmpty(x.comment) &&
  941. x.status_flag == BLWording.STATUS_FLAG_ON && !string.IsNullOrEmpty(x.group_user_id) && x.uid == dicData["uid"].ToString()).Select(x => new
  942. {
  943. x.uid,
  944. x.group_user_id,
  945. x.comment,
  946. x.comment_time
  947. });
  948. if (commentData.Any())
  949. {
  950. CommentModel tempComment = new CommentModel()
  951. {
  952. uid = commentData.Select(x => x.uid).FirstOrDefault(),
  953. comment = commentData.Select(x => x.comment).FirstOrDefault(),
  954. group_user_id = commentData.Select(x => x.group_user_id).FirstOrDefault(),
  955. comment_time = commentData.Select(x => x.comment_time).FirstOrDefault()
  956. };
  957. data.Add(tempComment);
  958. }
  959. }
  960. if (!data.Any())
  961. {
  962. return null;
  963. }
  964. List<Command> lCmds = new List<Command>();
  965. List<tb_ord_order_detail> lOrderDetails = new List<tb_ord_order_detail>();
  966. ArsenalInterface ai = null;
  967. foreach (var item in data)
  968. {
  969. // 解析留言訂購格式,以每一項為單位塞到DB去
  970. var products = JsonConvert.DeserializeObject<IEnumerable<GroupBuyParser.ParserProduct>>(item.comment);
  971. foreach (var product in products)
  972. {
  973. // 目前暫定A = 0 B = 1...
  974. var productIndex = product.Name[0] - 'A';
  975. var productItem = productData.FirstOrDefault(x => x.seq == productIndex);
  976. if (product.Branch == "未知" || string.IsNullOrWhiteSpace(product.Branch))
  977. {
  978. break;
  979. }
  980. var branch_uid = branchDict[product.Branch];
  981. // 如果目前沒有主檔,新增主檔
  982. if (!orderMasterDic.ContainsKey(branch_uid))
  983. {
  984. // 查詢group_uid
  985. tb_grp_branch cBranch = new tb_grp_branch();
  986. cBranch.SetDirty(tb_grp_branch.CN_GROUP_UID);
  987. tb_grp_branch cCon = new tb_grp_branch() { uid = branch_uid };
  988. Command cSelect = Command.SetupSelectCmd(cBranch, cCon);
  989. ai = ArsenalDBMgr.GetInst(cSelect);
  990. tb_grp_branch qds = ai.RunQuerySingleORM<tb_grp_branch>(cSelect);
  991. var newOrderMaster = new tb_ord_order_master
  992. {
  993. uid = Guid.NewGuid().ToString(),
  994. type = 1,
  995. name = orderName,
  996. order_code = orderCode,
  997. article_uid = article_uid,
  998. branch_uid = branch_uid,
  999. group_uid = qds.group_uid,
  1000. status = (int)OrderStatus.NotArrived,
  1001. };
  1002. lCmds.Add(Command.SetupInsertCmd(newOrderMaster));
  1003. // 增加Dictionary的內容,避免內容被重複新增
  1004. orderMasterDic.Add(branch_uid, newOrderMaster);
  1005. }
  1006. if (product.Qty > 0)
  1007. {
  1008. var order = new tb_ord_order_detail
  1009. {
  1010. uid = Guid.NewGuid().ToString(),
  1011. order_uid = orderMasterDic[branch_uid].uid,
  1012. article2product_uid = productItem.uid,
  1013. member_uid = memberDict[item.group_user_id],
  1014. specification = product.Specification != "" ? product.Specification : null,
  1015. order_qty = product.Qty,
  1016. price = productItem.price * product.Qty,
  1017. comment_time = item.comment_time,
  1018. comment_uid = item.uid,
  1019. status = (int)OrderStatus.NotArrived
  1020. };
  1021. lOrderDetails.Add(order);
  1022. // 更新留言變成不顯示
  1023. tb_grp_comment updateComment = new tb_grp_comment { status = (int)CommentStatus.TransferOrder };
  1024. tb_grp_comment updateCommentCond = new tb_grp_comment { uid = item.uid };
  1025. lCmds.Add(Command.SetupUpdateCmd(updateComment, updateCommentCond));
  1026. }
  1027. }
  1028. }
  1029. if (lOrderDetails.Count == 0)
  1030. {
  1031. return "結單錯誤(請確認訂單資訊)";
  1032. }
  1033. if (article.post_status < 64)
  1034. {
  1035. tb_grp_article updateArticle = new tb_grp_article { post_status = (int)EPostStatus.EPS_ORDER };
  1036. tb_grp_article updateArticleCond = new tb_grp_article { uid = article_uid };
  1037. lCmds.Add(Command.SetupUpdateCmd(updateArticle, updateArticleCond));
  1038. }
  1039. lCmds.AddRange(lOrderDetails.Select(x => Command.SetupInsertCmd(x)));
  1040. ai = ArsenalDBMgr.GetInst(lCmds[0], GetDefaultSystemColumnInfo());
  1041. ai.RunEditCmds(lCmds);
  1042. var sMsg = GetLastErrorCode(lCmds);
  1043. return sMsg;
  1044. }
  1045. private List<tb_ord_order_master> GetOrderMasters(string article_uid)
  1046. {
  1047. tb_ord_order_master cDisplay = new tb_ord_order_master();
  1048. cDisplay.SetFullDirty();
  1049. var whereNode = new WhereNode(tb_ord_order_master.CN_ARTICLE_UID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_ord_order_master), article_uid);
  1050. var cSelect = Command.SetupSelectCmd(cDisplay, whereNode);
  1051. var ai = ArsenalDBMgr.GetInst(cSelect);
  1052. var data = ai.RunQueryList<tb_ord_order_master>(cSelect);
  1053. return data;
  1054. }
  1055. /// <summary>
  1056. /// 用文章FB ID取回貼文部分資訊
  1057. /// </summary>
  1058. /// <param name="post_id"></param>
  1059. /// <returns></returns>
  1060. private static tb_grp_article GetArticleByPostID(string articleId)
  1061. {
  1062. QueryJsonElementCollection lBlocks = new QueryJsonElementCollection();
  1063. QueryJsonElement qjeOrigin = lBlocks.GetInst();
  1064. qjeOrigin.table = tb_grp_article.TABLENAME;
  1065. qjeOrigin.displaycols = new List<string>() { tb_grp_article.CN_UID, tb_grp_article.CN_FB_ARTICLE_ID, tb_grp_article.CN_GROUP_UID };
  1066. qjeOrigin.wherecols = new WhereNode(tb_grp_article.CN_UID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_grp_article), articleId);
  1067. lBlocks.Add(qjeOrigin);
  1068. string sMsg = MakeSelectJoinByBlocks(lBlocks, out Command cRes);
  1069. var ai = ArsenalDBMgr.GetInst(cRes);
  1070. var articles = ai.RunQueryList<tb_grp_article>(cRes);
  1071. return articles.First();
  1072. }
  1073. /// <summary>
  1074. /// 用文章UID取回貼文部分資訊
  1075. /// </summary>
  1076. /// <param name="article_uid"></param>
  1077. /// <returns></returns>
  1078. private tb_grp_article GetArticle(string article_uid)
  1079. {
  1080. QueryJsonElementCollection lBlocks = new QueryJsonElementCollection();
  1081. QueryJsonElement qjeOrigin = lBlocks.GetInst();
  1082. qjeOrigin.table = tb_grp_article.TABLENAME;
  1083. qjeOrigin.displaycols = new List<string>
  1084. {
  1085. tb_grp_article.CN_GROUP_UID,
  1086. tb_grp_article.CN_FB_ARTICLE_ID,
  1087. tb_grp_article.CN_POST_STATUS,
  1088. tb_grp_article.CN_NAME
  1089. };
  1090. qjeOrigin.wherecols = new WhereNode(tb_grp_article.CN_UID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_grp_article), article_uid);
  1091. lBlocks.Add(qjeOrigin);
  1092. string sMsg = MakeSelectJoinByBlocks(lBlocks, out Command cRes);
  1093. var ai = ArsenalDBMgr.GetInst(cRes);
  1094. var articles = ai.RunQueryList<tb_grp_article>(cRes);
  1095. return articles.First();
  1096. }
  1097. /// <summary>
  1098. /// 用文章UID取回原先的留言
  1099. /// </summary>
  1100. /// <param name="article_uid"></param>
  1101. /// <returns></returns>
  1102. private List<tb_grp_comment> GetComments(string article_uid)
  1103. {
  1104. tb_grp_comment cDisplay = new tb_grp_comment();
  1105. cDisplay.SetFullDirty();
  1106. var whereNode = new WhereNode(tb_grp_comment.CN_ARTICLE_UID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_grp_comment), article_uid);
  1107. var cSelect = Command.SetupSelectCmd(cDisplay, whereNode);
  1108. var ai = ArsenalDBMgr.GetInst(cSelect);
  1109. var originComments = ai.RunQueryList<tb_grp_comment>(cSelect);
  1110. return originComments;
  1111. }
  1112. /// <summary>
  1113. /// 用社團UID取回取貨地點
  1114. /// </summary>
  1115. /// <param name="group_uid"></param>
  1116. /// <returns></returns>
  1117. private List<tb_grp_branch> GetBranches(string group_uid)
  1118. {
  1119. tb_grp_branch cDisplay = new tb_grp_branch();
  1120. cDisplay.SetFullDirty();
  1121. var whereNode = new WhereNode(tb_grp_branch.CN_GROUP_UID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_grp_branch), group_uid);
  1122. var cSelect = Command.SetupSelectCmd(cDisplay, whereNode);
  1123. var ai = ArsenalDBMgr.GetInst(cSelect);
  1124. var data = ai.RunQueryList<tb_grp_branch>(cSelect);
  1125. return data;
  1126. }
  1127. /// <summary>
  1128. /// 用貼文UID取回該貼文所有商品的部分資訊
  1129. /// </summary>
  1130. /// <param name="article_uid"></param>
  1131. /// <returns></returns>
  1132. private List<tb_prd_article2product> GetProducts(string article_uid)
  1133. {
  1134. /**開始組指令**/
  1135. QueryJsonElementCollection lBlocks = new QueryJsonElementCollection();
  1136. QueryJsonElement qjeArticleToProduct = lBlocks.GetInst();
  1137. qjeArticleToProduct.table = tb_prd_article2product.TABLENAME;
  1138. qjeArticleToProduct.displaycols = new List<string>()
  1139. {
  1140. tb_prd_article2product.CN_UID,
  1141. tb_prd_article2product.CN_NAME,
  1142. tb_prd_article2product.CN_PRICE,
  1143. tb_prd_article2product.CN_SEQ,
  1144. tb_prd_article2product.CN_SPECIFICATION
  1145. };
  1146. qjeArticleToProduct.wherecols = new WhereNode(tb_prd_article2product.CN_ARTICLE_UID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_prd_article2product), article_uid);
  1147. lBlocks.Add(qjeArticleToProduct);
  1148. QueryJsonElement qjeProduct = lBlocks.GetInst();
  1149. qjeProduct.table = tb_prd_product.TABLENAME;
  1150. qjeProduct.jointable = qjeArticleToProduct;
  1151. qjeProduct.joincols = new Dictionary<string, string>()
  1152. {
  1153. { tb_prd_product.CN_UID, tb_prd_article2product.CN_PRD_UID }
  1154. };
  1155. lBlocks.Add(qjeProduct);
  1156. var sMsg = MakeSelectJoinByBlocks(lBlocks, out Command cRes);
  1157. var ai = ArsenalDBMgr.GetInst(cRes);
  1158. List<tb_prd_article2product> data = ai.RunQueryList<tb_prd_article2product>(cRes);
  1159. return data.ToList();
  1160. }
  1161. /// <summary>
  1162. /// 用FB社團ID取回所有使用者資訊
  1163. /// </summary>
  1164. /// <param name="group_id"></param>
  1165. /// <returns></returns>
  1166. private List<tb_meb_member> GetMembers(string group_id)
  1167. {
  1168. tb_meb_member tDisplay = new tb_meb_member();
  1169. tDisplay.SetFullDirty();
  1170. List<WhereNode> lwWhereData = new List<WhereNode>();
  1171. lwWhereData.Add(new WhereNode(tb_meb_member.CN_GROUP_ID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_meb_member), group_id));
  1172. lwWhereData.Add(new WhereNode(tb_meb_member.CN_NAME, WhereNode.EColumnOperation.EOT_NEQ, typeof(tb_meb_member), "現貨銷售"));
  1173. Command cSelect = Command.SetupSelectCmd(tDisplay, new WhereNode(WhereNode.ENodeOperation.ENO_AND, lwWhereData.ToArray()));
  1174. ArsenalInterface ai = ArsenalDBMgr.GetInst(cSelect);
  1175. List<tb_meb_member> members = ai.RunQueryList<tb_meb_member>(cSelect);
  1176. return members;
  1177. }
  1178. /// <summary>
  1179. /// 取得目前的訂單號碼
  1180. /// </summary>
  1181. /// <param name="post_id"></param>
  1182. /// <returns></returns>
  1183. public string GetOrderCode()
  1184. {
  1185. string dateString = DateTime.Now.ToString("yyMMdd");
  1186. QueryJsonElementCollection lBlocks = new QueryJsonElementCollection();
  1187. QueryJsonElement qjeOrigin = lBlocks.GetInst();
  1188. qjeOrigin.table = tb_ord_order_master.TABLENAME;
  1189. qjeOrigin.displaycols = new List<string>() { tb_ord_order_master.CN_ORDER_CODE };
  1190. qjeOrigin.wherecols = new WhereNode(tb_ord_order_master.CN_ORDER_CODE, WhereNode.EColumnOperation.EOT_LIKE, typeof(tb_ord_order_master), dateString + "%");
  1191. lBlocks.Add(qjeOrigin);
  1192. string sMsg = MakeSelectJoinByBlocks(lBlocks, out Command cRes);
  1193. var ai = ArsenalDBMgr.GetInst(cRes);
  1194. var orders = ai.RunQueryList<tb_ord_order_master>(cRes);
  1195. // 兩碼流水號,例如20082801 = 2020/8/28 第一批訂單
  1196. var lastOrderNo = orders.Select(x => x.order_code).OrderByDescending(x => x).FirstOrDefault();
  1197. int newIndex = 1;
  1198. if (!string.IsNullOrEmpty(lastOrderNo))
  1199. {
  1200. newIndex = int.Parse(lastOrderNo.Substring(6, 2)) + 1;
  1201. }
  1202. return dateString + newIndex.ToString("00");
  1203. }
  1204. #endregion
  1205. private void SendGetFbApi(string url, Action<HttpResponseMessage> successHandle_, Action<HttpResponseMessage, string> errorHandle_)
  1206. {
  1207. APIHelper.BaseGet(url, null, new Dictionary<string, string>(), out HttpResponseMessage responseMessage);
  1208. FbApiResponseHandler(responseMessage, successHandle_, errorHandle_);
  1209. }
  1210. private void SendPostFbApi(string url, dynamic postContent, Action<HttpResponseMessage> successHandle_, Action<HttpResponseMessage, string> errorHandle_)
  1211. {
  1212. APIHelper.BasePost(url, null, postContent, out HttpResponseMessage responseMessage, "json");
  1213. FbApiResponseHandler(responseMessage, successHandle_, errorHandle_);
  1214. }
  1215. /// <summary>
  1216. /// If FB API response SUCCESS return true, else you can defined your error handle function like write log
  1217. /// </summary>
  1218. /// <param name="httpResponseMessage_"></param>
  1219. /// <param name="errorHandle_"></param>
  1220. /// <returns></returns>
  1221. private void FbApiResponseHandler(HttpResponseMessage httpResponseMessage_, Action<HttpResponseMessage> successHandle_, Action<HttpResponseMessage, string> errorHandle_)
  1222. {
  1223. // check response header
  1224. if (!httpResponseMessage_.IsSuccessStatusCode)
  1225. {
  1226. var headerError = $"{httpResponseMessage_.ReasonPhrase}, {httpResponseMessage_.Headers.WwwAuthenticate}";
  1227. errorHandle_(httpResponseMessage_, headerError);
  1228. return;
  1229. }
  1230. // check response content
  1231. var bodyError = GetFbApiError(httpResponseMessage_);
  1232. if (!string.IsNullOrWhiteSpace(bodyError))
  1233. {
  1234. errorHandle_(httpResponseMessage_, bodyError);
  1235. return;
  1236. }
  1237. successHandle_(httpResponseMessage_);
  1238. }
  1239. /// <summary>
  1240. /// 檢查Response code 200後, FB回傳的內容是否包含錯誤訊息
  1241. /// </summary>
  1242. /// <param name="httpMessage_"></param>
  1243. /// <returns></returns>
  1244. public static string GetFbApiError(HttpResponseMessage httpMessage_)
  1245. {
  1246. var sContent = httpMessage_.Content.ReadAsStringAsync().Result;
  1247. var jsonObject = JObject.Parse(sContent);
  1248. if (jsonObject["error"] != null)
  1249. {
  1250. return jsonObject["error"].ToString();
  1251. }
  1252. return "";
  1253. }
  1254. }
  1255. }